Files
Condominio_SeConectai/Schemas/000 - arquitetura-schema-condominio-contabilidade-v3.0-FINAL.md
T
2026-09-29 12:12:31 -03:00

9.6 KiB

Sistema de Contabilidade de Condomínios — Arquitetura v3.0 (FINAL)

Substitui v2.0. Escopo drasticamente simplificado: o sistema é um cadastro de referência para o escritório — não um ERP de condomínio. Sem reservas, sem moradores, sem financeiro do condomínio, sem ocorrências, sem fornecedores, sem votação. Só: condomínios, contatos (síndico/subsíndico/conselheiro), funcionários vinculados, áreas comuns, assembleias e avisos/alertas com documentos anexados.

Stack: Java puro (JDBC) + HttpServer do JDK · PostgreSQL 16 (1 database por empresa) · Frontend HTML/CSS/JS puro no mesmo processo · Docker Compose.


1. Diagrama — db_master (sem mudança desde v2.0)

erDiagram
    EMPRESAS ||--o{ FUNCIONARIOS : tem
    EMPRESAS ||--o{ API_KEYS : possui
    EMPRESAS ||--o{ EMPRESA_FUNCIONALIDADES : libera
    FUNCIONALIDADES ||--o{ EMPRESA_FUNCIONALIDADES : referenciada_em
    EMPRESAS ||--o{ EVOLUTION_INSTANCIAS : cadastra
    PLANOS ||--o{ PLANO_FUNCIONALIDADES : inclui
    FUNCIONALIDADES ||--o{ PLANO_FUNCIONALIDADES : referenciada_em
    PLANOS ||--o{ ASSINATURAS : usado_em
    EMPRESAS ||--o{ ASSINATURAS : possui
    EMPRESAS ||--o{ PERIODOS_USO : tem
    PERIODOS_USO ||--o{ PAGAMENTOS : gera
    EMPRESAS ||--o{ LOGS_ENVIO_AVISOS : gera
    EMPRESAS ||--o{ LEMBRETES_COBRANCA : recebe

Schema igual ao documento v2.0 (empresas, funcionarios, api_keys, funcionalidades, empresa_funcionalidades, evolution_instancias, configuracoes_plataforma, planos, plano_funcionalidades, assinaturas, periodos_uso, pagamentos, logs_envio_avisos, lembretes_cobranca) — nada disso mudou.


2. Diagrama — db_empresa_<slug> (NOVO, bem mais simples)

erDiagram
    CONDOMINIOS ||--o{ CONTATO_CONDOMINIO : vincula
    CONTATOS ||--o{ CONTATO_CONDOMINIO : vinculado_a
    CONDOMINIOS ||--o{ FUNCIONARIO_CONDOMINIO : atendido_por
    CONDOMINIOS ||--o{ ESPACOS_COMUNS : possui
    CONDOMINIOS ||--o{ ASSEMBLEIAS : realiza
    CONDOMINIOS ||--o{ AVISOS : publica
    ASSEMBLEIAS ||--o{ AVISOS : gera
    AVISOS ||--o{ AVISO_DOCUMENTOS : anexa
    DOCUMENTOS ||--o{ AVISO_DOCUMENTOS : anexado_em
    AVISOS ||--o{ AVISO_DESTINATARIOS : enviado_para
    CONDOMINIOS ||--o{ DOCUMENTOS : arquiva

Schema

CREATE TABLE condominios (
    id          BIGSERIAL PRIMARY KEY,
    nome        VARCHAR(150) NOT NULL,
    cnpj        VARCHAR(18) UNIQUE,
    endereco    VARCHAR(255),
    criado_em   TIMESTAMP NOT NULL DEFAULT now()
);

-- pessoa física (síndico/subsíndico/conselheiro) — cadastrada uma vez,
-- pode ser vinculada a mais de um condomínio
CREATE TABLE contatos (
    id          BIGSERIAL PRIMARY KEY,
    nome        VARCHAR(150) NOT NULL,
    telefone    VARCHAR(20),        -- WhatsApp
    email       VARCHAR(150),
    criado_em   TIMESTAMP NOT NULL DEFAULT now()
);

-- vínculo N:N entre contato e condomínio, com o papel que exerce ali
CREATE TABLE contato_condominio (
    contato_id          BIGINT NOT NULL REFERENCES contatos(id),
    condominio_id       BIGINT NOT NULL REFERENCES condominios(id),
    tipo                VARCHAR(20) NOT NULL,   -- sindico, subsindico, conselheiro
    data_inicio_mandato DATE,
    data_fim_mandato    DATE,
    status              VARCHAR(20) NOT NULL DEFAULT 'ativo',
    PRIMARY KEY (contato_id, condominio_id, tipo)
);
-- "síndico atual" de um condomínio = SELECT ... WHERE condominio_id=X AND tipo='sindico' AND status='ativo'

-- funcionário do escritório (cadastro fica em db_master.funcionarios) vinculado
-- a quais condomínios ele cuida — também recebe avisos/alertas desses condomínios
CREATE TABLE funcionario_condominio (
    funcionario_id  BIGINT NOT NULL,   -- referência a db_master.funcionarios, sem FK cross-db
    condominio_id   BIGINT NOT NULL REFERENCES condominios(id),
    PRIMARY KEY (funcionario_id, condominio_id)
);

CREATE TABLE espacos_comuns (
    id                          BIGSERIAL PRIMARY KEY,
    condominio_id               BIGINT NOT NULL REFERENCES condominios(id),
    nome                        VARCHAR(100) NOT NULL,     -- salão de festas, churrasqueira, quadra...
    descricao                   TEXT,
    valor_utilizacao_centavos   BIGINT,
    indice_correcao             VARCHAR(30),    -- IGPM, IPCA, definido em assembleia...
    data_ultimo_reajuste        DATE,
    criado_em                   TIMESTAMP NOT NULL DEFAULT now()
);

CREATE TABLE assembleias (
    id              BIGSERIAL PRIMARY KEY,
    condominio_id   BIGINT NOT NULL REFERENCES condominios(id),
    tipo            VARCHAR(20) NOT NULL,   -- ordinaria, extraordinaria
    data_hora       TIMESTAMP NOT NULL,
    local           VARCHAR(150),
    pauta           TEXT,
    status          VARCHAR(20) NOT NULL DEFAULT 'agendada',  -- agendada, realizada, cancelada
    criado_em       TIMESTAMP NOT NULL DEFAULT now()
);

CREATE TABLE documentos (
    id                      BIGSERIAL PRIMARY KEY,
    condominio_id           BIGINT NOT NULL REFERENCES condominios(id),
    tipo                    VARCHAR(40),    -- ata, convocacao, regimento, convencao, contrato, outro
    nome_arquivo            VARCHAR(255) NOT NULL,
    caminho_armazenamento   VARCHAR(500) NOT NULL,
    versao                  INT NOT NULL DEFAULT 1,
    enviado_por             BIGINT,     -- id em db_master.funcionarios
    criado_em               TIMESTAMP NOT NULL DEFAULT now()
);

CREATE TABLE avisos (
    id                      BIGSERIAL PRIMARY KEY,
    condominio_id           BIGINT NOT NULL REFERENCES condominios(id),
    assembleia_id           BIGINT REFERENCES assembleias(id),  -- opcional: aviso sobre uma assembleia específica
    tipo                    VARCHAR(20) NOT NULL DEFAULT 'aviso',  -- aviso, alerta
    titulo                  VARCHAR(150) NOT NULL,
    mensagem                TEXT NOT NULL,
    data_evento             TIMESTAMP,      -- data/hora do evento relacionado (se houver)
    data_publicacao         TIMESTAMP NOT NULL DEFAULT now(),
    data_expiracao          TIMESTAMP,
    prioridade              VARCHAR(10) DEFAULT 'normal',   -- baixa, normal, alta, urgente
    enviar_whatsapp         BOOLEAN NOT NULL DEFAULT false,
    enviar_email            BOOLEAN NOT NULL DEFAULT false,
    status_envio            VARCHAR(20) NOT NULL DEFAULT 'nao_enviado', -- nao_enviado, enviado, falhou
    criado_por_funcionario  BIGINT,     -- id em db_master.funcionarios
    criado_em               TIMESTAMP NOT NULL DEFAULT now()
);

CREATE TABLE aviso_documentos (
    aviso_id        BIGINT NOT NULL REFERENCES avisos(id),
    documento_id    BIGINT NOT NULL REFERENCES documentos(id),
    PRIMARY KEY (aviso_id, documento_id)
);

-- destinatário pode ser um contato (síndico/subsíndico/conselheiro) OU um funcionário do escritório
CREATE TABLE aviso_destinatarios (
    aviso_id            BIGINT NOT NULL REFERENCES avisos(id),
    tipo_destinatario   VARCHAR(20) NOT NULL,   -- contato, funcionario
    destinatario_id     BIGINT NOT NULL,        -- contatos.id ou db_master.funcionarios.id, conforme tipo
    PRIMARY KEY (aviso_id, tipo_destinatario, destinatario_id)
);

CREATE TABLE log_auditoria (
    id                  BIGSERIAL PRIMARY KEY,
    funcionario_id      BIGINT,
    acao                VARCHAR(20) NOT NULL,   -- create, update, delete
    tabela_afetada      VARCHAR(60) NOT NULL,
    registro_id         BIGINT,
    dados_anteriores    JSONB,
    dados_novos         JSONB,
    criado_em           TIMESTAMP NOT NULL DEFAULT now()
);

Removido em relação à v2.0: contatos_condominio (virou contatos + contato_condominio), reservas_area_comum, regras_cobranca, historico_reajustes, prestacoes_contas, lancamentos_financeiros, ocorrencias, fornecedores, votacoes.


3. Fluxo do exemplo que você deu

"Assembleia dia 23/11/2026 às 18:00 → vincular documentos pertinentes":

  1. Cadastra em assembleias: condominio_id, tipo='ordinaria', data_hora='2026-11-23 18:00', pauta.
  2. Cria um avisos com assembleia_id apontando pra ela, tipo='aviso', data_evento = mesma data/hora.
  3. Anexa os documentos (convocação, pauta detalhada) via aviso_documentos.
  4. Escolhe destinatários em aviso_destinatarios (síndico, subsíndico, conselheiros daquele condomínio + funcionários vinculados) — ou marca "todos" como padrão sugerido.
  5. Marca enviar_whatsapp/enviar_email e dispara.

4. Autenticação, financeiro/AbacatePay, dashboard, catálogo de funcionalidades

Sem mudanças em relação à v2.0 — seguem valendo:

  • 3 camadas de auth (master / escritório / API Key)
  • Módulo financeiro do escritório (assinaturas, períodos de uso, pagamentos PIX via AbacatePay, bloqueio automático)
  • Menu do dashboard (Master: Clientes/Planos/Financeiro/Configurações · Cliente: Cadastro Condomínio/Financeiro/Configurações)
  • Catálogo de funcionalidades (whatsapp, e-mail, API, exportação, auditoria etc.)

5. Endpoints ajustados

CRUD   /api/condominios
CRUD   /api/condominios/{id}/contatos                (vincula/desvincula tipo=sindico|subsindico|conselheiro)
CRUD   /api/condominios/{id}/funcionarios-vinculados
CRUD   /api/condominios/{id}/espacos-comuns
CRUD   /api/condominios/{id}/assembleias
CRUD   /api/condominios/{id}/documentos
POST   /api/condominios/{id}/avisos                  (body: assembleia_id?, documentos: [id,...], destinatarios: [{tipo, id}, ...])
GET    /api/condominios/{id}/avisos/{id}

App externo (API Key)

GET    /api/external/condominios/{id}/resumo
       → síndico/subsíndico/conselheiros atuais, próxima assembleia, avisos ativos, espaços comuns

6. Próximos passos

Escopo definitivo fechado. Posso começar os prompt files numerados agora (01-setup-projeto-docker.md em diante)?