| # Banco de Dados Postgres | # Banco de Dados PostgreSQL | ||
| O projeto WeConecta utiliza o PostgreSQL como sistema gerenciador de banco de dados. | O projeto **WeConecta** utiliza o **PostgreSQL** como sistema gerenciador de banco de dados. | ||
| O PostgreSQL é um banco de dados relacional robusto, confiável e amplamente utilizado em aplicações que exigem consistência, integridade e suporte a operações complexas. Ele oferece recursos avançados como controle de concorrência multiversão (MVCC), suporte a transações ACID, extensibilidade com funções e tipos personalizados, além de boa performance em ambientes de produção com grande volume de dados. | O PostgreSQL é um SGBD relacional robusto, confiável e amplamente utilizado em aplicações que exigem consistência, integridade referencial e transações ACID. Ele oferece recursos avançados como controle de concorrência multiversão (MVCC), extensibilidade com funções e tipos personalizados e excelente performance em ambientes com grande volume de dados. | ||
| ## Modelo Conceitual | |||
| A modelagem conceitual foi desenvolvida utilizando a ferramenta **brModelo**: | |||
|  | |||
| ## Modelo Lógico | ## Modelo Lógico | ||
| A seguinte modelagem foi desenvolvida utilizando a ferramenta online dbdiagram.io: | A modelagem lógica foi criada na ferramenta online **dbdiagram.io**: | ||
|  | |||
| ## Estrutura das Tabelas | |||
| A seguir estão as tabelas e descrições detalhadas do banco de dados. | |||
| ### users | |||
| Armazena os dados dos usuários do sistema (autenticação, perfil e status). | |||
| Cada registro representa um usuário único da API. | |||
| | Coluna | Tipo | Restrições | Descrição | Exemplo | | |||
| |--------|------|-------------|------------|----------| | |||
| | id | `uuid` | **PRIMARY KEY**, **DEFAULT** `gen_random_uuid()` | Identificador único do usuário. | `a6e1b7b2-12ef-4c45-a8f2-78c41d7f3321` | | |||
| | email | `varchar(255)` | **UNIQUE**, **NOT NULL** | E-mail de login do usuário. | [email protected] | | |||
| | password | `varchar(255)` | **NOT NULL** | Hash da senha. | `$2a$10$...` | | |||
| | phone | `varchar(11)` | **UNIQUE**, **NULLABLE** | Telefone (somente dígitos). | `51999990000` | | |||
| | friendly_name | `varchar(255)` | **NOT NULL** | Nome de exibição. | João Silva | | |||
| | role | `enum(UserRole)` | **DEFAULT** `'MEMBER'` | Papel do usuário: `ADMIN` ou `MEMBER`. | MEMBER | | |||
| | blocked_at | `timestamp` | **NULLABLE** | Data/hora de bloqueio do usuário. | 2025-09-01 13:45:12 | | |||
| | first_login | `boolean` | **DEFAULT** `true` | Indica se é o primeiro acesso. | false | | |||
| | created_at | `timestamp` | **DEFAULT** `CURRENT_TIMESTAMP` | Data/hora de criação. | 2025-09-01 12:30:00 | | |||
| **Relacionamentos:** | |||
| - 1:N com `users_surveys` (`User` → `UsersSurveys`). | |||
| ### surveys | |||
| Representa os questionários cadastrados no sistema, contendo metadados, fluxo de navegação e status de publicação. | |||
| | Coluna | Tipo | Restrições | Descrição | Exemplo | | |||
| |--------|------|-------------|------------|----------| | |||
| | id | `integer` | **PRIMARY KEY** | Identificador único. | 12 | | |||
| | first_survey_element | `integer` | **FK → survey_elements(id)**, **NULLABLE**, **ON DELETE SET NULL** | Primeiro elemento do fluxo. | 101 | | |||
| | title | `varchar(255)` | **NOT NULL** | Título do questionário. | Pesquisa de Satisfação | | |||
| | description | `varchar(500)` | **NULLABLE** | Descrição breve. | Avalie seu atendimento | | |||
| | url | `varchar(255)` | **NULLABLE** | URL pública do questionário. | `/q/satisfacao-2025` | | |||
| | flow | `jsonb` | **NULLABLE**, **DEFAULT null** | Define o fluxo entre os elementos (nós e setas). | — | | |||
| | is_published | `boolean` | **DEFAULT false** | Indica se está publicado. | true | | |||
| | created_at | `timestamp` | **DEFAULT CURRENT_TIMESTAMP** | Data de criação. | 2025-09-01 12:30:00 | | |||
| **Relacionamentos:** | |||
| - 1:N com `users_surveys` (`Survey` → `UsersSurveys`). | |||
| - 1:N com `survey_answers` (`Survey` → `SurveyAnswers`). | |||
| - N:1 com `survey_elements` via `first_survey_element`. | |||
| ### users_surveys | |||
| Tabela intermediária que representa o relacionamento **N:N** entre usuários e questionários. | |||
| | Coluna | Tipo | Restrições | Descrição | Exemplo | | |||
| |--------|------|-------------|------------|----------| | |||
| | id | `integer` | **PRIMARY KEY** | Identificador único da relação. | 45 | | |||
| | user_id | `uuid` | **FK → users(id)**, **NOT NULL**, **ON DELETE CASCADE** | Usuário vinculado. | `a6e1b7b2-12ef-4c45-a8f2-78c41d7f3321` | | |||
| | survey_id | `integer` | **FK → surveys(id)**, **NOT NULL**, **ON DELETE CASCADE** | Questionário vinculado. | 12 | | |||
| **Relacionamentos:** | |||
| - N:1 com `users`. | |||
| - N:1 com `surveys`. | |||
| - Representa `users (0..N) ⇄ (0..N) surveys`. | |||
| ### survey_elements | |||
| Armazena os elementos que compõem os questionários (perguntas, mensagens ou campos de entrada). | |||
| | Coluna | Tipo | Restrições | Descrição | Exemplo | | |||
| |--------|------|-------------|------------|----------| | |||
| | id | `integer` | **PRIMARY KEY** | Identificador único do elemento. | 101 | | |||
| | description | `varchar(500)` | **NOT NULL** | Texto ou enunciado exibido. | Qual sua idade? | | |||
| | type | `enum(SurveyElementType)` | **NOT NULL** | Tipo de elemento: `OPTION`, `MULTIPLE_CHOICE`, `INPUT`, `MESSAGE`. | MULTIPLE_CHOICE | | |||
| | tag | `varchar(255)` | **NOT NULL** | Tag de identificação lógica no fluxo. | idade_usuario | | |||
| **Relacionamentos:** | |||
| - 1:N com `options` (`SurveyElement` → `Option`). | |||
| - 1:N com `survey_answers` (`SurveyElement` → `SurveyAnswer`). | |||
| - Referenciado em `surveys.flow`. | |||
| ### options | |||
| Representa as opções vinculadas a um `survey_element` (quando o tipo é escolha). | |||
| | Coluna | Tipo | Restrições | Descrição | Exemplo | | |||
| |--------|------|-------------|------------|----------| | |||
| | id | `integer` | **PRIMARY KEY** | Identificador único da opção. | 301 | | |||
| | survey_element_id | `integer` | **FK → survey_elements(id)**, **NOT NULL**, **ON DELETE CASCADE** | Elemento ao qual pertence. | 101 | | |||
| | description | `varchar(255)` | **NOT NULL** | Texto da opção. | 18 a 24 anos | | |||
| **Relacionamentos:** | |||
| - N:1 com `survey_elements`. | |||
| - 1:N com `survey_answers` (`Option` → `SurveyAnswer`), pois uma opção pode ser escolhida em várias respostas. | |||
| ### survey_answers | |||
|  | Armazena as respostas dos usuários aos questionários. | ||
| Cada linha representa **uma resposta individual** de um participante. | |||
| ## Tabelas | |||
| A seguir, têm-se explicações detalhadas sobre as tabelas desenvolvidas para o banco de dados. | | Coluna | Tipo | Restrições | Descrição | Exemplo | | ||
| |--------|------|-------------|------------|----------| | |||
| ## users | | identifier | `varchar(255)` | **NOT NULL** | Identificador único do respondente (token). | `resp-9df7a3b1` | | ||
| | survey_id | `integer` | **FK → surveys(id)**, **NOT NULL**, **ON DELETE CASCADE** | Questionário ao qual a resposta pertence. | 12 | | |||
| Tabela que armazena os usuários do sistema (autenticação, perfil e status). Cada registro representa um usuário único da API. | | survey_element_id | `integer` | **FK → survey_elements(id)**, **NOT NULL**, **ON DELETE CASCADE** | Elemento respondido. | 101 | | ||
| | option_id | `integer` | **FK → options(id)**, **NULLABLE**, **ON DELETE SET NULL** | Opção marcada (para perguntas de escolha). | 301 | | |||
| | Nome da Coluna | Tipo de Dado | Restrições (Constraints) | Descrição | Valor Exemplo | | | input_response | `varchar(500)` | **NULLABLE** | Resposta textual (para perguntas `INPUT`). | “25 anos” | | ||
| |---|---|---|---|---| | |||
| | id | integer (auto-increment) | **PRIMARY KEY** | Identificador único do usuário. | 57 | | **Relacionamentos:** | ||
| | email | varchar(255) | **UNIQUE**, **NOT NULL** | E-mail de login do usuário. | [email protected] | | - N:1 com `surveys`. | ||
| | password | varchar(255) | **NOT NULL** | Hash da senha do usuário. | `$2a$10$...` | | - N:1 com `survey_elements`. | ||
| | phone | varchar(11) | **UNIQUE**, **NULLABLE** | Telefone (somente dígitos). Pode ficar vazio. | `51999990000` | | - 0..1:N com `options` — uma `survey_answer` pode ter **0 ou 1 option**, e uma `option` pode estar em **0 ou N answers**. | ||
| | friendly_name | varchar(255) | **NOT NULL** | Nome de exibição do usuário. | João Silva | | |||
| | role | enum(`UserRole`) | **DEFAULT** `'MEMBER'` | Papel do usuário no sistema. Pode ser `ADMIN` (administrador, com acesso total e permissões de gerenciamento) ou `MEMBER` (usuário comum, com permissões limitadas). O valor padrão é `MEMBER`. | MEMBER | | |||
| | blocked_at | timestamp | **NULLABLE** | Data/hora em que o usuário foi bloqueado (se houver). | 2025-09-01 13:45:12 | | |||
| | first_login | boolean | **DEFAULT** `true` | Indica se é o primeiro acesso após cadastro. | false | | |||
| | created_at | timestamp | **DEFAULT** `CURRENT_TIMESTAMP` | Momento de criação do registro. | 2025-09-01 12:30:00 | | |||
| ### Observações e Relacionamentos | |||
| - **Relacionamentos**: 1:N com `users_surveys` (`User` → `UsersSurveys`), permitindo consultar os questionários vinculados a cada usuário. | |||
| ## surveys | |||
| Tabela que representa os questionários do sistema (metadados, status de publicação e fluxo de navegação entre elementos). | |||
| | Nome da Coluna | Tipo de Dado | Restrições (Constraints) | Descrição | Valor Exemplo | | |||
| |---|---|---|---|---| | |||
| | id | integer (auto-increment) | **PRIMARY KEY** | Identificador único do questionário. | 12 | | |||
| | first_survey_element | integer | **FK** → `survey_elements(id)`, **NULLABLE**, **ON DELETE SET NULL** | Primeiro elemento do fluxo do questionário. | 101 | | |||
| | title | varchar(255) | **NOT NULL** | Título do questionário. | Pesquisa de Satisfação | | |||
| | description | varchar(500) | **NULLABLE** | Descrição breve do questionário. | Avalie seu atendimento | | |||
| | url | varchar(255) | **NULLABLE** | URL pública/slug de acesso ao questionário. | `/q/satisfacao-2025` | | |||
| | is_published | boolean | **DEFAULT** `false` | Indica se o questionário está publicado. | true | | |||
| | created_at | timestamp | **DEFAULT** `CURRENT_TIMESTAMP` | Momento de criação do registro. | 2025-09-01 12:30:00 | | |||
| | flow | json | **NULLABLE**, **DEFAULT** `null` | Definição do fluxo entre elementos (nós e setas/opções). | ver abaixo | | |||
| ### Observações e Relacionamentos | |||
| - **flow (JSON)**: lista de nós do fluxo. Cada item mapeia um elemento do questionário e suas opções de saída (com setas para o próximo elemento). Estrutura esperada: | |||
| ```json | |||
| [ | |||
| { | |||
| "surveyElementId": 101, | |||
| "coordinates": { "x": 120, "y": 80 }, | |||
| "options": [ | |||
| { | |||
| "coordinates": { "x": 200, "y": 80 }, | |||
| "optionId": 5, | |||
| "nextSurveyElementId": 102 | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| - `nextSurveyElementId` pode ser `null` (fim de fluxo). | |||
| ### Relacionamentos | |||
| - **N:1** com `survey_elements` via `first_survey_element`. | |||
| - **1:N** com `users_surveys` (`Survey` → `UsersSurveys`) para vincular usuários aos questionários. | |||
| ## users_surveys | |||
| Tabela de junção que relaciona usuários (`users`) com questionários (`surveys`). Cada registro indica que um usuário está vinculado a um determinado questionário. | |||
| | Nome da Coluna | Tipo de Dado | Restrições (Constraints) | Descrição | Valor Exemplo | | |||
| |---|---|---|---|---| | |||
| | id | integer (auto-increment) | **PRIMARY KEY** | Identificador único da relação. | 45 | | |||
| | user_id | integer | **FK** → `users(id)`, **NOT NULL**, **ON DELETE CASCADE** | Referência ao usuário vinculado. | 57 | | |||
| | survey_id | integer | **FK** → `surveys(id)`, **NOT NULL**, **ON DELETE CASCADE** | Referência ao questionário vinculado. | 12 | | |||
| ### Relacionamentos | |||
| - **N:1** com `users` (um vínculo pertence a um único usuário). | |||
| - **N:1** com `surveys` (um vínculo pertence a um único questionário). | |||
| - Forma a relação **N:N** entre `users` e `surveys`, pois um usuário pode estar em vários questionários, e um questionário pode estar vinculado a vários usuários. | |||
| ## survey_elements | |||
| Tabela que representa os elementos de um questionário. Cada elemento pode ser um campo de entrada, uma mensagem ou um conjunto de opções. | |||
| | Nome da Coluna | Tipo de Dado | Restrições (Constraints) | Descrição | Valor Exemplo | | |||
| |---|---|---|---|---| | |||
| | id | integer (auto-increment) | **PRIMARY KEY** | Identificador único do elemento. | 101 | | |||
| | description | varchar(500) | **NOT NULL** | Texto descritivo ou enunciado exibido no elemento do questionário. | Qual sua idade? | | |||
| | type | enum(`SurveyElementType`) | **NOT NULL** | Tipo do elemento no questionário. Pode ser:<br> - `OPTION`: elemento de opção única<br> - `MULTIPLE_CHOICE`: múltipla escolha<br> - `INPUT`: campo de entrada de texto<br> - `MESSAGE`: mensagem informativa | OPTION | | |||
| | tag | varchar(255) | **NOT NULL** | Identificador único (slug/tag) usado para referência lógica no fluxo. | idade_usuario | | |||
| ### Relacionamentos | |||
| - **1:N** com `options` (`SurveyElement` → `Option`), permitindo definir as opções vinculadas ao elemento. | |||
| - Pode ser referenciado em `surveys.flow` como parte do fluxo de execução do questionário. | |||
| ## options | |||
| Tabela que representa as opções vinculadas a elementos do tipo escolha em um questionário. Cada opção pertence a um `survey_element`. | |||
| | Nome da Coluna | Tipo de Dado | Restrições (Constraints) | Descrição | Valor Exemplo | | |||
| |---|---|---|---|---| | |||
| | id | integer (auto-increment) | **PRIMARY KEY** | Identificador único da opção. | 301 | | |||
| | survey_element_id | integer | **FK** → `survey_elements(id)`, **NOT NULL**, **ON DELETE CASCADE** | Referência ao elemento do questionário ao qual a opção pertence. | 101 | | |||
| | description | varchar(255) | **NOT NULL** | Texto exibido como alternativa ao usuário. | 18 a 24 anos | | |||
| ### Relacionamentos | |||
| - **N:1** com `survey_elements` (`Option` → `SurveyElement`), pois cada opção pertence a um elemento. | |||
| - Usado em conjunto com o fluxo (`surveys.flow`) para definir a navegação entre elementos. |