> ## Documentation Index
> Fetch the complete documentation index at: https://developers.googa.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Mapeamento de fluxo de dados

> Onde cada dado entra, em qual projeto Supabase é processado e armazenado, quem tem acesso interno, e como um pedido de exclusão se propaga pelas tabelas.

<Info>
  Esta página é o complemento operacional de [LGPD](/security/lgpd) — aqui o foco é o caminho
  técnico real do dado, não o enquadramento legal.
</Info>

## Entrada — de onde o dado vem

| Origem                                                                                  | Como chega                                                                                                                                                                                                                                | Status                         |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| App oficial (Web/PWA — não há apps nativos)                                             | Direto para o Supabase do produto via SDK cliente (`@supabase/supabase-js`), autenticado com JWT de usuário                                                                                                                               | **GA**                         |
| Webhook **de entrada** do parceiro (ex: Algar chamando um endpoint de webhook da Googa) | Não existe e não está desenhado — a mudança de plano entra pela API (`POST /entitlements`), não por webhook de entrada                                                                                                                    | —                              |
| Webhook **de saída** (Googa → parceiro: `subscriber.updated`, `subscription.canceled`)  | Implementado no código (função `webhook-dispatch`, assinatura HMAC, entrega única — ver [Modelo de autenticação](/architecture/supabase-auth-model)); deploy em produção pendente                                                         | Código pronto, deploy pendente |
| Edge Function de terceiro (TTS, e-mail)                                                 | O app chama a Edge Function do próprio produto, que por sua vez chama o provedor externo (gateway de LLM/TTS) — o dado do usuário (texto a sintetizar) trafega por esse provedor, mas a orquestração e a quota são controladas pela Googa | **GA**                         |

## Onde é processado e armazenado

| Produto                    | Projeto Supabase                                                                                                       | Isolamento                                                                                                                                                                                                                                                                                                                                                                                     |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| NovelAI + NovelAudio       | "Novel" (`<ref-novel>`)                                                                                                | Compartilhado entre os dois produtos — mesmo Postgres, RLS separa por `user_id`/`app`                                                                                                                                                                                                                                                                                                          |
| HistorinhAI                | "HistorinhAI" (`<ref-historinhai>`)                                                                                    | Projeto próprio, isolado dos demais — decisão deliberada dado o tratamento de dados de crianças                                                                                                                                                                                                                                                                                                |
| Platform (API de parceiro) | Projeto dedicado — já existe no código (schema e Edge Functions no repo `googa-platform`), deploy em produção pendente | Guarda só metadado de integração, nunca dado de leitor: `partners` (incluindo `webhook_url` e `webhook_secret` — este em texto puro **de propósito**, porque assinar HMAC de cada entrega exige o segredo de volta; a tabela é acessível só por `service_role`), `partner_credentials` (hash do secret) e `partner_api_keys` — ver [Modelo de autenticação](/architecture/supabase-auth-model) |

Cada projeto é Postgres com Row Level Security habilitado nas tabelas que guardam dado de usuário
— não existe uma cópia "de leitura geral" fora do RLS para uso interno (ex: um data warehouse
espelhado sem controle de acesso próprio). Onde uma função `security definer` precisa contornar o
RLS para uma operação legítima (ex: `export_my_data()`, `delete_my_account()`), ela é escrita para
filtrar explicitamente pelo próprio `auth.uid()`/`family_id` do chamador — nunca por um parâmetro
livre.

## Quem tem acesso interno

Hoje o controle de acesso interno é o modelo de membros de projeto do próprio Supabase (quem tem
login no dashboard do projeto) — não existe ainda uma segmentação formal de papéis internos
(editorial, engenharia, suporte) com permissões diferenciadas por função dentro da plataforma:

| Papel interno (proposto)          | Acesso pretendido                                                                                                                             | Status                                                                                               |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Engenharia                        | Acesso completo ao projeto Supabase (schema, funções, dados) para debug e operação                                                            | **GA hoje** (mas sem segmentação — é "acesso total" para quem está no time, não escopado por tarefa) |
| Editorial (curadoria de catálogo) | Acesso só às tabelas de catálogo/conteúdo (obras, capítulos, metadados), sem acesso a dado de usuário/família                                 | Roadmap — hoje quem cura catálogo não tem uma visão de banco separada de quem opera o backend        |
| Suporte ao cliente                | Acesso de leitura a conta/assinatura de um usuário específico mediante ticket, sem acesso a dado de outros usuários nem a exportação em massa | Roadmap — hoje suporte é feito manualmente por quem já tem acesso de engenharia                      |

Essa segmentação formal (RBAC interno por função, não só por produto) é um item real de roadmap de
maturidade organizacional — citamos aqui sem inflar: hoje o time é pequeno o suficiente para que o
acesso "de fato" seja mais amplo do que o princípio de menor privilégio recomendaria em regime
permanente, e achamos mais honesto declarar isso do que descrever uma segmentação que ainda não
existe.

## Como um pedido de exclusão se propaga

A exclusão de conta usa duas camadas: `on delete cascade` no schema (para o caso simples) e uma
função explícita para os casos onde apagar em cascata ingenuamente afetaria outra pessoa.

**Caso simples — NovelAI/NovelAudio** (conta individual, sem conceito de família): a função
`delete_my_account()` apaga a linha em `auth.users`, e isso cascateia automaticamente para
`profiles`, `subscriptions`, `favorites`, `reading_progress`, `listening_progress`, `tts_usage`,
`audio_access_log`, `email_log`, `free_time_grants` e `referral_codes` — todas com
`on delete cascade` apontando para `auth.users(id)`. Uma tabela exigiu ajuste antes: `promo_codes`
tinha `created_by` sem regra de exclusão (`NO ACTION`), o que impediria um administrador de excluir
a própria conta sem quebrar os códigos promocionais que ele criou — trocado para `on delete set
null`, preservando o código para quem já o resgatou.

**Caso com família — HistorinhAI**: apagar em cascata direto pela conta seria perigoso, porque uma
família pode ter mais de um adulto (`family_members`). A função `delete_my_account()` primeiro
verifica se a pessoa é **dona** de uma família com outros membros — se sim, bloqueia com
`family_has_other_members` até que os outros membros sejam removidos primeiro (fluxo já disponível
no app). Registros que a pessoa criou mas que pertencem a uma família da qual ela é só membro
(`children.user_id`, `reading_sessions.user_id` como proveniência, não como posse) são
reatribuídos ao dono da família antes da exclusão, para não apagar dado de uma família que ela só
visitava. Só quando a pessoa é dona sem outros membros é que a função apaga explicitamente
`reading_sessions`, `subscriptions` e `children` da própria família antes de apagar a família e,
por fim, a linha em `auth.users` — que cascateia o resto (perfil, código de indicação, etc.).

Este desenho — cascade automático onde é seguro, função explícita onde exige avaliar posse
compartilhada primeiro — é o que garante que um pedido de exclusão (Art. 18, VI da LGPD) nunca
deixa dado pessoal órfão nem, no outro extremo, remove acesso de alguém que não pediu para saber
saída da família.
