... | ... | @@ -19,8 +19,6 @@ |
|
|
## Visão Geral
|
|
|
O banco de dados foi projetado para suportar a plataforma de campanhas de arrecadação, contemplando usuários (administradores e doadores), endereços, campanhas, doações, pagamentos e eventos.
|
|
|
|
|
|
---
|
|
|
|
|
|
## Tecnologias
|
|
|
|
|
|
Para a implementação do banco, a equipe decidiu por utilizar PostgreSQL junto com ORM Prisma, devida à familiaridade do time com as mesmas, além da fácil integração entre as duas.
|
... | ... | @@ -29,81 +27,196 @@ O PostgreSQL é um sistema de gerenciamento de banco de dados relacional (SGBD) |
|
|
|
|
|
O Prisma é uma ferramenta ORM (Object-Relational Mapping) avançada para Node.js (assim como NestJS) e TypeScript, projetada para simplificar a interação entre a aplicação e o banco de dados. Ele gera um cliente fortemente tipado a partir de um arquivo de esquema (schema.prisma), proporcionando consultas seguras e fáceis de entender. Além disso, o Prisma oferece suporte a migrações versionadas com histórico, introspecção e um modelo declarativo, o que melhora o fluxo de desenvolvimento e facilita a manutenção do banco de dados. Com isso, o Prisma contribui para um desenvolvimento backend mais ágil, reduzindo a possibilidade de erros em consultas e potencializando a produtividade de equipes que utilizam TypeScript.
|
|
|
|
|
|
---
|
|
|
|
|
|
## Entidades e Estrutura
|
|
|
### `user_account`
|
|
|
- `id` (UUID, PK)
|
|
|
- `full_name`, `email` (único, obrigatório)
|
|
|
- `password_hash`
|
|
|
|
|
|
### `password_reset_token`
|
|
|
- `id` (UUID, PK)
|
|
|
- `token`, `created_at`, `expires_at`
|
|
|
- `user_id` (FK → user_account.id)
|
|
|
|
|
|
### `admin`
|
|
|
- `user_id` (PK, FK → user_account.id)
|
|
|
- `root` (boolean, indica superadmin)
|
|
|
|
|
|
### `donor`
|
|
|
- `user_id` (PK, FK → user_account.id)
|
|
|
- `tax_id` (CPF, único)
|
|
|
- `birth_date`, `gender`, `phone`
|
|
|
|
|
|
### `address`
|
|
|
- `id` (UUID, PK)
|
|
|
- `state`, `city`, `district`, `street`, `number`, `complement`
|
|
|
|
|
|
### `campaign`
|
|
|
- `id` (UUID, PK)
|
|
|
- `title`, `description`, `target_amount`, `current_amount`, `start_date`, `end_date`, `image_url`
|
|
|
- `status` (`campaign_status`)
|
|
|
- `admin_id` (FK → admin.user_id)
|
|
|
- `created_by` (FK → user_account.id)
|
|
|
|
|
|
### `donation`
|
|
|
- `id` (UUID, PK)
|
|
|
- `donation_type`
|
|
|
- `amount`, `periodicity`,
|
|
|
- `donor_id` (FK → donor.user_id)
|
|
|
- `campaign_id` (FK → campaign.id)
|
|
|
- `created_at` (timestamptz)
|
|
|
|
|
|
### `payment`
|
|
|
- `id` (UUID, PK)
|
|
|
- `method` (`payment_method`)
|
|
|
- `status` (`payment_status`)
|
|
|
- `amount`, `paid_at`
|
|
|
- `donation_id` (FK → donation.id)
|
|
|
|
|
|
### `events`
|
|
|
- `id` (UUID, PK)
|
|
|
- `title`, `description`, `date_start`, `date_end`, `location`, `url`, `created_at`, `updated_at`
|
|
|
Este documento descreve a estrutura do banco de dados da aplicação!
|
|
|
|
|
|
---
|
|
|
|
|
|
### `users`
|
|
|
- `id` (String, PK)
|
|
|
- `email` (String, único, obrigatório)
|
|
|
- `password` (String, obrigatório)
|
|
|
- `role` (Enum `UserRole`, obrigatório)
|
|
|
- `image_url` (String, opcional)
|
|
|
- `full_name` (String, obrigatório)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
- `updated_at` (DateTime, obrigatório, on update)
|
|
|
- deleted_at` (DateTime, opcional)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `password_reset_tokens`
|
|
|
- `id` (String, PK)
|
|
|
- `token` (String, obrigatório)
|
|
|
- `user_id` (String, único, FK → users.id)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
- `expires_at` (DateTime, obrigatório)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `donors`
|
|
|
- `id` (String, PK, FK → users.id)
|
|
|
- `birth_date` (Date, obrigatório)
|
|
|
- `gender` (Enum `Gender`, obrigatório)
|
|
|
- `phone` (String, obrigatório)
|
|
|
- `cpf` (String, único, obrigatório)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `admins`
|
|
|
- `id` (String, PK, FK → users.id)
|
|
|
- `root` (Boolean, obrigatório, default `false`)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `addresses`
|
|
|
- `id` (String, PK)
|
|
|
- `state` (String(2), obrigatório)
|
|
|
- `city` (String, obrigatório)
|
|
|
- `district` (String, obrigatório)
|
|
|
- `street` (String, obrigatório)
|
|
|
- `number` (String, obrigatório)
|
|
|
- `postal_code` (String, obrigatório)
|
|
|
- `complement` (String, opcional)
|
|
|
- `donor_id` (String, obrigatório, FK → donors.id)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `campaigns`
|
|
|
- `id` (String, PK)
|
|
|
- `title` (String, obrigatório)
|
|
|
- `description` (String, obrigatório)
|
|
|
- `target_amount` (Decimal, obrigatório)
|
|
|
- `current_amount` (Decimal, obrigatório, default 0)
|
|
|
- `start_date` (Date, opcional)
|
|
|
-`end_date` (Date, opcional)
|
|
|
- `image_url` (String, opcional)
|
|
|
- `status` (Enum `CampaignStatus`, obrigatório, default `PENDING`)
|
|
|
- `created_by` (String, obrigatório, FK → users.id)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `donations`
|
|
|
- `id` (String, PK)
|
|
|
- `amount` (Decimal, obrigatório)
|
|
|
- `periodicity` (Enum `Periodicity`, opcional)
|
|
|
- `donor_id` (String, opcional, FK → donors.id)
|
|
|
- `campaign_id` (String, opcional, FK → campaigns.id)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
|
|
|
---
|
|
|
|
|
|
### `payments`
|
|
|
- `id` (String, PK)
|
|
|
- `payment_method` (Enum `PaymentMethod`, obrigatório)
|
|
|
- `status` (Enum `PaymentStatus`, obrigatório, default `PENDING`)
|
|
|
- `amount` (Decimal, opcional)
|
|
|
- `paid_at` (DateTime, opcional)
|
|
|
- `donation_id` (String, obrigatório, FK → donations.id)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `news`
|
|
|
- `id` (UUID, PK)
|
|
|
- `title`, `description`, `date`, `location`, `url`, `created_at`, `updated_at`
|
|
|
- `id` (String, PK)
|
|
|
- `title` (String, obrigatório)
|
|
|
- `description` (String, obrigatório)
|
|
|
- `date` (Date, opcional)
|
|
|
- `location` (String, opcional)
|
|
|
- `url` (String, opcional)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
- `updated_at` (DateTime, obrigatório, on update)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `events`
|
|
|
- `id` (String, PK)
|
|
|
- `title` (String, obrigatório)
|
|
|
- `description` (String, obrigatório)
|
|
|
- `date_start` (DateTime, obrigatório)
|
|
|
- `date_end` (DateTime, obrigatório)
|
|
|
- `location` (String, obrigatório)
|
|
|
- `url` (String, opcional)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
- `updated_at` (DateTime, obrigatório, on update)
|
|
|
|
|
|
---
|
|
|
|
|
|
### `newsletter`
|
|
|
- `id` (String, PK)
|
|
|
- `email` (String, único, obrigatório)
|
|
|
- `created_at` (DateTime, obrigatório, default now())
|
|
|
|
|
|
---
|
|
|
|
|
|
## Enums (Tipos de Dados Personalizados)
|
|
|
|
|
|
### `UserRole`
|
|
|
- `ADMIN`
|
|
|
- `DONOR`
|
|
|
|
|
|
### `CampaignStatus`
|
|
|
- `PENDING`
|
|
|
- `ACTIVE`
|
|
|
- `PAUSED`
|
|
|
- `FINISHED`
|
|
|
- `CANCELED`
|
|
|
|
|
|
### `PaymentMethod`
|
|
|
- `PIX`
|
|
|
- `BANK_SLIP`
|
|
|
- `CREDIT_CARD`
|
|
|
|
|
|
### `PaymentStatus`
|
|
|
- `PENDING`
|
|
|
- `AUTHORIZED`
|
|
|
- `CONFIRMED`
|
|
|
- `FAILED`
|
|
|
- `REFUNDED`
|
|
|
- `CANCELED`
|
|
|
|
|
|
### `Gender`
|
|
|
- `MALE`
|
|
|
- `FEMALE`
|
|
|
- `OTHER`
|
|
|
|
|
|
### `Periodicity`
|
|
|
- `MONTHLY`
|
|
|
- `QUARTERLY`
|
|
|
- `SEMI_ANNUAL`
|
|
|
- `YEARLY`
|
|
|
|
|
|
---
|
|
|
|
|
|
## Índices
|
|
|
- `campaign(admin_id)`
|
|
|
- `donation(donor_id)`
|
|
|
- `donation(campaign_id)`
|
|
|
- `payment(donation_id)`
|
|
|
- `password_reset_tokens(user_id)`
|
|
|
- `donors(cpf)`
|
|
|
- `addresses(donor_id)`
|
|
|
- `campaigns(created_by)`
|
|
|
- `donations(donor_id)`
|
|
|
- `donations(campaign_id)`
|
|
|
- `payments(donation_id)`
|
|
|
- `newsletter(email)`
|
|
|
|
|
|
---
|
|
|
|
|
|
## Observações
|
|
|
- Constraints de **ON DELETE** foram configuradas conforme regras de negócio.
|
|
|
- Doações preservam histórico mesmo se a campanha for excluída.
|
|
|
- Defaults: `uuid_generate_v4()` para IDs e `NOW()` para timestamps.
|
|
|
|
|
|
- **Gerenciamento de IDs**: Todas as chaves primárias (`id`) são do tipo `String` e utilizam `cuid()` como valor padrão para gerar identificadores únicos e seguros.
|
|
|
|
|
|
## Diagrama Entidade-Relacionamento
|
|
|
- **Exclusão em Cascata**: Ao excluir um `User`, seus perfis associados de `Admin` ou `Donor` serão automaticamente excluídos do banco de dados. Isso se deve à regra `onDelete: Cascade`.
|
|
|
|
|
|

|
|
|
- **Preservação de Histórico**: O histórico de doações (`Donation`) é preservado mesmo que a campanha (`Campaign`) ou o doador (`Donor`) associado seja excluído. Nesses casos, a referência à entidade apagada se tornará nula na doação, mantendo o registro da transação.
|
|
|
|
|
|
- **Timestamps Automatizados**: Campos como `created_at` são preenchidos automaticamente com a data e hora atuais no momento da criação de um registro. Campos chamados `updated_at` são atualizados automaticamente toda vez que o registro é modificado.
|
|
|
|
|
|
- **Padrão de Nomenclatura**: O schema utiliza os atributos `@@map` e `@map` para garantir que os nomes das tabelas e colunas no banco de dados sigam o padrão `snake_case` (ex: `fullName` no código vira `full_name` no banco), o que é uma excelente prática para consistência.
|
|
|
|
|
|
- **Precisão Financeira**: Valores monetários, como os de campanhas e doações, utilizam o tipo `Decimal(12, 2)` para garantir a precisão matemática e evitar problemas de arredondamento comuns com tipos de ponto flutuante.
|
|
|
|
|
|
## Diagrama Entidade-Relacionamento
|
|
|
|
|
|
O diagrama representa as principais entidades, atributos e relacionamentos do sistema, incluindo os atributos que utilizam os enums `user_role`, `campaign_status`, `payment_method`, `payment_status` e `gender`.
|
|
|

|
|
|
|
|
|
O diagrama mapeia a estrutura de dados do sistema, apresentando suas principais entidades, atributos e relacionamentos. Destaque para o uso de enums em campos-chave, como `user_role` e `payment_status`, para garantir a consistência e integridade dos dados |