1 - Configuração de Ambiente

Como configurar o ambiente local e utilizar arquivos .env no projeto.

Configuração de Ambiente e Variáveis .env

Este guia explica como preparar o ambiente de desenvolvimento e configurar os arquivos .env no backend e no frontend.


1. Visão Geral do Projeto

  • Backend: Node.js, Express, Sequelize, testes com Jest e Supertest.
  • Frontend: Next.js, TailwindCSS e componentes da biblioteca Shadcn UI.
  • Banco de Dados: PostgreSQL (Sequelize).
  • Armazenamento de arquivos: buckets em S3 compatível.
  • Envio de e-mails: serviço configurado via variáveis .env.

2. Pré-requisitos

Antes de iniciar, certifique-se de que as seguintes ferramentas estão instaladas:

  • Node.js (versão LTS, 18 ou superior) Download Node.js Verifique a instalação:

    node -v
    
  • pnpm (gerenciador de pacotes) Instalação:

    npm install -g pnpm
    

    Verifique a instalação:

    pnpm -v
    
  • PostgreSQL (instalação local ou acesso a servidor remoto) Download PostgreSQL Verifique a instalação:

    psql --version
    
  • Hugo (Necessário para rodar a documentação) Download Hugo Verifique a instalação:

    hugo version
    
  • Outras ferramentas úteis:

    • Docker (opcional, para rodar banco ou serviços auxiliares em containers)
    • pgAdmin ou DBeaver (clientes gráficos para PostgreSQL)

3. Arquivos .env

Cada parte do sistema possui um arquivo de variáveis de ambiente de exemplo. Esses arquivos não devem ser versionados com dados reais, apenas mantidos como .env.example para referência.

Backend (.env.example)

PORT=

JWT_KEY=

DB_SGBD=
DB_USER=
DB_PASSWORD=
DB_HOST=
DB_PORT=
DB_NAME=

S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_ENDPOINT=

S3_DOCS_BUCKET=
S3_PS_BUCKET=
S3_IMAGE_BUCKET=
S3_CONTRACT_AMMENDMENTS_BUCKET=

MAIL_HOST=
MAIL_PORT=
MAIL_ADDRESS=
ADMIN_MANAGER_MAIL=

Frontend (.env.development.example)

NEXT_PUBLIC_API_BASE_URL="http://localhost:5000/api"

4. Setup do Ambiente

4.1 Backend

  1. Instale dependências:

    pnpm install
    
  2. Copie o arquivo .env.example para .env e preencha os valores locais:

    cp .env.example .env
    
  3. Inicie o servidor em modo desenvolvimento:

    pnpm start
    

4.2 Frontend

  1. Instale dependências:

    pnpm install
    
  2. Copie o arquivo .env.development.example para .env.development e preecha os valores locais:

    cp .env.development.example .env.development
    
  3. Inicie o servidor de desenvolvimento do Next.js:

    pnpm dev
    

O frontend será iniciado normalmente em http://localhost:3000 (ou na porta configurada).


4.3 Banco de Dados

O banco usado é PostgreSQL. Para acessar manualmente o ambiente de desenvolvimento:

psql -h <DB_HOST> -U <DB_USER> -d <DB_NAME>

Substitua <DB_HOST>, <DB_USER> e <DB_NAME> pelos valores definidos no .env.


4.4 Documentação

Para rodar a documentação localmente, basta acessar o diretorio específico e executar o comando:

hugo server

5. Boas Práticas

  • Sempre mantenha arquivos .env.example atualizados com todas as variáveis necessárias.
  • Nunca versione o arquivo .env com dados reais.
  • Utilize variáveis distintas para desenvolvimento, teste e produção.
  • Em produção, as variáveis devem ser configuradas diretamente no ambiente (por exemplo, via secrets do GitLab CI/CD). Apenas maintainers do projeto têm acesso a essas configurações.
  • Sempre que uma variável for criada ou alterada, comunique a equipe Root, que é responsável por atualizar os valores nas variáveis de ambiente do Kubernetes.

2 - Configuração de Servidor de E-mails

Como configurar o servidor de emails

Visão Geral

O envio de e-mails no Ademir é feito utilizando o msmtp, uma ferramenta leve que funciona como cliente SMTP e pode ser usada como substituto do sendmail. A configuração é feita por meio do arquivo .msmtprc, que define os parâmetros de autenticação e envio.


Exemplo de Arquivo de Configuração

