Banco-de-Dados.md
0 → 100644
# Banco de Dados | |||
--- | |||
## Visão Geral | |||
O projeto utiliza **Cloud Firestore**, um banco de dados NoSQL do Firebase, para gerenciar eventos interativos. O banco de dados foi projetado para acesso em tempo real, alta escalabilidade e performance de leitura, utilizando referências e denormalização planejada. O sistema é estruturado em torno das coleções centrais `users` (os participantes) e `events` (os contêineres principais da experiência). | |||
Para gerenciar as interações, a plataforma utiliza outras coleções: | |||
* `activities`: Agenda detalhada do evento, como palestras e workshops. | |||
* `tasks`: Desafios gamificados para engajar o público. | |||
* `user_event`: Gerencia as inscrições dos participantes e consolida a pontuação final. | |||
* `user_task`: Registra em detalhes as submissões de tarefas, incluindo as respostas dos usuários e os resultados das validações. | |||
A arquitetura da plataforma é construída sobre o ecossistema Google Firebase, utilizando serviços como **Cloud Firestore**, **Firebase Authentication**, **Cloud Functions**, **Cloud Storage** e **Firestore Security Rules**. | |||
--- | |||
## Coleções e Campos | |||
### users | |||
Armazena os dados de perfil de cada indivíduo cadastrado na plataforma. É a coleção fundamental que gerencia a identidade e as permissões dos usuários, como se são administradores ou usuários comuns. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único do documento na coleção `users`, gerado automaticamente pelo Firestore. | `aG8jL2xRkM4nB7oP3jL5`| | |||
| **firebase uid** | `String` | Obrigatório. | ID de autenticação do usuário, gerado pelo Firebase Auth. Usado para vincular o login aos dados do usuário. | `4f2bT8aG9qN3x5H7s2`| | |||
| **name** | `String` | Obrigatório. | Nome completo do usuário. | `Juca da Silva`| | |||
| **email** | `String` | Obrigatório. Validador de formato. | E-mail do usuário. | `[email protected]`| | |||
| **birth date** | `Timestamp` | Opcional. | Data de nascimento do usuário. | `October 20, 1995 at 12:00:00 AM UTC-3`| | |||
| **field** | `String` | Opcional. | Área de atuação profissional do usuário. | `Engenharia de Software`| | |||
| **phone_number** | `String` | Obrigatório. Validador de formato. | Número de telefone do usuário. | `+5551999998888`| | |||
| **city** | `String` | Obrigatório. | Cidade de residência do usuário. | `Porto Alegre`| | |||
| **state** | `String` | Obrigatório. | Estado de residência do usuário. | `Rio Grande do Sul`| | |||
| **country** | `String` | Obrigatório. | País de residência do usuário. | `Brasil`| | |||
| **gender** | `String` | Opcional. Valores Permitidos: `male`, `female`, `non_binary`, `other`, `no_info`. | Gênero com o qual o usuário se identifica. | `male`| | |||
| **is_active** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indicador se o usuário está ativo ou inativo no sistema (soft delete). | `true`| | |||
| **is_admin** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indicador se o usuário é administrador do sistema. | `true`| | |||
| **created_at** | `Timestamp` | Obrigatório. | Data e hora de criação do registro. | `August 19, 2025 at 4:13:40 AM UTC-3`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização do registro. | `August 19, 2025 at 4:13:40 AM UTC-3`| | |||
--- | |||
### events | |||
Define os eventos principais. Cada documento é um evento único (ex: congresso, feira, simpósio) que serve como um contêiner para todas as atividades e tarefas relacionadas a ele. Controla informações macro como datas, título e o status geral do evento. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único do documento na coleção `events`, gerado automaticamente pelo Firestore. | `kM4nB7oP3jL5aG8jL2xR`| | |||
| **title** | `String` | Obrigatório. | Título principal do evento. | `Semana da Inovação 2025`| | |||
| **description** | `String` | Obrigatório. | Descrição completa do evento. | `Um evento focado nas últimas tendências de IA e desenvolvimento de software...`| | |||
| **access_code** | `String` | Obrigatório. Deve conter 5 caracteres. | Código alfanumérico para o usuário se inscrever no evento. | `1A5VP`| | |||
| **field** | `String` | Obrigatório. | Área de conhecimento ou setor principal ao qual o evento pertence. | `Tecnologia da Informação`| | |||
| **start_date** | `Timestamp` | Obrigatório. | Data e hora exatas de início do evento. | `November 10, 2025 at 9:00:00 AM UTC-3`| | |||
| **end_date** | `Timestamp` | Obrigatório. | Data e hora exatas de término do evento. | `November 12, 2025 at 6:00:00 PM UTC-3`| | |||
| **type** | `String` | Obrigatório. | Tipo de evento, usado para classificar sua natureza e formato. | `Feira`| | |||
| **status** | `String` | Obrigatório. Valores Permitidos: `draft`, `published`, `ongoing`, `ended`, `canceled`. | Status atual do ciclo de vida do evento. | `ongoing`| | |||
| **is_active** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indicador para exclusão lógica (soft delete). | `True`| | |||
| **customization** | `Map` | Obrigatório. | Objeto (Map) contendo as personalizações visuais da página do evento. | `{ "primary_color": "#3A10E5", "banner_url": "https://.../banner.png"}`| | |||
| **tasks** | `Array` | Opcional. | Array de objects tasks embarcados como sub coleção. Representa as tarefas associadas a este evento. | `{ "taskld01", "taskld02"}`| | |||
| **activities** | `Array` | Opcional. | Array de objects activities embarcados como sub coleção. Representa as atividades associadas a este evento. | `{ "activityld01", "activityld02"}`| | |||
| **created_at** | `Timestamp` | Obrigatório. | Data e hora de criação do registro. | `August 19, 2025 at 4:38:20 AM UTC-3`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização do registro. | `August 19, 2025 at 4:38:20 AM UTC-3`| | |||
--- | |||
### events.customization | |||
Este objeto funciona como um painel de controle para a identidade visual de um evento, permitindo a personalização de cores, fontes e imagens para criar uma experiência única para os participantes. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **primary_color** | `String` | Obrigatório. Formato HEX. | Cor primária usada nos elementos visuais do evento. | `#3A10E5`| | |||
| **secondary_color** | `String` | Obrigatório. Formato HEX. | Cor secundária usada nos elementos visuais do evento. | `#FFFFFF`| | |||
| **tertiary_color** | `String` | Obrigatório. Formato HEX. | Cor terciária usada nos elementos visuais do evento. | `#000000`| | |||
| **font** | `String` | Obrigatório. | Família de fonte a ser utilizada na página do evento. | `Roboto`| | |||
| **banner_url** | `String` | Obrigatório. | URL do banner do evento. | `https//.../banner.png:`| | |||
--- | |||
### events.tasks | |||
Contém o catálogo de todas as tarefas interativas que os usuários podem realizar. Cada sub documento define uma tarefa, seja ela um quiz, uma question ou um challenge. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único do sub documento da tarefa na coleção events. | `bH9kL2xRkM4nB7oP3jL5`| | |||
| **is_active** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indicador para definir se a task está disponível para o usuário. | `True`| | |||
| **number** | `number` | Obrigatório para `normal_task` em `task_category`. | Número que define a ordem de execução da tarefa. | `1`| | |||
| **score** | `number` | Obrigatório. | Pontuação máxima que o usuário pode obter ao completar a tarefa. | `100`| | |||
| **description** | `String` | Obrigatório. | Instrução ou descrição da tarefa. | `Responda ao quiz sobre a palestra de abertura.`| | |||
| **title** | `String` | Obrigatório. | Título curto da tarefa. | `Quiz: Palestra de Abertura`| | |||
| **status** | `String` | Obrigatório. Valores Permitidos: `upcoming`, `underway`, `ended`. | Status da tarefa, que pode controlar se ela está visível ou aceitando respostas. | `underaway`| | |||
| **task_type** | `String` | Obrigatório. Valores Permitidos: `quiz`, `question`, `challenge`. | Tipo de tarefa, para diferenciar lógicas de negócio. | `quiz`| | |||
| **task_category** | `String` | Obrigatório. Valores Permitidos: `normal`, `lightining`. | Categoria de tarefa para definir o comportamento. | `Normal`| | |||
| **questions** | `Array` | Obrigatório para `quiz` e `question` em `task_type`. | Array de objetos (Map), onde cada objeto representa uma pergunta da tarefa. | `[ { "question_type": "multiple_choice", ...}]`| | |||
| **created_at** | `Timestamp` | Obrigatório. | Data e hora de criação da tarefa. | `August 19, 2025`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização. | `August 19, 2025`| | |||
--- | |||
### events.tasks.questions | |||
Objeto aninhado que define a estrutura de uma pergunta. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **question_type** | `String` | Obrigatório. Valores Permitidos: `multiple_choice`, `single_choice`, `text_input`. | Formato da pergunta, para renderizar o componente correto na interface. | `multiple_choice`| | |||
| **text** | `String` | Obrigatório. | Texto da pergunta que será exibido ao usuário. | `Qual foi o tema principal da palestra de abertura?`| | |||
| **options** | `Array` | Obrigatório para `question_type` do tipo `choice`. | Array de objetos (Map), onde cada objeto representa uma opção de resposta. | `({"text": "Letra A: ...", "is_correct": true}, ...]`| | |||
--- | |||
### events.tasks.questions.options | |||
Objeto aninhado que representa uma opção de resposta. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `number` | Obrigatório. | Identificador único da opção. | `1`| | |||
| **text** | `String` | Obrigatório. | O texto da opção de resposta. | `Letra A: IA`| | |||
| **is_correct** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indica se a opção é a resposta correta ou não. | `True`| | |||
--- | |||
### events.activities | |||
Representa a agenda ou a programação de um evento. Cada documento é uma atividade específica e agendada. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único do sub documento da atividade na coleção event. | `cH1jL2xRkM4nB7oP3jL5`| | |||
| **title** | `String` | Obrigatório. | Título da atividade. | `Coffee Break da Manhã`| | |||
| **start_at** | `Timestamp` | Obrigatório. | Data e hora exatas de início da atividade. | `November 10, 2025 at 10:00:00 AM UTC-3`| | |||
| **end_at** | `Timestamp` | Obrigatório. | Data e hora exatas de término da atividade. | `November 10, 2025 at 11:00:00 AM UTC-3`| | |||
| **description** | `String` | Obrigatório. | Resumo ou sinopse da atividade. | `Uma pausa para recarregar as energias. Serão servidos café, chás, sucos, água, mini sanduíches, pães de queijo e uma seleção de bolos e frutas da estação.`| | |||
| **type** | `String` | Obrigatório. Valores Permitidos: `meal`, `other`. | Categoria da atividade, usada para organização da agenda. | `meal`| | |||
| **image_url** | `String` | Obrigatório. | URL de uma imagem de banner para a atividade. | `https://.../banner-photo.png`| | |||
| **is_active** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indicador para exclusão lógica (soft delete). | `True`| | |||
| **created_at** | `Timestamp` | Obrigatório. | Data e hora de criação do registro. | `August 19, 2025 at 4:13:40 AM UTC-3`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização do registro. | `August 19, 2025 at 4:13:40 AM UTC-3`| | |||
--- | |||
### user_task | |||
É o registro de auditoria de todas as interações. Cada documento representa uma única tentativa que um usuário fez em uma tarefa. Armazena as respostas exatas, o resultado da correção e a pontuação obtida. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único do documento, formado pela junção de `user_id` e `task_id`. | `4f2b...s2_bH9k...jL5`| | |||
| **user_id** | `String` | Obrigatório. | ID do usuário (da coleção `users`) que realizou a tarefa. | `4f2bT8aG9qN3x5H7s2`| | |||
| **task_id** | `String` | Obrigatório. | ID da tarefa (da coleção `tasks`) que foi realizada. | `bH9kL2xRkM4nB7oP3jL5`| | |||
| **event_id** | `String` | Obrigatório. | ID do evento ao qual esta submissão pertence. Denormalizado da tarefa para facilitar consultas. | `kM4nB7oP3jL5aG8jL2xR`| | |||
| **answers** | `Array` | Obrigatório. | Array de objetos (Map) contendo as respostas enviadas pelo usuário para as perguntas da tarefa. | `{ "question_text": "...", "user_answer": "..."}`| | |||
| **is_correct** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indica se o conjunto de respostas está 100% correto. | `True`| | |||
| **is_validated** | `boolean` | Obrigatório. Valores Permitidos: `true`, `false`. | Indica se a submissão foi validada por um administrador. | `True`| | |||
| **score** | `number` | Obrigatório. | Pontuação que o usuário obteve nesta tarefa. | `50`| | |||
| **created_at** | `Timestamp` | Obrigatório. | Data e hora exatas em que o usuário submeteu a tarefa. | `August 19, 2025 at 7:22:41 AM UTC-3`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização do registro. | `August 19, 2025 at 7:22:41 AM UTC-3`| | |||
--- | |||
### user_task.answers | |||
Detalha as respostas de uma submissão de tarefa. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **question_text** | `String` | Obrigatório para `quiz` e `question` em `task_type`. | Cópia do texto da pergunta no momento da resposta. | `Qual foi o tema principal da palestra de abertura?`| | |||
| **user_answer** | `String` | Obrigatório para `quiz` e `question` em `task_type`. | Para quiz, armazena o `option_id`. Para question, armazena o texto livre. | `"Inteligência Artificial"` ou `1`| | |||
| **is_correct** | `boolean` | Obrigatório para `quiz` em `task_type`. Valores Permitidos: `true`, `false`. | Resultado da verificação automática da resposta do quiz. | `true`| | |||
| **submission_type** | `String` | Obrigatório para `challenge` em `task_type`. Valores Permtidos: `image`, `video`. | Define o tipo de arquivo enviado. | `image`| | |||
| **submission_url** | `String` | Obrigatório para `challenge` em `task_type`. | URL do arquivo (imagem ou vídeo) enviado. | `https://storage.googleapis.com/...`| | |||
--- | |||
### user_event | |||
Funciona como a lista de inscrição oficial, conectando usuários a eventos. Cada documento é a prova de que um usuário está participando de um evento específico. Além disso, serve como um placar consolidado, armazenando o `total_score` do usuário. | |||
| Campo | Tipo | Restrições | Descrição | Exemplo | | |||
| :--- | :--- | :--- | :--- | :--- | | |||
| **id** | `String` | Obrigatório. | Identificador único, formado pela junção de `user_id` e `event_id`. | `4f2b... H7s2_kM4n...L2xR`| | |||
| **user_id** | `String` | Obrigatório. | ID do usuário (da coleção `users`) que está participando. | `4f2bT8aG9qN3x5H7s2...`| | |||
| **event_id** | `String` | Obrigatório. | ID do evento (da coleção `events`) do qual o usuário está participando. | `kM4nB7oP3jL5aG8jL2xR`| | |||
| **total_score** | `number` | Obrigatório. | Placar final do usuário no evento. Calculado por uma Cloud Function ao final do período de revisão. | `150`| | |||
| **enrollment_date** | `Timestamp` | Obrigatório. | Data e hora em que o usuário se inscreveu no evento. | `August 19, 2025 at 8:25:10 AM UTC-3`| | |||
| **updated_at** | `Timestamp` | Obrigatório. | Data e hora da última atualização neste registro. | `August 19, 2025 at 8:28:00 AM UTC-3`| | |||
--- | |||
## Relacionamentos | |||
### Relações Principais | |||
* **events (Eventos):** Um evento contém subcoleções aninhadas de `activities` e `tasks`. Um evento tem muitos `users` participantes, através da coleção de junção `user_event`. | |||
* **users (Usuários):** Um usuário pode participar de muitos `events` através da coleção `user_event`. Um usuário pode submeter muitas `tasks` através da coleção `user_task`. | |||
### Relações nas Coleções "Filhas" | |||
* **activities (Atividades):** É uma subcoleção aninhada dentro de cada documento de evento. Cada `activity` pertence ao evento pai por meio de sua hierarquia de caminho (`/events/{event_id}/activities/{activity_id}`). | |||
* **tasks (Tarefas):** É uma subcoleção aninhada dentro de cada documento de evento. Cada `task` pertence ao evento pai por meio de sua hierarquia de caminho (`/events/{event_id}/tasks/{task_id}`). | |||
### Relações nas Coleções de Junção | |||
* **user_event:** Conecta um `user` a um `event`. Serve como a "inscrição" e o placar geral, contendo o `user_id` e o `event_id`. | |||
* **user_task:** Conecta um `user` a uma `task`. Representa a "submissão", registrando a ação de um usuário em uma tarefa específica. Contém o `user_id` e o `task_id`, além de uma cópia do `event_id` para otimização de consultas. | |||
--- | |||
## Convenções de Nomenclatura | |||
Para manter a consistência e a clareza do banco de dados, todas as coleções e campos devem seguir as seguintes convenções de nomenclatura: | |||
* **Coleções:** Nomes de coleções devem ser escritos em `snake_case` (letras minúsculas separadas por underscore) e sempre no plural. **Exemplos**: `users`, `events`, `user_tasks`. | |||
* **Campos:** Nomes de campos devem ser escritos em `snake_case`. **Exemplos**: `total_score`, `start_date`, `access_code`. | |||
* **Campos de Identificação (IDs):** Campos que armazenam referências (chaves estrangeiras) devem seguir o padrão `nome_da_colecao_no_singular_id`. **Exemplos**: `user_id`, `event_id`, `task_id`. | |||
* **Campos Booleanos:** Preferencialmente, devem começar com um prefixo como `is_`, `has_` ou `can_` para que a leitura se assemelhe a uma pergunta. **Exemplos**: `is_active`, `is_admin`, `is_correct`. | |||
* **Campos de Data e Hora:** Devem terminar com o sufixo `_at`. **Exemplos**: `created_at`, `updated_at`, `start_at`. | |||
* **IDs de Documento Compostos:** Para coleções de junção, o ID do documento deve ser composto pelos IDs das entidades relacionadas, separados por um underscore (`_`). **Exemplos**: `user_event` (ID: `${user_id}_${event_id}`), `user_task` (ID: `${user_id}_${task_id}`). | |||
--- | |||
\ No newline at end of file |