Cobre: contas sociais ligadas (+ activar/desactivar), schedules de auto-post e Share Now, logs de publicacao, resumo de falhas por plataforma, analytics, estado da licenca Pro. 12 tools, testado ponta-a-ponta em producao 19-08-2026. references/data-model.md com o schema completo wpah_bit_social_* e references/diagnostics.md com o playbook de investigacao de falhas (inclui o caso real recorrente do Pinterest sem imagem).
5.6 KiB
BitSocial — modelo de dados (confirmado em produção, 2026-08-19)
Prefixo real de tabela em descomplicar.pt: wpah_ (WP table prefix) + bit_social_ (Config::VAR_PREFIX).
Todas as tabelas usam Schema::withPrefix(...), timestamps() standard (created_at/updated_at).
Tabelas
wpah_bit_social_accounts (4 linhas)
| Coluna | Tipo | Notas |
|---|---|---|
id |
bigint PK | |
custom_app_id |
bigint, nullable, FK → custom_apps.id |
null quando usa a app proxy da BitApps |
profile_id |
string | ID do perfil/utilizador na plataforma |
account_id |
string | ID da conta/página na plataforma (ex.: Facebook page id) |
account_name |
string | |
details |
longtext (JSON) | NUNCA seleccionar — contém access_token OAuth em claro, icon, category, etc. |
platform |
string | facebook, linkedin, pinterest, tumblr, instagram, twitter, discord, threads, tiktok, bluesky, telegram, googleBusinessProfile, … |
account_type |
int | Account::accountType: DEFAULT=1 (app proxy BitApps), CUSTOM=2 (app própria), AI_PLATFORM=3 |
status |
int (bool) | 1 activo, 0 inactivo |
wpah_bit_social_custom_apps (1 linha)
| Coluna | Tipo | Notas |
|---|---|---|
id |
bigint PK | |
name |
string | |
platform |
string | |
credential |
longtext | NUNCA seleccionar — segredo de app cifrado (base64 de payload AES) |
status |
int (bool) |
wpah_bit_social_schedules (175 linhas)
Cobre dois fluxos diferentes na mesma tabela, distinguidos por schedule_type:
| Coluna | Tipo | Notas |
|---|---|---|
id |
bigint PK | |
name |
string | Ex.: "Auto Post - Post ID: 60261" (auto-post) |
config |
longtext (JSON) | Ver forma abaixo. Coluna aninhada — precisa de segundo JSON.parse no lado do cliente. |
published_post_ids |
longtext (JSON, array de ints) | Posts já publicados por este schedule |
repeat_schedule |
bool | |
schedule_type |
int | Schedule::scheduleType: SCHEDULE_SHARE=1 (auto-post recorrente/agendado), DIRECT_SHARE=2 ("Share Now") |
status |
int | Schedule::status: INACTIVE=0, ACTIVE=1, COMPLETED=2, DRAFT=3, MISSED=4 |
cron_status |
int | INACTIVE=0, ACTIVE=1 |
started_at, ended_at, last_published_at, next_published_at |
timestamp, nullable |
Forma real de config (exemplo de um schedule de auto-post):
{
"settings": { "started_at": "2026-08-11 11:50:34" },
"post_filters": { "post_type": "post", "specific_postIds": [60261] },
"accounts": { "accountIds": [1, 4, 5, 6], "groupIds": [] },
"templates": {
"facebook": { "postingType": "isFeaturedImage", "content": "{post_title}", "trimMessage": false },
"pinterest": { "postingType": "isLinkCard", "content": "{post_title}", "trimMessage": true, "isLinkCard": false },
"...": "uma entrada por plataforma, mesma forma que bit_social_templates_settings"
}
}
wpah_bit_social_logs (1825 linhas)
Uma linha por tentativa de publicação (schedule × plataforma).
| Coluna | Tipo | Notas |
|---|---|---|
id |
bigint PK | |
schedule_id |
bigint, nullable, FK → schedules.id |
|
details |
longtext (JSON) | Ver forma abaixo |
platform |
string | |
status |
int (bool) | 1 sucesso, 0 falha — confirmado em AnalyticsController::index (Log::where('status', true)) |
Forma de details em sucesso:
{
"account_id": "164743196715367",
"account_name": "Descomplicar - Agência de Aceleração Digital",
"response": { "id": "164743196715367_122245726064096762", "post_supports_client_mutation_id": true },
"post_id": 60261,
"post_url": "https://fb.com/164743196715367_122245726064096762"
}
Forma de details em falha (o caso real mais comum, Pinterest):
{
"account_id": "1051238806710440771",
"account_name": "Blog Descomplicar",
"post_id": 60261,
"response": { "status": "error", "error_msg": "Must have image for create pin in Pinterest." },
"post_url": null
}
O erro está sempre em details.response.error_msg nos casos observados; extractErrorMessage()
no MCP também tenta response.message, error, message como fallback para plataformas com
forma diferente.
wpah_bit_social_groups / wpah_bit_social_groups_accounts (Pro, 0 linhas em produção)
groups: id, name, status. groups_accounts: pivot group_id × account_id, cascade on
delete. Um grupo pode substituir uma lista explícita de accountIds num config.accounts.groupIds.
wp_options relevantes
| Chave | Conteúdo |
|---|---|
bit_social_version / bit_social_pro_version |
string, ex. "1.16.0" |
bit_social_db_version / bit_social_pro_db_version |
string |
bit_social_installed / bit_social_pro_installed |
bool |
bit_social_auto_post_settings |
{isEnabled, keepLogs, taxonomies[], accounts:{accountIds[],groupIds[]}, postType[], postDelay:{every,unit}} |
bit_social_templates_settings |
um objecto por plataforma, mesma forma que config.templates num schedule |
bit_social_pro_settings |
{cron:{isExternalCronEnabled}} |
bit_social_pro_license_data |
{key, status, expireIn} — key nunca deve ser devolvida sem máscara |
bit_social_secret_key |
segredo interno do plugin — nunca ler/expor |
Análogo AnalyticsController (referência, não reimplementação 1:1)
AnalyticsController::index só calcula active_account_count, published_post_count (logs com
status=true) e active_schedule_count. bs_get_analytics estende com failed_post_count
(logs com status=0) porque o controller original omite essa contagem apesar de ser a métrica
mais accionável.