A seguir, um exemplo funcional de configuração (/etc/msmtprc ou ~/.msmtprc):

# Configuração padrão do msmtp

# Conta padrão utilizada pelo sistema
account default

# Servidor SMTP (smarthost)
host smtp.c3sl.ufpr.br
port 25
from root@ademir.c3sl.ufpr.br
domain ademir.c3sl.ufpr.br
user ademir

# Log via syslog com a facility LOG_MAIL
syslog LOG_MAIL

Detalhes dos Parâmetros

  • account default → define a conta padrão para envio.
  • host → endereço do servidor SMTP.
  • port → porta utilizada (no exemplo, 25).
  • from → endereço de e-mail que será usado como remetente.
  • domain → domínio associado ao envio.
  • user → usuário da conta SMTP.
  • syslog LOG_MAIL → ativa logs no syslog com facility LOG_MAIL, permitindo auditoria.

Uso no Sistema

Com essa configuração, o msmtp pode ser utilizado como se fosse o sendmail, por exemplo:

echo "Teste de envio" | msmtp -a default destinatario@exemplo.com

No Ademir, essa configuração é usada pelo backend (via Nodemailer) para envio de e-mails transacionais e notificações.


Boas Práticas

  • Proteger o arquivo .msmtprc com permissões restritas:

    chmod 600 ~/.msmtprc
    
  • Em ambientes de produção, considerar uso de autenticação segura (porta 587 + STARTTLS).

  • Monitorar os logs via syslog para depuração de problemas de envio.

3 - Fluxo do Git

Guia de como usar Git no projeto: branches, commits, rebase e merge requests.

Guia de Fluxo de Trabalho

1. Selecionar uma Issue

Escolha uma issue entre as que estão atribuídas a você. Verifique as tarefas e determine qual delas será sua responsabilidade.


2. Criar uma Branch a partir da develop

Certifique-se de que a branch develop está atualizada antes de criar sua nova branch.

  1. Vá para a branch develop:
git checkout develop
  1. Atualize a branch develop com as últimas alterações do repositório remoto:
git pull origin develop
  1. Criar e mudar para uma nova branch seguindo o padrão da issue:
issue-<número_da_issue>/<palavras-chave>

📌 Por que usar esse padrão?

  • Cada issue no GitLab recebe automaticamente um número único.
  • Esse número deve estar presente no nome da branch para facilitar a rastreabilidade.
  • As palavras-chave, separadas exclusivamente por hífens, descrevem de forma objetiva o que está sendo feito.

Exemplo:

issue-256/fix-login-form

Criação da branch:

git checkout -B issue-<número_da_issue>/<palavras-chave>

3. Desenvolver a Feature na Branch

Faça as alterações necessárias para resolver a issue. Lembre-se de fazer commits pequenos e descritivos.

  1. Adicione as alterações ao índice:
git add .

💡 Dica: O comando git add -A é mais confiável que o git add ., pois o segundo refere-se somente à pasta atual e suas subpastas.

  1. Faça o commit das alterações:
git commit -m "breve descrição"

4. Rebase da develop para Sua Branch

Antes de finalizar o trabalho, faça um rebase para garantir que sua branch esteja atualizada com as últimas mudanças da develop e para transformar todos seus commits em um só.

  1. Vá para a branch develop:
git checkout develop
  1. Atualize a branch develop:
git pull origin develop
  1. Volte para sua branch de desenvolvimento:
git checkout nome-da-branch

💡 Dica: O comando git checkout - volta para a última branch acessada.

  1. Rebase da branch em relação à develop:
git rebase -i develop

Isso abrirá uma tela no editor com a lista de commits da sua branch, todos precedidos por "pick".

✏️ Como editar os commits?

  1. Mantenha pick apenas no primeiro commit.
  2. Altere todos os demais para f (de fixup), consolidando-os no primeiro.
  3. Verifique se a mensagem do primeiro commit está correta, seguindo o formato:
Issue #<número_da_issue>: <Palavra de Poder> <descrição do que foi feito, em inglês>
  • Se estiver correto: basta salvar e fechar o editor.
  • Se estiver errado: troque pick para r (reword), salve e feche o editor. Um novo editor irá abrir somente com o nome do commit a ser alterado.

🔹 Palavras de Poder

Use uma das palavras abaixo para indicar a natureza da mudança:

  • Add
  • Change
  • Deprecate
  • Remove
  • Fix
  • Security

Essas palavras seguem o padrão Keep a Changelog.


📌 Exemplo de commit correto

Issue #256: Fix login form was not working when Enter was pressed

Conflitos durante o rebase

Caso ocorram conflitos, resolva-os e depois:

git add -A
git rebase --continue

💡 Dica: O VSCode possui uma interface que ajuda muito nessa hora!


5. Push e Merge Request (MR)

Depois de finalizar o trabalho, envie sua branch para o repositório remoto e abra um Merge Request (MR) para revisão de código.

  1. Envie a branch para o repositório remoto:
git push origin nome-da-branch -f

💡 Dica: A flag -f (force) deve ser usada porque após o rebase o histórico foi reescrito.

  1. Verifique se sua branch está com 0 commits atrás da develop e 1 commit à frente da develop. Isso é indicado no GitLab pela notação 0|1 ao lado do nome da branch.

  2. Abra o Merge Request (MR) no GitLab para revisão de código. Inclua uma descrição clara (o quê e por quê) e cite impactos (ex.: variáveis .env, migrações).


Conclusão

Esse fluxo de trabalho:

  • Mantém o histórico do Git limpo (1 commit por issue).
  • Organiza as alterações de forma eficiente.
  • Facilita a colaboração em equipe, revisões e criação de releases.

Este fluxo é obrigatório dentro do C3SL e não deve ser alterado sem um motivo justificado de organização de código e fluxo de trabalho.


Guia rápido para criar uma Tag de Release

Para gerar uma nova Release e disparar o CI, basta criar e enviar a tag:

git tag vX.X.X
git push origin vX.X.X

Substitua vX.X.X pela versão desejada (ex.: v1.0.0). Isso acionará os jobs de release e criação de imagens no pipeline.

4 - Gerando o seed.sql para inicialização do banco no Docker

Passo a passo para criar e manter atualizado o arquivo seed.sql, usado para inicializar o banco de dados com esquema, usuário e permissões.

Objetivo: gerar um arquivo seed.sql que inicializa o banco com esquema, usuário de aplicação e permissões de aplicação. Observação: os itens “usuário” e “permissões” abaixo referem-se às tabelas da aplicação (ex.: user_system, permissions), não a roles do PostgreSQL.


Pré-requisitos

  • Docker e Docker Compose instalados.
  • Acesso ao banco remoto postgres.c3sl.ufpr.br com o usuário ademir.
  • Arquitetura do projeto contendo a pasta database/.

0) Backup do seed atual (opcional, recomendado)

Renomeie o seed atual para manter como backup.

mv database/seed.sql database/seed_$(date +%Y%m%d_%H%M%S).sql

1) Exportar apenas o esquema do banco remoto

Na raiz do projeto, execute:

pg_dump -h postgres.c3sl.ufpr.br -U ademir -d ademir --schema-only > database/seed.sql

Quando solicitado, insira a senha do banco.

Dica: para evitar prompt interativo, você pode usar PGPASSWORD=suasenha pg_dump ....


2) Subir o Postgres local via Docker Compose

docker compose up postgres -d

3) Acessar o banco dentro do container

docker exec -it ademir-db psql -U ademir -d ademir

4) Criar permissões na tabela permissions

INSERT INTO permissions (name, "createdAt", "updatedAt")
SELECT 'admin', NOW(), NOW()
WHERE NOT EXISTS (
    SELECT 1 FROM permissions WHERE name = 'admin'
);

INSERT INTO permissions (name, "createdAt", "updatedAt")
SELECT 'common', NOW(), NOW()
WHERE NOT EXISTS (
    SELECT 1 FROM permissions WHERE name = 'common'
);

INSERT INTO permissions (name, "createdAt", "updatedAt")
SELECT 'manager', NOW(), NOW()
WHERE NOT EXISTS (
    SELECT 1 FROM permissions WHERE name = 'manager'
);

5) Criar usuário inicial admin

INSERT INTO user_system (
    name, 
    email, 
    password, 
    is_active, 
    "isEmailVerified", 
    register_date, 
    verification_date, 
    last_login
) VALUES (
    'admin',
    'admin@mail.com',
    'mudar123*',  -- ⚠️ idealmente armazenar com hash
    TRUE,
    TRUE,
    NOW(),
    NOW(),
    NOW()
);

6) Gerar o novo seed.sql com dados

Ainda na raiz do projeto, execute:

