Skip to content

hectornetf/ControlJira

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Control Tickets

Projeto full-stack (Angular + Node/Express/TypeScript) para autenticação via OTP por e-mail e gestão de tickets integrados ao Jira.

Sumário

  • Visão Geral e Arquitetura
  • Requisitos
  • Configuração (Backend e Frontend)
  • Variáveis de Ambiente
  • Como Rodar em Desenvolvimento
  • Build de Produção (Frontend) e Execução do Backend
  • Fluxo de Autenticação (OTP, JWT e Refresh Token)
  • Integração com Jira (Endpoints e Regras)
  • Regras de Negócio Implementadas
  • Upload de Anexos (Limites e Tipos)
  • Boas Práticas e Segurança
  • Solução de Problemas (FAQ)

Visão Geral e Arquitetura

  • Backend: Node.js + Express + TypeScript
    • Rotas de autenticação (OTP) e rotas de integração Jira sob /api (protegidas por JWT).
    • Logs de erro em backend/logs/error.log.
  • Frontend: Angular 19 standalone + Angular Material
    • Interceptor HTTP envia Authorization: Bearer <token>.
    • Proxy em dev para backend: proxy.conf.json.

Fluxo:

  1. Usuário solicita OTP; recebe por e-mail.
  2. Usuário valida OTP; backend emite Access Token (curto) + Refresh Token (cookie httpOnly).
  3. Frontend usa o Access Token para chamar /api/*. Se 401, faz refresh e repete.

Requisitos

  • Node.js 18+
  • NPM 9+
  • Angular CLI (opcional)
  • Conta Jira Cloud com token de API
  • Servidor SMTP (para envio de OTP)

Configuração

Backend

  1. Instale dependências:
cd backend
npm install
  1. Crie o arquivo backend/.env (ver Variáveis de Ambiente abaixo).
  2. Rode em dev:
npm run dev

Frontend

  1. Instale dependências:
cd frontend
npm install
  1. Rode com proxy:
npm start -- --proxy-config proxy.conf.json

Acesse: http://localhost:4200


Variáveis de Ambiente (backend/.env)

Obrigatórias e recomendadas:

# Servidor
PORT=3000

# Jira
JIRA_URL=https://SEU-DOMINIO.atlassian.net
JIRA_EMAIL=seu-email@dominio.com
JIRA_API_TOKEN=seu-token-api
JIRA_PROJECT_KEY=DDWB

# E-mail (OTP)
EMAIL_HOST=smtp.seuprovedor.com
EMAIL_PORT=587
EMAIL_SECURE=false
EMAIL_USER=usuario
EMAIL_PASS=senha
EMAIL_FROM="Nome <no-reply@dominio.com>"
ALLOWED_EMAIL_DOMAINS=teste.com.br

# JWT
JWT_SECRET=coloque-um-segredo-forte-aqui
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
# (Opcional) domínio do cookie de refresh
# COOKIE_DOMAIN=localhost

# Upload (opcional)
UPLOAD_MAX_BYTES=10485760
UPLOAD_ALLOWED_TYPES=image/png,image/jpeg,application/pdf,text/plain

Notas:

  • Gere JWT_SECRET com 32–64 bytes aleatórios (ex.: openssl rand -base64 64).
  • PowerShell
  • [Convert]::ToBase64String((New-Object Byte[] 64 | % { (New-Object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($) ; $ }))
  • Node
  • node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"
  • Em produção, use EMAIL_SECURE=true se porta 465/SSL.

Como Rodar em Desenvolvimento

Backend e frontend rodam em portas diferentes, com proxy no Angular redirecionando /api e /auth para o backend.

  • Backend: cd backend && npm run dev
  • Frontend: cd frontend && npm start -- --proxy-config proxy.conf.json

Build de Produção (Frontend) e Execução do Backend

Build do Frontend

cd frontend
npm run build

O output fica em frontend/dist/.

Executar Backend (produção)

  • Provisione as variáveis de ambiente
  • Inicie o servidor (ex.: PM2, Docker, ou Node) apontando para backend/src/index.ts via ts-node ou transpilado se preferir.

Obs.: O projeto não inclui hoje um servidor de arquivos estáticos para servir o Angular em produção; normalmente se usa um web server (Nginx/Apache) ou um host estático (S3/CloudFront) e o backend fica atrás de um reverse proxy no mesmo domínio.


Fluxo de Autenticação (OTP, JWT e Refresh Token)

  • POST /auth/request-otp recebe { email }, verifica domínio permitido e envia OTP por e-mail (validade 5 min).
  • POST /auth/verify-otp recebe { email, otp } e, se válido:
    • Emite access token (JWT) de curta duração (padrão 15m) retornado no corpo: token.
    • Emite refresh token (JWT) de longa duração (padrão 7d) em cookie httpOnly refresh_token.
  • Frontend salva o access token no localStorage.
  • Interceptor envia Authorization: Bearer <token> para /api/*.
  • Se algum /api/* retornar 401, o interceptor chama POST /auth/refresh para obter novo access token e repete a requisição.

Middleware no backend protege app.use('/api', authenticateToken, ticketsRouter) validando o Bearer token.


Integração com Jira (Endpoints e Campos)

Endpoints no backend (todos sob /api, protegidos por JWT):

  • POST /api/tickets cria issue no Jira.
  • GET /api/tickets busca issues do projeto (exclui status category "Done" e ordena por prioridade desc/created asc). Campos selecionados: summary, assignee, priority, status, timetracking, description, customfield_10020.
  • GET /api/tickets/search?jql=... executa JQL customizada.
  • PUT /api/tickets/:id atualiza issue.
  • DELETE /api/tickets/:id remove issue.
  • GET /api/users usuários atribuíveis no projeto.
  • POST /api/tickets/:id/attachments upload de anexo para a issue.
  • GET /api/tickets/customfield/:fieldId/options opções de um custom field (API v3 com contexts/options; cache em memória 5 min).
  • GET /api/sprints/:boardId obtém sprints (Agile API v1.0; cache em memória 5 min).

Cache em memória (5 min) para sprints e opções de customfield.


Regras de Negócio Implementadas

Frontend (resumo principal):

  • Lista de tickets
    • Filtra tickets com status category "Done" (feito na query do backend) e ordena por prioridade desc/creation asc.
    • Calcula horas totais gastas no sprint do mês corrente a partir de timetracking.timeSpentSeconds.
    • Barra de progresso contra limite de 30h (capped em 100%).
    • Polling após criação de ticket: a cada 2s até 20s para garantir que o novo ticket apareça.
  • Formulário de ticket
    • Prefixa novo summary com DDWB_Desenv_.
    • Busca Epic do mês atual (padrão de nome: DDWB - <Mês> <Ano>).
    • Busca Sprint do mês atual (padrão de nome: Sprint <Mês>) no board id 107 (fixo no código atual do frontend).
    • Cria issue com:
      • project.key = 'DDWB'
      • issuetype = 'desenvolvimento avulso' (deve existir no seu Jira)
      • customfield_10014 (Epic Link) = epicKey
      • customfield_10020 (Sprint) = sprintId
    • Limites por prioridade (Highest 2, High 5, Medium 10). Valida antes de criar, consultando contagem no backend.

Observações importantes:

  • Os nomes/tipos de issue e IDs de campos (customfield_10014, customfield_10020) dependem da configuração do seu Jira. Ajuste conforme necessário.
  • O board id 107 está fixo no frontend (arquivo ticket-form.component.ts). Caso mude, atualize o valor.

Pontos importantes no código

Backend:

  • backend/src/index.ts:
    • Middleware authenticateToken: valida JWT (header Authorization: Bearer) com JWT_SECRET. Registra erros em logs/error.log.
    • Rotas públicas em /auth; rotas protegidas em /api.
  • backend/src/routes/auth.ts:
    • POST /auth/request-otp: envia OTP (SMTP), restringe domínios via ALLOWED_EMAIL_DOMAINS.
    • POST /auth/verify-otp: emite Access (curto) + Refresh (cookie httpOnly), controla expiração com JWT_EXPIRES_IN/JWT_REFRESH_EXPIRES_IN.
    • POST /auth/refresh: renova access token a partir do refresh.
    • Rate limiting configurado para mitigar abuso.
  • backend/src/routes/tickets.ts:
    • Endpoints de CRUD e consulta ao Jira; upload com multer limitado por .env.
  • backend/src/services/jira.ts:
    • Cliente Axios para Jira; cache em memória para sprints e opções de custom field (5 min).
  • backend/src/services/auth.ts:
    • OTP em memória (apenas dev); configure Redis em produção.

Frontend:

  • frontend/src/app/services/auth.service.ts:
    • Guarda/recupera access token no sessionStorage; refresh via /auth/refresh.
  • frontend/src/app/services/auth.interceptor.ts:
    • Anexa Authorization: Bearer <token> nas chamadas /api; em 401, tenta refresh e repete.
  • frontend/src/app/components/ticket-form/ticket-form.component.ts:
    • Regras de criação (prefixo DDWB_Desenv_, Epic/Sprint do mês, tipos/fields Jira).
  • frontend/src/app/components/ticket-list/ticket-list.component.ts:
    • Cálculo de horas do sprint atual e progresso até limite (30h), ordenação e polling pós-criação.

Upload de Anexos

  • Endpoint: POST /api/tickets/:id/attachments
  • multer configurado com:
    • Limite de tamanho via UPLOAD_MAX_BYTES (padrão 10MB)
    • Tipos permitidos via UPLOAD_ALLOWED_TYPES (padrão image/png,image/jpeg,application/pdf,text/plain)
  • Envia header X-Atlassian-Token: no-check conforme exigência do Jira para anexos.

Boas Práticas e Segurança

  • Use JWT curto e refresh separado (já implementado). Não armazene refresh token no localStorage (usamos cookie httpOnly).
  • Rate limiting em /auth para reduzir abuso de OTP.
  • Não comite .env e segredos.
  • Ajuste CORS apenas se não usar proxy em dev; em produção, prefira mesmo domínio com reverse proxy.
  • Valide e monitore tamanhos/tipos de upload.

Solução de Problemas (FAQ)

  • "Server Misconfiguration: JWT_SECRET not set."
    • Defina JWT_SECRET no backend/.env e reinicie o backend.
  • 401 em /api/* após login
    • Verifique se o frontend está enviando Authorization: Bearer <token>.
    • Abra DevTools → Network e confira a requisição para /api/tickets.
    • Se 401, veja se /auth/refresh foi chamado. Confirme presença do cookie refresh_token na resposta de /auth/verify-otp.
  • Erro ao criar issue: issuetype/customfield não encontrado
    • Ajuste issuetype e IDs customfield_10014 (Epic Link) e customfield_10020 conforme sua instância Jira.
  • CORS em dev
    • Rode com proxy: ng serve --proxy-config proxy.conf.json.

Estrutura de Pastas (resumo)

backend/
  src/
    index.ts
    routes/
      auth.ts
      tickets.ts
    services/
      auth.ts
      jira.ts
    utils/
      logger.ts
  logs/error.log
frontend/
  src/app/
    components/
    services/
    guards/
  proxy.conf.json

Licença

Uso interno. Ajuste conforme a política da sua organização.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors