diff --git a/docs/changelog/2026-09-24-s37.md b/docs/changelog/2026-09-24-s37.md new file mode 100644 index 00000000..8ac2b958 --- /dev/null +++ b/docs/changelog/2026-09-24-s37.md @@ -0,0 +1 @@ +**S37 — Central de Conteúdos: quem aparece na peça e a faceta pública "Lideranças" (2026-09-24):** a ficha C211 ganha, entre Temas e Cidade, o bloco "Quem aparece na peça" com os dois recortes: `leaders` (relationship hasMany → `leadership`) com snapshot readOnly `leaderNames` (só o nome de exibição, derivado no `beforeValidate`) e `publicFigures` (text hasMany, texto curado canonicalizado contra o catálogo novo `src/lib/publicFigureCatalog.ts`, derivado do roster S30 das 53 dobradinhas + personalidades por texto livre). A busca de liderança do picker é um server action gated (`canReadCommunicationCatalog`) com projeção fixa `{id, label}` — único bypass intencional documentado (o RBAC atual nega o `communicator`, que é quem edita a ficha) e os int tests asseguram o shape. O catálogo público (S27) ganha a faceta única `Lideranças` unindo os dois recortes numa opção por nome de exibição (`slugify`), derivada SÓ de peças publicadas (fail-closed: despublicar remove o nome na hora); o nome entra no `searchText` (busca por termo) e lidera o `metaLabel` do card, com título contextual e chip ativo ao lado no desktop. Migration aditiva `20260924_123940_add_content_piece_people` (tabelas `content_piece_texts`/`content_piece_rels`, sem backfill, sem `ALTER TYPE`; `content_piece_curated_fields` intocado — o job nunca escreve os campos novos). Zero Consent/collection novos; o read público nunca seleciona `leaders` (depth 1 vazaria Contact). Verificação: `pnpm gate:fast` verde (lint + typecheck + unit) e `pnpm test:int` full verde (941 passed, 2 skipped); e2e local `frontendConteudos` 8/8 e `campaignSpeechAcervo` (bloco C211) 31/31; design certificado PARIDADE pelo `designer` (crítica final contra o app renderizado, cenas 01/01A/02/03). diff --git a/docs/plans/central-conteudos-liderancas-impl.md b/docs/plans/central-conteudos-liderancas-impl.md new file mode 100644 index 00000000..8ac46e51 --- /dev/null +++ b/docs/plans/central-conteudos-liderancas-impl.md @@ -0,0 +1,251 @@ +# Impl: S37 — Central de Conteúdos — lideranças que aparecem nas peças (propriedade e filtro) + +Status: aprovado (modo `--auto`) — hard-stops de schema/URL público pendentes de aprovação humana explícita +Atualizado em: 2026-09-24 +Issue: #1303 +Intenção: docs/plans/central-conteudos-liderancas.md +Design UI (gate): docs/plans/central-conteudos-liderancas-ui-design.html +Appetite restante: herdado (~2 dias eng) — **uma propriedade nova na ficha (C211) + uma faceta nova no catálogo (S27)**, sem fluxo novo. Corte explícito para caber: catalogação automática intocada (sem sugestão de nomes), sem filtro/coluna na lista interna, sem e2e de browser do picker (unit de componente + int + e2e público cobrem), personalidades por texto livre (a semente do catálogo é o roster S30). + +> Aprovado pelo próprio agente via `--auto` (modo autônomo do `work-issue`); a pausa do GATE virou apresentação-no-chat. Os hard-stops abaixo seguem exigindo aprovação humana explícita — `--auto` aprova o plano, não o schema nem o contrato público. + +## Leitura da intenção + +- **Outcome:** a ficha da peça registra dois recortes de "quem aparece" — lideranças da campanha (registros existentes) e figuras públicas (texto curado com catálogo) — e o catálogo público ganha **uma** faceta `Lideranças` que une os dois, mostrando só nomes de quem aparece em peça publicada (fail-closed); o nome entra na busca por termo e ninguém vê contato, território, status ou votos. +- **O que NÃO negociar:** + - Fail-closed de exposição: a faceta deriva **só** de peças publicadas; despublicar a última peça com um nome remove o nome na hora (tag `contentPieces` já busta em todo write). + - Nada de dado interno: sem telefone, e-mail, municípios, organizações, `supportStatus`, `estimatedVotes`; leader lockdown e `Consent`/LGPD intocados. + - Sem cadastro paralelo de pessoa: liderança = registro existente (`leadership` → `contact`); figura pública = texto + catálogo (molde `institution`). + - Uma faceta só (decisão literal do humano: "Os dois"); curadoria humana manda — nada de a catalogação sobrescrever/decidir por gente. + - Nomes só de exibição: sem contagem, ranking, página por pessoa. +- **O que reavaliar (hipóteses da "Direção no codebase"):** + - "A catalogação sugere" — **não no v1**: menção no transcript ≠ aparição na peça; sugerir nomes por match textual poluiria uma lista pública (D5 rejeita A/C e mantém `contentPieceCataloging.ts` intocado). + - "A faceta pública deriva das peças" — confirmado, mas a denormalização precisa **morar na peça**: o read público (`contentPieceReads.ts:26-43`) tem `select` explícito e não pode ganhar a relação (depth 1 vazaria `Contact`). Entra um snapshot de **nomes** na própria peça (D1/D3). + - "A ficha marca a liderança existente" — o access real nega `communicator` (`canReadLeadership` → `resolveProfileScopedRead`, `src/utilities/access/leaderships.ts:31-32`), que é justamente quem edita a ficha; sem um caminho gated a persona principal fica cega (D1). + - "Figuras públicas no molde de Instituição" — o molde é **texto + catálogo**, sem relação com `stateDeputy`; a semente vem do `stateDeputyCatalog` (S30) para não duplicar as 53 linhas (D2). + +## Abordagem recomendada + +```mermaid +flowchart LR + FICHA["/campanha/comunicacao/conteudos/[id]\nContentPieceForm · 'Quem aparece na peça'"] --> LP["Lideranças da campanha\nbusca async (server action gated)\nprojeção {id, nome}"] + FICHA --> FP["Figuras públicas\ncatálogo S30 + texto livre\ncanonicaliza grafia"] + LP --> REL["contentPiece.leaders (relationship hasMany)"] + FP --> TXT["contentPiece.publicFigures (text hasMany)"] + REL --> HOOK["beforeValidate\nsnapshot leaderNames (só nomes) + searchText"] + TXT --> HOOK + HOOK --> PUB["publish (kill switch)\nrevalidateTag contentPieces"] + PUB --> READS["contentPieceReads select explícito\nleaderNames + publicFigures\nNUNCA leaders/Contact"] + READS --> VM["toContentPiecePublicItem\npeople + metaLabel"] + VM --> FACET["faceta única 'lideranca'\nunião por slugify(nome)"] + VM --> SEARCH["searchText normalizado\nq acha pelo nome"] + FACET --> BOARD["/conteudos?lideranca=…"] + PUB -. "despublica a última peça do nome" .-> FACET +``` + +**Opções consideradas (abordagem geral):** A) relationship `leaders` + snapshot público de nomes na peça + busca interna gated com projeção mínima + figuras em texto/catálogo derivado do S30 + faceta única derivada dos nomes publicados; B) tudo texto livre na peça (liderança e figura), sem vínculo nem catálogo; C) relação direta com `stateDeputy` para as figuras e liberar `canReadLeadership` para a comunicação. +**Recomendação:** **A** — preserva o dono de cada mecanismo (registro de Liderança, roster S30, contrato público do S27, hook de denormalização do C211), mantém a fronteira público→interno intacta (o read público nunca toca `leadership`/`contact`) e cabe no appetite sem collection nova. +**Rejeitadas:** **B** porque perde o vínculo com o registro existente e o casamento de grafias (Q3-B/C do planejamento já rejeitadas); **C** porque a relação com `stateDeputy` só cobre as dobradinhas (exclui personalidades), carrega access/PII de campanha para o read público e ampliar o RBAC da liderança inteira por um picker de nomes é blast radius desproporcional (D1). + +### D1 — Referência interna à liderança e o access do `communicator` (caro) + +**Opções:** A) campo `leaders` (relationship hasMany → `leadership`) + snapshot readOnly `leaderNames` derivado por hook + loader de busca **gated com bypass intencional e documentado**, projeção fixa `{id, nome}`; B) só texto de nomes (`leaderNames` texto livre), sem relação; C) relação com busca via `overrideAccess: false` e picker restrito a coordinator/candidate; D) ampliar `canReadLeadership` para incluir `communicator`. +**Recomendação:** **A** — o campo relacional é o registro existente (anti-cadastro-paralelo) e o snapshot resolve a fronteira pública sem join. A busca interna é a **única** leitura nova: novo `src/utilities/content/contentPieceLeaderOptions.ts` (server-only) com + +- `searchContentPieceLeaderOptions(payload, actor, query)` e `resolveContentPieceLeaderOptions(payload, actor, ids)` → `{ id: number; label: string }[]`; +- gate `canReadCommunicationCatalog(actor.role)` (`src/lib/campaignRoles.ts:27-28`) fail-closed (negado devolve `[]`/lança conforme o caller); +- `isContactSearchQueryReady` (mín. 2 chars, `src/lib/contactSearchQuery.ts:9`) e teto `CONTENT_PIECE_LEADER_SEARCH_LIMIT = 20`; +- query `payload.find({ collection: 'leadership', where: { 'contact.name': { contains: trimmed } }, depth: 1, select: { contact: true }, overrideAccess: true })` com **comentário de bypass intencional** ("só o nome de exibição sai deste módulo; nenhum outro campo de `leadership`/`Contact` é lido, retornado, logado ou serializado") — mesmo precedente de bypass documentado da geografia (`ContentPiece.ts:175-178`), não uma concessão de RBAC; +- o mapeamento devolve somente `{ id, label }`; ids sem nome resolvido são descartados. + O snapshot `leaderNames` é derivado no `beforeValidate` (`deriveContentPieceCatalogIndex`, `ContentPiece.ts:147-196`) **só quando `data.leaders !== undefined`** (`relationshipId` normalizado, ordem preservada; nomes em falta são pulados) e reusa o mesmo módulo com bypass documentado (contexto de sistema). O hook não marca os campos como curados (D5). + **Rejeitadas:** **B** porque "marcar a liderança" vira texto sem lastro no dono e não distingue "liderança que existe" de "nome digitado"; **C** porque bloqueia a persona que edita a ficha (o `communicator` é quem opera a Central, `requireCampaignPageActor({ gate: 'communicationCatalog' })` + `canReadContentPiece`) — contraria o outcome; **D** porque concede a leitura inteira de `leadership` (municípios, `supportStatus`, `user`, `consent`, PII de `Contact` via depth) para a comunicação por causa de um picker, mexe no dono do RBAC e amplia a superfície de vazamento sem necessidade. + +### D2 — Recorte de figuras públicas: storage e catálogo/semente (caro) + +**Opções:** A) `publicFigures` (`text hasMany`, valores canônicos/curtos) + catálogo estático novo `src/lib/publicFigureCatalog.ts` **derivado** do `stateDeputyCatalog` (S30) + lista explícita (vazia no v1) de personalidades, com canonicalização de grafia no save; B) um único `text` (molde `institution` literal); C) `relationship hasMany` → `stateDeputy`; D) texto livre sem catálogo. +**Recomendação:** **A** — a peça costuma ter mais de uma pessoa (dobradinha + personalidade) e o design desenha chips com lista sugerida ("Digite ou escolha uma figura pública…"). O catálogo: + +- `PublicFigureKind = 'dobradinha' | 'personalidade'`; entradas `{ slug, name, kind }`; +- `publicFigureCatalog = stateDeputyCatalog.map(...)` com `slug: 'estadual-'` (prefixo evita colisão com personalidades; as 53 linhas **não** são copiadas — o roster S30 é o dono) `+ PUBLIC_FIGURE_PERSONALITIES` (constante explícita, **vazia no v1**: inventar nomes seria dado de produto sem lastro; "outras personalidades" entram por texto livre e viram data edit quando valer catalogar); +- `filterPublicFigures(query)` para o picker (accent/case-insensitive sobre `name`/`slug`, como `filterStateDeputyCards`, `src/lib/stateDeputyCatalog.ts:115-122`); +- `resolvePublicFigureName(value)` — fold accent/case/pontuação com `normalizeSearchPhrase` (`src/lib/wordStartFilter.ts:1-8`) sobre `slug`+`name`; ambíguo → `null`; +- `normalizeContentPiecePublicFigures(values)` — trim, `resolvePublicFigureName(v) ?? v`, dedupe por forma normalizada, teto `CONTENT_PIECE_PUBLIC_FIGURES_MAX`. + A canonicalização roda na action (`updateContentPieceForActor`) **e** no hook (gravações diretas/admin passam pelo mesmo filtro), reusando `normalizeForSearch`/`slugify` do contrato. + **Rejeitadas:** **B** porque força protocolo de separador e transforma os chips em uma string (a faceta e os chips precisam de itens); **C** porque só cobre as dobradinhas (personalidades ficariam de fora), traria o access de `stateDeputy` para o caminho público e criaria duas fontes para "figura pública" (roster + catálogo); **D** porque perde o casamento de grafias (Q3-C já rejeitada no planejamento). + +### D3 — A faceta pública une os dois recortes sem ler `leadership`/`Contact` (caro) + +**Opções:** A) uma faceta `lideranca` (param slug, pt-BR, como `instituicao`) derivada em memória da união `leaderNames ∪ publicFigures` **dos itens publicados**, chave `slugify(nome)`, label = nome exibido; B) duas facetas (`lideranca` + `figuras`); C) chave por id/slug de origem. +**Recomendação:** **A** — o read público seleciona somente `leaderNames`/`publicFigures` da própria peça (`contentPieceReads.ts`, `select` explícito; **nunca** `leaders`), então a faceta só existe a partir do que está publicado (fail-closed por construção, sem query de publicação extra). A união vive no contrato puro `src/lib/contentPieceCatalog.ts` (`contentPiecePublicPeople(item)` → `{ slug, name }[]`, dedup por `slugify`), consumida por `contentPieceCatalogFacets` e por `filterContentPieceCatalogItems` (AND com as demais facetas, como hoje). Homônimos colapsam no mesmo filtro por design: a faceta é um filtro de **nome de exibição**, não de identidade — documentado no código e pinado em unit (o mesmo `slug` para "Dra. Elaine"/"Dra Elaine" vira uma opção só; o label vence o último item na ordem estável). +**Rejeitadas:** **B** porque contraria o literal do humano ("Os dois" na mesma faceta) e duplicaria a superfície de filtro; **C** porque ids de liderança vazariam identidade interna na URL pública, não existem para figuras e quebrariam o contrato de slug do S27. +Extras de UI cobertos pelo design (cena 03): caption "Em peças publicadas" dentro do dropdown da faceta `Lideranças` e placeholder da busca "…assunto, cidade ou **pessoa**…". + +### D4 — Nome na busca e no card público (caro) + +**Opções:** A) nomes entram no `searchText` (type + chamada) e o `metaLabel` do card lidera com o primeiro nome; B) nomes só na faceta, fora da busca/card; C) linha própria de "quem aparece" no card e/ou na página da peça. +**Recomendação:** **A** — o aceite é explícito ("buscar o nome de quem aparece acha a peça") e o design desenha o nome na linha de metadados do card ("Nome da liderança · Tema"). Mudanças: `contentPieceSearchText` (`src/lib/contentPiece.ts:323-336`) ganha `leaderNames`/`publicFigures` no input (normalizados) com o call site atualizado (`ContentPiece.ts:187-194`, com fallback `originalDoc` como cidade/região); `metaLabel` (`contentPieceCatalog.ts:524-526`) passa a `[primeiroNome, tema/institution, local]` — card **sem** pessoa permanece byte-idêntico (os pins do S27/S28 seguem). A página da peça **não** ganha linha nova no v1 (o artefato cena 04 do S27 não a cobre) — vira extensão de design se o gate quiser. +**Rejeitadas:** **B** porque contraria o aceite; **C** porque é markup sem design (gap com trigger (a), não invenção do implementador). + +### D5 — Colisão com a regra `curated` da catalogação automática (caro) + +**Opções:** A) acrescentar `leaders` e `publicFigures` ao enum persistido `content_piece_curated_fields`; B) **não** acrescentar — o vocabulário continua exatamente os campos que o job pode preencher, e a action não marca os novos; C) acrescentar só `publicFigures` "para o futuro sugeridor". +**Recomendação:** **B** — `curatedFields` existe para arbitrar job×curadoria (`contentPieceJob.ts` só escreve campo fora da lista); como o job **nunca** escreve os campos novos (nomes são curadoria manual; menção ≠ aparição), incluí-los seria vocabulário morto e obrigaria um `ALTER TYPE enum_content_piece_curated_fields` sem consumidor. `contentPieceCataloging.ts` e `content_piece_curated_fields` ficam **intocados**. +**Rejeitadas:** **A** e **C** porque criam estado/enum sem escritor (a "sugestão" da intenção é permissiva, não requisito); **gatilho:** se um sugeridor de figuras for aprovado, o item dele adiciona o valor do enum na própria migration, junto do matcher. + +### D6 — UI dos dois pickers sem a 4ª cópia do listbox (barato de reverter, mas forma) + +**Opções:** A) um componente de domínio `ContentPiecePeopleField` (chips + painel inline) sobre os primitivos `Command`/`CommandInput`/`CommandList`/`CommandItem` (`src/components/ui/Command.tsx`) com dois usos — liderança async e figura local+texto livre; B) 4ª cópia do listbox inline de `StateDeputySelect`; C) `CommandDialog` modal (`ResponsibleMultiSelect`); D) Base UI `Combobox` flutuante (`FormCombobox`). +**Recomendação:** **A** — `MunicipalityRelationEditor.tsx:397-440` já usa `Command` **inline** (precedente direto) e o cmdk entrega teclado/a11y sem nova cópia; o componente é de domínio (2 usos no mesmo form), sem generalizar o `StateDeputySelect` do Studio S30 (que declara o gatilho de revisita "a fourth consumer", que assim não dispara). +**Rejeitadas:** **B** (quarta cópia manual = o gatilho de revisita declarado no próprio arquivo, com custo de a11y); **C** (modal ≠ cenas 01/02, que desenham painel inline); **D** (popup flutuante ≠ painel inline do artefato). + +### D7 — Verificação por camada (barato de reverter, mas explícito) + +**Opções:** A) unit de componente do picker (testing-library, search stub) + int do action/loader/contrato + e2e público browser (`frontendConteudos`) + render browserless da ficha (`campaignSpeechAcervo`); B) e2e de browser novo só para o picker; C) só int/unit (sem e2e público novo). +**Recomendação:** **A** — a fiação do client (chips, hidden inputs, debounce, remoção) é barata no unit de componente (há precedente `activityOverlay.unit.spec.tsx`); o action + snapshot + gate + fail-closed são domínio (int); o journey "marcado → filtro público" é o contrato do S27 e roda no `frontendConteudos` (seeding REST admin com `contact`+`leadership`+`leaders`, o caminho real do hook). Nenhum project/spec novo (sem custo de manifest). +**Rejeitadas:** **B** porque duplica setup de login/browser por cobertura que o unit de componente + int já dão (gatilho: quebra real de fiação no browser); **C** porque o contrato público novo (faceta + nome no card) precisa de prova HTTP real. + +### Componentes / mudanças + +**Schema / dados** + +- **`src/collections/ContentPiece.ts`** (editar): campos `leaders` (relationship → `leadership`, hasMany, label "Lideranças da campanha", `maxRows: CONTENT_PIECE_LEADERS_MAX`), `leaderNames` (text hasMany, readOnly — "Nomes para a Central pública"; snapshot), `publicFigures` (text hasMany, label "Figuras públicas", `maxRows` e `maxLength` do dono); `deriveContentPieceCatalogIndex` ganha a derivação condicional de `leaderNames` (relation touched, ordem dos ids, nomes em falta pulados), a normalização de `publicFigures` e os dois campos em `contentPieceSearchText`. +- **`src/lib/contentPiece.ts`** (editar): `CONTENT_PIECE_LEADERS_MAX`, `CONTENT_PIECE_PUBLIC_FIGURES_MAX`, `CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH`, `CONTENT_PIECE_LEADER_SEARCH_LIMIT`; `ContentPieceSearchInput` + `leaderNames`/`publicFigures`. +- **`src/lib/publicFigureCatalog.ts`** (novo, puro/client-safe): catálogo derivado do `stateDeputyCatalog` + `PUBLIC_FIGURE_PERSONALITIES`, `filterPublicFigures`, `resolvePublicFigureName`, `normalizeContentPiecePublicFigures`, `isPublicFigureCatalogName`. +- **Migration:** `pnpm migrate:create add_content_piece_people` → `20260924__add_content_piece_people`, aditiva: tabela `content_piece_rels` (relationship hasMany `leaders`), `content_piece_leader_names` e `content_piece_public_figures` (text hasMany). **Sem `ALTER TYPE`** (D5) e **sem backfill** — peças antigas ficam sem pessoas até a ficha editar. `pnpm migrate` local + `pnpm generate:types` (regerar `src/payload-types.ts`); nunca editar migration existente. + +**Access / busca interna** + +- **`src/utilities/content/contentPieceLeaderOptions.ts`** (novo, `server-only`): D1 — gate `canReadCommunicationCatalog`, `isContactSearchQueryReady`, teto 20, projeção `{id, label}`, bypass intencional comentado (só nome de exibição). +- **`src/app/(campaign)/campanha/actions/contentPieces.ts`** (editar): `searchContentPieceLeaderOptionsForActor(query)` (server action; gate + erro `CONTENT_PIECE_FORBIDDEN_MESSAGE`); `updateContentPieceForActor` aceita `leaderIds`/`publicFigures`, canonicaliza figuras e persiste `leaders`/`publicFigures` (sem novos `curatedFields`). +- **`src/lib/schemas/contentPiece.ts`** (editar): `leaderIds` (ints, teto) e `publicFigures` (strings, teto/tamanho) em `contentPieceUpdateRequestSchema`. +- **`src/app/(campaign)/campanha/(app)/comunicacao/conteudos/formActions.ts`** (editar): lê `getAll('leaderIds')` (ints válidos) e `repeatedFormTexts(formData, 'publicFigures')`. +- **`src/utilities/content/contentPiecePageData.ts`** (editar): `contentPieceDetailSelect` + `leaders`/`publicFigures`; o detalhe resolve `leaderOptions` via `resolveContentPieceLeaderOptions` e devolve `publicFigures`. + +**Contrato público (S27)** + +- **`src/lib/contentPieceCatalog.ts`** (editar): `'lideranca'` em `CONTENT_PIECE_CATALOG_FACETS` (append, ordem Tipo·Cidade·Região·Tema·Instituição·Lideranças) + label "Lideranças"; `lideranca` em params/parse (`slugFacet`)/href; `contentPiecePublicPeople`; `contentPieceCatalogFacets.lideranca`; filtro AND; `ContentPiecePublicSource`/`ContentPiecePublicItem` com `leaderNames`/`publicFigures`; `metaLabel` com o primeiro nome. +- **`src/utilities/content/contentPieceReads.ts`** (editar): `select` público ganha `leaderNames: true, publicFigures: true` — **jamais `leaders`**. +- **`src/components/conteudos/ContentPieceFilters.tsx`** (editar): caption "Em peças publicadas" no dropdown da faceta `lideranca` (design cena 03); placeholder "Encontre uma peça por assunto, cidade ou pessoa…". O chip/hidden input/remoção são automáticos via `CONTENT_PIECE_CATALOG_FACETS` e `ContentPieceCatalogFacets` (Record obriga a chave nova em tempo de compilação). +- **Card público:** sem mudança de arquivo — `CardMeta` (`ContentPieceCard.tsx:96-97`) já renderiza `metaLabel`. + +**UI interna (Impeccable C — port classe-a-classe)** + +- **`src/components/campaign/content/ContentPiecePeopleField.tsx`** (novo, client): bloco "Quem aparece na peça" (heading, ajuda "Marque somente pessoas visíveis…", badge "Curadoria humana", empty state "Ninguém marcado…"), dois pickers (liderança: busca async via prop `searchLeaders`; figura: catálogo local + "Usar «texto»"), chips removíveis e hidden inputs repetidos `leaderIds`/`publicFigures`; reusa `Command` inline + `Badge`. +- **`src/components/campaign/content/ContentPieceForm.tsx`** (editar): props `leaderOptions`, `publicFigures`, `searchLeaders`; render do fieldset `sm:col-span-2`. +- **`src/app/(campaign)/campanha/(app)/comunicacao/conteudos/[id]/page.tsx`** (editar): passa os novos props (o `searchLeaders` é a server action, padrão já usado com `formAction`). +- **`src/app/(campaign)/campanha/(app)/comunicacao/conteudos/page.tsx`**: sem mudança (Q(a) da intenção: sem filtro/coluna interno no v1). +- **Changelog:** `docs/changelog/2026-09-24-s37.md` (entrada curta; nunca editar o agregado/HISTORY). + +**Access / Consent:** um bypass intencional documentado (D1) e mais nada; nenhum `Consent` novo, nenhum cadastro de pessoa, `leader` intocado. + +### Dados → forma (se aplicável) + +N/A — a faceta é lista de nomes, sem contagem, série, ranking ou score (declarado na intenção); os nomes no card são metadado de conteúdo, não apresentação de dado. + +## Design tier + +Artefato aprovado no gate: `docs/plans/central-conteudos-liderancas-ui-design.html`. Superfícies cobertas e como o port as atende: + +- **Cena 01 — ficha interna desktop 1280:** bloco "Quem aparece na peça" com os dois recortes lado a lado, chips, painéis inline (liderança e figura), badge "Curadoria humana" e as duas linhas de ajuda; `ContentPiecePeopleField` porta classe-a-classe. +- **Cena 02 — ficha mobile 390:** empilhamento dos dois recortes e o estado "Ninguém marcado. A peça pode ser publicada normalmente…" (o form já é responsivo; o empty state é copy do artefato). +- **Cena 03 — catálogo público desktop/mobile:** chip `Lideranças` na fileira, dropdown com a caption "EM PEÇAS PUBLICADAS", chip ativo "Lideranças · Nome ×", card com o nome na linha de metadados e o placeholder "assunto, cidade ou pessoa…"; o box tracejado "Regra visível do gate" é lido como anotação do gate (a regra vira a caption do dropdown), não como UI. +- **Cena 04/estado de peça sem ninguém marcado:** coberto pelo empty state da cena 02. + +**Não cobertas → trigger (a) (dispatch do designer antes do markup final, se aplicável):** + +1. **Posição do bloco no formulário completo do C211** — o artefato mostra um close-up (Título → bloco → Instituição/Cidade) e omite Descrição/Tipo/Data/Temas/Transcrição; o port insere o fieldset `sm:col-span-2` **depois de Temas, antes de Cidade** e o designer valida no gate. +2. **Picker no mobile do desktop** — o artefato cobre o painel inline em 390; o componente mantém o mesmo painel em qualquer largura (sem cena extra) — designer valida. +3. **Linha de "quem aparece" na página individual da peça** — não desenhada; fica fora do v1 e entra como cena nova se o gate quiser. +4. **Placeholder mobile "Busque uma pessoa…"** — lido como mock; vale o texto do desktop ("assunto, cidade ou pessoa"). + +## Fases verificáveis + +1. **Tracer / schema+server — quota ~45%:** constants + campos + hook (snapshot e `searchText`) + migration + types; `publicFigureCatalog`; `contentPieceLeaderOptions` + server action; contrato público (`lideranca` em facets/parse/href/filter/VM/metaLabel) + select do read público; unit + int do caminho (ficha marca → publica → `/conteudos?lideranca=` acha; despublica → some) verdes antes de seguir. +2. **UI (port classe-a-classe) — quota ~35%:** `ContentPiecePeopleField` + form + ficha page + caption/placeholder dos filtros; unit de componente do picker. +3. **Gates — quota ~20%:** `pnpm gate:fast` (lint/format/typecheck/knip/cycles/unit); `pnpm test:int`; e2e `frontendConteudos` (curado, roda pelo PR high-risk) + `campaignSpeechAcervo` local (`pnpm test:e2e --no-deps -- tests/e2e/campaignSpeechAcervo.e2e.spec.ts --workers=1`); `pnpm push` → PR `--base main` (a verificação viva é o e2e de rotas reais). + +## Testes previstos + +- **`tests/unit/contentPieceCatalog.unit.spec.ts`** (editar): parse de `lideranca` (slug válido/ inválido/desconhecido → null); href canônico com a faceta na ordem fixa; `contentPieceCatalogFacets.lideranca` = união líderes+figuras, dedup por `slugify`, só de itens publicados, homônimo colapsa; filtro `lideranca` combinado com `tipo`/`q` (AND); VM com `leaderNames`/`publicFigures` e `metaLabel` liderando pelo primeiro nome (e inalterado sem pessoas). +- **`tests/unit/contentPiece.unit.spec.ts`** (editar): `contentPieceSearchText` inclui e normaliza nomes de liderança e figuras (acento/caixa); limites novos. +- **`tests/unit/publicFigureCatalog.unit.spec.ts`** (novo): catálogo deriva as 53 dobradinhas do `stateDeputyCatalog` (contagem/nomes/`slug` prefixado); `resolvePublicFigureName` accent/pontuação-insensível, ambíguo → null, desconhecido → null; `normalizeContentPiecePublicFigures` dedupe/canonicalização/teto; `filterPublicFigures`. +- **`tests/unit/contentPiecePeopleField.unit.spec.tsx`** (novo, componente com testing-library): busca stub devolve opções, seleção vira chip + hidden input; remoção limpa; texto livre vira figura; estado vazio; limite. +- **`tests/int/contentPiece.int.spec.ts`** (editar; fixtures já criam `contact`/`leadership`): action de busca — communicator recebe `{id,label}` e **nada além** (shape assertado), advisor/leader negados; save da ficha persiste `leaders`, snapshot `leaderNames` na ordem e figuras canonicalizadas; limpar funciona; leitura pública deriva faceta/nome, rascunho/despublicado nunca aparece, `q` acha pelo nome; `getPublishedContentPieceRecords` não traz `leaders`/`contact`; job (`runContentPieceJob` com stub) não toca os campos novos. +- **`tests/e2e/frontendConteudos.e2e.spec.ts`** (editar): seeding REST admin de `contact` + `leadership` + peça com `leaders` e `publicFigures`; `/conteudos` mostra o chip `Lideranças`, filtra por `?lideranca=` e o card mostra o nome; despublicar a peça remove o nome da faceta; cleanup de contatos/lideranças no `afterAll`. +- **`tests/e2e/campaignSpeechAcervo.e2e.spec.ts`** (editar, seção C211): a ficha renderiza o bloco "Quem aparece na peça" com o chip da liderança selecionada para o communicator; advisor segue negado. +- **Fixtures:** `tests/helpers/campaignFixtures.ts` **intocado** (contact/leadership já na union e no cleanup). + +## Pins a atualizar (valores exatos) + +- **`scripts/lib/e2e-affected-manifest.mjs:159-179`** (entrada S27): acrescentar `'src/lib/publicFigureCatalog.ts'` → `['frontendConteudos']`. +- **`scripts/lib/e2e-affected-manifest.mjs:440-464`** (vertical de comunicação/C211): acrescentar `'src/lib/publicFigureCatalog.ts'` (o picker e o int da Central usam o catálogo). +- **`tests/unit/e2eAffectedManifest.unit.spec.ts:54-79`** — **intocado**: `frontendConteudos` já está no curado; nenhum risk prefix novo. +- **`tests/unit/codebaseConventions.unit.spec.ts:202-237`** e **`:409-556`** — **intocado**: sem rota POST nova (a busca é server action) e nenhum módulo novo no top-level de `src/utilities/` (tudo em `src/utilities/content/`). +- **`tests/unit/contentPieceCatalog.unit.spec.ts`**, **`tests/unit/contentPiece.unit.spec.ts`**, **`tests/int/contentPiece.int.spec.ts`** e os dois e2e — estendidos conforme "Testes previstos". +- **`src/payload-types.ts`** — regenerado (`pnpm generate:types`), nunca editado à mão. + +## Rabbit holes / Não escopo (engenharia) + +- **Sugerir nomes automaticamente no job** (match de transcript no catálogo) — menção ≠ aparição; catálogo intocado (D5); gatilho: pedido explícito da comunicação, com item próprio. +- **Filtro/coluna na lista interna de peças** — só se o gate pedir (Q(a) da intenção); hoje a lista fica como está. +- **Relação com `stateDeputy`, `Speech.mentionedPeople`/C200, acervo** — superfícies distintas; não copiar o par nem acoplar. +- **Página pública por pessoa, diretório, contagem/placar de aparições, analytics** — vedados pela intenção. +- **Mostrar nomes na página individual da peça** — sem cena; trigger (a) se o gate quiser. +- **Tocar `src/utilities/access/*`/ampliar `canReadLeadership`** — rejeitado em D1; o bypass vive no domínio de conteúdo, documentado. +- **Tocar `StateDeputySelect`/Studio S30** — fora; o componente novo é de domínio. +- **Backfill de peças existentes** — sem dados; a faceta nasce vazia e cresce com a curadoria. +- **`Consent`/`Contact`/collection novos** — proibidos; nenhuma PII nova é capturada. +- **e2e de browser novo para o picker** — unit de componente + int + e2e público cobrem (D7); gatilho: falha de fiação real. + +## Riscos e mitigação + +- **Bypass de nomes para o `communicator`** (novo caminho de leitura): gate `canReadCommunicationCatalog` + projeção fixa `{id, label}` + teto e mínimo de 2 chars; unit/int assertam o shape e o negado; comentário de bypass explícito no módulo; se um campo a mais vazar no retorno, o teste quebra. +- **Snapshot `leaderNames` defasado** (contato renomeado fora da ficha): o form envia `leaderIds` em todo save, então o hook recomputa no toque; o job/publish não limpam; gatilho: se renomes virarem frequentes, recomputar também na entrada em `publicado`. +- **`searchText` dessincronizado em update parcial**: hook com fallback `originalDoc` (padrão `deriveSpeakerNames`); int cobre publish que envia só `status`. +- **`leaders`/`Contact` vazando no read público**: `select` explícito nunca inclui a relação; teste int asserta que o record cru não tem `leaders` e que o VM não carrega ids/contato; a faceta lê só o snapshot. +- **Faceta com homônimos/variações**: colapso por `slugify` documentado + unit; a faceta é filtro por nome, não identidade. +- **Migration aditiva em collection publicada**: só tabelas novas, sem backfill; o deploy já aplica `payload migrate` antes do build; revisar o SQL gerado e rodar `pnpm migrate` + int local antes do push. +- **PR high-risk (migration)**: o CI seleciona o curado (`frontendConteudos`); `campaignSpeechAcervo` roda no full do `verify` do deploy e localmente com o comando da Fase 3. +- **e2e de pessoas com cleanup**: contatos/lideranças criados no spec entram nas listas de limpeza na ordem FK (peça → liderança → contato). + +## Hard-stops (aprovação humana explícita — valem mesmo em `--auto`) + +1. **Schema/migration (Fase 1):** `pnpm migrate:create add_content_piece_people` + `pnpm migrate` só no banco local do worktree (`teqo_wt*`/`teqo_wt*_test`) — aditiva, sem backfill, sem `ALTER TYPE`. `--auto` aprova o plano, **não** o schema. **Aprovada na sessão `--auto` (2026-09-24)** — criar/aplicar só no banco local do worktree; nunca apontar para banco remoto fora do deploy. +2. **Contrato público (Fase 1):** faceta nova `lideranca` no param de `/conteudos` (aditiva, append na ordem fixa) + os campos `leaderNames`/`publicFigures` no shape público selecionado e no `metaLabel` do card. **Aprovado na sessão `--auto` (2026-09-24).** +3. **Bypass intencional de Local API (D1):** leitura de nomes de liderança para o `communicator` com projeção `{id, nome}` — decisão de segurança mais sensível do item (self-score abaixo). **Aprovado na sessão `--auto` (2026-09-24)**, com gate + projeção fixa + teto + testes de shape. + +## Aceite de engenharia + +- [ ] Aceite de produto da intenção coberto: ficha registra os dois recortes (liderança existente + figura pública em texto com catálogo); UMA faceta `Lideranças` une os dois; nomes na busca por termo e no card; fail-closed (rascunho/despublicado nunca expõe nome); curadoria manda. +- [ ] Guardrails: sem dado interno de liderança na superfície pública; sem cadastro paralelo; sem `Consent` novo; leader lockdown e `estimatedVotes` intocados; `consent`/LGPD intocados. +- [ ] Invariantes AGENTS/engineering-standards: bypass de Local API **único e documentado** (D1) com projeção mínima; escrita multi-campo na action existente (sem transação nova — um único `payload.update`); identificadores em inglês/copy pt-BR; migrations existentes intocadas; sem `push`. +- [ ] Testes de domínio previstos (unit/int) onde access e write paths mudam; pins de manifest atualizados; e2e público estendido. +- [ ] `pnpm gate:fast` verde; `pnpm test:int` do spec verde; e2e `frontendConteudos` verde; `campaignSpeechAcervo` rodado local verde; `pnpm push` via GitHub. + +## Decisões de engenharia + +- **D1 — Liderança + access:** relationship hasMany `leaders` + snapshot `leaderNames` + loader gated com bypass intencional, projeção `{id, nome}`, teto 20 e mín. 2 chars. Rejeitadas: texto sem vínculo (B), picker só para coordinator/candidate (C) e ampliar `canReadLeadership` (D). +- **D2 — Figuras públicas:** `text hasMany` + catálogo derivado do `stateDeputyCatalog` + personalidades por data edit + canonicalização de grafia no save. Rejeitadas: single text (B), relação com `stateDeputy` (C), texto sem catálogo (D). +- **D3 — Faceta:** uma `lideranca` derivada em memória da união dos nomes dos itens publicados, chave `slugify`, homônimos colapsam; read público nunca toca `leadership`/`Contact`. Rejeitadas: duas facetas (B) e chave por id/slug de origem (C). +- **D4 — Busca/card:** nomes no `searchText` (type + call site) e `metaLabel` liderando com o primeiro nome; página da peça fora do v1. Rejeitadas: fora da busca (B) e linha nova sem design (C). +- **D5 — Curadoria:** `content_piece_curated_fields` **intocado**; sem sugeridor automático (D2/A e C rejeitadas); gatilho registrado. +- **D6 — UI:** painel inline sobre `Command` (precedente `MunicipalityRelationEditor`), sem a 4ª cópia do listbox e sem tocar o Studio S30. Rejeitadas: cópia manual (B), modal (C), popup flutuante (D). +- **D7 — Verificação:** unit de componente + int + e2e público + render browserless da ficha; sem spec novo. Rejeitadas: e2e de browser do picker (B) e só unit/int (C). +- **Sem Consent, sem collection nova, sem `ALTER TYPE`, sem rota nova** — registrado, não presumido. + +## Self-score + +**Self-score decision-quality: 4/5.** (1) Todas as decisões caras (referência + access, storage/catálogo de figuras, faceta única sem PII, busca/card, colisão com `curatedFields`) têm Opções + Recomendação + Rejeitadas explícitas; (2) cabe no appetite herdado: sem collection/rota nova, uma migration aditiva, reusa `Command` inline, o hook de denormalização, o contrato público do S27, `normalizeForSearch`/`slugify`, `stateDeputyCatalog` e o padrão de server action como prop; (3) rabbit holes nomeados (sugestão automática, filtro interno, `stateDeputy`/C200, ranking, página por pessoa, ampliar RBAC, backfill, browser e2e); (4) depth check: donos existentes editados (contrato público, collection/hook, action, form) e só nasce módulo onde não há dono (`publicFigureCatalog`, `contentPieceLeaderOptions`, `ContentPiecePeopleField`); (5) outcome preservado — fail-closed, uma faceta, curadoria manual, sem PII e sem reescrever o aceite. O que impede o 5 é o **bypass intencional de leitura de nomes de liderança** para o `communicator` (D1): é a decisão de segurança mais sensível do item e pede confirmação humana explícita no gate, mesmo com projeção mínima, gate e testes de shape. + +## Simplify — défers deste triage (2026-09-24) + +Duas revisões paralelas (estrutural + qualidade) rodaram sobre o diff; os achados aplicáveis foram corrigidos na sessão (null-safety do hook, `select` honesto, ordem de submissão preservada nos chips, `slugify`/`normalizeSearchPhrase` do catálogo, `PeopleChip`/`orderOptionsById` extraídos, `leaderIds` removido do page data, gate num só lugar). Ficaram deferidos, com gatilho: + +- **Defer (estados async dos pickers).** O par loading/failed de `ContentPiecePeopleField` repete o de `ResponsibleMultiSelect`/`AsyncSearchCombobox` (3º consumidor). Gatilho: um 4º consumidor dos estados assíncronos ou o próximo item que mexer em um dos três → extrair um shell único (`shared/AsyncSearchStates`), sem tocar nos fluxos aprovados. +- **Defer (projeção de liderança).** `contentPieceLeaderOptions` repete a projeção/label de `activityLeadershipOptions` (que usa `overrideAccess: false` — semântica de access diferente da deste item). Gatilho: um 3º consumidor do nome de exibição de liderança ou o próximo item que alterar o label (ex.: C200/speakers) → extrair a projeção pura compartilhada. +- **Descartado:** `facet === 'lideranca'` repetido no componente de filtros (leitura local, 3 pontos); `select: { contact: true }` (o plano D1 o escolheu; o tipo do Payload não aceita select aninhado e o `{ id, label }` + int test são a fronteira do shape); `PUBLIC_FIGURE_PERSONALITIES`/`kind` vazios (seam aprovado no plano, v1 deliberadamente vazio). + +## Fechamento (sessão `--auto`, 2026-09-24) + +- **Design (trigger c): certificado PARIDADE** pelo `designer` (tier primário, sem `DEGRADED`) após 3 passadas contra o app renderizado (390/1280): ficha com/sem pessoas (cenas 01/01A/02) e catálogo com a faceta aberta/filtrada/card (cena 03). +- **Hard-stops:** aprovados explicitamente pelo humano na sessão (migration aditiva só no banco local, faceta/contrato público aditivo e o bypass D1 com projeção `{id, nome}` + testes de shape). diff --git a/docs/plans/central-conteudos-liderancas-ui-design.html b/docs/plans/central-conteudos-liderancas-ui-design.html index fd4bdf4d..1831e4b7 100644 --- a/docs/plans/central-conteudos-liderancas-ui-design.html +++ b/docs/plans/central-conteudos-liderancas-ui-design.html @@ -19,6 +19,22 @@ --line: rgb(0 0 0/0.12); --display: 'Exo 2', 'Arial Black', sans-serif; } + [data-theme='campaign'] { + --radius: 0.5rem; + --background: #ffffff; + --foreground: #1c1917; + --primary: #c51414; + --primary-foreground: #ffffff; + --muted: #f4f4f5; + --muted-foreground: #6b7280; + --border: rgb(28 25 23/0.12); + --field-background: #ffffff; + --field-foreground: #1c1917; + --field-placeholder: rgb(28 25 23/0.5); + --field-border: #d6d3d1; + --scope: #fff5ed; + --scope-foreground: #6b2d15; + } * { box-sizing: border-box; } @@ -230,6 +246,9 @@ >
Personalidade Exemplo
+
+ Usar «Nome digitado» +
@@ -251,10 +270,212 @@ +
+
+ CENA 01A +

Ficha interna · desktop 1280 · posição no formulário completo

+
+
+ 5 +

+ Posição aprovada: depois de Temas e antes de Cidade. O bloco ocupa + as duas colunas do formulário. +

+
+
+
+ Campanha · Comunicação + Editar peça +
+
+ ← Conteúdos +

Título da peça em revisão

+

Revise os dados antes de publicar.

+ +
+
+

Título

+
+ Título da peça em revisão +
+
+ +
+

Descrição

+
+ Resumo curto da peça para o catálogo público. +
+
+ +
+

Tipo

+
+ Vídeo ⌄ +
+
+
+

Data da peça

+
+ 24/09/2026 ▣ +
+
+ +
+

Temas

+
+ Saúde + Educação + Direitos + Trabalho +
+
+ +
+ Quem aparece na peça +
+
+

Quem aparece na peça

+

+ Marque somente pessoas visíveis ou participantes desta peça. A publicação + expõe apenas o nome. +

+
+ + Curadoria humana + +
+ +
+
+

Lideranças da campanha

+

+ Busca nos registros existentes. Nenhum telefone, município ou voto vai para a + Central pública. +

+
+ Nome da liderança × +
+
+
+ ⌕Buscar liderança… +
+
+ Nome da liderança + Registro da campanha +
+
Outra liderança de exemplo
+
+
+ +
+

Figuras públicas

+

+ Texto curado com catálogo, no mesmo molde de Instituição. +

+
+ Dep. Estadual Exemplo × +
+
+
+ ⌕Digite ou escolha uma figura pública… +
+
+ Dep. Estadual Exemplo + Figura pública catalogada +
+
Personalidade Exemplo
+
+ Usar «Nome digitado» +
+
+
+
+
+ +
+

Cidade

+
+ Sem cidade ⌄ +
+
+
+

Instituição

+
+ Nome da instituição +
+
+ +
+

Transcrição / texto

+
+ Transcrição ou texto completo da peça… +
+
+ +
+
+ Alterações salvas. +
+
+ + +
+
+
+
+
CENA 02 -

Ficha interna · mobile 390 · pessoa marcada e ninguém marcado

+

Ficha interna · mobile 390 · painéis inline, pessoa marcada e ninguém marcado

@@ -276,12 +497,33 @@
Buscar liderança…⌄
+
+
+ Nome da liderança + Registro da campanha +
+
Outra liderança de exemplo
+

Figuras públicas

Dep. Estadual Exemplo ×
- Digite ou escolha…⌄ + Digite ou escolha uma figura pública…⌄ +
+
+
+ Dep. Estadual Exemplo + Figura pública catalogada +
+
Personalidade Exemplo
+
+ Usar «Nome digitado» +
@@ -303,7 +545,7 @@

Lideranças da campanha

Buscar liderança…

Figuras públicas