docker exec -it ademir-db pg_dump -U ademir -d ademir > database/seed.sql

5 - Integração Contínua (CI/CD)

Como funcionam os pipelines no GitLab para lint, testes, build, release, imagens e documentação.

Integração Contínua (CI/CD)

Este guia explica o pipeline do GitLab: lint → test → build → release → image_create → create-pages. Também lista as variáveis necessárias e como acionar cada etapa.


1) Estrutura geral do pipeline

cache:
  paths:
    - node_modules

stages:
  - lint
  - test
  - build
  - release
  - image_create
  - create-pages

lint-job:
  image: $CI_REGISTRY/ademir/node-custom:latest
  stage: lint
  script:
    - ln -s /ci-modules/backend_node_modules backend/node_modules
    - cd backend
    - pnpm lint
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

test-job:
  image: $CI_REGISTRY/ademir/node-custom:latest
  stage: test
  script:
    - ln -s /ci-modules/backend_node_modules backend/node_modules
    - cd backend
    - pnpm exec tsc && pnpm exec jest --ci --forceExit --detectOpenHandles --runInBand --silent --verbose=false
  variables:
    NODE_ENV: testing
    DB_SGBD: ${DB_SGBD}
    DB_USER: ${DB_USER}
    DB_PASSWORD:  ${DB_PASSWORD}
    DB_HOST: ${DB_HOST}
    DB_PORT: ${DB_PORT}
    DB_NAME: ${DB_NAME}
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

build-job:
  image: $CI_REGISTRY/ademir/node-custom:latest
  stage: build
  script:
    - ln -s /ci-modules/frontend_node_modules frontend/node_modules
    - cd frontend
    - pnpm run build
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

create_release:
  stage: release
  image: $CI_REGISTRY/ademir/release-cli
  script:
    - |
      LAST_TAG=$(git tag --sort=-creatordate | sed -n 2p)
      if [ -z "$LAST_TAG" ]; then
        git log --pretty=format:"%s (%an)" | grep -v "^Merge branch" | sed 's/^/- /' > release_notes.md
      else
        git log "${LAST_TAG}"..HEAD --pretty=format:"%s (%an)" | grep -v "^Merge branch" | sed 's/^/- /' > release_notes.md
      fi
      echo "Versão: $CI_COMMIT_TAG" > full_release.md
      echo "" >> full_release.md
      echo "Mudanças:" >> full_release.md
      cat release_notes.md >> full_release.md
  release:
    tag_name: $CI_COMMIT_TAG
    name: "Release $CI_COMMIT_TAG"
    description: full_release.md
  rules:
    - if: '$CI_COMMIT_TAG'

image_create:
  stage: image_create
  image:
    name: $CI_REGISTRY/ademir/buildah
  script:
    - buildah login -u "$HARBOR_LOGIN" -p "$HARBOR_PASSWORD" "$CI_REGISTRY"
    - buildah build --layers --build-arg NEXT_PUBLIC_API_BASE_URL="$NEXT_PUBLIC_API_BASE_URL" --file frontend/Containerfile --tag $CI_REGISTRY/ademir/frontend:$CI_COMMIT_TAG --cache-from=$CI_REGISTRY/ademir/frontend --cache-to=$CI_REGISTRY/ademir/frontend frontend
    - buildah push harbor.c3sl.ufpr.br/ademir/frontend:$CI_COMMIT_TAG
    - buildah build --layers --file backend/Containerfile --tag harbor.c3sl.ufpr.br/ademir/backend:$CI_COMMIT_TAG --cache-from=$CI_REGISTRY/ademir/backend --cache-to=$CI_REGISTRY/ademir/backend backend
    - buildah push harbor.c3sl.ufpr.br/ademir/backend:$CI_COMMIT_TAG
  rules:
    - if: '$CI_COMMIT_TAG'

# deploy (k8s) — desativado
#deploy:
#  stage: deploy
#  image: bitnami/kubectl:latest
#  script:
#    - kubectl --kubeconfig $KUBECONFIG rollout restart deploy ademir -n ademir
#  rules:
#    - if: '$CI_COMMIT_TAG'

create-pages:
  image: hugomods/hugo:ci
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  before_script:
    - cd docs
    - npm i -D postcss postcss-cli autoprefixer
  script:
    - hugo --minify -D -d public
    - mv public ..
  pages: true
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      changes:
        - docs/**/*  
  environment: production