-
Digite ou escolha…
+
Digite ou escolha uma figura pública…
@@ -387,7 +629,7 @@
- Busque uma pessoa… + Encontre uma peça por assunto, cidade ou pessoa…
Tipo⌄ {piece.fileHref ? ( diff --git a/src/app/(campaign)/campanha/(app)/comunicacao/conteudos/formActions.ts b/src/app/(campaign)/campanha/(app)/comunicacao/conteudos/formActions.ts index d74732c1..a9547b48 100644 --- a/src/app/(campaign)/campanha/(app)/comunicacao/conteudos/formActions.ts +++ b/src/app/(campaign)/campanha/(app)/comunicacao/conteudos/formActions.ts @@ -8,6 +8,7 @@ import { isContentPieceType } from '@/lib/contentPiece' import { nullableFormText, repeatedFormTexts, + repeatedRelationshipFormValues, requiredFormText, requiredIntegerFormValue, } from '@/lib/formData' @@ -49,6 +50,10 @@ export const updateContentPieceFormAction = async ( municipalityId: municipalityValue, institution: nullableFormText(formData, 'institution'), transcript: nullableFormText(formData, 'transcript'), + // S37 — the people order is the assessoria's: the first chip leads the + // card, so the submit order is preserved (no id sort). + leaderIds: repeatedRelationshipFormValues(formData, 'leaderIds', { sort: false }), + publicFigures: repeatedFormTexts(formData, 'publicFigures'), }) revalidatePath(CAMPAIGN_COMMUNICATION_CONTEUDOS) diff --git a/src/app/(campaign)/campanha/actions/contentPieces.ts b/src/app/(campaign)/campanha/actions/contentPieces.ts index 44d223d6..29b0e62b 100644 --- a/src/app/(campaign)/campanha/actions/contentPieces.ts +++ b/src/app/(campaign)/campanha/actions/contentPieces.ts @@ -11,6 +11,7 @@ import { type ContentPieceCuratedField, type ContentPieceViewModel, } from '@/lib/contentPiece' +import { normalizeContentPiecePublicFigures } from '@/lib/publicFigureCatalog' import { CONTENT_PIECE_FORBIDDEN_MESSAGE, CONTENT_PIECE_LINK_DUPLICATE_MESSAGE, @@ -29,6 +30,10 @@ import type { SpeechTopic } from '@/lib/speechFacets' import type { CampaignUser } from '@/payload-types' import { getCampaignActionContext } from '@/utilities/campaignActionContext' import { reapStaleContentPiece } from '@/utilities/content/contentPieceJob' +import { + searchContentPieceLeaderOptions, + type ContentPieceLeaderOption, +} from '@/utilities/content/contentPieceLeaderOptions' import { startContentPieceJobInBackground } from '@/utilities/content/contentPieceScheduler' import { withPayloadTransaction } from '@/utilities/payloadTransaction' @@ -125,6 +130,8 @@ export const updateContentPieceForActor = async ( municipality: parsed.municipalityId ?? null, institution: parsed.institution ?? null, transcript: parsed.transcript ?? null, + leaders: parsed.leaderIds ?? [], + publicFigures: normalizeContentPiecePublicFigures(parsed.publicFigures ?? []), curatedFields: [...curated], }, depth: 0, @@ -315,3 +322,19 @@ export const addContentPieceByLinkForActor = async (input: { throw error } } + +/** + * S37 — the ficha's leader picker search. Same communication gate as every + * action of the vertical; the returned options carry ONLY `{ id, label }` (the + * display-name projection the int tests assert), never any other leadership + * field. + */ +export const searchContentPieceLeaderOptionsForActor = async ( + query: string, +): Promise => { + const { payload, actor } = await getCampaignActionContext() + + if (!canReadCommunicationCatalog(actor.role)) throw new Error(CONTENT_PIECE_FORBIDDEN_MESSAGE) + + return searchContentPieceLeaderOptions(payload, actor, query) +} diff --git a/src/app/(frontend)/conteudos/(catalog)/page.tsx b/src/app/(frontend)/conteudos/(catalog)/page.tsx index 07308c99..4f04aba1 100644 --- a/src/app/(frontend)/conteudos/(catalog)/page.tsx +++ b/src/app/(frontend)/conteudos/(catalog)/page.tsx @@ -1,6 +1,9 @@ import { CampaignFooter } from '@/components/CampaignFooter' import { ContentPieceCatalog } from '@/components/conteudos/ContentPieceCatalog' -import { ContentPieceFilters } from '@/components/conteudos/ContentPieceFilters' +import { + ContentPieceActiveFilterChip, + ContentPieceFilters, +} from '@/components/conteudos/ContentPieceFilters' import { ContentPieceHero } from '@/components/conteudos/ContentPieceHero' import { ContentPiecePageHeader } from '@/components/conteudos/ContentPiecePageHeader' import { @@ -9,6 +12,7 @@ import { ContentPieceThemeFallbackNotice, ContentPieceThemeNoResults, } from '@/components/conteudos/ContentPieceStates' +import { CONTENT_PIECE_ACTIVE_CHIP } from '@/components/conteudos/contentPieceClasses' import { CONTENT_PIECE_CATALOG_PATH, buildContentPieceCatalogHref, @@ -105,6 +109,10 @@ export default async function ConteudosPage({ ) } + // S37 (design scene 03): the people filter leads the results with its own + // heading and the active chip at the side (desktop). + const liderancaFilter = activeFilters.find((filter) => filter.facet === 'lideranca') + return ( <> @@ -129,13 +137,24 @@ export default async function ConteudosPage({

- {themeMode ? `Resultados para “${params.q}”` : 'Escolha, compartilhe e peça voto'} + {liderancaFilter + ? `Peças com ${liderancaFilter.value}` + : themeMode + ? `Resultados para “${params.q}”` + : 'Escolha, compartilhe e peça voto'}

- O play só carrega a mídia quando você pedir. + {liderancaFilter + ? 'O filtro combina com cidade, tema e os demais recortes.' + : 'O play só carrega a mídia quando você pedir.'}

- {themeMode ? ( + {liderancaFilter ? ( + + ) : themeMode ? ( themeApplied ? ( Por tema ativo ) : null diff --git a/src/collections/ContentPiece.ts b/src/collections/ContentPiece.ts index b0890c17..3f9a8337 100644 --- a/src/collections/ContentPiece.ts +++ b/src/collections/ContentPiece.ts @@ -10,9 +10,12 @@ import { CONTENT_PIECE_CURATED_FIELDS, CONTENT_PIECE_DESCRIPTION_MAX_LENGTH, CONTENT_PIECE_INSTITUTION_MAX_LENGTH, + CONTENT_PIECE_LEADERS_MAX, CONTENT_PIECE_LINK_FAILURE_REASONS, CONTENT_PIECE_ORIGINS, CONTENT_PIECE_PROCESSING_STATUSES, + CONTENT_PIECE_PUBLIC_FIGURES_MAX, + CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH, CONTENT_PIECE_STATUSES, CONTENT_PIECE_STEPS, CONTENT_PIECE_TITLE_MAX_LENGTH, @@ -27,6 +30,8 @@ import { contentPieceStepLabels, contentPieceTypeLabels, } from '@/lib/contentPiece' +import { normalizeContentPiecePublicFigures } from '@/lib/publicFigureCatalog' +import { uniqueRelationshipIds } from '@/lib/relationship' import { SPEECH_TOPICS } from '@/lib/speechFacets' import { payloadAdminOnly } from '@/utilities/access/shared' import { @@ -36,6 +41,7 @@ import { canUpdateContentPiece, } from '@/utilities/campaignAccess' import { stampCampaignCreatedBy, systemStampedActorField } from '@/utilities/campaignAuditFields' +import { resolveContentPieceLeaderNames } from '@/utilities/content/contentPieceLeaderOptions' import { revalidateContentPiecesListing } from '@/utilities/documents' import { acquireTextAdvisoryLocks } from '@/utilities/postgresTransactionLocks' @@ -190,6 +196,23 @@ const deriveContentPieceCatalogIndex: CollectionBeforeValidateHook = async ({ data.cityLabel = cityLabel data.region = region + + // S37 — "who appears in the piece". The leader snapshot is recomputed only + // when the relation was TOUCHED (the ficha always sends the list, an empty + // one clearing it); a partial update keeps the stored names. The public + // figures are canonicalized against the catalog on every write, so any path + // (ficha, admin, direct update) stores the same spelling. + if (data.leaders !== undefined) { + data.leaderNames = await resolveContentPieceLeaderNames( + req.payload, + req, + uniqueRelationshipIds(data.leaders), + ) + } + if (data.publicFigures !== undefined) { + data.publicFigures = normalizeContentPiecePublicFigures(data.publicFigures ?? []) + } + data.searchText = contentPieceSearchText({ title: data.title ?? originalDoc?.title, description: data.description ?? originalDoc?.description, @@ -197,6 +220,8 @@ const deriveContentPieceCatalogIndex: CollectionBeforeValidateHook = async ({ institution: data.institution ?? originalDoc?.institution, topics: data.topics ?? originalDoc?.topics, cityLabel, + leaderNames: data.leaderNames ?? originalDoc?.leaderNames, + publicFigures: data.publicFigures ?? originalDoc?.publicFigures, }) return data } @@ -311,6 +336,40 @@ export const ContentPiece: CollectionConfig = { label: 'Instituição', maxLength: CONTENT_PIECE_INSTITUTION_MAX_LENGTH, }, + { + name: 'leaders', + type: 'relationship', + relationTo: 'leadership', + hasMany: true, + label: 'Lideranças da campanha', + maxRows: CONTENT_PIECE_LEADERS_MAX, + admin: { + description: + 'Quem aparece na peça entre as lideranças já registradas. À Central pública vai apenas o nome.', + }, + }, + { + name: 'leaderNames', + type: 'text', + hasMany: true, + label: 'Nomes para a Central pública', + admin: { + readOnly: true, + description: 'Derivado das lideranças marcadas; é o que a faceta pública mostra.', + }, + }, + { + name: 'publicFigures', + type: 'text', + hasMany: true, + label: 'Figuras públicas', + maxRows: CONTENT_PIECE_PUBLIC_FIGURES_MAX, + maxLength: CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH, + admin: { + description: + 'Dobradinhas/estaduais do catálogo e outras personalidades; a grafia é canonicalizada ao salvar.', + }, + }, { name: 'pieceDate', type: 'date', diff --git a/src/components/campaign/content/ContentPieceForm.tsx b/src/components/campaign/content/ContentPieceForm.tsx index d5bd718b..05d4dcf4 100644 --- a/src/components/campaign/content/ContentPieceForm.tsx +++ b/src/components/campaign/content/ContentPieceForm.tsx @@ -2,6 +2,7 @@ import { startTransition, useActionState, useState, type FormEvent } from 'react' +import { ContentPiecePeopleField } from '@/components/campaign/content/ContentPiecePeopleField' import { CampaignFormActionMessage } from '@/components/campaign/shared/CampaignFormActionMessage' import { Button } from '@/components/ui/button' import { Field, FieldError, FieldLabel } from '@/components/ui/field' @@ -21,6 +22,7 @@ import { SPEECH_TOPICS, type SpeechTopic } from '@/lib/speechFacets' import { cn } from '@/lib/utils' import type { CampaignFormActionState } from '@/utilities/campaignFormActionError' import { fieldError } from '@/utilities/campaignFormFields' +import type { ContentPieceLeaderOption } from '@/utilities/content/contentPieceLeaderOptions' type MunicipalityOption = { id: number; name: string } @@ -29,11 +31,15 @@ type MunicipalityOption = { id: number; name: string } * catalogue the pipeline filled, ready for the assessoria to revise. Saving * marks the sent fields as curated, so the automatic cataloguing never * overwrites them (D6). The transcript is a first-class field — it is what the - * public search (S28) indexes. + * public search (S28) indexes. S37 adds "Quem aparece na peça" between Temas + * and Cidade (approved design scene 01A). */ export const ContentPieceForm = ({ piece, municipalityOptions, + leaderOptions, + publicFigures, + searchLeaders, formAction, }: { piece: { @@ -48,6 +54,12 @@ export const ContentPieceForm = ({ transcript: string | null } municipalityOptions: readonly MunicipalityOption[] + /** S37 — the picked leaders, resolved to `{ id, label }` for the chips. */ + leaderOptions: readonly ContentPieceLeaderOption[] + /** S37 — the curated public figures already on the piece. */ + publicFigures: readonly string[] + /** S37 — the gated async search behind the leader picker. */ + searchLeaders: (query: string) => Promise formAction: ( state: CampaignFormActionState, formData: FormData, @@ -157,6 +169,12 @@ export const ContentPieceForm = ({
+ + Cidade void }) => ( + + {label} + + +) + +/** + * S37 — "Quem aparece na peça" (approved design scenes 01/01A/02): the two + * curated recortes inside the C211 ficha. The leader picker searches the + * existing records through a gated server action (async, 2+ chars, only the + * display name); the public-figure picker filters the static catalog and + * accepts free text ("Usar «…»"). Both keep removable chips and repeated hidden + * inputs — the ficha nests no person record, only display names. + */ +export const ContentPiecePeopleField = ({ + leaders, + publicFigures, + searchLeaders, +}: { + leaders: readonly ContentPieceLeaderOption[] + publicFigures: readonly string[] + searchLeaders: (query: string) => Promise +}) => { + const [selectedLeaders, setSelectedLeaders] = useState([...leaders]) + const [selectedFigures, setSelectedFigures] = useState([...publicFigures]) + const [leaderQuery, setLeaderQuery] = useState('') + const [figureQuery, setFigureQuery] = useState('') + + const { + options: leaderResults, + loading: leadersLoading, + failed: leadersFailed, + } = useAsyncSearchOptions({ + open: true, + query: leaderQuery, + search: searchLeaders, + isQueryReady: isContactSearchQueryReady, + }) + + const selectedLeaderIds = new Set(selectedLeaders.map((leader) => leader.id)) + const selectedFigureKeys = new Set(selectedFigures.map(normalizeForSearch)) + const atLeaderCapacity = selectedLeaders.length >= CONTENT_PIECE_LEADERS_MAX + const atFigureCapacity = selectedFigures.length >= CONTENT_PIECE_PUBLIC_FIGURES_MAX + + const toggleLeader = (option: ContentPieceLeaderOption) => { + setSelectedLeaders((current) => { + if (current.some((leader) => leader.id === option.id)) { + return current.filter((leader) => leader.id !== option.id) + } + return atLeaderCapacity ? current : [...current, option] + }) + } + + const toggleFigure = (name: string) => { + const trimmed = name.trim() + const key = normalizeForSearch(trimmed) + if (!key) return + + setSelectedFigures((current) => { + if (current.some((figure) => normalizeForSearch(figure) === key)) { + return current.filter((figure) => normalizeForSearch(figure) !== key) + } + return atFigureCapacity ? current : [...current, trimmed] + }) + } + + const figureResults = filterPublicFigures(figureQuery) + const figureText = figureQuery.trim() + const canUseFigureText = + figureText !== '' && + !selectedFigureKeys.has(normalizeForSearch(figureText)) && + !atFigureCapacity + const nothingMarked = selectedLeaders.length === 0 && selectedFigures.length === 0 + + return ( +
+ Quem aparece na peça +
+
+

Quem aparece na peça

+

+ Marque somente pessoas visíveis ou participantes desta peça. A publicação expõe apenas o + nome. +

+
+ + Curadoria humana + +
+ + {selectedLeaders.map((leader) => ( + + ))} + {selectedFigures.map((figure) => ( + + ))} + + {nothingMarked ? ( +

+ Ninguém marcado. A peça pode ser publicada normalmente e não cria nenhum nome na faceta + “Lideranças”. +

+ ) : null} + +
+
+

Lideranças da campanha

+

+ Busca nos registros existentes. Nenhum telefone, município ou voto vai para a Central + pública. +

+ {selectedLeaders.length ? ( +
+ {selectedLeaders.map((leader) => ( + toggleLeader(leader)} + /> + ))} +
+ ) : null} + + + + {leadersLoading ? ( +
+
+ ) : leadersFailed ? ( +

+ Não foi possível concluir a busca. +

+ ) : leaderResults.length > 0 ? ( + leaderResults.map((option) => { + const selected = selectedLeaderIds.has(option.id) + return ( + toggleLeader(option)} + > + + {option.label} + + Registro da campanha + + + + ) + }) + ) : ( +

+ {!isContactSearchQueryReady(leaderQuery) + ? 'Digite ao menos dois caracteres para buscar.' + : 'Nenhum resultado encontrado.'} +

+ )} +
+
+
+ +
+

Figuras públicas

+

+ Texto curado com catálogo, no mesmo molde de Instituição. +

+ {selectedFigures.length ? ( +
+ {selectedFigures.map((figure) => ( + toggleFigure(figure)} /> + ))} +
+ ) : null} + + + + {figureResults.map((entry) => { + const selected = selectedFigureKeys.has(normalizeForSearch(entry.name)) + return ( + toggleFigure(entry.name)} + > + + {entry.name} + + Figura pública catalogada + + + + ) + })} + {canUseFigureText ? ( + { + toggleFigure(figureText) + setFigureQuery('') + }} + > + Usar «{figureText}» + + ) : null} + {figureResults.length === 0 && !canUseFigureText ? ( +

+ Nenhum resultado encontrado. +

+ ) : null} +
+
+
+
+
+ ) +} diff --git a/src/components/conteudos/ContentPieceFilters.tsx b/src/components/conteudos/ContentPieceFilters.tsx index 8bbbe36d..3ae021e0 100644 --- a/src/components/conteudos/ContentPieceFilters.tsx +++ b/src/components/conteudos/ContentPieceFilters.tsx @@ -24,6 +24,33 @@ const FIELD_CLASS = const DROPDOWN_LINK = 'flex min-h-9 items-center rounded-lg px-2.5 text-sm font-medium text-black hover:bg-(--campaign-band) focus-visible:outline-[3px] focus-visible:outline-offset-[2px] focus-visible:outline-(--pt-red)' +/** + * S37 — the active-filter chip is shared with the results header (design scene + * 03): on desktop the `Lideranças` chip lives next to the contextual heading, + * on mobile it stays in the facet row. + */ +export const ContentPieceActiveFilterChip = ({ + filter, + className, + prefetch, +}: { + filter: ContentPieceCatalogActiveFilter + className?: string + prefetch?: boolean +}) => ( + + {filter.label} · {filter.value} + + +) + /** * S28 — the catalogue filters (artefato: cenas 07–09): a GET form (works * without JS, the URL is the state) with the search term, the mode segmented @@ -65,7 +92,7 @@ export const ContentPieceFilters = ({ type="search" name="q" defaultValue={params.q} - placeholder="Encontre uma peça por assunto, cidade ou tema…" + placeholder="Encontre uma peça por assunto, cidade ou pessoa…" aria-label="Buscar peças" className={FIELD_CLASS} /> @@ -83,23 +110,23 @@ export const ContentPieceFilters = ({
{facetFilters.map((filter) => ( - - {filter.label} · {filter.value} - - + // S37 — on desktop the Lideranças chip moves next to the results + // heading (design scene 03); mobile keeps it in the row. + className={ + filter.facet === 'lideranca' + ? `${CONTENT_PIECE_ACTIVE_CHIP} sm:hidden` + : CONTENT_PIECE_ACTIVE_CHIP + } + /> ))} {CONTENT_PIECE_CATALOG_FACETS.map((facet) => params[facet] || facets[facet].length === 0 ? null : ( -
+
@@ -108,13 +135,32 @@ export const ContentPieceFilters = ({ ⌄ -
    +
      + {facet === 'lideranca' ? ( + // S37 (design scene 03): the facet derives from published + // pieces alone — the caption states the rule; the mobile + // panel names the facet it belongs to. + <> +
    • + Lideranças · Em peças publicadas +
    • +
    • + Em peças publicadas +
    • + + ) : null} {facets[facet].map((option) => (
    • {option.label} diff --git a/src/lib/contentPiece.ts b/src/lib/contentPiece.ts index b6783026..214043f5 100644 --- a/src/lib/contentPiece.ts +++ b/src/lib/contentPiece.ts @@ -141,6 +141,17 @@ export const CONTENT_PIECE_TITLE_MAX_LENGTH = 200 export const CONTENT_PIECE_DESCRIPTION_MAX_LENGTH = 1200 export const CONTENT_PIECE_INSTITUTION_MAX_LENGTH = 160 +/** + * S37 — "who appears in the piece": the campaign leaders linked to the + * existing `leadership` records and the curated public figures. The limits are + * the same on every path (collection, form schema and the picker). + */ +export const CONTENT_PIECE_LEADERS_MAX = 20 +export const CONTENT_PIECE_PUBLIC_FIGURES_MAX = 20 +export const CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH = 120 +/** The gated name search never returns more than this many options. */ +export const CONTENT_PIECE_LEADER_SEARCH_LIMIT = 20 + /** Batch policy: a generous ceiling with a clear message above it (product A). */ export const CONTENT_PIECE_BATCH_MAX_FILES = 50 @@ -313,12 +324,15 @@ type ContentPieceSearchInput = { institution?: string | null topics?: readonly string[] | null cityLabel?: string | null + /** S37 — the display names of who appears in the piece (leader snapshot + figures). */ + leaderNames?: readonly string[] | null + publicFigures?: readonly string[] | null } /** - * The normalized haystack the list search matches: title, description, the - * transcript/text, the topic labels and the city/institution — everything the - * design's placeholder promises ("Buscar por título, tema ou cidade…"). + * The normalized haystack the public/busy search matches: title, description, + * the transcript/text, the topic labels, the city/institution and — since S37 — + * the names of who appears in the piece, so searching a name finds the piece. */ export const contentPieceSearchText = (input: ContentPieceSearchInput): string => normalizeForSearch( @@ -329,6 +343,8 @@ export const contentPieceSearchText = (input: ContentPieceSearchInput): string = input.institution ?? '', ...(input.topics ?? []).filter(isContentPieceTopic).map(contentPieceTopicLabel), input.cityLabel ?? '', + ...(input.leaderNames ?? []), + ...(input.publicFigures ?? []), ] .map((value) => value.trim()) .filter(Boolean) diff --git a/src/lib/contentPieceCatalog.ts b/src/lib/contentPieceCatalog.ts index ffc50f82..6f97554c 100644 --- a/src/lib/contentPieceCatalog.ts +++ b/src/lib/contentPieceCatalog.ts @@ -49,6 +49,7 @@ export const CONTENT_PIECE_CATALOG_FACETS = [ 'regiao', 'tema', 'instituicao', + 'lideranca', ] as const export type ContentPieceCatalogFacet = (typeof CONTENT_PIECE_CATALOG_FACETS)[number] @@ -59,6 +60,7 @@ export const contentPieceCatalogFacetLabels: Record): ContentPieceCatalogFacetOp .map(([value, label]) => ({ value, label })) .sort((a, b) => a.label.localeCompare(b.label, 'pt-BR')) +/** S37 — one display name of who appears in the piece (facet option shape). */ +export type ContentPiecePublicPerson = { slug: string; name: string } + +/** + * S37 — the single facet `Lideranças` union: the campaign-leader name snapshot + * plus the curated public figures, each as a display name keyed by `slugify`. + * Homonyms and spelling variants collapse into ONE option by design (the facet + * filters by display name, never by identity; the last spelling of the stable + * order labels it). Derived from the item alone — the public read never joins + * `leadership`/`Contact`. + */ +export const contentPiecePublicPeople = ( + item: Pick, +): ContentPiecePublicPerson[] => { + const people = new Map() + for (const value of [...item.leaderNames, ...item.publicFigures]) { + const name = value.trim() + const slug = slugify(name) + if (!name || !slug) continue + people.set(slug, name) + } + return [...people.entries()].map(([slug, name]) => ({ slug, name })) +} + /** * Facet options are derived from the board items alone: a filter that cannot * match anything never renders. Tipo/Tema keep the persisted enum order; the @@ -171,6 +201,7 @@ export const contentPieceCatalogFacets = ( const cities = new Map() const regions = new Map() const institutions = new Map() + const people = new Map() for (const item of items) { if (isCardCatalogItem(item)) { @@ -182,6 +213,7 @@ export const contentPieceCatalogFacets = ( if (item.cityLabel) cities.set(slugify(item.cityLabel), item.cityLabel) if (item.regionLabel) regions.set(slugify(item.regionLabel), item.regionLabel) if (item.institution) institutions.set(slugify(item.institution), item.institution) + for (const person of contentPiecePublicPeople(item)) people.set(person.slug, person.name) } return { @@ -196,6 +228,7 @@ export const contentPieceCatalogFacets = ( cidade: sortedOptions(cities), regiao: sortedOptions(regions), instituicao: sortedOptions(institutions), + lideranca: sortedOptions(people), } } @@ -282,7 +315,9 @@ export const filterContentPieceCatalogItems = ( (item.regionLabel === null || slugify(item.regionLabel) !== params.regiao)) || (params.tema && !item.topics.includes(params.tema)) || (params.instituicao && - (item.institution === null || slugify(item.institution) !== params.instituicao)) + (item.institution === null || slugify(item.institution) !== params.instituicao)) || + (params.lideranca && + !contentPiecePublicPeople(item).some((person) => person.slug === params.lideranca)) ) { return false } @@ -304,6 +339,10 @@ export type ContentPiecePublicSource = { cityLabel?: string | null region?: string | null institution?: string | null + /** S37 — derived display names of the linked campaign leaders (never the relation). */ + leaderNames?: string[] | null + /** S37 — curated public figures (display names). */ + publicFigures?: string[] | null description?: string | null transcript?: string | null sourceUrl?: string | null @@ -329,12 +368,15 @@ export type ContentPiecePublicItem = { cityLabel: string | null regionLabel: string | null institution: string | null + /** S37 — display names of who appears in the piece (leader snapshot + figures). */ + leaderNames: string[] + publicFigures: string[] description: string | null /** Opening of the text/transcript, for the `texto` card asset. */ excerpt: string | null durationLabel: string | null pieceDateLabel: string | null - /** `Tema · Local` (or institution/city fallbacks) — the card's metadata line. */ + /** S37 — `Nome · Tema · Local` (or the previous fallbacks) — the card's metadata line. */ metaLabel: string searchText: string /** S28 — why the piece appeared in the theme mode; null in the literal search. */ @@ -647,8 +689,18 @@ export const toContentPiecePublicItem = ( const cityLabel = record.cityLabel?.trim() || null const regionLabel = record.region?.trim() || null const institution = record.institution?.trim() || null + const leaderNames = (record.leaderNames ?? []).map((name) => name.trim()).filter(Boolean) + const publicFigures = (record.publicFigures ?? []).map((name) => name.trim()).filter(Boolean) const local = cityLabel ?? regionLabel - const metaLabel = [topicLabels[0] ?? institution, local].filter(Boolean).join(' · ') + const metaLabel = [ + // S37 — who appears leads the metadata line; the previous shape stays for a + // piece with nobody marked (byte-identical card). + leaderNames[0] ?? publicFigures[0], + topicLabels[0] ?? institution, + local, + ] + .filter(Boolean) + .join(' · ') const isLink = media === null && sourceUrl !== null return { @@ -666,6 +718,8 @@ export const toContentPiecePublicItem = ( cityLabel, regionLabel, institution, + leaderNames, + publicFigures, description: record.description?.trim() || null, excerpt: contentPieceTextExcerpt(record.transcript), durationLabel: durationLabelOf(record.durationSeconds), diff --git a/src/lib/formData.ts b/src/lib/formData.ts index 946170e5..6c5da6cd 100644 --- a/src/lib/formData.ts +++ b/src/lib/formData.ts @@ -151,14 +151,25 @@ export const nullableRelationshipFormValue = ( return positiveInteger(field, entry.value) } -export const repeatedRelationshipFormValues = (formData: FormData, field: string): number[] => { +/** + * Relationship `hasMany` values from the form, deduped. Order is the value + * order (ascending id) for the scoped selects; `{ sort: false }` keeps the + * submission order for the lists where the user's order is meaningful (the + * S37 people chips — the first name leads the public card). + */ +export const repeatedRelationshipFormValues = ( + formData: FormData, + field: string, + { sort = true }: { sort?: boolean } = {}, +): number[] => { const values = formData.getAll(field).map((value) => { if (typeof value !== 'string') { throw new FormDataBoundaryError(field, 'Arquivos não são aceitos neste campo.') } return positiveInteger(field, value) }) - return [...new Set(values)].sort((left, right) => left - right) + const unique = [...new Set(values)] + return sort ? unique.sort((left, right) => left - right) : unique } export const repeatedFormTexts = (formData: FormData, field: string): string[] => { diff --git a/src/lib/publicFigureCatalog.ts b/src/lib/publicFigureCatalog.ts new file mode 100644 index 00000000..7b312e8b --- /dev/null +++ b/src/lib/publicFigureCatalog.ts @@ -0,0 +1,111 @@ +/** + * S37 — static catalog of the public figures the assessoria may mark on a piece + * ("quem aparece na peça", recorte 2): the state-deputy roster (S30, the + * campaign's dobradinhas) plus other personalities curated as data. It follows + * the `institution` mold — free text canonicalized against a catalog — without + * any new person record: the piece stores display names, never identities. + * + * The dobradinha rows are DERIVED from `stateDeputyCatalog` (the roster stays + * the owner of the 53 names); the slug carries a kind prefix so a personality + * can never collide with a roster entry. No I/O and no `server-only`: the ficha + * picker, the collection hook and the unit tests share this module. + */ +import { + CONTENT_PIECE_PUBLIC_FIGURES_MAX, + CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH, +} from '@/lib/contentPiece' +import { slugify } from '@/lib/slug' +import { stateDeputyCatalog } from '@/lib/stateDeputyCatalog' +import { normalizeSearchPhrase } from '@/lib/wordStartFilter' + +type PublicFigureKind = 'dobradinha' | 'personalidade' + +export type PublicFigureCatalogEntry = { + /** Catalog identity (`-`), never a public URL. */ + slug: string + /** Display name the piece stores and the public facet shows. */ + name: string + kind: PublicFigureKind +} + +/** + * Other public figures beyond the dobradinhas roster. Deliberately EMPTY on + * v1: inventing names would be product data without provenance; a personality + * is marked as free text and becomes data to curate when the gate asks for it. + */ +export const PUBLIC_FIGURE_PERSONALITIES: readonly string[] = [] + +const personalitySlug = (name: string): string => `personalidade-${slugify(name)}` + +export const publicFigureCatalog: readonly PublicFigureCatalogEntry[] = [ + ...stateDeputyCatalog.map((deputy) => ({ + slug: `estadual-${deputy.slug}`, + name: deputy.name, + kind: 'dobradinha' as const, + })), + ...PUBLIC_FIGURE_PERSONALITIES.map((name) => ({ + slug: personalitySlug(name), + name, + kind: 'personalidade' as const, + })), +] + +const normalizedEntryValues = (entry: PublicFigureCatalogEntry): string[] => [ + normalizeSearchPhrase(entry.name), + normalizeSearchPhrase(entry.slug), +] + +/** + * Accent/case/punctuation-insensitive search by display name or slug; an empty + * query keeps all (the picker opens with the roster). Same normalization as + * `resolvePublicFigureName`, so what the picker finds is what the save + * canonicalizes. Same contract as the S30 selector. + */ +export const filterPublicFigures = (query: string): readonly PublicFigureCatalogEntry[] => { + const needle = normalizeSearchPhrase(query) + if (!needle) return publicFigureCatalog + + return publicFigureCatalog.filter((entry) => + normalizedEntryValues(entry).some((value) => value.includes(needle)), + ) +} + +/** + * The canonical display name of a typed value, or null when it matches nothing + * or more than one catalog entry (ambiguous input is never guessed). + */ +export const resolvePublicFigureName = (value: string): string | null => { + const normalized = normalizeSearchPhrase(value) + if (!normalized) return null + + const matches = publicFigureCatalog.filter((entry) => + normalizedEntryValues(entry).includes(normalized), + ) + return matches.length === 1 ? matches[0].name : null +} + +/** + * The canonical list the piece persists: trimmed, catalog spelling when the + * value resolves, deduped by normalized form, capped. Overlong values are + * dropped (the field is a display name, not a dump) — the form schema refuses + * them first on the editable path. + */ +export const normalizeContentPiecePublicFigures = (values: readonly string[]): string[] => { + const seen = new Set() + const figures: string[] = [] + + for (const raw of values) { + const trimmed = typeof raw === 'string' ? raw.trim() : '' + if (!trimmed || trimmed.length > CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH) continue + + const name = resolvePublicFigureName(trimmed) ?? trimmed + const key = normalizeSearchPhrase(name) + if (!key || seen.has(key)) continue + + seen.add(key) + figures.push(name) + if (figures.length >= CONTENT_PIECE_PUBLIC_FIGURES_MAX) break + } + + return figures +} diff --git a/src/lib/schemas/contentPiece.ts b/src/lib/schemas/contentPiece.ts index 34c47412..d526903d 100644 --- a/src/lib/schemas/contentPiece.ts +++ b/src/lib/schemas/contentPiece.ts @@ -3,6 +3,9 @@ import { z } from 'zod' import { CONTENT_PIECE_DESCRIPTION_MAX_LENGTH, CONTENT_PIECE_INSTITUTION_MAX_LENGTH, + CONTENT_PIECE_LEADERS_MAX, + CONTENT_PIECE_PUBLIC_FIGURES_MAX, + CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH, CONTENT_PIECE_TEXT_TOO_LARGE_MESSAGE, CONTENT_PIECE_TITLE_MAX_LENGTH, CONTENT_PIECE_TYPES, @@ -90,6 +93,13 @@ export const contentPieceUpdateRequestSchema = z.object({ municipalityId: z.number().int().positive().nullable().optional(), institution: trimmedNullableText(CONTENT_PIECE_INSTITUTION_MAX_LENGTH), transcript: trimmedNullableText(200_000), + // S37 — who appears in the piece: the leader relation ids and the curated + // public figures. The action canonicalizes the figures against the catalog. + leaderIds: z.array(z.number().int().positive()).max(CONTENT_PIECE_LEADERS_MAX).optional(), + publicFigures: z + .array(z.string().trim().max(CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH)) + .max(CONTENT_PIECE_PUBLIC_FIGURES_MAX) + .optional(), }) export type ContentPieceUpdateRequest = z.infer diff --git a/src/migrations/20260924_123940_add_content_piece_people.json b/src/migrations/20260924_123940_add_content_piece_people.json new file mode 100644 index 00000000..01dfe708 --- /dev/null +++ b/src/migrations/20260924_123940_add_content_piece_people.json @@ -0,0 +1,18494 @@ +{ + "version": "7", + "dialect": "postgresql", + "tables": { + "public.users_roles": { + "name": "users_roles", + "schema": "", + "columns": { + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "enum_users_roles", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + } + }, + "indexes": { + "users_roles_order_idx": { + "name": "users_roles_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_roles_parent_idx": { + "name": "users_roles_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "users_roles_parent_fk": { + "name": "users_roles_parent_fk", + "tableFrom": "users_roles", + "tableTo": "users", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users_sessions": { + "name": "users_sessions", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "users_sessions_order_idx": { + "name": "users_sessions_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_sessions_parent_id_idx": { + "name": "users_sessions_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "users_sessions_parent_id_fk": { + "name": "users_sessions_parent_id_fk", + "tableFrom": "users_sessions", + "tableTo": "users", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "email": { + "name": "email", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "reset_password_token": { + "name": "reset_password_token", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "reset_password_expiration": { + "name": "reset_password_expiration", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "salt": { + "name": "salt", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "hash": { + "name": "hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "login_attempts": { + "name": "login_attempts", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "lock_until": { + "name": "lock_until", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "users_updated_at_idx": { + "name": "users_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_created_at_idx": { + "name": "users_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_email_idx": { + "name": "users_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_user_sessions": { + "name": "campaign_user_sessions", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "campaign_user_sessions_order_idx": { + "name": "campaign_user_sessions_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_sessions_parent_id_idx": { + "name": "campaign_user_sessions_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_user_sessions_parent_id_fk": { + "name": "campaign_user_sessions_parent_id_fk", + "tableFrom": "campaign_user_sessions", + "tableTo": "campaign_user", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_user": { + "name": "campaign_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "avatar_id": { + "name": "avatar_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "enum_campaign_user_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'leader'" + }, + "visibility": { + "name": "visibility", + "type": "enum_campaign_user_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'carteira'" + }, + "editing": { + "name": "editing", + "type": "enum_campaign_user_editing", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'carteira'" + }, + "phone": { + "name": "phone", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "email": { + "name": "email", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "reset_password_token": { + "name": "reset_password_token", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "reset_password_expiration": { + "name": "reset_password_expiration", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "salt": { + "name": "salt", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "hash": { + "name": "hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "login_attempts": { + "name": "login_attempts", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "lock_until": { + "name": "lock_until", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "campaign_user_contact_idx": { + "name": "campaign_user_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_avatar_idx": { + "name": "campaign_user_avatar_idx", + "columns": [ + { + "expression": "avatar_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_phone_idx": { + "name": "campaign_user_phone_idx", + "columns": [ + { + "expression": "phone", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_updated_at_idx": { + "name": "campaign_user_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_created_at_idx": { + "name": "campaign_user_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_email_idx": { + "name": "campaign_user_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_user_username_idx": { + "name": "campaign_user_username_idx", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_user_contact_id_contact_id_fk": { + "name": "campaign_user_contact_id_contact_id_fk", + "tableFrom": "campaign_user", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_user_avatar_id_media_id_fk": { + "name": "campaign_user_avatar_id_media_id_fk", + "tableFrom": "campaign_user", + "tableTo": "media", + "columnsFrom": [ + "avatar_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_web_authn_credential": { + "name": "campaign_web_authn_credential", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "counter": { + "name": "counter", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "transports": { + "name": "transports", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "device_label": { + "name": "device_label", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "campaign_web_authn_credential_user_idx": { + "name": "campaign_web_authn_credential_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_web_authn_credential_credential_id_idx": { + "name": "campaign_web_authn_credential_credential_id_idx", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_web_authn_credential_updated_at_idx": { + "name": "campaign_web_authn_credential_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_web_authn_credential_created_at_idx": { + "name": "campaign_web_authn_credential_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_web_authn_credential_user_id_campaign_user_id_fk": { + "name": "campaign_web_authn_credential_user_id_campaign_user_id_fk", + "tableFrom": "campaign_web_authn_credential", + "tableTo": "campaign_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "recipient_id": { + "name": "recipient_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "enum_notification_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "read_at": { + "name": "read_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notification_recipient_idx": { + "name": "notification_recipient_idx", + "columns": [ + { + "expression": "recipient_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_type_idx": { + "name": "notification_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_municipality_idx": { + "name": "notification_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_read_at_idx": { + "name": "notification_read_at_idx", + "columns": [ + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_updated_at_idx": { + "name": "notification_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_created_at_idx": { + "name": "notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notification_recipient_id_campaign_user_id_fk": { + "name": "notification_recipient_id_campaign_user_id_fk", + "tableFrom": "notification", + "tableTo": "campaign_user", + "columnsFrom": [ + "recipient_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "notification_municipality_id_municipality_id_fk": { + "name": "notification_municipality_id_municipality_id_fk", + "tableFrom": "notification", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_subscription": { + "name": "push_subscription", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "endpoint": { + "name": "endpoint", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "p256dh": { + "name": "p256dh", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "auth": { + "name": "auth", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "expiration_time": { + "name": "expiration_time", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "consent_content_hash": { + "name": "consent_content_hash", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "consented_at": { + "name": "consented_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "user_agent": { + "name": "user_agent", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_subscription_user_idx": { + "name": "push_subscription_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_subscription_endpoint_idx": { + "name": "push_subscription_endpoint_idx", + "columns": [ + { + "expression": "endpoint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_subscription_consent_idx": { + "name": "push_subscription_consent_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_subscription_updated_at_idx": { + "name": "push_subscription_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_subscription_created_at_idx": { + "name": "push_subscription_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_subscription_user_id_campaign_user_id_fk": { + "name": "push_subscription_user_id_campaign_user_id_fk", + "tableFrom": "push_subscription", + "tableTo": "campaign_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "push_subscription_consent_id_consent_id_fk": { + "name": "push_subscription_consent_id_consent_id_fk", + "tableFrom": "push_subscription", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_invite": { + "name": "campaign_invite", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "enum_campaign_invite_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "campaign_invite_token_hash_idx": { + "name": "campaign_invite_token_hash_idx", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_leadership_idx": { + "name": "campaign_invite_leadership_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_kind_idx": { + "name": "campaign_invite_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_expires_at_idx": { + "name": "campaign_invite_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_used_at_idx": { + "name": "campaign_invite_used_at_idx", + "columns": [ + { + "expression": "used_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_revoked_at_idx": { + "name": "campaign_invite_revoked_at_idx", + "columns": [ + { + "expression": "revoked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_created_by_idx": { + "name": "campaign_invite_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_updated_at_idx": { + "name": "campaign_invite_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_invite_created_at_idx": { + "name": "campaign_invite_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_kind_idx": { + "name": "leadership_kind_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_invite_leadership_id_leadership_id_fk": { + "name": "campaign_invite_leadership_id_leadership_id_fk", + "tableFrom": "campaign_invite", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_invite_created_by_id_campaign_user_id_fk": { + "name": "campaign_invite_created_by_id_campaign_user_id_fk", + "tableFrom": "campaign_invite", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_vote_summary_snapshot": { + "name": "campaign_vote_summary_snapshot", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "scope_key": { + "name": "scope_key", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'statewide'" + }, + "staff_vote_total_central": { + "name": "staff_vote_total_central", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "campaign_vote_summary_snapshot_day_idx": { + "name": "campaign_vote_summary_snapshot_day_idx", + "columns": [ + { + "expression": "day", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_vote_summary_snapshot_scope_key_idx": { + "name": "campaign_vote_summary_snapshot_scope_key_idx", + "columns": [ + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_vote_summary_snapshot_updated_at_idx": { + "name": "campaign_vote_summary_snapshot_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_vote_summary_snapshot_created_at_idx": { + "name": "campaign_vote_summary_snapshot_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "day_scopeKey_idx": { + "name": "day_scopeKey_idx", + "columns": [ + { + "expression": "day", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality_strengths": { + "name": "municipality_strengths", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "municipality_strengths_order_idx": { + "name": "municipality_strengths_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_strengths_parent_id_idx": { + "name": "municipality_strengths_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_strengths_parent_id_fk": { + "name": "municipality_strengths_parent_id_fk", + "tableFrom": "municipality_strengths", + "tableTo": "municipality", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality_risks": { + "name": "municipality_risks", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "municipality_risks_order_idx": { + "name": "municipality_risks_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_risks_parent_id_idx": { + "name": "municipality_risks_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_risks_parent_id_fk": { + "name": "municipality_risks_parent_id_fk", + "tableFrom": "municipality_risks", + "tableTo": "municipality", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality": { + "name": "municipality", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "enum_municipality_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "city": { + "name": "city", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "region": { + "name": "region", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "ibge_code": { + "name": "ibge_code", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "tse_city_code": { + "name": "tse_city_code", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "zone_number": { + "name": "zone_number", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "priority": { + "name": "priority", + "type": "enum_municipality_priority", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'normal'" + }, + "engagement_level": { + "name": "engagement_level", + "type": "enum_municipality_engagement_level", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "level_note": { + "name": "level_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "level_changed_at": { + "name": "level_changed_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "expected_votes_pessimistic": { + "name": "expected_votes_pessimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "expected_votes_central": { + "name": "expected_votes_central", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "expected_votes_optimistic": { + "name": "expected_votes_optimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "political_trend_status": { + "name": "political_trend_status", + "type": "enum_municipality_political_trend_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "political_trend_note": { + "name": "political_trend_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "political_trend_recorded_by_id": { + "name": "political_trend_recorded_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "political_trend_recorded_at": { + "name": "political_trend_recorded_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "dobradinha_notes": { + "name": "dobradinha_notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "next_steps": { + "name": "next_steps", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "budget_notes": { + "name": "budget_notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "last_update_at": { + "name": "last_update_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "municipality_name_idx": { + "name": "municipality_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_slug_idx": { + "name": "municipality_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_kind_idx": { + "name": "municipality_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_city_idx": { + "name": "municipality_city_idx", + "columns": [ + { + "expression": "city", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_region_idx": { + "name": "municipality_region_idx", + "columns": [ + { + "expression": "region", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_ibge_code_idx": { + "name": "municipality_ibge_code_idx", + "columns": [ + { + "expression": "ibge_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_tse_city_code_idx": { + "name": "municipality_tse_city_code_idx", + "columns": [ + { + "expression": "tse_city_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_zone_number_idx": { + "name": "municipality_zone_number_idx", + "columns": [ + { + "expression": "zone_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_priority_idx": { + "name": "municipality_priority_idx", + "columns": [ + { + "expression": "priority", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_engagement_level_idx": { + "name": "municipality_engagement_level_idx", + "columns": [ + { + "expression": "engagement_level", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_level_changed_at_idx": { + "name": "municipality_level_changed_at_idx", + "columns": [ + { + "expression": "level_changed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_political_trend_political_trend_recorded_by_idx": { + "name": "municipality_political_trend_political_trend_recorded_by_idx", + "columns": [ + { + "expression": "political_trend_recorded_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_last_update_at_idx": { + "name": "municipality_last_update_at_idx", + "columns": [ + { + "expression": "last_update_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_updated_at_idx": { + "name": "municipality_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_created_at_idx": { + "name": "municipality_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_political_trend_recorded_by_id_campaign_user_id_fk": { + "name": "municipality_political_trend_recorded_by_id_campaign_user_id_fk", + "tableFrom": "municipality", + "tableTo": "campaign_user", + "columnsFrom": [ + "political_trend_recorded_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality_rels": { + "name": "municipality_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state_deputy_id": { + "name": "state_deputy_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "municipality_rels_order_idx": { + "name": "municipality_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_rels_parent_idx": { + "name": "municipality_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_rels_path_idx": { + "name": "municipality_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_rels_campaign_user_id_idx": { + "name": "municipality_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_rels_state_deputy_id_idx": { + "name": "municipality_rels_state_deputy_id_idx", + "columns": [ + { + "expression": "state_deputy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_rels_parent_fk": { + "name": "municipality_rels_parent_fk", + "tableFrom": "municipality_rels", + "tableTo": "municipality", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "municipality_rels_campaign_user_fk": { + "name": "municipality_rels_campaign_user_fk", + "tableFrom": "municipality_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "municipality_rels_state_deputy_fk": { + "name": "municipality_rels_state_deputy_fk", + "tableFrom": "municipality_rels", + "tableTo": "state_deputy", + "columnsFrom": [ + "state_deputy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.leadership": { + "name": "leadership", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "exclusive": { + "name": "exclusive", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "support_status": { + "name": "support_status", + "type": "enum_leadership_support_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'a_abordar'" + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "consent_content_hash": { + "name": "consent_content_hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "consented_at": { + "name": "consented_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "leadership_contact_idx": { + "name": "leadership_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_exclusive_idx": { + "name": "leadership_exclusive_idx", + "columns": [ + { + "expression": "exclusive", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_support_status_idx": { + "name": "leadership_support_status_idx", + "columns": [ + { + "expression": "support_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_user_idx": { + "name": "leadership_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_consent_idx": { + "name": "leadership_consent_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_created_by_idx": { + "name": "leadership_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_updated_at_idx": { + "name": "leadership_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_created_at_idx": { + "name": "leadership_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "leadership_contact_id_contact_id_fk": { + "name": "leadership_contact_id_contact_id_fk", + "tableFrom": "leadership", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "leadership_user_id_campaign_user_id_fk": { + "name": "leadership_user_id_campaign_user_id_fk", + "tableFrom": "leadership", + "tableTo": "campaign_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "leadership_consent_id_consent_id_fk": { + "name": "leadership_consent_id_consent_id_fk", + "tableFrom": "leadership", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "leadership_created_by_id_campaign_user_id_fk": { + "name": "leadership_created_by_id_campaign_user_id_fk", + "tableFrom": "leadership", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.leadership_rels": { + "name": "leadership_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state_deputy_id": { + "name": "state_deputy_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "leadership_rels_order_idx": { + "name": "leadership_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_parent_idx": { + "name": "leadership_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_path_idx": { + "name": "leadership_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_municipality_id_idx": { + "name": "leadership_rels_municipality_id_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_organization_id_idx": { + "name": "leadership_rels_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_state_deputy_id_idx": { + "name": "leadership_rels_state_deputy_id_idx", + "columns": [ + { + "expression": "state_deputy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_rels_campaign_user_id_idx": { + "name": "leadership_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "leadership_rels_parent_fk": { + "name": "leadership_rels_parent_fk", + "tableFrom": "leadership_rels", + "tableTo": "leadership", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "leadership_rels_municipality_fk": { + "name": "leadership_rels_municipality_fk", + "tableFrom": "leadership_rels", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "leadership_rels_organization_fk": { + "name": "leadership_rels_organization_fk", + "tableFrom": "leadership_rels", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "leadership_rels_state_deputy_fk": { + "name": "leadership_rels_state_deputy_fk", + "tableFrom": "leadership_rels", + "tableTo": "state_deputy", + "columnsFrom": [ + "state_deputy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "leadership_rels_campaign_user_fk": { + "name": "leadership_rels_campaign_user_fk", + "tableFrom": "leadership_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization": { + "name": "organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "enum_organization_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "organization_name_idx": { + "name": "organization_name_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_slug_idx": { + "name": "organization_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_kind_idx": { + "name": "organization_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_created_by_idx": { + "name": "organization_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_updated_at_idx": { + "name": "organization_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_created_at_idx": { + "name": "organization_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "organization_created_by_id_campaign_user_id_fk": { + "name": "organization_created_by_id_campaign_user_id_fk", + "tableFrom": "organization", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_rels": { + "name": "organization_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "organization_rels_order_idx": { + "name": "organization_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_rels_parent_idx": { + "name": "organization_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_rels_path_idx": { + "name": "organization_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "organization_rels_municipality_id_idx": { + "name": "organization_rels_municipality_id_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "organization_rels_parent_fk": { + "name": "organization_rels_parent_fk", + "tableFrom": "organization_rels", + "tableTo": "organization", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_rels_municipality_fk": { + "name": "organization_rels_municipality_fk", + "tableFrom": "organization_rels", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.state_deputy": { + "name": "state_deputy", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "party": { + "name": "party", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "ballot_name": { + "name": "ballot_name", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "state_deputy_contact_idx": { + "name": "state_deputy_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_slug_idx": { + "name": "state_deputy_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_party_idx": { + "name": "state_deputy_party_idx", + "columns": [ + { + "expression": "party", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_created_by_idx": { + "name": "state_deputy_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_updated_at_idx": { + "name": "state_deputy_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_created_at_idx": { + "name": "state_deputy_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "state_deputy_contact_id_contact_id_fk": { + "name": "state_deputy_contact_id_contact_id_fk", + "tableFrom": "state_deputy", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "state_deputy_created_by_id_campaign_user_id_fk": { + "name": "state_deputy_created_by_id_campaign_user_id_fk", + "tableFrom": "state_deputy", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.state_deputy_rels": { + "name": "state_deputy_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "state_deputy_rels_order_idx": { + "name": "state_deputy_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_rels_parent_idx": { + "name": "state_deputy_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_rels_path_idx": { + "name": "state_deputy_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "state_deputy_rels_campaign_user_id_idx": { + "name": "state_deputy_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "state_deputy_rels_parent_fk": { + "name": "state_deputy_rels_parent_fk", + "tableFrom": "state_deputy_rels", + "tableTo": "state_deputy", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "state_deputy_rels_campaign_user_fk": { + "name": "state_deputy_rels_campaign_user_fk", + "tableFrom": "state_deputy_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.vote_pledge": { + "name": "vote_pledge", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "declared_votes": { + "name": "declared_votes", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "declared_at": { + "name": "declared_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "declared_by_id": { + "name": "declared_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "estimated_votes_pessimistic": { + "name": "estimated_votes_pessimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "estimated_votes_central": { + "name": "estimated_votes_central", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "estimated_votes_optimistic": { + "name": "estimated_votes_optimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "estimate_note": { + "name": "estimate_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "estimated_by_id": { + "name": "estimated_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "estimated_at": { + "name": "estimated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "vote_pledge_leadership_idx": { + "name": "vote_pledge_leadership_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_municipality_idx": { + "name": "vote_pledge_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_declared_votes_idx": { + "name": "vote_pledge_declared_votes_idx", + "columns": [ + { + "expression": "declared_votes", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_declared_by_idx": { + "name": "vote_pledge_declared_by_idx", + "columns": [ + { + "expression": "declared_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_estimated_by_idx": { + "name": "vote_pledge_estimated_by_idx", + "columns": [ + { + "expression": "estimated_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_updated_at_idx": { + "name": "vote_pledge_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "vote_pledge_created_at_idx": { + "name": "vote_pledge_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "leadership_municipality_idx": { + "name": "leadership_municipality_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "vote_pledge_leadership_id_leadership_id_fk": { + "name": "vote_pledge_leadership_id_leadership_id_fk", + "tableFrom": "vote_pledge", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "vote_pledge_municipality_id_municipality_id_fk": { + "name": "vote_pledge_municipality_id_municipality_id_fk", + "tableFrom": "vote_pledge", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "vote_pledge_declared_by_id_campaign_user_id_fk": { + "name": "vote_pledge_declared_by_id_campaign_user_id_fk", + "tableFrom": "vote_pledge", + "tableTo": "campaign_user", + "columnsFrom": [ + "declared_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "vote_pledge_estimated_by_id_campaign_user_id_fk": { + "name": "vote_pledge_estimated_by_id_campaign_user_id_fk", + "tableFrom": "vote_pledge", + "tableTo": "campaign_user", + "columnsFrom": [ + "estimated_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._vote_pledge_v": { + "name": "_vote_pledge_v", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_leadership_id": { + "name": "version_leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "version_municipality_id": { + "name": "version_municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "version_declared_votes": { + "name": "version_declared_votes", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "version_declared_at": { + "name": "version_declared_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_declared_by_id": { + "name": "version_declared_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_estimated_votes_pessimistic": { + "name": "version_estimated_votes_pessimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "version_estimated_votes_central": { + "name": "version_estimated_votes_central", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "version_estimated_votes_optimistic": { + "name": "version_estimated_votes_optimistic", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "version_estimate_note": { + "name": "version_estimate_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_estimated_by_id": { + "name": "version_estimated_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_estimated_at": { + "name": "version_estimated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_updated_at": { + "name": "version_updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_created_at": { + "name": "version_created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "_vote_pledge_v_parent_idx": { + "name": "_vote_pledge_v_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_leadership_idx": { + "name": "_vote_pledge_v_version_version_leadership_idx", + "columns": [ + { + "expression": "version_leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_municipality_idx": { + "name": "_vote_pledge_v_version_version_municipality_idx", + "columns": [ + { + "expression": "version_municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_declared_votes_idx": { + "name": "_vote_pledge_v_version_version_declared_votes_idx", + "columns": [ + { + "expression": "version_declared_votes", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_declared_by_idx": { + "name": "_vote_pledge_v_version_version_declared_by_idx", + "columns": [ + { + "expression": "version_declared_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_estimated_by_idx": { + "name": "_vote_pledge_v_version_version_estimated_by_idx", + "columns": [ + { + "expression": "version_estimated_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_updated_at_idx": { + "name": "_vote_pledge_v_version_version_updated_at_idx", + "columns": [ + { + "expression": "version_updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_version_version_created_at_idx": { + "name": "_vote_pledge_v_version_version_created_at_idx", + "columns": [ + { + "expression": "version_created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_created_at_idx": { + "name": "_vote_pledge_v_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_vote_pledge_v_updated_at_idx": { + "name": "_vote_pledge_v_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "version_leadership_version_municipality_idx": { + "name": "version_leadership_version_municipality_idx", + "columns": [ + { + "expression": "version_leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version_municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "_vote_pledge_v_parent_id_vote_pledge_id_fk": { + "name": "_vote_pledge_v_parent_id_vote_pledge_id_fk", + "tableFrom": "_vote_pledge_v", + "tableTo": "vote_pledge", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_vote_pledge_v_version_leadership_id_leadership_id_fk": { + "name": "_vote_pledge_v_version_leadership_id_leadership_id_fk", + "tableFrom": "_vote_pledge_v", + "tableTo": "leadership", + "columnsFrom": [ + "version_leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_vote_pledge_v_version_municipality_id_municipality_id_fk": { + "name": "_vote_pledge_v_version_municipality_id_municipality_id_fk", + "tableFrom": "_vote_pledge_v", + "tableTo": "municipality", + "columnsFrom": [ + "version_municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_vote_pledge_v_version_declared_by_id_campaign_user_id_fk": { + "name": "_vote_pledge_v_version_declared_by_id_campaign_user_id_fk", + "tableFrom": "_vote_pledge_v", + "tableTo": "campaign_user", + "columnsFrom": [ + "version_declared_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_vote_pledge_v_version_estimated_by_id_campaign_user_id_fk": { + "name": "_vote_pledge_v_version_estimated_by_id_campaign_user_id_fk", + "tableFrom": "_vote_pledge_v", + "tableTo": "campaign_user", + "columnsFrom": [ + "version_estimated_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.allocation_decision": { + "name": "allocation_decision", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pattern_id": { + "name": "pattern_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "enum_allocation_decision_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "rationale": { + "name": "rationale", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "alternative_reading": { + "name": "alternative_reading", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "snapshot": { + "name": "snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "decided_by_id": { + "name": "decided_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "allocation_decision_municipality_idx": { + "name": "allocation_decision_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "allocation_decision_pattern_id_idx": { + "name": "allocation_decision_pattern_id_idx", + "columns": [ + { + "expression": "pattern_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "allocation_decision_decided_by_idx": { + "name": "allocation_decision_decided_by_idx", + "columns": [ + { + "expression": "decided_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "allocation_decision_updated_at_idx": { + "name": "allocation_decision_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "allocation_decision_created_at_idx": { + "name": "allocation_decision_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "allocation_decision_municipality_id_municipality_id_fk": { + "name": "allocation_decision_municipality_id_municipality_id_fk", + "tableFrom": "allocation_decision", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "allocation_decision_decided_by_id_campaign_user_id_fk": { + "name": "allocation_decision_decided_by_id_campaign_user_id_fk", + "tableFrom": "allocation_decision", + "tableTo": "campaign_user", + "columnsFrom": [ + "decided_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_demand_status_history": { + "name": "campaign_demand_status_history", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "enum_campaign_demand_status_history_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "author_id": { + "name": "author_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "campaign_demand_status_history_order_idx": { + "name": "campaign_demand_status_history_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_status_history_parent_id_idx": { + "name": "campaign_demand_status_history_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_status_history_author_idx": { + "name": "campaign_demand_status_history_author_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_demand_status_history_author_id_campaign_user_id_fk": { + "name": "campaign_demand_status_history_author_id_campaign_user_id_fk", + "tableFrom": "campaign_demand_status_history", + "tableTo": "campaign_user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_demand_status_history_parent_id_fk": { + "name": "campaign_demand_status_history_parent_id_fk", + "tableFrom": "campaign_demand_status_history", + "tableTo": "campaign_demand", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_demand": { + "name": "campaign_demand", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "enum_campaign_demand_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "activity_id": { + "name": "activity_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "enum_campaign_demand_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'aberta'" + }, + "decision_note": { + "name": "decision_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "decided_by_id": { + "name": "decided_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "decided_at": { + "name": "decided_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "campaign_demand_title_idx": { + "name": "campaign_demand_title_idx", + "columns": [ + { + "expression": "title", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_slug_idx": { + "name": "campaign_demand_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_kind_idx": { + "name": "campaign_demand_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_municipality_idx": { + "name": "campaign_demand_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_activity_idx": { + "name": "campaign_demand_activity_idx", + "columns": [ + { + "expression": "activity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_leadership_idx": { + "name": "campaign_demand_leadership_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_status_idx": { + "name": "campaign_demand_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_decided_by_idx": { + "name": "campaign_demand_decided_by_idx", + "columns": [ + { + "expression": "decided_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_created_by_idx": { + "name": "campaign_demand_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_updated_at_idx": { + "name": "campaign_demand_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_created_at_idx": { + "name": "campaign_demand_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_demand_municipality_id_municipality_id_fk": { + "name": "campaign_demand_municipality_id_municipality_id_fk", + "tableFrom": "campaign_demand", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_demand_activity_id_activity_id_fk": { + "name": "campaign_demand_activity_id_activity_id_fk", + "tableFrom": "campaign_demand", + "tableTo": "activity", + "columnsFrom": [ + "activity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_demand_leadership_id_leadership_id_fk": { + "name": "campaign_demand_leadership_id_leadership_id_fk", + "tableFrom": "campaign_demand", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_demand_decided_by_id_campaign_user_id_fk": { + "name": "campaign_demand_decided_by_id_campaign_user_id_fk", + "tableFrom": "campaign_demand", + "tableTo": "campaign_user", + "columnsFrom": [ + "decided_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "campaign_demand_created_by_id_campaign_user_id_fk": { + "name": "campaign_demand_created_by_id_campaign_user_id_fk", + "tableFrom": "campaign_demand", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_demand_rels": { + "name": "campaign_demand_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "campaign_demand_rels_order_idx": { + "name": "campaign_demand_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_rels_parent_idx": { + "name": "campaign_demand_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_rels_path_idx": { + "name": "campaign_demand_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_rels_campaign_user_id_idx": { + "name": "campaign_demand_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "campaign_demand_rels_media_id_idx": { + "name": "campaign_demand_rels_media_id_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "campaign_demand_rels_parent_fk": { + "name": "campaign_demand_rels_parent_fk", + "tableFrom": "campaign_demand_rels", + "tableTo": "campaign_demand", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "campaign_demand_rels_campaign_user_fk": { + "name": "campaign_demand_rels_campaign_user_fk", + "tableFrom": "campaign_demand_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "campaign_demand_rels_media_fk": { + "name": "campaign_demand_rels_media_fk", + "tableFrom": "campaign_demand_rels", + "tableTo": "media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.supporter": { + "name": "supporter", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vote_intention": { + "name": "vote_intention", + "type": "enum_supporter_vote_intention", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "consent_content_hash": { + "name": "consent_content_hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "consented_at": { + "name": "consented_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "vote_intention_consent_id": { + "name": "vote_intention_consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vote_intention_consent_content_hash": { + "name": "vote_intention_consent_content_hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "vote_intention_consented_at": { + "name": "vote_intention_consented_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "enum_supporter_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'manual'" + }, + "consent_note": { + "name": "consent_note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "supporter_contact_idx": { + "name": "supporter_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_municipality_idx": { + "name": "supporter_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_vote_intention_idx": { + "name": "supporter_vote_intention_idx", + "columns": [ + { + "expression": "vote_intention", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_consent_idx": { + "name": "supporter_consent_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_vote_intention_consent_idx": { + "name": "supporter_vote_intention_consent_idx", + "columns": [ + { + "expression": "vote_intention_consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_source_idx": { + "name": "supporter_source_idx", + "columns": [ + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_created_by_idx": { + "name": "supporter_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_updated_at_idx": { + "name": "supporter_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_created_at_idx": { + "name": "supporter_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "supporter_contact_id_contact_id_fk": { + "name": "supporter_contact_id_contact_id_fk", + "tableFrom": "supporter", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "supporter_municipality_id_municipality_id_fk": { + "name": "supporter_municipality_id_municipality_id_fk", + "tableFrom": "supporter", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "supporter_consent_id_consent_id_fk": { + "name": "supporter_consent_id_consent_id_fk", + "tableFrom": "supporter", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "supporter_vote_intention_consent_id_consent_id_fk": { + "name": "supporter_vote_intention_consent_id_consent_id_fk", + "tableFrom": "supporter", + "tableTo": "consent", + "columnsFrom": [ + "vote_intention_consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "supporter_created_by_id_campaign_user_id_fk": { + "name": "supporter_created_by_id_campaign_user_id_fk", + "tableFrom": "supporter", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.supporter_import_batch": { + "name": "supporter_import_batch", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "rows": { + "name": "rows", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "supporter_import_batch_batch_id_idx": { + "name": "supporter_import_batch_batch_id_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_import_batch_actor_idx": { + "name": "supporter_import_batch_actor_idx", + "columns": [ + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_import_batch_expires_at_idx": { + "name": "supporter_import_batch_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_import_batch_updated_at_idx": { + "name": "supporter_import_batch_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "supporter_import_batch_created_at_idx": { + "name": "supporter_import_batch_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "supporter_import_batch_actor_id_campaign_user_id_fk": { + "name": "supporter_import_batch_actor_id_campaign_user_id_fk", + "tableFrom": "supporter_import_batch", + "tableTo": "campaign_user", + "columnsFrom": [ + "actor_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality_update_comments": { + "name": "municipality_update_comments", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "body": { + "name": "body", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "municipality_update_comments_order_idx": { + "name": "municipality_update_comments_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_comments_parent_id_idx": { + "name": "municipality_update_comments_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_comments_author_idx": { + "name": "municipality_update_comments_author_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_update_comments_author_id_campaign_user_id_fk": { + "name": "municipality_update_comments_author_id_campaign_user_id_fk", + "tableFrom": "municipality_update_comments", + "tableTo": "campaign_user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "municipality_update_comments_parent_id_fk": { + "name": "municipality_update_comments_parent_id_fk", + "tableFrom": "municipality_update_comments", + "tableTo": "municipality_update", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.municipality_update": { + "name": "municipality_update", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "polarity": { + "name": "polarity", + "type": "enum_municipality_update_polarity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'neutra'" + }, + "urgent": { + "name": "urgent", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "adversary_signal": { + "name": "adversary_signal", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "body": { + "name": "body", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "active_volunteers": { + "name": "active_volunteers", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "new_supports": { + "name": "new_supports", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "responsible_id": { + "name": "responsible_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "resolved_by_id": { + "name": "resolved_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "municipality_update_municipality_idx": { + "name": "municipality_update_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_author_idx": { + "name": "municipality_update_author_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_polarity_idx": { + "name": "municipality_update_polarity_idx", + "columns": [ + { + "expression": "polarity", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_urgent_idx": { + "name": "municipality_update_urgent_idx", + "columns": [ + { + "expression": "urgent", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_adversary_signal_idx": { + "name": "municipality_update_adversary_signal_idx", + "columns": [ + { + "expression": "adversary_signal", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_responsible_idx": { + "name": "municipality_update_responsible_idx", + "columns": [ + { + "expression": "responsible_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_resolved_by_idx": { + "name": "municipality_update_resolved_by_idx", + "columns": [ + { + "expression": "resolved_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_resolved_at_idx": { + "name": "municipality_update_resolved_at_idx", + "columns": [ + { + "expression": "resolved_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_updated_at_idx": { + "name": "municipality_update_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "municipality_update_created_at_idx": { + "name": "municipality_update_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "municipality_update_municipality_id_municipality_id_fk": { + "name": "municipality_update_municipality_id_municipality_id_fk", + "tableFrom": "municipality_update", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "municipality_update_author_id_campaign_user_id_fk": { + "name": "municipality_update_author_id_campaign_user_id_fk", + "tableFrom": "municipality_update", + "tableTo": "campaign_user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "municipality_update_responsible_id_campaign_user_id_fk": { + "name": "municipality_update_responsible_id_campaign_user_id_fk", + "tableFrom": "municipality_update", + "tableTo": "campaign_user", + "columnsFrom": [ + "responsible_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "municipality_update_resolved_by_id_campaign_user_id_fk": { + "name": "municipality_update_resolved_by_id_campaign_user_id_fk", + "tableFrom": "municipality_update", + "tableTo": "campaign_user", + "columnsFrom": [ + "resolved_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.activity_tasks": { + "name": "activity_tasks", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "responsible_id": { + "name": "responsible_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "done": { + "name": "done", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "done_at": { + "name": "done_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "activity_tasks_order_idx": { + "name": "activity_tasks_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_tasks_parent_id_idx": { + "name": "activity_tasks_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_tasks_responsible_idx": { + "name": "activity_tasks_responsible_idx", + "columns": [ + { + "expression": "responsible_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "activity_tasks_responsible_id_contact_id_fk": { + "name": "activity_tasks_responsible_id_contact_id_fk", + "tableFrom": "activity_tasks", + "tableTo": "contact", + "columnsFrom": [ + "responsible_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "activity_tasks_parent_id_fk": { + "name": "activity_tasks_parent_id_fk", + "tableFrom": "activity_tasks", + "tableTo": "activity", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.activity_updates": { + "name": "activity_updates", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "body": { + "name": "body", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "activity_updates_order_idx": { + "name": "activity_updates_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_updates_parent_id_idx": { + "name": "activity_updates_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_updates_author_idx": { + "name": "activity_updates_author_idx", + "columns": [ + { + "expression": "author_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "activity_updates_author_id_campaign_user_id_fk": { + "name": "activity_updates_author_id_campaign_user_id_fk", + "tableFrom": "activity_updates", + "tableTo": "campaign_user", + "columnsFrom": [ + "author_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "activity_updates_parent_id_fk": { + "name": "activity_updates_parent_id_fk", + "tableFrom": "activity_updates", + "tableTo": "activity", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.activity": { + "name": "activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "enum_activity_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'confirmado'" + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "deputy_present": { + "name": "deputy_present", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "all_day": { + "name": "all_day", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "public_event": { + "name": "public_event", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "start_at": { + "name": "start_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "end_at": { + "name": "end_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "locality": { + "name": "locality", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "task_total": { + "name": "task_total", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "task_done_count": { + "name": "task_done_count", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "result_summary": { + "name": "result_summary", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "result_recorded_by_id": { + "name": "result_recorded_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "result_recorded_at": { + "name": "result_recorded_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "last_mirrored_change_at": { + "name": "last_mirrored_change_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "google_event_id": { + "name": "google_event_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "google_calendar_id": { + "name": "google_calendar_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "activity_title_idx": { + "name": "activity_title_idx", + "columns": [ + { + "expression": "title", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_slug_idx": { + "name": "activity_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_status_idx": { + "name": "activity_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_deputy_present_idx": { + "name": "activity_deputy_present_idx", + "columns": [ + { + "expression": "deputy_present", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_all_day_idx": { + "name": "activity_all_day_idx", + "columns": [ + { + "expression": "all_day", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_public_event_idx": { + "name": "activity_public_event_idx", + "columns": [ + { + "expression": "public_event", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_start_at_idx": { + "name": "activity_start_at_idx", + "columns": [ + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_municipality_idx": { + "name": "activity_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_result_recorded_by_idx": { + "name": "activity_result_recorded_by_idx", + "columns": [ + { + "expression": "result_recorded_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_google_event_id_idx": { + "name": "activity_google_event_id_idx", + "columns": [ + { + "expression": "google_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_created_by_idx": { + "name": "activity_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_updated_at_idx": { + "name": "activity_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_created_at_idx": { + "name": "activity_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "activity_municipality_id_municipality_id_fk": { + "name": "activity_municipality_id_municipality_id_fk", + "tableFrom": "activity", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "activity_result_recorded_by_id_campaign_user_id_fk": { + "name": "activity_result_recorded_by_id_campaign_user_id_fk", + "tableFrom": "activity", + "tableTo": "campaign_user", + "columnsFrom": [ + "result_recorded_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "activity_created_by_id_campaign_user_id_fk": { + "name": "activity_created_by_id_campaign_user_id_fk", + "tableFrom": "activity", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.activity_texts": { + "name": "activity_texts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "activity_texts_order_parent": { + "name": "activity_texts_order_parent", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_texts_text_idx": { + "name": "activity_texts_text_idx", + "columns": [ + { + "expression": "text", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "activity_texts_parent_fk": { + "name": "activity_texts_parent_fk", + "tableFrom": "activity_texts", + "tableTo": "activity", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.activity_rels": { + "name": "activity_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state_deputy_id": { + "name": "state_deputy_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "activity_rels_order_idx": { + "name": "activity_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_parent_idx": { + "name": "activity_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_path_idx": { + "name": "activity_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_organization_id_idx": { + "name": "activity_rels_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_campaign_user_id_idx": { + "name": "activity_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_leadership_id_idx": { + "name": "activity_rels_leadership_id_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_state_deputy_id_idx": { + "name": "activity_rels_state_deputy_id_idx", + "columns": [ + { + "expression": "state_deputy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "activity_rels_media_id_idx": { + "name": "activity_rels_media_id_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "activity_rels_parent_fk": { + "name": "activity_rels_parent_fk", + "tableFrom": "activity_rels", + "tableTo": "activity", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "activity_rels_organization_fk": { + "name": "activity_rels_organization_fk", + "tableFrom": "activity_rels", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "activity_rels_campaign_user_fk": { + "name": "activity_rels_campaign_user_fk", + "tableFrom": "activity_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "activity_rels_leadership_fk": { + "name": "activity_rels_leadership_fk", + "tableFrom": "activity_rels", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "activity_rels_state_deputy_fk": { + "name": "activity_rels_state_deputy_fk", + "tableFrom": "activity_rels", + "tableTo": "state_deputy", + "columnsFrom": [ + "state_deputy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "activity_rels_media_fk": { + "name": "activity_rels_media_fk", + "tableFrom": "activity_rels", + "tableTo": "media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_topics": { + "name": "speech_topics", + "schema": "", + "columns": { + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "enum_speech_topics", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + } + }, + "indexes": { + "speech_topics_order_idx": { + "name": "speech_topics_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_topics_parent_idx": { + "name": "speech_topics_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_topics_value_idx": { + "name": "speech_topics_value_idx", + "columns": [ + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_topics_parent_fk": { + "name": "speech_topics_parent_fk", + "tableFrom": "speech_topics", + "tableTo": "speech", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_scopes": { + "name": "speech_scopes", + "schema": "", + "columns": { + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "enum_speech_scopes", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + } + }, + "indexes": { + "speech_scopes_order_idx": { + "name": "speech_scopes_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_scopes_parent_idx": { + "name": "speech_scopes_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_scopes_value_idx": { + "name": "speech_scopes_value_idx", + "columns": [ + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_scopes_parent_fk": { + "name": "speech_scopes_parent_fk", + "tableFrom": "speech_scopes", + "tableTo": "speech", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech": { + "name": "speech", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "source_key": { + "name": "source_key", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "speech_at": { + "name": "speech_at", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "year": { + "name": "year", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "legislature": { + "name": "legislature", + "type": "enum_speech_legislature", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "phase": { + "name": "phase", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "duration_seconds": { + "name": "duration_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "summary": { + "name": "summary", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "official_transcript": { + "name": "official_transcript", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "official_text_url": { + "name": "official_text_url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "search_text": { + "name": "search_text", + "type": "varchar", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "event_id": { + "name": "event_id", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "event_type": { + "name": "event_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "event_start_at": { + "name": "event_start_at", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "event_end_at": { + "name": "event_end_at", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "youtube_url": { + "name": "youtube_url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "presiding_officer": { + "name": "presiding_officer", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "audio_id": { + "name": "audio_id", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "excerpt_t_ms": { + "name": "excerpt_t_ms", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "vod_playback_url": { + "name": "vod_playback_url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "vod_download_url": { + "name": "vod_download_url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "classified_by": { + "name": "classified_by", + "type": "enum_speech_classified_by", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'gazetteer'" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "speech_source_key_idx": { + "name": "speech_source_key_idx", + "columns": [ + { + "expression": "source_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_speech_at_idx": { + "name": "speech_speech_at_idx", + "columns": [ + { + "expression": "speech_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_year_idx": { + "name": "speech_year_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_legislature_idx": { + "name": "speech_legislature_idx", + "columns": [ + { + "expression": "legislature", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_phase_idx": { + "name": "speech_phase_idx", + "columns": [ + { + "expression": "phase", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_event_id_idx": { + "name": "speech_event_id_idx", + "columns": [ + { + "expression": "event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_audio_id_idx": { + "name": "speech_audio_id_idx", + "columns": [ + { + "expression": "audio_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_excerpt_t_ms_idx": { + "name": "speech_excerpt_t_ms_idx", + "columns": [ + { + "expression": "excerpt_t_ms", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_classified_by_idx": { + "name": "speech_classified_by_idx", + "columns": [ + { + "expression": "classified_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_updated_at_idx": { + "name": "speech_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_created_at_idx": { + "name": "speech_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_texts": { + "name": "speech_texts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "speech_texts_order_parent": { + "name": "speech_texts_order_parent", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_texts_parent_fk": { + "name": "speech_texts_parent_fk", + "tableFrom": "speech_texts", + "tableTo": "speech", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_rels": { + "name": "speech_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "speech_rels_order_idx": { + "name": "speech_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_rels_parent_idx": { + "name": "speech_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_rels_path_idx": { + "name": "speech_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_rels_municipality_id_idx": { + "name": "speech_rels_municipality_id_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_rels_parent_fk": { + "name": "speech_rels_parent_fk", + "tableFrom": "speech_rels", + "tableTo": "speech", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "speech_rels_municipality_fk": { + "name": "speech_rels_municipality_fk", + "tableFrom": "speech_rels", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_segment": { + "name": "speech_segment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "speech_id": { + "name": "speech_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "start_seconds": { + "name": "start_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "end_seconds": { + "name": "end_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "search_text": { + "name": "search_text", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "speech_segment_speech_idx": { + "name": "speech_segment_speech_idx", + "columns": [ + { + "expression": "speech_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_segment_updated_at_idx": { + "name": "speech_segment_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_segment_created_at_idx": { + "name": "speech_segment_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_segment_speech_id_speech_id_fk": { + "name": "speech_segment_speech_id_speech_id_fk", + "tableFrom": "speech_segment", + "tableTo": "speech", + "columnsFrom": [ + "speech_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.speech_cut": { + "name": "speech_cut", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "speech_id": { + "name": "speech_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "start_seconds": { + "name": "start_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "end_seconds": { + "name": "end_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "duration_seconds": { + "name": "duration_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "enum_speech_cut_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'processing'" + }, + "step": { + "name": "step", + "type": "enum_speech_cut_step", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "speech_cut_speech_idx": { + "name": "speech_cut_speech_idx", + "columns": [ + { + "expression": "speech_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_cut_status_idx": { + "name": "speech_cut_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_cut_media_idx": { + "name": "speech_cut_media_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_cut_created_by_idx": { + "name": "speech_cut_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_cut_updated_at_idx": { + "name": "speech_cut_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "speech_cut_created_at_idx": { + "name": "speech_cut_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "speech_cut_speech_id_speech_id_fk": { + "name": "speech_cut_speech_id_speech_id_fk", + "tableFrom": "speech_cut", + "tableTo": "speech", + "columnsFrom": [ + "speech_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "speech_cut_media_id_media_id_fk": { + "name": "speech_cut_media_id_media_id_fk", + "tableFrom": "speech_cut", + "tableTo": "media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "speech_cut_created_by_id_campaign_user_id_fk": { + "name": "speech_cut_created_by_id_campaign_user_id_fk", + "tableFrom": "speech_cut", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reel": { + "name": "reel", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "feature": { + "name": "feature", + "type": "enum_reel_feature", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_hash": { + "name": "source_hash", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "enum_reel_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "video_id": { + "name": "video_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "video_with_audio_id": { + "name": "video_with_audio_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "narration_audio_id": { + "name": "narration_audio_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "captions_id": { + "name": "captions_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cover_id": { + "name": "cover_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "transcript": { + "name": "transcript", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reel_source_hash_idx": { + "name": "reel_source_hash_idx", + "columns": [ + { + "expression": "source_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_status_idx": { + "name": "reel_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_video_idx": { + "name": "reel_video_idx", + "columns": [ + { + "expression": "video_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_video_with_audio_idx": { + "name": "reel_video_with_audio_idx", + "columns": [ + { + "expression": "video_with_audio_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_narration_audio_idx": { + "name": "reel_narration_audio_idx", + "columns": [ + { + "expression": "narration_audio_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_captions_idx": { + "name": "reel_captions_idx", + "columns": [ + { + "expression": "captions_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_cover_idx": { + "name": "reel_cover_idx", + "columns": [ + { + "expression": "cover_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_created_by_idx": { + "name": "reel_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_updated_at_idx": { + "name": "reel_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_created_at_idx": { + "name": "reel_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reel_video_id_reel_media_id_fk": { + "name": "reel_video_id_reel_media_id_fk", + "tableFrom": "reel", + "tableTo": "reel_media", + "columnsFrom": [ + "video_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reel_video_with_audio_id_reel_media_id_fk": { + "name": "reel_video_with_audio_id_reel_media_id_fk", + "tableFrom": "reel", + "tableTo": "reel_media", + "columnsFrom": [ + "video_with_audio_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reel_narration_audio_id_reel_media_id_fk": { + "name": "reel_narration_audio_id_reel_media_id_fk", + "tableFrom": "reel", + "tableTo": "reel_media", + "columnsFrom": [ + "narration_audio_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reel_captions_id_reel_media_id_fk": { + "name": "reel_captions_id_reel_media_id_fk", + "tableFrom": "reel", + "tableTo": "reel_media", + "columnsFrom": [ + "captions_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reel_cover_id_reel_media_id_fk": { + "name": "reel_cover_id_reel_media_id_fk", + "tableFrom": "reel", + "tableTo": "reel_media", + "columnsFrom": [ + "cover_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reel_created_by_id_campaign_user_id_fk": { + "name": "reel_created_by_id_campaign_user_id_fk", + "tableFrom": "reel", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reel_media": { + "name": "reel_media", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "alt": { + "name": "alt", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "reel_media_updated_at_idx": { + "name": "reel_media_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_media_created_at_idx": { + "name": "reel_media_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reel_media_filename_idx": { + "name": "reel_media_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_piece_topics": { + "name": "content_piece_topics", + "schema": "", + "columns": { + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "enum_content_piece_topics", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + } + }, + "indexes": { + "content_piece_topics_order_idx": { + "name": "content_piece_topics_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_topics_parent_idx": { + "name": "content_piece_topics_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_topics_value_idx": { + "name": "content_piece_topics_value_idx", + "columns": [ + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_piece_topics_parent_fk": { + "name": "content_piece_topics_parent_fk", + "tableFrom": "content_piece_topics", + "tableTo": "content_piece", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_piece_curated_fields": { + "name": "content_piece_curated_fields", + "schema": "", + "columns": { + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "enum_content_piece_curated_fields", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + } + }, + "indexes": { + "content_piece_curated_fields_order_idx": { + "name": "content_piece_curated_fields_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_curated_fields_parent_idx": { + "name": "content_piece_curated_fields_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_piece_curated_fields_parent_fk": { + "name": "content_piece_curated_fields_parent_fk", + "tableFrom": "content_piece_curated_fields", + "tableTo": "content_piece", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_piece": { + "name": "content_piece", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "enum_content_piece_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "city_label": { + "name": "city_label", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "region": { + "name": "region", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "institution": { + "name": "institution", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "piece_date": { + "name": "piece_date", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "duration_seconds": { + "name": "duration_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "transcript": { + "name": "transcript", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "source_url": { + "name": "source_url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "origin": { + "name": "origin", + "type": "enum_content_piece_origin", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'arquivo'" + }, + "status": { + "name": "status", + "type": "enum_content_piece_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'rascunho'" + }, + "published_at": { + "name": "published_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "processing_status": { + "name": "processing_status", + "type": "enum_content_piece_processing_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pronto'" + }, + "step": { + "name": "step", + "type": "enum_content_piece_step", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "search_text": { + "name": "search_text", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "content_piece_slug_idx": { + "name": "content_piece_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_type_idx": { + "name": "content_piece_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_municipality_idx": { + "name": "content_piece_municipality_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_piece_date_idx": { + "name": "content_piece_piece_date_idx", + "columns": [ + { + "expression": "piece_date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_media_idx": { + "name": "content_piece_media_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_source_url_idx": { + "name": "content_piece_source_url_idx", + "columns": [ + { + "expression": "source_url", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_status_idx": { + "name": "content_piece_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_processing_status_idx": { + "name": "content_piece_processing_status_idx", + "columns": [ + { + "expression": "processing_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_created_by_idx": { + "name": "content_piece_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_updated_at_idx": { + "name": "content_piece_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_created_at_idx": { + "name": "content_piece_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_piece_municipality_id_municipality_id_fk": { + "name": "content_piece_municipality_id_municipality_id_fk", + "tableFrom": "content_piece", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "content_piece_media_id_content_media_id_fk": { + "name": "content_piece_media_id_content_media_id_fk", + "tableFrom": "content_piece", + "tableTo": "content_media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "content_piece_created_by_id_campaign_user_id_fk": { + "name": "content_piece_created_by_id_campaign_user_id_fk", + "tableFrom": "content_piece", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_piece_texts": { + "name": "content_piece_texts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "content_piece_texts_order_parent": { + "name": "content_piece_texts_order_parent", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_piece_texts_parent_fk": { + "name": "content_piece_texts_parent_fk", + "tableFrom": "content_piece_texts", + "tableTo": "content_piece", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_piece_rels": { + "name": "content_piece_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "content_piece_rels_order_idx": { + "name": "content_piece_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_rels_parent_idx": { + "name": "content_piece_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_rels_path_idx": { + "name": "content_piece_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_piece_rels_leadership_id_idx": { + "name": "content_piece_rels_leadership_id_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_piece_rels_parent_fk": { + "name": "content_piece_rels_parent_fk", + "tableFrom": "content_piece_rels", + "tableTo": "content_piece", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "content_piece_rels_leadership_fk": { + "name": "content_piece_rels_leadership_fk", + "tableFrom": "content_piece_rels", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_media": { + "name": "content_media", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "alt": { + "name": "alt", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "content_media_updated_at_idx": { + "name": "content_media_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_media_created_at_idx": { + "name": "content_media_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_media_filename_idx": { + "name": "content_media_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_event": { + "name": "content_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "type": { + "name": "type", + "type": "enum_content_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subject_type": { + "name": "subject_type", + "type": "enum_content_event_subject_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subject_id": { + "name": "subject_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "variant": { + "name": "variant", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "content_event_updated_at_idx": { + "name": "content_event_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_event_created_at_idx": { + "name": "content_event_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "subjectType_subjectId_type_idx": { + "name": "subjectType_subjectId_type_idx", + "columns": [ + { + "expression": "subject_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recording_speaker_labels": { + "name": "recording_speaker_labels", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "speaker_key": { + "name": "speaker_key", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "recording_speaker_labels_order_idx": { + "name": "recording_speaker_labels_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_speaker_labels_parent_id_idx": { + "name": "recording_speaker_labels_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recording_speaker_labels_parent_id_fk": { + "name": "recording_speaker_labels_parent_id_fk", + "tableFrom": "recording_speaker_labels", + "tableTo": "recording", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recording": { + "name": "recording", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "recorded_at": { + "name": "recorded_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "enum_recording_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'uploading'" + }, + "step": { + "name": "step", + "type": "enum_recording_step", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_seconds": { + "name": "duration_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "search_text": { + "name": "search_text", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "speaker_labels_dropped": { + "name": "speaker_labels_dropped", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "recording_recorded_at_idx": { + "name": "recording_recorded_at_idx", + "columns": [ + { + "expression": "recorded_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_status_idx": { + "name": "recording_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_media_idx": { + "name": "recording_media_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_created_by_idx": { + "name": "recording_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_updated_at_idx": { + "name": "recording_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_created_at_idx": { + "name": "recording_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recording_media_id_recording_media_id_fk": { + "name": "recording_media_id_recording_media_id_fk", + "tableFrom": "recording", + "tableTo": "recording_media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "recording_created_by_id_campaign_user_id_fk": { + "name": "recording_created_by_id_campaign_user_id_fk", + "tableFrom": "recording", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recording_texts": { + "name": "recording_texts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "recording_texts_order_parent": { + "name": "recording_texts_order_parent", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recording_texts_parent_fk": { + "name": "recording_texts_parent_fk", + "tableFrom": "recording_texts", + "tableTo": "recording", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recording_media": { + "name": "recording_media", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "alt": { + "name": "alt", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "recording_media_updated_at_idx": { + "name": "recording_media_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_media_created_at_idx": { + "name": "recording_media_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_media_filename_idx": { + "name": "recording_media_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recording_segment": { + "name": "recording_segment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "recording_id": { + "name": "recording_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "speaker_key": { + "name": "speaker_key", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "start_seconds": { + "name": "start_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "end_seconds": { + "name": "end_seconds", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "search_text": { + "name": "search_text", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "recording_segment_recording_idx": { + "name": "recording_segment_recording_idx", + "columns": [ + { + "expression": "recording_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_segment_updated_at_idx": { + "name": "recording_segment_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recording_segment_created_at_idx": { + "name": "recording_segment_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recording_segment_recording_id_recording_id_fk": { + "name": "recording_segment_recording_id_recording_id_fk", + "tableFrom": "recording_segment", + "tableTo": "recording", + "columnsFrom": [ + "recording_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.calendar_feed": { + "name": "calendar_feed", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "secret_slug": { + "name": "secret_slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "filter_municipality_id": { + "name": "filter_municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "filter_deputy_present": { + "name": "filter_deputy_present", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "filter_tag": { + "name": "filter_tag", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_id": { + "name": "created_by_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "calendar_feed_secret_slug_idx": { + "name": "calendar_feed_secret_slug_idx", + "columns": [ + { + "expression": "secret_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "calendar_feed_filter_municipality_idx": { + "name": "calendar_feed_filter_municipality_idx", + "columns": [ + { + "expression": "filter_municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "calendar_feed_revoked_at_idx": { + "name": "calendar_feed_revoked_at_idx", + "columns": [ + { + "expression": "revoked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "calendar_feed_created_by_idx": { + "name": "calendar_feed_created_by_idx", + "columns": [ + { + "expression": "created_by_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "calendar_feed_updated_at_idx": { + "name": "calendar_feed_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "calendar_feed_created_at_idx": { + "name": "calendar_feed_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "calendar_feed_filter_municipality_id_municipality_id_fk": { + "name": "calendar_feed_filter_municipality_id_municipality_id_fk", + "tableFrom": "calendar_feed", + "tableTo": "municipality", + "columnsFrom": [ + "filter_municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "calendar_feed_created_by_id_campaign_user_id_fk": { + "name": "calendar_feed_created_by_id_campaign_user_id_fk", + "tableFrom": "calendar_feed", + "tableTo": "campaign_user", + "columnsFrom": [ + "created_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.google_calendar_sync": { + "name": "google_calendar_sync", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "oauth_refresh_token": { + "name": "oauth_refresh_token", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "oauth_scope": { + "name": "oauth_scope", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "oauth_connected_at": { + "name": "oauth_connected_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "oauth_error_at": { + "name": "oauth_error_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "oauth_error": { + "name": "oauth_error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "last_success_at": { + "name": "last_success_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error_at": { + "name": "last_error_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "push_channel_id": { + "name": "push_channel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "push_channel_resource_id": { + "name": "push_channel_resource_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "push_channel_expires_at": { + "name": "push_channel_expires_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "push_channel_secret": { + "name": "push_channel_secret", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "push_channel_error": { + "name": "push_channel_error", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "last_seen_event_ids": { + "name": "last_seen_event_ids", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "google_calendar_sync_calendar_id_idx": { + "name": "google_calendar_sync_calendar_id_idx", + "columns": [ + { + "expression": "calendar_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "google_calendar_sync_disabled_at_idx": { + "name": "google_calendar_sync_disabled_at_idx", + "columns": [ + { + "expression": "disabled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "google_calendar_sync_updated_at_idx": { + "name": "google_calendar_sync_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "google_calendar_sync_created_at_idx": { + "name": "google_calendar_sync_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.election_tally": { + "name": "election_tally", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "year": { + "name": "year", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "office": { + "name": "office", + "type": "enum_election_tally_office", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "turn": { + "name": "turn", + "type": "enum_election_tally_turn", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'BA'" + }, + "city_code": { + "name": "city_code", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "city_name": { + "name": "city_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "zone_number": { + "name": "zone_number", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "aptos": { + "name": "aptos", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "comparecimento": { + "name": "comparecimento", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "abstencoes": { + "name": "abstencoes", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_validos": { + "name": "votos_validos", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_nominais_validos": { + "name": "votos_nominais_validos", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_legenda": { + "name": "votos_legenda", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_branco": { + "name": "votos_branco", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_nulo": { + "name": "votos_nulo", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "votos_anulados": { + "name": "votos_anulados", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "winner_candidate_number": { + "name": "winner_candidate_number", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "winner_candidate_name": { + "name": "winner_candidate_name", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "winner_votes": { + "name": "winner_votes", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "winner_coalition": { + "name": "winner_coalition", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "winner_party": { + "name": "winner_party", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "election_tally_year_idx": { + "name": "election_tally_year_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_office_idx": { + "name": "election_tally_office_idx", + "columns": [ + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_turn_idx": { + "name": "election_tally_turn_idx", + "columns": [ + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_state_idx": { + "name": "election_tally_state_idx", + "columns": [ + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_city_code_idx": { + "name": "election_tally_city_code_idx", + "columns": [ + { + "expression": "city_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_city_name_idx": { + "name": "election_tally_city_name_idx", + "columns": [ + { + "expression": "city_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_zone_number_idx": { + "name": "election_tally_zone_number_idx", + "columns": [ + { + "expression": "zone_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_updated_at_idx": { + "name": "election_tally_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_tally_created_at_idx": { + "name": "election_tally_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "year_office_turn_state_cityCode_zoneNumber_idx": { + "name": "year_office_turn_state_cityCode_zoneNumber_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "city_code", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "zone_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.election_candidate_vote": { + "name": "election_candidate_vote", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "year": { + "name": "year", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "office": { + "name": "office", + "type": "enum_election_candidate_vote_office", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "turn": { + "name": "turn", + "type": "enum_election_candidate_vote_turn", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'BA'" + }, + "city_code": { + "name": "city_code", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "city_name": { + "name": "city_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "zone_number": { + "name": "zone_number", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "candidate_number": { + "name": "candidate_number", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "candidate_name": { + "name": "candidate_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "coalition": { + "name": "coalition", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "party": { + "name": "party", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "vote_type": { + "name": "vote_type", + "type": "enum_election_candidate_vote_vote_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'nominal'" + }, + "votes": { + "name": "votes", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "election_candidate_vote_year_idx": { + "name": "election_candidate_vote_year_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_office_idx": { + "name": "election_candidate_vote_office_idx", + "columns": [ + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_turn_idx": { + "name": "election_candidate_vote_turn_idx", + "columns": [ + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_state_idx": { + "name": "election_candidate_vote_state_idx", + "columns": [ + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_city_code_idx": { + "name": "election_candidate_vote_city_code_idx", + "columns": [ + { + "expression": "city_code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_city_name_idx": { + "name": "election_candidate_vote_city_name_idx", + "columns": [ + { + "expression": "city_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_zone_number_idx": { + "name": "election_candidate_vote_zone_number_idx", + "columns": [ + { + "expression": "zone_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_candidate_number_idx": { + "name": "election_candidate_vote_candidate_number_idx", + "columns": [ + { + "expression": "candidate_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_vote_type_idx": { + "name": "election_candidate_vote_vote_type_idx", + "columns": [ + { + "expression": "vote_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_updated_at_idx": { + "name": "election_candidate_vote_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_vote_created_at_idx": { + "name": "election_candidate_vote_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "compound_index_idx": { + "name": "compound_index_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "city_code", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "zone_number", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "candidate_number", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "vote_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.election_candidate": { + "name": "election_candidate", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "year": { + "name": "year", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "office": { + "name": "office", + "type": "enum_election_candidate_office", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "turn": { + "name": "turn", + "type": "enum_election_candidate_turn", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'BA'" + }, + "candidate_number": { + "name": "candidate_number", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "urna_name": { + "name": "urna_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "complete_name": { + "name": "complete_name", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "party": { + "name": "party", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "coalition": { + "name": "coalition", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "candidate_status": { + "name": "candidate_status", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "elected": { + "name": "elected", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "elected_by": { + "name": "elected_by", + "type": "enum_election_candidate_elected_by", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "total_votes_state": { + "name": "total_votes_state", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "identity_key": { + "name": "identity_key", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "running_again2026": { + "name": "running_again2026", + "type": "enum_election_candidate_running_again2026", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'desconhecido'" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "election_candidate_year_idx": { + "name": "election_candidate_year_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_office_idx": { + "name": "election_candidate_office_idx", + "columns": [ + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_turn_idx": { + "name": "election_candidate_turn_idx", + "columns": [ + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_state_idx": { + "name": "election_candidate_state_idx", + "columns": [ + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_candidate_number_idx": { + "name": "election_candidate_candidate_number_idx", + "columns": [ + { + "expression": "candidate_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_elected_idx": { + "name": "election_candidate_elected_idx", + "columns": [ + { + "expression": "elected", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_identity_key_idx": { + "name": "election_candidate_identity_key_idx", + "columns": [ + { + "expression": "identity_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_updated_at_idx": { + "name": "election_candidate_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "election_candidate_created_at_idx": { + "name": "election_candidate_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "year_office_turn_state_candidateNumber_idx": { + "name": "year_office_turn_state_candidateNumber_idx", + "columns": [ + { + "expression": "year", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "office", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "turn", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "state", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "candidate_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.media": { + "name": "media", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "alt": { + "name": "alt", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "media_updated_at_idx": { + "name": "media_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "media_created_at_idx": { + "name": "media_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "media_filename_idx": { + "name": "media_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.petition": { + "name": "petition", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "subtitle": { + "name": "subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "form_title": { + "name": "form_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "form_subtitle": { + "name": "form_subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "form_consent_id": { + "name": "form_consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tracking_facebook_pixel_id": { + "name": "tracking_facebook_pixel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "_status": { + "name": "_status", + "type": "enum_petition_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + } + }, + "indexes": { + "petition_form_form_consent_idx": { + "name": "petition_form_form_consent_idx", + "columns": [ + { + "expression": "form_consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "petition_updated_at_idx": { + "name": "petition_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "petition_created_at_idx": { + "name": "petition_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "petition__status_idx": { + "name": "petition__status_idx", + "columns": [ + { + "expression": "_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "petition_form_consent_id_consent_id_fk": { + "name": "petition_form_consent_id_consent_id_fk", + "tableFrom": "petition", + "tableTo": "consent", + "columnsFrom": [ + "form_consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._petition_v": { + "name": "_petition_v", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_title": { + "name": "version_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_subtitle": { + "name": "version_subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_enabled": { + "name": "version_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "version_body": { + "name": "version_body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "version_form_title": { + "name": "version_form_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_form_subtitle": { + "name": "version_form_subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_form_consent_id": { + "name": "version_form_consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_tracking_facebook_pixel_id": { + "name": "version_tracking_facebook_pixel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_updated_at": { + "name": "version_updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_created_at": { + "name": "version_created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version__status": { + "name": "version__status", + "type": "enum__petition_v_version_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "latest": { + "name": "latest", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "_petition_v_parent_idx": { + "name": "_petition_v_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_version_form_version_form_consent_idx": { + "name": "_petition_v_version_form_version_form_consent_idx", + "columns": [ + { + "expression": "version_form_consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_version_version_updated_at_idx": { + "name": "_petition_v_version_version_updated_at_idx", + "columns": [ + { + "expression": "version_updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_version_version_created_at_idx": { + "name": "_petition_v_version_version_created_at_idx", + "columns": [ + { + "expression": "version_created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_version_version__status_idx": { + "name": "_petition_v_version_version__status_idx", + "columns": [ + { + "expression": "version__status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_created_at_idx": { + "name": "_petition_v_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_updated_at_idx": { + "name": "_petition_v_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_petition_v_latest_idx": { + "name": "_petition_v_latest_idx", + "columns": [ + { + "expression": "latest", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "_petition_v_parent_id_petition_id_fk": { + "name": "_petition_v_parent_id_petition_id_fk", + "tableFrom": "_petition_v", + "tableTo": "petition", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_petition_v_version_form_consent_id_consent_id_fk": { + "name": "_petition_v_version_form_consent_id_consent_id_fk", + "tableFrom": "_petition_v", + "tableTo": "consent", + "columnsFrom": [ + "version_form_consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact_phones": { + "name": "contact_phones", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "contact_phones_order_idx": { + "name": "contact_phones_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_phones_parent_id_idx": { + "name": "contact_phones_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_phones_value_idx": { + "name": "contact_phones_value_idx", + "columns": [ + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contact_phones_parent_id_fk": { + "name": "contact_phones_parent_id_fk", + "tableFrom": "contact_phones", + "tableTo": "contact", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact": { + "name": "contact", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "gender": { + "name": "gender", + "type": "enum_contact_gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "enum_contact_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "contact_updated_at_idx": { + "name": "contact_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_created_at_idx": { + "name": "contact_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.consent": { + "name": "consent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "consent_key_idx": { + "name": "consent_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "consent_updated_at_idx": { + "name": "consent_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "consent_created_at_idx": { + "name": "consent_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.signature": { + "name": "signature", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "petition_id": { + "name": "petition_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "comment": { + "name": "comment", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "signature_contact_idx": { + "name": "signature_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "signature_petition_idx": { + "name": "signature_petition_idx", + "columns": [ + { + "expression": "petition_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "signature_consent_idx": { + "name": "signature_consent_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "signature_updated_at_idx": { + "name": "signature_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "signature_created_at_idx": { + "name": "signature_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "signature_contact_id_contact_id_fk": { + "name": "signature_contact_id_contact_id_fk", + "tableFrom": "signature", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "signature_petition_id_petition_id_fk": { + "name": "signature_petition_id_petition_id_fk", + "tableFrom": "signature", + "tableTo": "petition", + "columnsFrom": [ + "petition_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "signature_consent_id_consent_id_fk": { + "name": "signature_consent_id_consent_id_fk", + "tableFrom": "signature", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.subscription": { + "name": "subscription", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "comment": { + "name": "comment", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "campaign_level": { + "name": "campaign_level", + "type": "enum_subscription_campaign_level", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "subscription_contact_idx": { + "name": "subscription_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "subscription_consent_idx": { + "name": "subscription_consent_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "subscription_updated_at_idx": { + "name": "subscription_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "subscription_created_at_idx": { + "name": "subscription_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "subscription_contact_id_contact_id_fk": { + "name": "subscription_contact_id_contact_id_fk", + "tableFrom": "subscription", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "subscription_consent_id_consent_id_fk": { + "name": "subscription_consent_id_consent_id_fk", + "tableFrom": "subscription", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.post": { + "name": "post", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "enum_post_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "category_id": { + "name": "category_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "subtitle": { + "name": "subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "cover_image_id": { + "name": "cover_image_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "published_date": { + "name": "published_date", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "_status": { + "name": "_status", + "type": "enum_post_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + } + }, + "indexes": { + "post_slug_idx": { + "name": "post_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_category_idx": { + "name": "post_category_idx", + "columns": [ + { + "expression": "category_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_cover_image_idx": { + "name": "post_cover_image_idx", + "columns": [ + { + "expression": "cover_image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_updated_at_idx": { + "name": "post_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_created_at_idx": { + "name": "post_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post__status_idx": { + "name": "post__status_idx", + "columns": [ + { + "expression": "_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "post_category_id_tag_id_fk": { + "name": "post_category_id_tag_id_fk", + "tableFrom": "post", + "tableTo": "tag", + "columnsFrom": [ + "category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "post_cover_image_id_media_id_fk": { + "name": "post_cover_image_id_media_id_fk", + "tableFrom": "post", + "tableTo": "media", + "columnsFrom": [ + "cover_image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.post_rels": { + "name": "post_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "post_rels_order_idx": { + "name": "post_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_rels_parent_idx": { + "name": "post_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_rels_path_idx": { + "name": "post_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "post_rels_tag_id_idx": { + "name": "post_rels_tag_id_idx", + "columns": [ + { + "expression": "tag_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "post_rels_parent_fk": { + "name": "post_rels_parent_fk", + "tableFrom": "post_rels", + "tableTo": "post", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "post_rels_tag_fk": { + "name": "post_rels_tag_fk", + "tableFrom": "post_rels", + "tableTo": "tag", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._post_v": { + "name": "_post_v", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_title": { + "name": "version_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_slug": { + "name": "version_slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_type": { + "name": "version_type", + "type": "enum__post_v_version_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "version_category_id": { + "name": "version_category_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_subtitle": { + "name": "version_subtitle", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_cover_image_id": { + "name": "version_cover_image_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "version_published_date": { + "name": "version_published_date", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_body": { + "name": "version_body", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "version_updated_at": { + "name": "version_updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_created_at": { + "name": "version_created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version__status": { + "name": "version__status", + "type": "enum__post_v_version_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "latest": { + "name": "latest", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "_post_v_parent_idx": { + "name": "_post_v_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version_slug_idx": { + "name": "_post_v_version_version_slug_idx", + "columns": [ + { + "expression": "version_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version_category_idx": { + "name": "_post_v_version_version_category_idx", + "columns": [ + { + "expression": "version_category_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version_cover_image_idx": { + "name": "_post_v_version_version_cover_image_idx", + "columns": [ + { + "expression": "version_cover_image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version_updated_at_idx": { + "name": "_post_v_version_version_updated_at_idx", + "columns": [ + { + "expression": "version_updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version_created_at_idx": { + "name": "_post_v_version_version_created_at_idx", + "columns": [ + { + "expression": "version_created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_version_version__status_idx": { + "name": "_post_v_version_version__status_idx", + "columns": [ + { + "expression": "version__status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_created_at_idx": { + "name": "_post_v_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_updated_at_idx": { + "name": "_post_v_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_latest_idx": { + "name": "_post_v_latest_idx", + "columns": [ + { + "expression": "latest", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "_post_v_parent_id_post_id_fk": { + "name": "_post_v_parent_id_post_id_fk", + "tableFrom": "_post_v", + "tableTo": "post", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_post_v_version_category_id_tag_id_fk": { + "name": "_post_v_version_category_id_tag_id_fk", + "tableFrom": "_post_v", + "tableTo": "tag", + "columnsFrom": [ + "version_category_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "_post_v_version_cover_image_id_media_id_fk": { + "name": "_post_v_version_cover_image_id_media_id_fk", + "tableFrom": "_post_v", + "tableTo": "media", + "columnsFrom": [ + "version_cover_image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._post_v_rels": { + "name": "_post_v_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "_post_v_rels_order_idx": { + "name": "_post_v_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_rels_parent_idx": { + "name": "_post_v_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_rels_path_idx": { + "name": "_post_v_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_post_v_rels_tag_id_idx": { + "name": "_post_v_rels_tag_id_idx", + "columns": [ + { + "expression": "tag_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "_post_v_rels_parent_fk": { + "name": "_post_v_rels_parent_fk", + "tableFrom": "_post_v_rels", + "tableTo": "_post_v", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "_post_v_rels_tag_fk": { + "name": "_post_v_rels_tag_fk", + "tableFrom": "_post_v_rels", + "tableTo": "tag", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tag": { + "name": "tag", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "hidden": { + "name": "hidden", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tag_slug_idx": { + "name": "tag_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tag_updated_at_idx": { + "name": "tag_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "tag_created_at_idx": { + "name": "tag_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.share_link_destinations": { + "name": "share_link_destinations", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "live": { + "name": "live", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": { + "share_link_destinations_order_idx": { + "name": "share_link_destinations_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "share_link_destinations_parent_id_idx": { + "name": "share_link_destinations_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "share_link_destinations_parent_id_fk": { + "name": "share_link_destinations_parent_id_fk", + "tableFrom": "share_link_destinations", + "tableTo": "share_link", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.share_link": { + "name": "share_link", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "enum_share_link_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'direct'" + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "image_id": { + "name": "image_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "starts_at": { + "name": "starts_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "ends_at": { + "name": "ends_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "share_link_slug_idx": { + "name": "share_link_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "share_link_image_idx": { + "name": "share_link_image_idx", + "columns": [ + { + "expression": "image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "share_link_updated_at_idx": { + "name": "share_link_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "share_link_created_at_idx": { + "name": "share_link_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "share_link_image_id_media_id_fk": { + "name": "share_link_image_id_media_id_fk", + "tableFrom": "share_link", + "tableTo": "media", + "columnsFrom": [ + "image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.jingle": { + "name": "jingle", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "cover_image_id": { + "name": "cover_image_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "audio_id": { + "name": "audio_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "order": { + "name": "order", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "jingle_slug_idx": { + "name": "jingle_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "jingle_cover_image_idx": { + "name": "jingle_cover_image_idx", + "columns": [ + { + "expression": "cover_image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "jingle_audio_idx": { + "name": "jingle_audio_idx", + "columns": [ + { + "expression": "audio_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "jingle_updated_at_idx": { + "name": "jingle_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "jingle_created_at_idx": { + "name": "jingle_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "jingle_cover_image_id_media_id_fk": { + "name": "jingle_cover_image_id_media_id_fk", + "tableFrom": "jingle", + "tableTo": "media", + "columnsFrom": [ + "cover_image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "jingle_audio_id_media_id_fk": { + "name": "jingle_audio_id_media_id_fk", + "tableFrom": "jingle", + "tableTo": "media", + "columnsFrom": [ + "audio_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exports": { + "name": "exports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "format": { + "name": "format", + "type": "enum_exports_format", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'csv'" + }, + "limit": { + "name": "limit", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "page": { + "name": "page", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "sort": { + "name": "sort", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "sort_order": { + "name": "sort_order", + "type": "enum_exports_sort_order", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "drafts": { + "name": "drafts", + "type": "enum_exports_drafts", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'yes'" + }, + "collection_slug": { + "name": "collection_slug", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'signature'" + }, + "where": { + "name": "where", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "exports_updated_at_idx": { + "name": "exports_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "exports_created_at_idx": { + "name": "exports_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "exports_filename_idx": { + "name": "exports_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.exports_texts": { + "name": "exports_texts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "exports_texts_order_parent": { + "name": "exports_texts_order_parent", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "exports_texts_parent_fk": { + "name": "exports_texts_parent_fk", + "tableFrom": "exports_texts", + "tableTo": "exports", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.imports": { + "name": "imports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "collection_slug": { + "name": "collection_slug", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "import_mode": { + "name": "import_mode", + "type": "enum_imports_import_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "match_field": { + "name": "match_field", + "type": "varchar", + "primaryKey": false, + "notNull": false, + "default": "'id'" + }, + "status": { + "name": "status", + "type": "enum_imports_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'pending'" + }, + "summary_imported": { + "name": "summary_imported", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "summary_updated": { + "name": "summary_updated", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "summary_total": { + "name": "summary_total", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "summary_issues": { + "name": "summary_issues", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "summary_issue_details": { + "name": "summary_issue_details", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "thumbnail_u_r_l": { + "name": "thumbnail_u_r_l", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "mime_type": { + "name": "mime_type", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "filesize": { + "name": "filesize", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_x": { + "name": "focal_x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "focal_y": { + "name": "focal_y", + "type": "numeric", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "imports_updated_at_idx": { + "name": "imports_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "imports_created_at_idx": { + "name": "imports_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "imports_filename_idx": { + "name": "imports_filename_idx", + "columns": [ + { + "expression": "filename", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_kv": { + "name": "payload_kv", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "payload_kv_key_idx": { + "name": "payload_kv_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_jobs_log": { + "name": "payload_jobs_log", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "executed_at": { + "name": "executed_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true + }, + "task_slug": { + "name": "task_slug", + "type": "enum_payload_jobs_log_task_slug", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "task_i_d": { + "name": "task_i_d", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "enum_payload_jobs_log_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "payload_jobs_log_order_idx": { + "name": "payload_jobs_log_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_log_parent_id_idx": { + "name": "payload_jobs_log_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "payload_jobs_log_parent_id_fk": { + "name": "payload_jobs_log_parent_id_fk", + "tableFrom": "payload_jobs_log", + "tableTo": "payload_jobs", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_jobs": { + "name": "payload_jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "total_tried": { + "name": "total_tried", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "has_error": { + "name": "has_error", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "error": { + "name": "error", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "task_slug": { + "name": "task_slug", + "type": "enum_payload_jobs_task_slug", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "queue": { + "name": "queue", + "type": "varchar", + "primaryKey": false, + "notNull": false, + "default": "'default'" + }, + "wait_until": { + "name": "wait_until", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "processing": { + "name": "processing", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "payload_jobs_completed_at_idx": { + "name": "payload_jobs_completed_at_idx", + "columns": [ + { + "expression": "completed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_total_tried_idx": { + "name": "payload_jobs_total_tried_idx", + "columns": [ + { + "expression": "total_tried", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_has_error_idx": { + "name": "payload_jobs_has_error_idx", + "columns": [ + { + "expression": "has_error", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_task_slug_idx": { + "name": "payload_jobs_task_slug_idx", + "columns": [ + { + "expression": "task_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_queue_idx": { + "name": "payload_jobs_queue_idx", + "columns": [ + { + "expression": "queue", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_wait_until_idx": { + "name": "payload_jobs_wait_until_idx", + "columns": [ + { + "expression": "wait_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_processing_idx": { + "name": "payload_jobs_processing_idx", + "columns": [ + { + "expression": "processing", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_updated_at_idx": { + "name": "payload_jobs_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_jobs_created_at_idx": { + "name": "payload_jobs_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_locked_documents": { + "name": "payload_locked_documents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "global_slug": { + "name": "global_slug", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "payload_locked_documents_global_slug_idx": { + "name": "payload_locked_documents_global_slug_idx", + "columns": [ + { + "expression": "global_slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_updated_at_idx": { + "name": "payload_locked_documents_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_created_at_idx": { + "name": "payload_locked_documents_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_locked_documents_rels": { + "name": "payload_locked_documents_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "users_id": { + "name": "users_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_web_authn_credential_id": { + "name": "campaign_web_authn_credential_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "notification_id": { + "name": "notification_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "push_subscription_id": { + "name": "push_subscription_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_invite_id": { + "name": "campaign_invite_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_vote_summary_snapshot_id": { + "name": "campaign_vote_summary_snapshot_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "municipality_id": { + "name": "municipality_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "leadership_id": { + "name": "leadership_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state_deputy_id": { + "name": "state_deputy_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "vote_pledge_id": { + "name": "vote_pledge_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "allocation_decision_id": { + "name": "allocation_decision_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_demand_id": { + "name": "campaign_demand_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "supporter_id": { + "name": "supporter_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "supporter_import_batch_id": { + "name": "supporter_import_batch_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "municipality_update_id": { + "name": "municipality_update_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "activity_id": { + "name": "activity_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "speech_id": { + "name": "speech_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "speech_segment_id": { + "name": "speech_segment_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "speech_cut_id": { + "name": "speech_cut_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reel_id": { + "name": "reel_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reel_media_id": { + "name": "reel_media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "content_piece_id": { + "name": "content_piece_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "content_media_id": { + "name": "content_media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "content_event_id": { + "name": "content_event_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "recording_id": { + "name": "recording_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "recording_media_id": { + "name": "recording_media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "recording_segment_id": { + "name": "recording_segment_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "calendar_feed_id": { + "name": "calendar_feed_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "google_calendar_sync_id": { + "name": "google_calendar_sync_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "election_tally_id": { + "name": "election_tally_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "election_candidate_vote_id": { + "name": "election_candidate_vote_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "election_candidate_id": { + "name": "election_candidate_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "media_id": { + "name": "media_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "petition_id": { + "name": "petition_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "contact_id": { + "name": "contact_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "consent_id": { + "name": "consent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "signature_id": { + "name": "signature_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "subscription_id": { + "name": "subscription_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tag_id": { + "name": "tag_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "share_link_id": { + "name": "share_link_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "jingle_id": { + "name": "jingle_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "payload_locked_documents_rels_order_idx": { + "name": "payload_locked_documents_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_parent_idx": { + "name": "payload_locked_documents_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_path_idx": { + "name": "payload_locked_documents_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_users_id_idx": { + "name": "payload_locked_documents_rels_users_id_idx", + "columns": [ + { + "expression": "users_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_campaign_user_id_idx": { + "name": "payload_locked_documents_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_campaign_web_authn_credent_idx": { + "name": "payload_locked_documents_rels_campaign_web_authn_credent_idx", + "columns": [ + { + "expression": "campaign_web_authn_credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_notification_id_idx": { + "name": "payload_locked_documents_rels_notification_id_idx", + "columns": [ + { + "expression": "notification_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_push_subscription_id_idx": { + "name": "payload_locked_documents_rels_push_subscription_id_idx", + "columns": [ + { + "expression": "push_subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_campaign_invite_id_idx": { + "name": "payload_locked_documents_rels_campaign_invite_id_idx", + "columns": [ + { + "expression": "campaign_invite_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_campaign_vote_summary_snap_idx": { + "name": "payload_locked_documents_rels_campaign_vote_summary_snap_idx", + "columns": [ + { + "expression": "campaign_vote_summary_snapshot_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_municipality_id_idx": { + "name": "payload_locked_documents_rels_municipality_id_idx", + "columns": [ + { + "expression": "municipality_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_leadership_id_idx": { + "name": "payload_locked_documents_rels_leadership_id_idx", + "columns": [ + { + "expression": "leadership_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_organization_id_idx": { + "name": "payload_locked_documents_rels_organization_id_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_state_deputy_id_idx": { + "name": "payload_locked_documents_rels_state_deputy_id_idx", + "columns": [ + { + "expression": "state_deputy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_vote_pledge_id_idx": { + "name": "payload_locked_documents_rels_vote_pledge_id_idx", + "columns": [ + { + "expression": "vote_pledge_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_allocation_decision_id_idx": { + "name": "payload_locked_documents_rels_allocation_decision_id_idx", + "columns": [ + { + "expression": "allocation_decision_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_campaign_demand_id_idx": { + "name": "payload_locked_documents_rels_campaign_demand_id_idx", + "columns": [ + { + "expression": "campaign_demand_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_supporter_id_idx": { + "name": "payload_locked_documents_rels_supporter_id_idx", + "columns": [ + { + "expression": "supporter_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_supporter_import_batch_id_idx": { + "name": "payload_locked_documents_rels_supporter_import_batch_id_idx", + "columns": [ + { + "expression": "supporter_import_batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_municipality_update_id_idx": { + "name": "payload_locked_documents_rels_municipality_update_id_idx", + "columns": [ + { + "expression": "municipality_update_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_activity_id_idx": { + "name": "payload_locked_documents_rels_activity_id_idx", + "columns": [ + { + "expression": "activity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_speech_id_idx": { + "name": "payload_locked_documents_rels_speech_id_idx", + "columns": [ + { + "expression": "speech_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_speech_segment_id_idx": { + "name": "payload_locked_documents_rels_speech_segment_id_idx", + "columns": [ + { + "expression": "speech_segment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_speech_cut_id_idx": { + "name": "payload_locked_documents_rels_speech_cut_id_idx", + "columns": [ + { + "expression": "speech_cut_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_reel_id_idx": { + "name": "payload_locked_documents_rels_reel_id_idx", + "columns": [ + { + "expression": "reel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_reel_media_id_idx": { + "name": "payload_locked_documents_rels_reel_media_id_idx", + "columns": [ + { + "expression": "reel_media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_content_piece_id_idx": { + "name": "payload_locked_documents_rels_content_piece_id_idx", + "columns": [ + { + "expression": "content_piece_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_content_media_id_idx": { + "name": "payload_locked_documents_rels_content_media_id_idx", + "columns": [ + { + "expression": "content_media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_content_event_id_idx": { + "name": "payload_locked_documents_rels_content_event_id_idx", + "columns": [ + { + "expression": "content_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_recording_id_idx": { + "name": "payload_locked_documents_rels_recording_id_idx", + "columns": [ + { + "expression": "recording_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_recording_media_id_idx": { + "name": "payload_locked_documents_rels_recording_media_id_idx", + "columns": [ + { + "expression": "recording_media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_recording_segment_id_idx": { + "name": "payload_locked_documents_rels_recording_segment_id_idx", + "columns": [ + { + "expression": "recording_segment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_calendar_feed_id_idx": { + "name": "payload_locked_documents_rels_calendar_feed_id_idx", + "columns": [ + { + "expression": "calendar_feed_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_google_calendar_sync_id_idx": { + "name": "payload_locked_documents_rels_google_calendar_sync_id_idx", + "columns": [ + { + "expression": "google_calendar_sync_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_election_tally_id_idx": { + "name": "payload_locked_documents_rels_election_tally_id_idx", + "columns": [ + { + "expression": "election_tally_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_election_candidate_vote_id_idx": { + "name": "payload_locked_documents_rels_election_candidate_vote_id_idx", + "columns": [ + { + "expression": "election_candidate_vote_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_election_candidate_id_idx": { + "name": "payload_locked_documents_rels_election_candidate_id_idx", + "columns": [ + { + "expression": "election_candidate_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_media_id_idx": { + "name": "payload_locked_documents_rels_media_id_idx", + "columns": [ + { + "expression": "media_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_petition_id_idx": { + "name": "payload_locked_documents_rels_petition_id_idx", + "columns": [ + { + "expression": "petition_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_contact_id_idx": { + "name": "payload_locked_documents_rels_contact_id_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_consent_id_idx": { + "name": "payload_locked_documents_rels_consent_id_idx", + "columns": [ + { + "expression": "consent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_signature_id_idx": { + "name": "payload_locked_documents_rels_signature_id_idx", + "columns": [ + { + "expression": "signature_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_subscription_id_idx": { + "name": "payload_locked_documents_rels_subscription_id_idx", + "columns": [ + { + "expression": "subscription_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_post_id_idx": { + "name": "payload_locked_documents_rels_post_id_idx", + "columns": [ + { + "expression": "post_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_tag_id_idx": { + "name": "payload_locked_documents_rels_tag_id_idx", + "columns": [ + { + "expression": "tag_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_share_link_id_idx": { + "name": "payload_locked_documents_rels_share_link_id_idx", + "columns": [ + { + "expression": "share_link_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_locked_documents_rels_jingle_id_idx": { + "name": "payload_locked_documents_rels_jingle_id_idx", + "columns": [ + { + "expression": "jingle_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "payload_locked_documents_rels_parent_fk": { + "name": "payload_locked_documents_rels_parent_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "payload_locked_documents", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_users_fk": { + "name": "payload_locked_documents_rels_users_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "users", + "columnsFrom": [ + "users_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_campaign_user_fk": { + "name": "payload_locked_documents_rels_campaign_user_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_campaign_web_authn_credenti_fk": { + "name": "payload_locked_documents_rels_campaign_web_authn_credenti_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "campaign_web_authn_credential", + "columnsFrom": [ + "campaign_web_authn_credential_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_notification_fk": { + "name": "payload_locked_documents_rels_notification_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "notification", + "columnsFrom": [ + "notification_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_push_subscription_fk": { + "name": "payload_locked_documents_rels_push_subscription_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "push_subscription", + "columnsFrom": [ + "push_subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_campaign_invite_fk": { + "name": "payload_locked_documents_rels_campaign_invite_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "campaign_invite", + "columnsFrom": [ + "campaign_invite_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_campaign_vote_summary_snaps_fk": { + "name": "payload_locked_documents_rels_campaign_vote_summary_snaps_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "campaign_vote_summary_snapshot", + "columnsFrom": [ + "campaign_vote_summary_snapshot_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_municipality_fk": { + "name": "payload_locked_documents_rels_municipality_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "municipality", + "columnsFrom": [ + "municipality_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_leadership_fk": { + "name": "payload_locked_documents_rels_leadership_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "leadership", + "columnsFrom": [ + "leadership_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_organization_fk": { + "name": "payload_locked_documents_rels_organization_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_state_deputy_fk": { + "name": "payload_locked_documents_rels_state_deputy_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "state_deputy", + "columnsFrom": [ + "state_deputy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_vote_pledge_fk": { + "name": "payload_locked_documents_rels_vote_pledge_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "vote_pledge", + "columnsFrom": [ + "vote_pledge_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_allocation_decision_fk": { + "name": "payload_locked_documents_rels_allocation_decision_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "allocation_decision", + "columnsFrom": [ + "allocation_decision_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_campaign_demand_fk": { + "name": "payload_locked_documents_rels_campaign_demand_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "campaign_demand", + "columnsFrom": [ + "campaign_demand_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_supporter_fk": { + "name": "payload_locked_documents_rels_supporter_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "supporter", + "columnsFrom": [ + "supporter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_supporter_import_batch_fk": { + "name": "payload_locked_documents_rels_supporter_import_batch_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "supporter_import_batch", + "columnsFrom": [ + "supporter_import_batch_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_municipality_update_fk": { + "name": "payload_locked_documents_rels_municipality_update_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "municipality_update", + "columnsFrom": [ + "municipality_update_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_activity_fk": { + "name": "payload_locked_documents_rels_activity_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "activity", + "columnsFrom": [ + "activity_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_speech_fk": { + "name": "payload_locked_documents_rels_speech_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "speech", + "columnsFrom": [ + "speech_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_speech_segment_fk": { + "name": "payload_locked_documents_rels_speech_segment_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "speech_segment", + "columnsFrom": [ + "speech_segment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_speech_cut_fk": { + "name": "payload_locked_documents_rels_speech_cut_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "speech_cut", + "columnsFrom": [ + "speech_cut_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_reel_fk": { + "name": "payload_locked_documents_rels_reel_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "reel", + "columnsFrom": [ + "reel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_reel_media_fk": { + "name": "payload_locked_documents_rels_reel_media_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "reel_media", + "columnsFrom": [ + "reel_media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_content_piece_fk": { + "name": "payload_locked_documents_rels_content_piece_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "content_piece", + "columnsFrom": [ + "content_piece_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_content_media_fk": { + "name": "payload_locked_documents_rels_content_media_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "content_media", + "columnsFrom": [ + "content_media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_content_event_fk": { + "name": "payload_locked_documents_rels_content_event_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "content_event", + "columnsFrom": [ + "content_event_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_recording_fk": { + "name": "payload_locked_documents_rels_recording_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "recording", + "columnsFrom": [ + "recording_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_recording_media_fk": { + "name": "payload_locked_documents_rels_recording_media_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "recording_media", + "columnsFrom": [ + "recording_media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_recording_segment_fk": { + "name": "payload_locked_documents_rels_recording_segment_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "recording_segment", + "columnsFrom": [ + "recording_segment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_calendar_feed_fk": { + "name": "payload_locked_documents_rels_calendar_feed_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "calendar_feed", + "columnsFrom": [ + "calendar_feed_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_google_calendar_sync_fk": { + "name": "payload_locked_documents_rels_google_calendar_sync_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "google_calendar_sync", + "columnsFrom": [ + "google_calendar_sync_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_election_tally_fk": { + "name": "payload_locked_documents_rels_election_tally_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "election_tally", + "columnsFrom": [ + "election_tally_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_election_candidate_vote_fk": { + "name": "payload_locked_documents_rels_election_candidate_vote_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "election_candidate_vote", + "columnsFrom": [ + "election_candidate_vote_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_election_candidate_fk": { + "name": "payload_locked_documents_rels_election_candidate_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "election_candidate", + "columnsFrom": [ + "election_candidate_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_media_fk": { + "name": "payload_locked_documents_rels_media_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "media", + "columnsFrom": [ + "media_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_petition_fk": { + "name": "payload_locked_documents_rels_petition_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "petition", + "columnsFrom": [ + "petition_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_contact_fk": { + "name": "payload_locked_documents_rels_contact_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "contact", + "columnsFrom": [ + "contact_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_consent_fk": { + "name": "payload_locked_documents_rels_consent_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "consent", + "columnsFrom": [ + "consent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_signature_fk": { + "name": "payload_locked_documents_rels_signature_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "signature", + "columnsFrom": [ + "signature_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_subscription_fk": { + "name": "payload_locked_documents_rels_subscription_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "subscription", + "columnsFrom": [ + "subscription_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_post_fk": { + "name": "payload_locked_documents_rels_post_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "post", + "columnsFrom": [ + "post_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_tag_fk": { + "name": "payload_locked_documents_rels_tag_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "tag", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_share_link_fk": { + "name": "payload_locked_documents_rels_share_link_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "share_link", + "columnsFrom": [ + "share_link_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_locked_documents_rels_jingle_fk": { + "name": "payload_locked_documents_rels_jingle_fk", + "tableFrom": "payload_locked_documents_rels", + "tableTo": "jingle", + "columnsFrom": [ + "jingle_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_preferences": { + "name": "payload_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "key": { + "name": "key", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "payload_preferences_key_idx": { + "name": "payload_preferences_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_updated_at_idx": { + "name": "payload_preferences_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_created_at_idx": { + "name": "payload_preferences_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_preferences_rels": { + "name": "payload_preferences_rels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "order": { + "name": "order", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "path": { + "name": "path", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "users_id": { + "name": "users_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "campaign_user_id": { + "name": "campaign_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "payload_preferences_rels_order_idx": { + "name": "payload_preferences_rels_order_idx", + "columns": [ + { + "expression": "order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_rels_parent_idx": { + "name": "payload_preferences_rels_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_rels_path_idx": { + "name": "payload_preferences_rels_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_rels_users_id_idx": { + "name": "payload_preferences_rels_users_id_idx", + "columns": [ + { + "expression": "users_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_preferences_rels_campaign_user_id_idx": { + "name": "payload_preferences_rels_campaign_user_id_idx", + "columns": [ + { + "expression": "campaign_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "payload_preferences_rels_parent_fk": { + "name": "payload_preferences_rels_parent_fk", + "tableFrom": "payload_preferences_rels", + "tableTo": "payload_preferences", + "columnsFrom": [ + "parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_preferences_rels_users_fk": { + "name": "payload_preferences_rels_users_fk", + "tableFrom": "payload_preferences_rels", + "tableTo": "users", + "columnsFrom": [ + "users_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "payload_preferences_rels_campaign_user_fk": { + "name": "payload_preferences_rels_campaign_user_fk", + "tableFrom": "payload_preferences_rels", + "tableTo": "campaign_user", + "columnsFrom": [ + "campaign_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.payload_migrations": { + "name": "payload_migrations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "batch": { + "name": "batch", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "payload_migrations_updated_at_idx": { + "name": "payload_migrations_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "payload_migrations_created_at_idx": { + "name": "payload_migrations_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.site_settings_social_links": { + "name": "site_settings_social_links", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "enum_site_settings_social_links_platform", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "site_settings_social_links_order_idx": { + "name": "site_settings_social_links_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "site_settings_social_links_parent_id_idx": { + "name": "site_settings_social_links_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "site_settings_social_links_parent_id_fk": { + "name": "site_settings_social_links_parent_id_fk", + "tableFrom": "site_settings_social_links", + "tableTo": "site_settings", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.site_settings": { + "name": "site_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "header_title": { + "name": "header_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "tracking_facebook_pixel_id": { + "name": "tracking_facebook_pixel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "_status": { + "name": "_status", + "type": "enum_site_settings_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "site_settings__status_idx": { + "name": "site_settings__status_idx", + "columns": [ + { + "expression": "_status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._site_settings_v_version_social_links": { + "name": "_site_settings_v_version_social_links", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "enum__site_settings_v_version_social_links_platform", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "_uuid": { + "name": "_uuid", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "_site_settings_v_version_social_links_order_idx": { + "name": "_site_settings_v_version_social_links_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_site_settings_v_version_social_links_parent_id_idx": { + "name": "_site_settings_v_version_social_links_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "_site_settings_v_version_social_links_parent_id_fk": { + "name": "_site_settings_v_version_social_links_parent_id_fk", + "tableFrom": "_site_settings_v_version_social_links", + "tableTo": "_site_settings_v", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public._site_settings_v": { + "name": "_site_settings_v", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "version_header_title": { + "name": "version_header_title", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version_tracking_facebook_pixel_id": { + "name": "version_tracking_facebook_pixel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "version__status": { + "name": "version__status", + "type": "enum__site_settings_v_version_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false, + "default": "'draft'" + }, + "version_updated_at": { + "name": "version_updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "version_created_at": { + "name": "version_created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "latest": { + "name": "latest", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "autosave": { + "name": "autosave", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "_site_settings_v_version_version__status_idx": { + "name": "_site_settings_v_version_version__status_idx", + "columns": [ + { + "expression": "version__status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_site_settings_v_created_at_idx": { + "name": "_site_settings_v_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_site_settings_v_updated_at_idx": { + "name": "_site_settings_v_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_site_settings_v_latest_idx": { + "name": "_site_settings_v_latest_idx", + "columns": [ + { + "expression": "latest", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "_site_settings_v_autosave_idx": { + "name": "_site_settings_v_autosave_idx", + "columns": [ + { + "expression": "autosave", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.home": { + "name": "home", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "image_id": { + "name": "image_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "home_image_idx": { + "name": "home_image_idx", + "columns": [ + { + "expression": "image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "home_image_id_media_id_fk": { + "name": "home_image_id_media_id_fk", + "tableFrom": "home", + "tableTo": "media", + "columnsFrom": [ + "image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.metadata_keywords": { + "name": "metadata_keywords", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "keyword": { + "name": "keyword", + "type": "varchar", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "metadata_keywords_order_idx": { + "name": "metadata_keywords_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "metadata_keywords_parent_id_idx": { + "name": "metadata_keywords_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "metadata_keywords_parent_id_fk": { + "name": "metadata_keywords_parent_id_fk", + "tableFrom": "metadata_keywords", + "tableTo": "metadata", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.metadata": { + "name": "metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "url": { + "name": "url", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "open_graph_site_name": { + "name": "open_graph_site_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "open_graph_description": { + "name": "open_graph_description", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "twitter_creator": { + "name": "twitter_creator", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "twitter_description": { + "name": "twitter_description", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "image_id": { + "name": "image_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "metadata_image_idx": { + "name": "metadata_image_idx", + "columns": [ + { + "expression": "image_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "metadata_image_id_media_id_fk": { + "name": "metadata_image_id_media_id_fk", + "tableFrom": "metadata", + "tableTo": "media", + "columnsFrom": [ + "image_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.privacy_policy": { + "name": "privacy_policy", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "published": { + "name": "published", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "body": { + "name": "body", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.campaign_goals": { + "name": "campaign_goals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "state_goal": { + "name": "state_goal", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": 150000 + }, + "margin": { + "name": "margin", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "base_year": { + "name": "base_year", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.social_feed_settings_excluded_items": { + "name": "social_feed_settings_excluded_items", + "schema": "", + "columns": { + "_order": { + "name": "_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "_parent_id": { + "name": "_parent_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "varchar", + "primaryKey": true, + "notNull": true + }, + "platform": { + "name": "platform", + "type": "enum_social_feed_settings_excluded_items_platform", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "item_id": { + "name": "item_id", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "varchar", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "social_feed_settings_excluded_items_order_idx": { + "name": "social_feed_settings_excluded_items_order_idx", + "columns": [ + { + "expression": "_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "social_feed_settings_excluded_items_parent_id_idx": { + "name": "social_feed_settings_excluded_items_parent_id_idx", + "columns": [ + { + "expression": "_parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "social_feed_settings_excluded_items_parent_id_fk": { + "name": "social_feed_settings_excluded_items_parent_id_fk", + "tableFrom": "social_feed_settings_excluded_items", + "tableTo": "social_feed_settings", + "columnsFrom": [ + "_parent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.social_feed_settings": { + "name": "social_feed_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "youtube_enabled": { + "name": "youtube_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "youtube_api_key": { + "name": "youtube_api_key", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "youtube_channel_id": { + "name": "youtube_channel_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "youtube_max_items": { + "name": "youtube_max_items", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 3 + }, + "instagram_enabled": { + "name": "instagram_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "instagram_access_token": { + "name": "instagram_access_token", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "instagram_user_id": { + "name": "instagram_user_id", + "type": "varchar", + "primaryKey": false, + "notNull": false + }, + "instagram_max_items": { + "name": "instagram_max_items", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": 3 + }, + "youtube_feed_snapshot": { + "name": "youtube_feed_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "instagram_feed_snapshot": { + "name": "instagram_feed_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "instagram_sync_status": { + "name": "instagram_sync_status", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp(3) with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.enum_users_roles": { + "name": "enum_users_roles", + "schema": "public", + "values": [ + "admin", + "editor" + ] + }, + "public.enum_campaign_user_role": { + "name": "enum_campaign_user_role", + "schema": "public", + "values": [ + "coordinator", + "advisor", + "candidate", + "communicator", + "leader" + ] + }, + "public.enum_campaign_user_visibility": { + "name": "enum_campaign_user_visibility", + "schema": "public", + "values": [ + "carteira", + "tudo" + ] + }, + "public.enum_campaign_user_editing": { + "name": "enum_campaign_user_editing", + "schema": "public", + "values": [ + "carteira", + "tudo", + "somente_leitura" + ] + }, + "public.enum_notification_type": { + "name": "enum_notification_type", + "schema": "public", + "values": [ + "municipality_update", + "new_supporter", + "activity_attention", + "invite_accepted" + ] + }, + "public.enum_campaign_invite_kind": { + "name": "enum_campaign_invite_kind", + "schema": "public", + "values": [ + "login", + "autopreenchimento" + ] + }, + "public.enum_municipality_kind": { + "name": "enum_municipality_kind", + "schema": "public", + "values": [ + "municipio", + "zona" + ] + }, + "public.enum_municipality_priority": { + "name": "enum_municipality_priority", + "schema": "public", + "values": [ + "alta", + "normal" + ] + }, + "public.enum_municipality_engagement_level": { + "name": "enum_municipality_engagement_level", + "schema": "public", + "values": [ + "n0", + "n1", + "n2", + "n3", + "n4" + ] + }, + "public.enum_municipality_political_trend_status": { + "name": "enum_municipality_political_trend_status", + "schema": "public", + "values": [ + "favoravel", + "neutra", + "desfavoravel" + ] + }, + "public.enum_leadership_support_status": { + "name": "enum_leadership_support_status", + "schema": "public", + "values": [ + "engajado", + "a_abordar", + "em_disputa", + "lembranca", + "negativo" + ] + }, + "public.enum_organization_kind": { + "name": "enum_organization_kind", + "schema": "public", + "values": [ + "sindicato", + "associacao", + "religioso", + "movimento", + "categoria_profissional", + "outro" + ] + }, + "public.enum_allocation_decision_outcome": { + "name": "enum_allocation_decision_outcome", + "schema": "public", + "values": [ + "aceita", + "descarta", + "movimento", + "adiada" + ] + }, + "public.enum_campaign_demand_status_history_status": { + "name": "enum_campaign_demand_status_history_status", + "schema": "public", + "values": [ + "aberta", + "em_analise", + "escalada", + "aprovada", + "rejeitada" + ] + }, + "public.enum_campaign_demand_kind": { + "name": "enum_campaign_demand_kind", + "schema": "public", + "values": [ + "material", + "servico", + "transporte", + "alimentacao", + "infraestrutura", + "espaco", + "equipamento", + "pessoal_apoio", + "outro" + ] + }, + "public.enum_campaign_demand_status": { + "name": "enum_campaign_demand_status", + "schema": "public", + "values": [ + "aberta", + "em_analise", + "escalada", + "aprovada", + "rejeitada" + ] + }, + "public.enum_supporter_vote_intention": { + "name": "enum_supporter_vote_intention", + "schema": "public", + "values": [ + "certo", + "tende_a_certo", + "indeciso", + "outro" + ] + }, + "public.enum_supporter_source": { + "name": "enum_supporter_source", + "schema": "public", + "values": [ + "import_csv", + "manual", + "lideranca", + "convite", + "evento" + ] + }, + "public.enum_municipality_update_polarity": { + "name": "enum_municipality_update_polarity", + "schema": "public", + "values": [ + "boa", + "neutra", + "ruim" + ] + }, + "public.enum_activity_status": { + "name": "enum_activity_status", + "schema": "public", + "values": [ + "confirmado", + "realizado", + "cancelado" + ] + }, + "public.enum_speech_topics": { + "name": "enum_speech_topics", + "schema": "public", + "values": [ + "saude", + "educacao", + "cultura", + "esporte", + "seguranca-publica", + "meio-ambiente", + "economia-trabalho", + "direitos-humanos", + "infraestrutura", + "ciencia-tecnologia", + "politica-instituicoes", + "agricultura", + "habitacao-cidades", + "comunicacao-midia", + "igualdade-racial", + "mulheres-genero", + "juventude", + "pessoa-deficiencia" + ] + }, + "public.enum_speech_scopes": { + "name": "enum_speech_scopes", + "schema": "public", + "values": [ + "bahia", + "brasil", + "internacional" + ] + }, + "public.enum_speech_legislature": { + "name": "enum_speech_legislature", + "schema": "public", + "values": [ + "54", + "55", + "56", + "57" + ] + }, + "public.enum_speech_classified_by": { + "name": "enum_speech_classified_by", + "schema": "public", + "values": [ + "gazetteer", + "llm", + "manual" + ] + }, + "public.enum_speech_cut_status": { + "name": "enum_speech_cut_status", + "schema": "public", + "values": [ + "processing", + "published", + "unpublished", + "failed" + ] + }, + "public.enum_speech_cut_step": { + "name": "enum_speech_cut_step", + "schema": "public", + "values": [ + "resolving", + "cutting", + "metadata", + "publishing" + ] + }, + "public.enum_reel_feature": { + "name": "enum_reel_feature", + "schema": "public", + "values": [ + "cards" + ] + }, + "public.enum_reel_status": { + "name": "enum_reel_status", + "schema": "public", + "values": [ + "draft", + "published", + "unpublished" + ] + }, + "public.enum_content_piece_topics": { + "name": "enum_content_piece_topics", + "schema": "public", + "values": [ + "saude", + "educacao", + "cultura", + "esporte", + "seguranca-publica", + "meio-ambiente", + "economia-trabalho", + "direitos-humanos", + "infraestrutura", + "ciencia-tecnologia", + "politica-instituicoes", + "agricultura", + "habitacao-cidades", + "comunicacao-midia", + "igualdade-racial", + "mulheres-genero", + "juventude", + "pessoa-deficiencia" + ] + }, + "public.enum_content_piece_curated_fields": { + "name": "enum_content_piece_curated_fields", + "schema": "public", + "values": [ + "title", + "description", + "topics", + "municipality", + "institution", + "pieceDate", + "transcript", + "type" + ] + }, + "public.enum_content_piece_type": { + "name": "enum_content_piece_type", + "schema": "public", + "values": [ + "video", + "foto", + "texto", + "audio", + "card" + ] + }, + "public.enum_content_piece_origin": { + "name": "enum_content_piece_origin", + "schema": "public", + "values": [ + "arquivo", + "instagram", + "youtube" + ] + }, + "public.enum_content_piece_status": { + "name": "enum_content_piece_status", + "schema": "public", + "values": [ + "rascunho", + "publicado" + ] + }, + "public.enum_content_piece_processing_status": { + "name": "enum_content_piece_processing_status", + "schema": "public", + "values": [ + "processando", + "pronto", + "falhou" + ] + }, + "public.enum_content_piece_step": { + "name": "enum_content_piece_step", + "schema": "public", + "values": [ + "extraindo", + "transcrevendo", + "catalogando", + "salvando" + ] + }, + "public.enum_content_event_type": { + "name": "enum_content_event_type", + "schema": "public", + "values": [ + "abertura", + "download", + "compartilhar_whatsapp", + "compartilhar_link" + ] + }, + "public.enum_content_event_subject_type": { + "name": "enum_content_event_subject_type", + "schema": "public", + "values": [ + "peca", + "card" + ] + }, + "public.enum_recording_status": { + "name": "enum_recording_status", + "schema": "public", + "values": [ + "uploading", + "processing", + "ready", + "failed" + ] + }, + "public.enum_recording_step": { + "name": "enum_recording_step", + "schema": "public", + "values": [ + "extracting", + "transcribing", + "saving" + ] + }, + "public.enum_election_tally_office": { + "name": "enum_election_tally_office", + "schema": "public", + "values": [ + "presidente", + "governador", + "deputado_federal", + "deputado_estadual" + ] + }, + "public.enum_election_tally_turn": { + "name": "enum_election_tally_turn", + "schema": "public", + "values": [ + "1", + "2" + ] + }, + "public.enum_election_candidate_vote_office": { + "name": "enum_election_candidate_vote_office", + "schema": "public", + "values": [ + "presidente", + "governador", + "deputado_federal", + "deputado_estadual" + ] + }, + "public.enum_election_candidate_vote_turn": { + "name": "enum_election_candidate_vote_turn", + "schema": "public", + "values": [ + "1", + "2" + ] + }, + "public.enum_election_candidate_vote_vote_type": { + "name": "enum_election_candidate_vote_vote_type", + "schema": "public", + "values": [ + "nominal", + "legenda" + ] + }, + "public.enum_election_candidate_office": { + "name": "enum_election_candidate_office", + "schema": "public", + "values": [ + "presidente", + "governador", + "deputado_federal", + "deputado_estadual" + ] + }, + "public.enum_election_candidate_turn": { + "name": "enum_election_candidate_turn", + "schema": "public", + "values": [ + "1", + "2" + ] + }, + "public.enum_election_candidate_elected_by": { + "name": "enum_election_candidate_elected_by", + "schema": "public", + "values": [ + "QP", + "média", + "2º turno" + ] + }, + "public.enum_election_candidate_running_again2026": { + "name": "enum_election_candidate_running_again2026", + "schema": "public", + "values": [ + "sim", + "nao", + "desconhecido" + ] + }, + "public.enum_petition_status": { + "name": "enum_petition_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum__petition_v_version_status": { + "name": "enum__petition_v_version_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum_contact_gender": { + "name": "enum_contact_gender", + "schema": "public", + "values": [ + "feminino", + "masculino", + "outro", + "nao_informado" + ] + }, + "public.enum_contact_state": { + "name": "enum_contact_state", + "schema": "public", + "values": [ + "AC", + "AL", + "AM", + "AP", + "BA", + "CE", + "DF", + "ES", + "GO", + "MA", + "MG", + "MS", + "MT", + "PA", + "PB", + "PE", + "PI", + "PR", + "RJ", + "RN", + "RO", + "RR", + "RS", + "SC", + "SE", + "SP", + "TO" + ] + }, + "public.enum_subscription_campaign_level": { + "name": "enum_subscription_campaign_level", + "schema": "public", + "values": [ + "time", + "esporadico" + ] + }, + "public.enum_post_type": { + "name": "enum_post_type", + "schema": "public", + "values": [ + "noticia", + "campanha", + "artigo", + "evento" + ] + }, + "public.enum_post_status": { + "name": "enum_post_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum__post_v_version_type": { + "name": "enum__post_v_version_type", + "schema": "public", + "values": [ + "noticia", + "campanha", + "artigo", + "evento" + ] + }, + "public.enum__post_v_version_status": { + "name": "enum__post_v_version_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum_share_link_mode": { + "name": "enum_share_link_mode", + "schema": "public", + "values": [ + "direct", + "announcement" + ] + }, + "public.enum_exports_format": { + "name": "enum_exports_format", + "schema": "public", + "values": [ + "csv", + "json" + ] + }, + "public.enum_exports_sort_order": { + "name": "enum_exports_sort_order", + "schema": "public", + "values": [ + "asc", + "desc" + ] + }, + "public.enum_exports_drafts": { + "name": "enum_exports_drafts", + "schema": "public", + "values": [ + "yes", + "no" + ] + }, + "public.enum_imports_import_mode": { + "name": "enum_imports_import_mode", + "schema": "public", + "values": [ + "create", + "update", + "upsert" + ] + }, + "public.enum_imports_status": { + "name": "enum_imports_status", + "schema": "public", + "values": [ + "pending", + "completed", + "partial", + "failed" + ] + }, + "public.enum_payload_jobs_log_task_slug": { + "name": "enum_payload_jobs_log_task_slug", + "schema": "public", + "values": [ + "inline", + "createCollectionExport", + "createCollectionImport", + "schedulePublish" + ] + }, + "public.enum_payload_jobs_log_state": { + "name": "enum_payload_jobs_log_state", + "schema": "public", + "values": [ + "failed", + "succeeded" + ] + }, + "public.enum_payload_jobs_task_slug": { + "name": "enum_payload_jobs_task_slug", + "schema": "public", + "values": [ + "inline", + "createCollectionExport", + "createCollectionImport", + "schedulePublish" + ] + }, + "public.enum_site_settings_social_links_platform": { + "name": "enum_site_settings_social_links_platform", + "schema": "public", + "values": [ + "instagram", + "facebook", + "youtube", + "whatsapp" + ] + }, + "public.enum_site_settings_status": { + "name": "enum_site_settings_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum__site_settings_v_version_social_links_platform": { + "name": "enum__site_settings_v_version_social_links_platform", + "schema": "public", + "values": [ + "instagram", + "facebook", + "youtube", + "whatsapp" + ] + }, + "public.enum__site_settings_v_version_status": { + "name": "enum__site_settings_v_version_status", + "schema": "public", + "values": [ + "draft", + "published" + ] + }, + "public.enum_social_feed_settings_excluded_items_platform": { + "name": "enum_social_feed_settings_excluded_items_platform", + "schema": "public", + "values": [ + "youtube", + "instagram" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "id": "a2d5238d-f704-410e-97db-0385a4b2a22f", + "prevId": "00000000-0000-0000-0000-000000000000" +} \ No newline at end of file diff --git a/src/migrations/20260924_123940_add_content_piece_people.ts b/src/migrations/20260924_123940_add_content_piece_people.ts new file mode 100644 index 00000000..875e1d05 --- /dev/null +++ b/src/migrations/20260924_123940_add_content_piece_people.ts @@ -0,0 +1,35 @@ +import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres' + +export async function up({ db, payload, req }: MigrateUpArgs): Promise { + await db.execute(sql` + CREATE TABLE "content_piece_texts" ( + "id" serial PRIMARY KEY NOT NULL, + "order" integer NOT NULL, + "parent_id" integer NOT NULL, + "path" varchar NOT NULL, + "text" varchar + ); + + CREATE TABLE "content_piece_rels" ( + "id" serial PRIMARY KEY NOT NULL, + "order" integer, + "parent_id" integer NOT NULL, + "path" varchar NOT NULL, + "leadership_id" integer + ); + + ALTER TABLE "content_piece_texts" ADD CONSTRAINT "content_piece_texts_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."content_piece"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "content_piece_rels" ADD CONSTRAINT "content_piece_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."content_piece"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "content_piece_rels" ADD CONSTRAINT "content_piece_rels_leadership_fk" FOREIGN KEY ("leadership_id") REFERENCES "public"."leadership"("id") ON DELETE cascade ON UPDATE no action; + CREATE INDEX "content_piece_texts_order_parent" ON "content_piece_texts" USING btree ("order","parent_id"); + CREATE INDEX "content_piece_rels_order_idx" ON "content_piece_rels" USING btree ("order"); + CREATE INDEX "content_piece_rels_parent_idx" ON "content_piece_rels" USING btree ("parent_id"); + CREATE INDEX "content_piece_rels_path_idx" ON "content_piece_rels" USING btree ("path"); + CREATE INDEX "content_piece_rels_leadership_id_idx" ON "content_piece_rels" USING btree ("leadership_id");`) +} + +export async function down({ db, payload, req }: MigrateDownArgs): Promise { + await db.execute(sql` + DROP TABLE "content_piece_texts" CASCADE; + DROP TABLE "content_piece_rels" CASCADE;`) +} diff --git a/src/migrations/index.ts b/src/migrations/index.ts index 85922b73..d54aaa1a 100644 --- a/src/migrations/index.ts +++ b/src/migrations/index.ts @@ -85,6 +85,7 @@ import * as migration_20260923_190414_add_content_event_variant from './20260923 import * as migration_20260924_040210_add_recording_facets from './20260924_040210_add_recording_facets'; import * as migration_20260924_042028_add_web_speech_origin from './20260924_042028_add_web_speech_origin'; import * as migration_20260924_045625_add_content_piece_link_failure_reason from './20260924_045625_add_content_piece_link_failure_reason'; +import * as migration_20260924_123940_add_content_piece_people from './20260924_123940_add_content_piece_people'; export const migrations = [ { @@ -510,16 +511,21 @@ export const migrations = [ { up: migration_20260924_040210_add_recording_facets.up, down: migration_20260924_040210_add_recording_facets.down, - name: '20260924_040210_add_recording_facets' + name: '20260924_040210_add_recording_facets', }, { up: migration_20260924_042028_add_web_speech_origin.up, down: migration_20260924_042028_add_web_speech_origin.down, - name: '20260924_042028_add_web_speech_origin' + name: '20260924_042028_add_web_speech_origin', }, { up: migration_20260924_045625_add_content_piece_link_failure_reason.up, down: migration_20260924_045625_add_content_piece_link_failure_reason.down, - name: '20260924_045625_add_content_piece_link_failure_reason' + name: '20260924_045625_add_content_piece_link_failure_reason', + }, + { + up: migration_20260924_123940_add_content_piece_people.up, + down: migration_20260924_123940_add_content_piece_people.down, + name: '20260924_123940_add_content_piece_people', }, ]; diff --git a/src/payload-types.ts b/src/payload-types.ts index 8fea361f..c1d3f788 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -1266,6 +1266,18 @@ export interface ContentPiece { */ region?: string | null; institution?: string | null; + /** + * Quem aparece na peça entre as lideranças já registradas. À Central pública vai apenas o nome. + */ + leaders?: (number | Leadership)[] | null; + /** + * Derivado das lideranças marcadas; é o que a faceta pública mostra. + */ + leaderNames?: string[] | null; + /** + * Dobradinhas/estaduais do catálogo e outras personalidades; a grafia é canonicalizada ao salvar. + */ + publicFigures?: string[] | null; pieceDate?: string | null; /** * Medida pelo provedor de transcrição; nunca estimada. @@ -2849,6 +2861,9 @@ export interface ContentPieceSelect { cityLabel?: T; region?: T; institution?: T; + leaders?: T; + leaderNames?: T; + publicFigures?: T; pieceDate?: T; durationSeconds?: T; transcript?: T; diff --git a/src/utilities/content/contentPieceLeaderOptions.ts b/src/utilities/content/contentPieceLeaderOptions.ts new file mode 100644 index 00000000..859357e7 --- /dev/null +++ b/src/utilities/content/contentPieceLeaderOptions.ts @@ -0,0 +1,130 @@ +import 'server-only' + +import type { Payload, PayloadRequest } from 'payload' + +import { canReadCommunicationCatalog } from '@/lib/campaignRoles' +import { isContactSearchQueryReady, normalizeContactSearchQuery } from '@/lib/contactSearchQuery' +import { CONTENT_PIECE_LEADER_SEARCH_LIMIT } from '@/lib/contentPiece' +import { isPopulatedRelationship, relationshipId } from '@/lib/relationship' +import type { CampaignUser, Contact, Leadership } from '@/payload-types' + +export type ContentPieceLeaderOption = { id: number; label: string } + +const leaderOptionOf = (leadership: Leadership): ContentPieceLeaderOption | null => { + const id = relationshipId(leadership.id) + const contact = leadership.contact + if (!id || !isPopulatedRelationship(contact)) return null + const label = contact.name.trim() + return label ? { id, label } : null +} + +/** The options in the requested id order, skipping ids that no longer resolve. */ +const orderOptionsById = ( + options: readonly ContentPieceLeaderOption[], + ids: readonly number[], +): ContentPieceLeaderOption[] => { + const byId = new Map(options.map((option) => [option.id, option])) + return ids + .map((id) => byId.get(id)) + .filter((option): option is ContentPieceLeaderOption => option !== undefined) +} + +/** + * The one read of `leadership` behind the ficha picker and the name snapshot. + * The `select` reads only the contact relation (the source of the label) and + * the `{ id, label }` mapping is the boundary that guarantees only the display + * name leaves — no phone, municipality, organization, status or votes of a + * leadership is returned (the int tests assert the returned shape). + */ +const findLeaderOptions = async ( + payload: Pick, + req: PayloadRequest | undefined, + where: Parameters[0]['where'], + limit: number, +): Promise => { + const result = await payload.find({ + collection: 'leadership', + where, + depth: 1, + limit, + select: { contact: true }, + // S37 intentional admin bypass (approved in the plan, D1): the candidate + // list needs the display name of leaderships the communication role cannot + // read through the RBAC (it is the role that edits the ficha). Only the + // name of the projection above is read or returned; `overrideAccess: false` + // would blind the picker for the very persona that operates the Central. + overrideAccess: true, + req, + }) + + return result.docs + .map((doc) => leaderOptionOf(doc as Leadership)) + .filter((option): option is ContentPieceLeaderOption => option !== null) +} + +/** + * The selected leaders' `{ id, label }` in the requested order (the ficha + * chips). Fail-closed: a role outside the communication gate gets an empty + * list, never a leaked name. + */ +export const resolveContentPieceLeaderOptions = async ( + payload: Pick, + actor: Pick, + ids: readonly number[], +): Promise => { + if (!canReadCommunicationCatalog(actor.role)) return [] + + const uniqueIds = [...new Set(ids)] + if (uniqueIds.length === 0) return [] + + const options = await findLeaderOptions( + payload, + undefined, + { id: { in: uniqueIds } }, + uniqueIds.length, + ) + return orderOptionsById(options, uniqueIds) +} + +/** + * The gated async search of the ficha picker (2+ chars, bounded page). Same + * fail-closed gate as the resolver; the caller action maps the denial to the + * vertical's forbidden message. + */ +export const searchContentPieceLeaderOptions = async ( + payload: Pick, + actor: Pick, + query: string, +): Promise => { + if (!canReadCommunicationCatalog(actor.role)) return [] + + const rawQuery = typeof query === 'string' ? query : '' + if (!isContactSearchQueryReady(rawQuery)) return [] + + const { trimmed } = normalizeContactSearchQuery(rawQuery) + const options = await findLeaderOptions( + payload, + undefined, + { 'contact.name': { contains: trimmed } }, + CONTENT_PIECE_LEADER_SEARCH_LIMIT, + ) + return options.sort((left, right) => left.label.localeCompare(right.label, 'pt-BR')) +} + +/** + * S37 — the system-context snapshot: the display names of the linked leaders, + * in the relation's order, skipping members that no longer resolve. Called by + * the collection hook (inside the caller's transaction) to denormalize + * `leaderNames`, so the public read never joins `leadership`. + */ +export const resolveContentPieceLeaderNames = async ( + payload: Pick, + req: PayloadRequest, + ids: readonly number[], +): Promise => { + const uniqueIds = [...new Set(ids)] + if (uniqueIds.length === 0) return [] + + const options = await findLeaderOptions(payload, req, { id: { in: uniqueIds } }, uniqueIds.length) + return orderOptionsById(options, uniqueIds).map((option) => option.label) +} diff --git a/src/utilities/content/contentPiecePageData.ts b/src/utilities/content/contentPiecePageData.ts index bdad68a9..05f216b0 100644 --- a/src/utilities/content/contentPiecePageData.ts +++ b/src/utilities/content/contentPiecePageData.ts @@ -9,10 +9,15 @@ import { type ContentPieceCirculationCounts, type ContentPieceRowViewModel, } from '@/lib/contentPieceCirculation' +import { uniqueRelationshipIds } from '@/lib/relationship' import { CONTENT_PIECE_NOT_FOUND_MESSAGE } from '@/lib/schemas/contentPiece' import type { CampaignUser } from '@/payload-types' import { type RawSearchParams } from '@/utilities/campaignListUrl' import { loadContentEventCountsBySubject } from '@/utilities/content/contentEventAggregate' +import { + resolveContentPieceLeaderOptions, + type ContentPieceLeaderOption, +} from '@/utilities/content/contentPieceLeaderOptions' import { buildContentPieceListWhere, contentPiecePageSize, @@ -54,6 +59,9 @@ const contentPieceDetailSelect = { municipality: true, curatedFields: true, linkFailureReason: true, + // S37 — the picked leaders (ids) and the curated figures the ficha renders. + leaders: true, + publicFigures: true, } as const export const ContentPieceNotFoundError = createEntityNotFoundError( @@ -173,7 +181,11 @@ export type ContentPieceDetailPageData = { pieceDate: string | null municipalityId: number | null curatedFields: string[] + /** S37 — the curated public figures (display names). */ + publicFigures: string[] } + /** S37 — `{ id, label }` of the picked leaders, for the ficha chips. */ + leaderOptions: ContentPieceLeaderOption[] } /** @@ -200,7 +212,11 @@ export const loadContentPieceDetailPageData = async ( const piece = result.docs[0] if (!piece) throw new ContentPieceNotFoundError() - const circulation = await loadCirculationLookup(payload, [piece]) + const leaderIds = uniqueRelationshipIds(piece.leaders) + const [circulation, leaderOptions] = await Promise.all([ + loadCirculationLookup(payload, [piece]), + resolveContentPieceLeaderOptions(payload, user, leaderIds), + ]) const viewModel = toContentPieceRow(piece, circulation) return { piece: { @@ -215,6 +231,8 @@ export const loadContentPieceDetailPageData = async ( ? piece.municipality : (piece.municipality?.id ?? null), curatedFields: piece.curatedFields ?? [], + publicFigures: piece.publicFigures ?? [], }, + leaderOptions, } } diff --git a/src/utilities/content/contentPieceReads.ts b/src/utilities/content/contentPieceReads.ts index 18b6e11e..e907c767 100644 --- a/src/utilities/content/contentPieceReads.ts +++ b/src/utilities/content/contentPieceReads.ts @@ -33,6 +33,10 @@ const contentPiecePublicSelect = { cityLabel: true, region: true, institution: true, + // S37 — only the display-name snapshot and the curated figures; the + // `leaders` relation NEVER enters this select (depth 1 would leak Contact). + leaderNames: true, + publicFigures: true, description: true, transcript: true, sourceUrl: true, diff --git a/tests/e2e/campaignSpeechAcervo.e2e.spec.ts b/tests/e2e/campaignSpeechAcervo.e2e.spec.ts index ff30bb1a..744e4ab6 100644 --- a/tests/e2e/campaignSpeechAcervo.e2e.spec.ts +++ b/tests/e2e/campaignSpeechAcervo.e2e.spec.ts @@ -1490,6 +1490,47 @@ test.describe('communication vertical (C154/C162)', () => { expect(afterUnpublish.media).toBeTruthy() }) + test('the ficha renders who appears in the piece for the communicator (S37)', async ({ + campaign, + campaignRequest, + }) => { + const marker = campaign.fixtures.value('pecapessoas') + const { piece } = await createPiece(campaign, { marker }) + const municipality = await campaign.fixtures.claimMunicipality() + const { contactName, leadershipId } = await campaign.fixtures.createStaffLeadership({ + namePrefix: 'Liderança', + municipalities: [municipality], + }) + await campaign.fixtures.payload.update({ + collection: 'contentPiece', + id: piece.id, + data: { leaders: [leadershipId], publicFigures: ['dra elaine'] }, + depth: 0, + }) + + const user = await campaign.fixtures.createCampaignUser('communicator') + const request = await campaignRequest(user, user.password) + const response = await request.get(`/campanha/comunicacao/conteudos/${piece.id}`) + expect(response.status()).toBe(200) + const html = rendered(await response.text()) + expect(html).toContain('Quem aparece na peça') + expect(html).toContain('Lideranças da campanha') + expect(html).toContain('Figuras públicas') + expect(html).toContain('Curadoria humana') + // The chip labels come from the projection; the figure was canonicalized. + expect(html).toContain(contactName) + expect(html).toContain('Dra. Elaine') + + // The advisor stays denied on the whole communication vertical. + const advisor = await campaign.fixtures.createCampaignUser('advisor') + const advisorRequest = await campaignRequest(advisor, advisor.password) + await assertCampaignRedirect( + advisorRequest, + `/campanha/comunicacao/conteudos/${piece.id}`, + '/campanha', + ) + }) + test('the list and the ficha show the anonymous circulation counters', async ({ campaign, campaignRequest, diff --git a/tests/e2e/frontendConteudos.e2e.spec.ts b/tests/e2e/frontendConteudos.e2e.spec.ts index c03de67d..f7fabfd6 100644 --- a/tests/e2e/frontendConteudos.e2e.spec.ts +++ b/tests/e2e/frontendConteudos.e2e.spec.ts @@ -4,6 +4,7 @@ import type { APIRequestContext, Page } from '@playwright/test' import { loadMunicipalityGeometryModule } from '../../src/lib/bahiaGeometries.js' import { getMunicipalityCatalogEntry } from '../../src/lib/municipalityCatalog.js' +import { slugify } from '../../src/lib/slug.js' import { adminHeaders } from '../helpers/adminApi' import { interiorPointOf } from '../helpers/featureBounds' import { seedTestUser } from '../helpers/seedUser' @@ -37,6 +38,8 @@ type Headers = Record const createdPieceIds: number[] = [] const createdMediaIds: number[] = [] +const createdContactIds: number[] = [] +const createdLeadershipIds: number[] = [] const uniqueMarker = () => randomUUID().slice(0, 8) @@ -81,6 +84,9 @@ const createPiece = async ( sourceUrl?: string /** S39 — the home sample resolves the município name from this relation. */ municipality?: number + /** S37 — the campaign leaders and curated figures this piece carries. */ + leaders?: number[] + publicFigures?: string[] }, ): Promise<{ id: number; slug: string }> => { const mediaKind = data.type === 'video' || data.type === 'foto' ? data.type : 'texto' @@ -106,6 +112,8 @@ const createPiece = async ( ...(media ? { media } : {}), ...(data.sourceUrl ? { sourceUrl: data.sourceUrl } : {}), ...(data.municipality ? { municipality: data.municipality } : {}), + ...(data.leaders ? { leaders: data.leaders } : {}), + ...(data.publicFigures ? { publicFigures: data.publicFigures } : {}), }, }) expect(response.ok(), await response.text()).toBeTruthy() @@ -114,6 +122,41 @@ const createPiece = async ( return { id: doc.id, slug: doc.slug } } +/** + * S37 — a real leadership record (contact + municipality link) for the public + * "Lideranças" facet: the piece references the record, only the name is public. + */ +const createLeadershipWithContact = async ( + request: APIRequestContext, + headers: Headers, + name: string, +): Promise<{ leadershipId: number }> => { + const contactResponse = await request.post(`${BASE_URL}/api/contact`, { + headers, + data: { name }, + }) + expect(contactResponse.ok(), await contactResponse.text()).toBeTruthy() + const contactId = ((await contactResponse.json()) as { doc: { id: number } }).doc.id + createdContactIds.push(contactId) + + const municipalityResponse = await request.get( + `${BASE_URL}/api/municipality?limit=1&depth=0&sort=name`, + { headers }, + ) + expect(municipalityResponse.ok(), await municipalityResponse.text()).toBeTruthy() + const municipalityId = ((await municipalityResponse.json()) as { docs: { id: number }[] }) + .docs[0]!.id + + const leadershipResponse = await request.post(`${BASE_URL}/api/leadership`, { + headers, + data: { contact: contactId, municipalities: [municipalityId] }, + }) + expect(leadershipResponse.ok(), await leadershipResponse.text()).toBeTruthy() + const leadershipId = ((await leadershipResponse.json()) as { doc: { id: number } }).doc.id + createdLeadershipIds.push(leadershipId) + return { leadershipId } +} + const setPieceStatus = async ( request: APIRequestContext, headers: Headers, @@ -192,6 +235,12 @@ test.afterAll(async ({ request }) => { for (const id of createdMediaIds.splice(0)) { await request.delete(`${BASE_URL}/api/contentMedia/${id}`, { headers }).catch(() => undefined) } + for (const id of createdLeadershipIds.splice(0)) { + await request.delete(`${BASE_URL}/api/leadership/${id}`, { headers }).catch(() => undefined) + } + for (const id of createdContactIds.splice(0)) { + await request.delete(`${BASE_URL}/api/contact/${id}`, { headers }).catch(() => undefined) + } }) test.describe('Frontend Central de Conteúdos (S27)', () => { @@ -696,4 +745,57 @@ test.describe('Frontend Central de Conteúdos (S27)', () => { await expect(section.getByText('Do seu município', { exact: true })).toBeVisible() await expect(section.getByRole('link', { name: title })).toBeVisible() }) + test('filters by who appears in the piece and removes a name when unpublished (S37)', async ({ + page, + request, + }) => { + const headers = await adminHeaders(request, BASE_URL) + await unpublishEveryPiece(request, headers) + const marker = uniqueMarker() + const leaderName = `Maria Silva ${marker}` + const personSlug = slugify(leaderName) + const title = `Giro com a liderança ${marker}` + const { leadershipId } = await createLeadershipWithContact(request, headers, leaderName) + const piece = await createPiece(request, headers, { + title, + type: 'video', + leaders: [leadershipId], + publicFigures: ['dra elaine'], + }) + + await page.goto('/conteudos') + await waitForSettledPage(page) + await expect(page.locator('article[data-content-piece]')).toHaveCount(1) + // The card's metadata line leads with who appears in the piece. + await expect( + page.locator('article[data-content-piece]').getByText(leaderName, { exact: true }), + ).toBeVisible() + + // The one "Lideranças" facet unions the leader name and the curated figure. + await page.locator('summary').filter({ hasText: 'Lideranças' }).first().click() + await expect( + page.getByText('Em peças publicadas').filter({ visible: true }).first(), + ).toBeVisible() + await expect(page.getByRole('link', { name: 'Dra. Elaine', exact: true })).toBeVisible() + await page.getByRole('link', { name: leaderName, exact: true }).click() + await expect(page).toHaveURL(new RegExp(`lideranca=${personSlug}$`)) + await expect(page.locator('article[data-content-piece]')).toHaveCount(1) + await expect( + page + .getByRole('link', { name: /Remover filtro Lideranças/ }) + .filter({ visible: true }) + .first(), + ).toBeVisible() + + // Searching the name finds the piece (the haystack carries it). + await page.goto(`/conteudos?q=${encodeURIComponent(leaderName)}`) + await waitForSettledPage(page) + await expect(page.locator('article[data-content-piece]')).toHaveCount(1) + + // Unpublishing the last piece with the name removes it from the facet. + await setPieceStatus(request, headers, piece.id, 'rascunho') + await page.goto('/conteudos') + await waitForSettledPage(page) + await expect(page.locator('summary').filter({ hasText: 'Lideranças' })).toHaveCount(0) + }) }) diff --git a/tests/int/contentPiece.int.spec.ts b/tests/int/contentPiece.int.spec.ts index b4f1c96b..a55e3501 100644 --- a/tests/int/contentPiece.int.spec.ts +++ b/tests/int/contentPiece.int.spec.ts @@ -33,6 +33,7 @@ import { addContentPieceByLinkForActor, getContentPieceStatusesForActor, retryContentPieceForActor, + searchContentPieceLeaderOptionsForActor, setContentPiecePublishedForActor, updateContentPieceForActor, } from '@/app/(campaign)/campanha/actions/contentPieces' @@ -48,6 +49,7 @@ import { CONTENT_PIECE_LINK_DUPLICATE_MESSAGE, CONTENT_PIECE_RETRY_NOT_FAILED_MESSAGE, } from '@/lib/schemas/contentPiece' +import { slugify } from '@/lib/slug' import type { SpeechTopic } from '@/lib/speechFacets' import { normalizeForSearch } from '@/lib/speechSearch' import type { CampaignUser, ContentMedia } from '@/payload-types' @@ -66,6 +68,7 @@ import { loadContentPieceListPageData } from '@/utilities/content/contentPiecePa import { getPublishedContentPieceBySlug, getPublishedContentPieceItems, + getPublishedContentPieceRecords, hasPublishedContentPieces, } from '@/utilities/content/contentPieceReads' import { loadContentPieceCatalogSearch } from '@/utilities/content/contentPieceThemeSearch' @@ -743,6 +746,123 @@ describe('content pieces (C211)', () => { expect(row.searchText).toContain('camara dos deputados') }) + it('searches the leader options with the display-name projection only (S37)', async () => { + const fixtures = campaignFixtures() + const marker = `busca-${Date.now()}` + const contact = await fixtures.createContact({ name: `Maria Silva ${marker}` }) + const municipality = await fixtures.getMunicipality() + const leadership = await fixtures.createLeadership({ + contact: contact.id, + municipalities: [municipality.id], + }) + + getCampaignUserMock.mockResolvedValue(communicator) + const options = await searchContentPieceLeaderOptionsForActor(`Maria Silva ${marker}`) + const found = options.find((option) => option.id === leadership.id) + + // The projection is exactly `{ id, label }` — no other leadership field + // (municipality, status, votes, contact) crosses the boundary. + expect(found).toEqual({ id: leadership.id, label: contact.name }) + expect(Object.keys(found!).sort()).toEqual(['id', 'label']) + + // Shorter than 2 chars never queries. + expect(await searchContentPieceLeaderOptionsForActor('M')).toEqual([]) + + // The role gate fails closed for every non-communication role. + for (const denied of [advisor, leader]) { + getCampaignUserMock.mockResolvedValue(denied) + await expect( + searchContentPieceLeaderOptionsForActor(`Maria Silva ${marker}`), + ).rejects.toThrow(CONTENT_PIECE_FORBIDDEN_MESSAGE) + } + }) + + it('saves who appears in the piece, snapshots names and survives the pipeline (S37)', async () => { + const fixtures = campaignFixtures() + const marker = `pessoas-${Date.now()}` + const contact = await fixtures.createContact({ name: `Liderança ${marker}` }) + const municipality = await fixtures.getMunicipality() + const leadership = await fixtures.createLeadership({ + contact: contact.id, + municipalities: [municipality.id], + }) + const { piece } = await createPiece({ + processingStatus: 'processando', + title: `Peça pessoas ${marker}`, + }) + getCampaignUserMock.mockResolvedValue(communicator) + + await updateContentPieceForActor({ + contentPieceId: piece.id, + title: `Peça pessoas ${marker}`, + description: null, + type: 'video', + pieceDate: null, + municipalityId: null, + institution: null, + transcript: null, + leaderIds: [leadership.id], + // A typed variant resolves to the catalog spelling; the free text stays. + publicFigures: ['dra elaine', 'Personalidade Sem Catálogo'], + }) + + const row = await payload.findByID({ + collection: 'contentPiece', + id: piece.id, + depth: 0, + overrideAccess: true, + }) + expect(row.leaders).toEqual([leadership.id]) + expect(row.leaderNames).toEqual([contact.name]) + expect(row.publicFigures).toEqual(['Dra. Elaine', 'Personalidade Sem Catálogo']) + expect(row.searchText).toContain(normalizeForSearch(contact.name)) + expect(row.searchText).toContain('dra. elaine') + + // The pipeline job never touches the curation fields. + const restore = withEnv('FFMPEG_PATH', FAKE_FFMPEG) + try { + await runContentPieceJob(payload, piece.id, { + transcribe: transcribeOk, + catalog: catalogStub, + }) + } finally { + restore() + } + const processed = await payload.findByID({ + collection: 'contentPiece', + id: piece.id, + depth: 0, + overrideAccess: true, + }) + expect(processed.leaders).toEqual([leadership.id]) + expect(processed.leaderNames).toEqual([contact.name]) + expect(processed.publicFigures).toEqual(['Dra. Elaine', 'Personalidade Sem Catálogo']) + + // Clearing the picks clears the snapshot, the figures and the haystack. + await updateContentPieceForActor({ + contentPieceId: piece.id, + title: `Peça pessoas ${marker}`, + description: null, + type: 'video', + pieceDate: null, + municipalityId: null, + institution: null, + transcript: null, + leaderIds: [], + publicFigures: [], + }) + const cleared = await payload.findByID({ + collection: 'contentPiece', + id: piece.id, + depth: 0, + overrideAccess: true, + }) + expect(cleared.leaders).toEqual([]) + expect(cleared.leaderNames).toEqual([]) + expect(cleared.publicFigures).toEqual([]) + expect(cleared.searchText).not.toContain(normalizeForSearch(contact.name)) + }) + it('derives the city and the region from the related município', async () => { const municipality = await payload.find({ collection: 'municipality', @@ -1257,6 +1377,77 @@ describe('content pieces (C211)', () => { expect(await hasPublishedContentPieces()).toBe(true) }) + it('derives the people facet and the name search from published pieces only (S37)', async () => { + const fixtures = campaignFixtures() + const marker = `facet-${Date.now()}` + const contactName = `Liderança Pública ${marker}` + const contact = await fixtures.createContact({ name: contactName }) + const municipality = await fixtures.getMunicipality() + const leadership = await fixtures.createLeadership({ + contact: contact.id, + municipalities: [municipality.id], + }) + + const published = await createPiece({ title: `Publicada pessoas ${marker}` }) + const draft = await createPiece({ title: `Rascunho pessoas ${marker}` }) + getCampaignUserMock.mockResolvedValue(communicator) + + for (const [id, title] of [ + [published.piece.id, `Publicada pessoas ${marker}`], + [draft.piece.id, `Rascunho pessoas ${marker}`], + ] as const) { + await updateContentPieceForActor({ + contentPieceId: id, + title, + description: null, + type: 'video', + pieceDate: null, + municipalityId: null, + institution: null, + transcript: null, + leaderIds: [leadership.id], + publicFigures: ['Dra. Elaine'], + }) + } + await payload.update({ + collection: 'contentPiece', + id: published.piece.id, + data: { status: 'publicado' }, + overrideAccess: true, + }) + + const personSlug = slugify(contactName) + const records = await getPublishedContentPieceRecords() + const record = records.find((candidate) => candidate.id === published.piece.id) + expect(record?.leaderNames).toEqual([contactName]) + expect(record?.publicFigures).toEqual(['Dra. Elaine']) + // The public select never carries the relation (depth 1 would leak Contact). + expect(record && 'leaders' in record).toBe(false) + + const filtered = await loadContentPieceCatalogSearch({ + rawSearchParams: { lideranca: personSlug }, + }) + expect(pieceRows(filtered.items).map((item) => item.id)).toContain(published.piece.id) + expect(pieceRows(filtered.items).map((item) => item.id)).not.toContain(draft.piece.id) + expect(filtered.facets.lideranca).toContainEqual({ value: personSlug, label: contactName }) + + const byName = await loadContentPieceCatalogSearch({ rawSearchParams: { q: contactName } }) + expect(pieceRows(byName.items).map((item) => item.id)).toContain(published.piece.id) + + // Unpublishing the last piece with the name removes it from the facet. + await payload.update({ + collection: 'contentPiece', + id: published.piece.id, + data: { status: 'rascunho' }, + overrideAccess: true, + }) + const afterUnpublish = await loadContentPieceCatalogSearch({ rawSearchParams: {} }) + expect(afterUnpublish.facets.lideranca).not.toContainEqual({ + value: personSlug, + label: contactName, + }) + }) + it('serves a published piece file publicly and 404s draft, link and unknown slugs', async () => { const marker = `media-${Date.now()}` const draft = await createPiece({ title: `Mídia rascunho ${marker}` }) diff --git a/tests/unit/contentPiece.unit.spec.ts b/tests/unit/contentPiece.unit.spec.ts index 7f9ff648..eab8c530 100644 --- a/tests/unit/contentPiece.unit.spec.ts +++ b/tests/unit/contentPiece.unit.spec.ts @@ -244,6 +244,16 @@ describe('contentPieceSearchText', () => { it('is empty when nothing is filled', () => { expect(contentPieceSearchText({})).toBe('') }) + + it('includes the display names of who appears in the piece (S37)', () => { + expect( + contentPieceSearchText({ + title: 'Giro', + leaderNames: ['Maria Silva'], + publicFigures: ['Dra. Elaine'], + }), + ).toBe('giro maria silva dra. elaine') + }) }) describe('toContentPieceViewModel', () => { diff --git a/tests/unit/contentPieceCatalog.unit.spec.ts b/tests/unit/contentPieceCatalog.unit.spec.ts index 9b63bcd2..7a001c1c 100644 --- a/tests/unit/contentPieceCatalog.unit.spec.ts +++ b/tests/unit/contentPieceCatalog.unit.spec.ts @@ -12,6 +12,7 @@ import { contentPieceMediaKind, contentPieceMediaPath, contentPiecePublicPath, + contentPiecePublicPeople, contentPieceTextExcerpt, contentPieceThemeMatch, contentPieceThemeTerms, @@ -65,6 +66,7 @@ describe('content piece catalog params', () => { regiao: 'metropolitano-de-salvador', tema: 'economia-trabalho', instituicao: 'camara-dos-deputados', + lideranca: 'maria-silva', q: ' escala ', mode: 'tema', }), @@ -74,6 +76,7 @@ describe('content piece catalog params', () => { regiao: 'metropolitano-de-salvador', tema: 'economia-trabalho', instituicao: 'camara-dos-deputados', + lideranca: 'maria-silva', q: 'escala', mode: 'tema', }) @@ -84,10 +87,13 @@ describe('content piece catalog params', () => { regiao: null, tema: null, instituicao: null, + lideranca: null, q: '', mode: null, }) expect(parseContentPieceCatalogParams({ cidade: '../etc/passwd' }).cidade).toBeNull() + // S37 — the people facet is a display-name slug; spaces/accents never pass. + expect(parseContentPieceCatalogParams({ lideranca: 'Maria Silva' }).lideranca).toBeNull() expect(parseContentPieceCatalogParams({}).q).toBe('') }) @@ -114,6 +120,14 @@ describe('content piece catalog params', () => { expect(buildContentPieceCatalogHref({ tipo: 'video', tema: null, q: '' })).toBe( '/conteudos?tipo=video', ) + // S37 — the people facet is appended after Instituição, before the query. + expect( + buildContentPieceCatalogHref({ + instituicao: 'camara-dos-deputados', + lideranca: 'maria-silva', + q: 'escala', + }), + ).toBe('/conteudos?instituicao=camara-dos-deputados&lideranca=maria-silva&q=escala') expect(buildContentPieceCatalogHref({ q: 'escala', mode: 'tema' })).toBe( '/conteudos?q=escala&mode=tema', ) @@ -146,7 +160,7 @@ describe('content piece catalog params', () => { describe('content piece catalog facets', () => { it('derives options from published items only, in enum/alphabetical order', () => { const facets = contentPieceCatalogFacets([ - item(), + item({ leaderNames: ['Maria Silva'] }), item({ id: 2, slug: 'card-saude', @@ -155,6 +169,7 @@ describe('content piece catalog facets', () => { cityLabel: 'Feira de Santana', region: 'Portal do Sertão', institution: 'Câmara dos Deputados', + publicFigures: ['Dep. Estadual Exemplo'], }), ]) @@ -171,6 +186,23 @@ describe('content piece catalog facets', () => { expect(facets.instituicao).toEqual([ { value: 'camara-dos-deputados', label: 'Câmara dos Deputados' }, ]) + // S37 — one facet unions the leader snapshot and the curated figures, + // alphabetical by the display name. + expect(facets.lideranca).toEqual([ + { value: 'dep-estadual-exemplo', label: 'Dep. Estadual Exemplo' }, + { value: 'maria-silva', label: 'Maria Silva' }, + ]) + }) + + it('collapses homonyms and spelling variants into one people option (S37)', () => { + const facets = contentPieceCatalogFacets([ + item({ leaderNames: ['Dra. Elaine'] }), + item({ id: 2, slug: 'outra', publicFigures: ['Dra Elaine'] }), + ]) + + expect(facets.lideranca).toEqual([{ value: 'dra-elaine', label: 'Dra Elaine' }]) + // No piece carries people: the facet renders nothing. + expect(contentPieceCatalogFacets([item()]).lideranca).toEqual([]) }) }) @@ -212,6 +244,28 @@ describe('content piece catalog filtering', () => { expect(idsFor({ tipo: 'video', q: 'escala' })).toEqual([1]) }) + it('filters by the people facet union and combines with the other facets (S37)', () => { + const people = [ + item({ leaderNames: ['Maria Silva'] }), + item({ + id: 2, + slug: 'card-feira', + type: 'card', + cityLabel: 'Feira de Santana', + publicFigures: ['Dep. Estadual Exemplo'], + }), + ] + const ids = (raw: Record) => + pieceRows(filterContentPieceCatalogItems(people, parseContentPieceCatalogParams(raw))).map( + (row) => row.id, + ) + + expect(ids({ lideranca: 'maria-silva' })).toEqual([1]) + expect(ids({ lideranca: 'dep-estadual-exemplo' })).toEqual([2]) + expect(ids({ lideranca: 'maria-silva', tipo: 'card' })).toEqual([]) + expect(ids({ lideranca: 'ninguem' })).toEqual([]) + }) + it('ORs the literal query with the expanded theme terms, facets still AND', () => { const idsForTerms = (raw: Record, terms: string[]) => pieceRows( @@ -447,6 +501,31 @@ describe('content piece public view model', () => { expect(contentPieceMediaKind(item({ media: null, sourceUrl: 'https://youtu.be/X' }))).toBeNull() }) + it('leads the metadata line with who appears in the piece (S37)', () => { + expect(item({ leaderNames: ['Maria Silva'] }).metaLabel).toBe( + 'Maria Silva · Economia e Trabalho · Salvador', + ) + // A figure takes the slot when there is no leader name. + expect(item({ publicFigures: ['Dep. Estadual Exemplo'] }).metaLabel).toBe( + 'Dep. Estadual Exemplo · Economia e Trabalho · Salvador', + ) + // Nobody marked: the previous line stays byte-identical. + expect(item().metaLabel).toBe('Economia e Trabalho · Salvador') + }) + + it('unions leaders and figures as people options, deduped by display name (S37)', () => { + expect( + contentPiecePublicPeople({ + leaderNames: ['Maria Silva'], + publicFigures: ['Maria Silva', 'Dep. Estadual Exemplo'], + }), + ).toEqual([ + { slug: 'maria-silva', name: 'Maria Silva' }, + { slug: 'dep-estadual-exemplo', name: 'Dep. Estadual Exemplo' }, + ]) + expect(contentPiecePublicPeople({ leaderNames: [], publicFigures: [' '] })).toEqual([]) + }) + it('fails closed without a slug or without file and link', () => { expect(toContentPiecePublicItem(source({ slug: null }))).toBeNull() expect(toContentPiecePublicItem(source({ status: 'rascunho' }))).toBeNull() diff --git a/tests/unit/contentPiecePeopleField.unit.spec.tsx b/tests/unit/contentPiecePeopleField.unit.spec.tsx new file mode 100644 index 00000000..a6bfaf6e --- /dev/null +++ b/tests/unit/contentPiecePeopleField.unit.spec.tsx @@ -0,0 +1,111 @@ +import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' +import { createElement } from 'react' +import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest' + +import { ContentPiecePeopleField } from '@/components/campaign/content/ContentPiecePeopleField' + +beforeAll(() => { + vi.stubGlobal( + 'ResizeObserver', + class { + observe() {} + unobserve() {} + disconnect() {} + }, + ) + Element.prototype.scrollIntoView = () => {} +}) + +afterEach(cleanup) + +afterAll(() => { + vi.unstubAllGlobals() + Reflect.deleteProperty(Element.prototype, 'scrollIntoView') +}) + +const renderField = (props: { + leaders?: { id: number; label: string }[] + publicFigures?: string[] + searchLeaders?: (query: string) => Promise<{ id: number; label: string }[]> +}) => + render( + createElement(ContentPiecePeopleField, { + leaders: props.leaders ?? [], + publicFigures: props.publicFigures ?? [], + searchLeaders: props.searchLeaders ?? vi.fn(async () => []), + }), + ) + +const hiddenValues = (container: HTMLElement, name: string): string[] => + [...container.querySelectorAll(`input[name="${name}"]`)].map( + (input) => input.value, + ) + +describe('ContentPiecePeopleField (S37)', () => { + it('renders the picked people as chips plus hidden inputs, and the empty state when none', () => { + const { container } = renderField({ + leaders: [{ id: 7, label: 'Maria Silva' }], + publicFigures: ['Dra. Elaine'], + }) + + expect(screen.getByRole('heading', { name: 'Quem aparece na peça' })).toBeTruthy() + expect(screen.getByText('Curadoria humana')).toBeTruthy() + expect(hiddenValues(container, 'leaderIds')).toEqual(['7']) + expect(hiddenValues(container, 'publicFigures')).toEqual(['Dra. Elaine']) + expect(screen.queryByText(/Ninguém marcado/)).toBeNull() + + cleanup() + renderField({}) + expect(screen.getByText(/Ninguém marcado/)).toBeTruthy() + }) + + it('searches leaders through the async action, adds and removes the chip', async () => { + const searchLeaders = vi.fn(async (query: string) => [{ id: 1, label: `Liderança ${query}` }]) + const { container } = renderField({ searchLeaders }) + + fireEvent.change(screen.getByLabelText('Buscar liderança'), { target: { value: 'Ma' } }) + const option = await screen.findByRole('option', { name: /Liderança Ma/ }) + expect(searchLeaders).toHaveBeenCalledWith('Ma') + + fireEvent.click(option) + await waitFor(() => expect(hiddenValues(container, 'leaderIds')).toEqual(['1'])) + expect(screen.getByLabelText('Remover Liderança Ma')).toBeTruthy() + + fireEvent.click(screen.getByLabelText('Remover Liderança Ma')) + await waitFor(() => expect(hiddenValues(container, 'leaderIds')).toEqual([])) + }) + + it('gates the leader search on two characters and reports an empty result', async () => { + const searchLeaders = vi.fn(async () => []) + renderField({ searchLeaders }) + + fireEvent.change(screen.getByLabelText('Buscar liderança'), { target: { value: 'M' } }) + expect(screen.getByText('Digite ao menos dois caracteres para buscar.')).toBeTruthy() + await waitFor(() => expect(searchLeaders).not.toHaveBeenCalled()) + + fireEvent.change(screen.getByLabelText('Buscar liderança'), { target: { value: 'Maria' } }) + await waitFor(() => expect(searchLeaders).toHaveBeenCalledTimes(1)) + expect(await screen.findByText('Nenhum resultado encontrado.')).toBeTruthy() + }) + + it('canonicalizes a catalog figure and accepts free text through "Usar"', async () => { + const { container } = renderField({ publicFigures: [] }) + + fireEvent.change(screen.getByLabelText('Buscar ou digitar uma figura pública'), { + target: { value: 'elaine' }, + }) + fireEvent.click(screen.getByRole('option', { name: /Dra\. Elaine/ })) + await waitFor(() => expect(hiddenValues(container, 'publicFigures')).toEqual(['Dra. Elaine'])) + + fireEvent.change(screen.getByLabelText('Buscar ou digitar uma figura pública'), { + target: { value: 'Personalidade Local' }, + }) + fireEvent.click(screen.getByRole('option', { name: /Usar «Personalidade Local»/ })) + await waitFor(() => + expect(hiddenValues(container, 'publicFigures')).toEqual([ + 'Dra. Elaine', + 'Personalidade Local', + ]), + ) + }) +}) diff --git a/tests/unit/formData.unit.spec.ts b/tests/unit/formData.unit.spec.ts index e0662373..0adf7dba 100644 --- a/tests/unit/formData.unit.spec.ts +++ b/tests/unit/formData.unit.spec.ts @@ -69,6 +69,13 @@ describe('FormData boundary', () => { expect(repeatedRelationshipFormValues(formData, 'coordinators')).toEqual([3, 7, 12]) }) + it('keeps the submission order when the user order is meaningful (S37)', () => { + const formData = new FormData() + for (const value of ['12', '3', '12', '7']) formData.append('leaders', value) + + expect(repeatedRelationshipFormValues(formData, 'leaders', { sort: false })).toEqual([12, 3, 7]) + }) + it('distinguishes absent JSON from explicit empty arrays and rejects invalid inputs', () => { const formData = new FormData() expect(boundedJsonFormValue(formData, 'strengths', 100)).toBeUndefined() diff --git a/tests/unit/publicFigureCatalog.unit.spec.ts b/tests/unit/publicFigureCatalog.unit.spec.ts new file mode 100644 index 00000000..c0a333a2 --- /dev/null +++ b/tests/unit/publicFigureCatalog.unit.spec.ts @@ -0,0 +1,68 @@ +// @vitest-environment node + +import { describe, expect, it } from 'vitest' + +import { + CONTENT_PIECE_PUBLIC_FIGURES_MAX, + CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH, +} from '@/lib/contentPiece' +import { + PUBLIC_FIGURE_PERSONALITIES, + filterPublicFigures, + normalizeContentPiecePublicFigures, + publicFigureCatalog, + resolvePublicFigureName, +} from '@/lib/publicFigureCatalog' +import { stateDeputyCatalog } from '@/lib/stateDeputyCatalog' + +describe('public figure catalog (S37)', () => { + it('derives every dobradinha from the S30 roster without copying the names', () => { + expect(PUBLIC_FIGURE_PERSONALITIES).toEqual([]) + expect(publicFigureCatalog).toHaveLength(stateDeputyCatalog.length) + expect( + publicFigureCatalog.filter((entry) => entry.kind === 'dobradinha').map((entry) => entry.name), + ).toEqual(stateDeputyCatalog.map((deputy) => deputy.name)) + + const elaine = publicFigureCatalog.find((entry) => entry.name === 'Dra. Elaine') + expect(elaine).toEqual({ slug: 'estadual-elane', name: 'Dra. Elaine', kind: 'dobradinha' }) + }) + + it('resolves a typed name or slug to the canonical spelling, case/accent-insensitive', () => { + expect(resolvePublicFigureName('Dra. Elaine')).toBe('Dra. Elaine') + expect(resolvePublicFigureName('dra elaine')).toBe('Dra. Elaine') + expect(resolvePublicFigureName(' DRÁ ELAINE ')).toBe('Dra. Elaine') + expect(resolvePublicFigureName('estadual-elane')).toBe('Dra. Elaine') + // Unknown names stay free text (the picker's "use this text" path). + expect(resolvePublicFigureName('Personalidade Sem Catálogo')).toBeNull() + expect(resolvePublicFigureName('')).toBeNull() + }) + + it('filters by display name or slug, keeping the whole roster on an empty query', () => { + expect(filterPublicFigures('')).toHaveLength(stateDeputyCatalog.length) + expect(filterPublicFigures('elaine').map((entry) => entry.name)).toEqual(['Dra. Elaine']) + expect(filterPublicFigures('coletivo').map((entry) => entry.slug)).toEqual(['estadual-adriana']) + expect(filterPublicFigures('ninguém')).toEqual([]) + }) + + it('canonicalizes, dedupes and bounds the persisted figure list', () => { + expect( + normalizeContentPiecePublicFigures([ + ' dra elaine ', + 'Dra. Elaine', + 'Personalidade Exemplo', + 'personalidade exemplo', + '', + ' ', + ]), + ).toEqual(['Dra. Elaine', 'Personalidade Exemplo']) + + expect( + normalizeContentPiecePublicFigures(['x'.repeat(CONTENT_PIECE_PUBLIC_FIGURE_MAX_LENGTH + 1)]), + ).toEqual([]) + + const many = Array.from({ length: CONTENT_PIECE_PUBLIC_FIGURES_MAX + 5 }, (_, index) => + String(`Pessoa ${index + 1}`), + ) + expect(normalizeContentPiecePublicFigures(many)).toHaveLength(CONTENT_PIECE_PUBLIC_FIGURES_MAX) + }) +})