Observação: os blocos estão sem linguagem para manter compatibilidade com a diretriz de apenas blocos de código Markdown.


2) Quando cada estágio roda

  • lint, test, build → executam em Merge Requests (rules: if: $CI_PIPELINE_SOURCE == "merge_request_event").
  • release e image_create → executam somente em tag (rules: if: $CI_COMMIT_TAG).
  • create-pages (Hugo) → executa na branch padrão (ex.: develop) quando houver mudanças em docs/.

Disparo prático

  • Abrir MR → roda lint, test, build.
  • Criar tag (ex.: v1.2.3) → roda create_release e image_create (gera release e imagens e faz push no registry).
  • Commits em docs/ na branch padrão → roda create-pages e publica a documentação.

3) Variáveis de ambiente (CI/CD) necessárias

Crie/atualize em Settings → CI/CD → Variables no GitLab:

Backend / Testes

  • DB_SGBD
  • DB_USER
  • DB_PASSWORD
  • DB_HOST
  • DB_PORT
  • DB_NAME

Release / Imagens

  • HARBOR_LOGIN — login no registry
  • HARBOR_PASSWORD — senha/token do registry
  • NEXT_PUBLIC_API_BASE_URL — base URL injetada no build do frontend
  • (opcional) CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD se o runner exigir login explícito

Outras

  • CI_DEFAULT_BRANCH (já fornecida pelo GitLab)
  • KUBECONFIG (se reativar o job de deploy)

Boas práticas: marque variáveis sensíveis como masked e protected; ligue Protect para usar apenas em branches/tags protegidas.


4) Detalhes de cada job

lint-job

  • Usa imagem Node custom.
  • Cria symlink para backend/node_modules apontando para /ci-modules/backend_node_modules (cache aquecido da imagem).
  • Roda pnpm lint no diretório backend.

test-job

  • Mesmo setup de node_modules do lint-job.
  • Compila TypeScript (pnpm exec tsc) e executa testes com Jest/Supertest.
  • Injeta variáveis de banco para testes.

build-job

  • Prepara frontend/node_modules via symlink.
  • Executa pnpm run build em frontend (Next.js + Tailwind + shadcn).

create_release

  • Gera release notes a partir do git log (desde a última tag) e cria um Release associado à tag atual ($CI_COMMIT_TAG).

image_create

  • Autentica no registry (buildah login).
  • Frontend: build da imagem passando NEXT_PUBLIC_API_BASE_URL por --build-arg; faz push para harbor.c3sl.ufpr.br/ademir/frontend:$CI_COMMIT_TAG.
  • Backend: build e push da imagem harbor.c3sl.ufpr.br/ademir/backend:$CI_COMMIT_TAG.
  • Usa camadas em cache (--layers, --cache-from/--cache-to).

create-pages

  • Usa imagem do Hugo.
  • Instala postcss, postcss-cli e autoprefixer para o tema.
  • Gera site (hugo --minify -D) e publica artefatos para Pages.

5) Fluxos típicos

A) Verificação de MR

  1. Abrir MR → pipeline executa lint, test, build.
  2. Corrigir problemas (se houver) → push para a mesma branch reexecuta as etapas.

B) Criar release e imagens

  1. Marcar uma tag (ex.: v1.2.3).
  2. Pipeline executa create_release e image_create.
  3. Conferir release no GitLab e imagens no registry Harbor.

C) Publicar documentação

  1. Subir commits na branch padrão alterando docs/.
  2. Pipeline executa create-pages e publica o site (GitLab Pages).

6) Troubleshooting

  • lint/test falhando: rode localmente pnpm lint e pnpm exec jest no diretório correspondente e verifique versões do Node.
  • Falha no build do frontend: cheque dependências (pnpm install) e teste pnpm build localmente.
  • Erro no image_create: valide HARBOR_LOGIN/HARBOR_PASSWORD e permissão de push no registry. Confirme o nome das imagens e tags.
  • create-pages não dispara: confirme a branch padrão e se houve mudanças dentro de docs/.
  • Variáveis ausentes: adicione em CI/CD Variables (acessível apenas pra mantainers) e proteja-as quando necessário.

7) Boas práticas

  • Mantenha o pipeline rápido (cache eficiente, jobs paralelos quando possível).
  • Use tags semânticas (ex.: vX.Y.Z) para releases.
  • Centralize secrets apenas no CI/CD; não versionar .env reais.