Skip to content

diogon01/biblioteca-angular-nestjs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sistema de Biblioteca — Desafio Técnico

Índice

  1. Visão Geral
  2. Tecnologias Utilizadas
  3. Arquitetura Geral
  4. Modelagem de Domínio
  5. Regras de Negócio Implementadas
  6. Dashboard Administrativo
  7. Seeds e Cenários de Teste
  8. API e Swagger
  9. Testes
  10. Como Rodar o Projeto
  11. Considerações Finais

📚 Documentação Complementar


1. Visão Geral

Este projeto implementa um sistema completo de gestão de biblioteca desenvolvido como resposta a um desafio técnico. O objetivo é demonstrar a capacidade de construir uma solução de software estruturada, testável e escalável, aplicando boas práticas de engenharia de software em stack moderna.

O sistema permite:

  • Gerenciamento de clientes da biblioteca (membros) com validação rigorosa de CPF
  • Catálogo de livros com controle granular de disponibilidade por exemplar físico
  • Fluxo completo de reservas e empréstimos
  • Identificação automática de atrasos e cálculo de multas progressivas
  • Dashboard administrativo com métricas em tempo real
  • Autenticação baseada em JWT com controle de acesso por perfil (roles)

A solução atende integralmente ao escopo solicitado, com melhorias estruturais para garantir consistência de dados, separação de responsabilidades e facilidade de manutenção.


2. Tecnologias Utilizadas

Backend

  • NestJS — Framework escolhido pela arquitetura modular baseada em injeção de dependências, facilitando testes e manutenção. Segue padrões estabelecidos (decorators, guards, interceptors) que tornam o código previsível e escalável.
  • Prisma ORM — Provê tipagem end-to-end do banco de dados para o TypeScript, migrations versionadas, e relacionamentos declarativos. Elimina classes de bugs relacionados a inconsistência de schema.
  • MariaDB / MySQL — Banco relacional robusto, com suporte a transações ACID, essencial para garantir integridade em operações críticas (reservas, empréstimos, pagamentos).
  • JWT (Passport) — Autenticação stateless via JSON Web Tokens, com estratégia de roles (ADMIN / USER) para controle fino de permissões.
  • Swagger / OpenAPI — Documentação automática da API gerada a partir dos decorators NestJS, facilitando integração e testes.

Frontend

  • Angular (Standalone) — Framework declarativo e fortemente tipado, ideal para aplicações corporativas. Uso de componentes standalone elimina módulos desnecessários e simplifica a estrutura.
  • Angular Material — Biblioteca de componentes UI que garante consistência visual, acessibilidade e responsividade sem necessidade de CSS customizado excessivo.

Infraestrutura e Qualidade

  • Docker Compose — Ambiente de desenvolvimento reprodutível (MySQL + Adminer).
  • Jest — Framework de testes com threshold mínimo de 80% de cobertura no backend.
  • ESLint + Prettier — Garantia de padrão de código consistente.

3. Arquitetura Geral

A solução segue uma arquitetura em camadas, com separação clara entre apresentação, lógica de negócio e persistência:

┌─────────────────────────────────────────────────┐
│          Frontend (Angular + Material)         │
│             apps/web (porta 4200)              │
│  - Standalone components                        │
│  - Guards client-side para proteção de rotas   │
│  - Interceptor HTTP para injeção de JWT        │
└─────────────────┬───────────────────────────────┘
                  │
                  │ HTTP REST + JWT
                  │
┌─────────────────▼───────────────────────────────┐
│         Backend (NestJS + Guards)              │
│             apps/api (porta 3000)              │
│  - Controllers (validação de entrada)          │
│  - Services (regras de negócio)                │
│  - Repositories (Prisma abstraído)             │
│  - Guards (JwtAuthGuard, RolesGuard)           │
│  - Swagger em /docs                            │
└─────────────────┬───────────────────────────────┘
                  │
                  │ Prisma ORM
                  │
┌─────────────────▼───────────────────────────────┐
│       Banco de Dados (MariaDB/MySQL)           │
│        - 15+ tabelas relacionais               │
│        - Constraints de integridade            │
│        - Índices estratégicos                  │
└─────────────────────────────────────────────────┘

Diagramas Técnicos

Para facilitar a compreensão da arquitetura e fluxos de dados, consulte:

📊 Diagramas Completos — Inclui:

  • Diagrama de Arquitetura (Frontend → API → DB)
  • Diagrama Entidade-Relacionamento (ER) completo
  • Diagramas de Estados (Reservation, Loan, Fine)
  • Sequências de Fluxo de Negócio

Separação de Responsabilidades

  • Frontend: apresentação, validação básica de UX, gerenciamento de estado local (não usa Redux/NgRx para evitar complexidade desnecessária).
  • Backend: toda a lógica de negócio, validações críticas (CPF, disponibilidade, cálculo de multas), geração de tokens JWT.
  • Banco de Dados: integridade referencial, constraints de unicidade (CPF, email, ISBN), índices para performance em queries comuns.

Comunicação

  • Requisições HTTP via HttpClient do Angular.
  • Autenticação via header Authorization: Bearer <token>.
  • Respostas padronizadas com { items, meta } para paginação.

4. Modelagem de Domínio (PONTO FORTE)

A modelagem do banco de dados reflete uma separação explícita entre conceitos de autenticação e domínio de negócio, evitando acoplamento entre "quem acessa o sistema" e "quem é cliente da biblioteca".

Decisão Arquitetural: User vs Member

User (1) ──── (0..1) Member
  • User: representa uma identidade de acesso ao sistema (email, senha, role). Armazena credenciais e permissões (ADMIN, USER).
  • Member: representa um cliente da biblioteca (nome, CPF, telefone, multas, empréstimos). É a entidade de domínio central.

Justificativa:

Separar autenticação de domínio permite que:

  1. Um cliente da biblioteca exista sem usuário de acesso (cadastrado presencialmente).
  2. Um usuário ADMIN gerencie o sistema sem ser cliente.
  3. Regras de negócio (multas, bloqueios) fiquem desacopladas de autenticação.

Essa separação é uma prática comum em sistemas corporativos que distinguem "identidade" de "entidade de negócio".

Entidades Principais

Entidade Responsabilidade Ponto-Chave
User Autenticação e autorização Email único, hash bcrypt, role
Member Cliente da biblioteca CPF validado e único, status (ACTIVE/BLOCKED), configurações de multa personalizáveis
Book Livro do catálogo Metadados (título, ISBN, autores), status agregado (AVAILABLE/RESERVED)
BookCopy Exemplar físico Barcode único, localização, status individual (AVAILABLE/ON_LOAN/RESERVED/LOST/DAMAGED)
Reservation Reserva de livro Status versionado (ACTIVE → READY_FOR_PICKUP → FULFILLED), expiração automática
Loan Empréstimo ativo Data de vencimento, status (ACTIVE/OVERDUE/CLOSED), itens associados
LoanItem Item específico emprestado Associa um BookCopy a um Loan, permite renovação (renewCount), rastreamento de devolução
Fine Multa aplicada Tipo (OVERDUE/LOST/DAMAGED), valor em centavos, status de pagamento (OPEN/PARTIALLY_PAID/PAID)
Payment Pagamento realizado Associado a uma ou mais multas via PaymentFine, método (CASH/PIX/CARD)

Relacionamentos Críticos

Member ────┬──── Reservation (n)
           ├──── Loan (n)
           ├──── Fine (n)
           └──── Payment (n)

Book ──────┬──── BookCopy (1:n)
           └──── Reservation (n)

BookCopy ──┬──── LoanItem (n)
           └──── Reservation (opcional, quando reserva específica)

Loan ──────┬──── LoanItem (n)
           └──── Fine (n)

Modelagem de exemplares separados (Book vs BookCopy):

Permite que a biblioteca tenha múltiplas cópias físicas do mesmo livro, cada uma com estado independente. Um livro pode estar "disponível" no catálogo enquanto todos os exemplares estão emprestados — o sistema sabe disso porque agrega o status dos BookCopy.


5. Regras de Negócio Implementadas

Todas as regras de negócio vivem exclusivamente no backend. O frontend apenas consome e exibe informações.

Validação de CPF

  • CPF validado com algoritmo de dígitos verificadores.
  • Constraint de unicidade no banco (cpf UNIQUE).
  • Mensagens de erro claras ao tentar cadastrar CPF duplicado ou inválido.

Controle de Disponibilidade de Livros

  • Status do Book: agregação derivada dos BookCopy.
  • Status do BookCopy: atualizado em tempo real ao criar/cancelar reserva ou empréstimo.
  • Lógica:
    • AVAILABLE: nenhum empréstimo/reserva ativo.
    • RESERVED: reserva ativa aguardando retirada.
    • ON_LOAN: emprestado para membro.
    • LOST/DAMAGED/MAINTENANCE: fora de circulação.

Reservas e Vencimento

  • Reserva criada com dueDate (prazo para retirada).
  • Sistema identifica reservas expiradas (expiresAt < now).
  • Status de reserva:
    • ACTIVE: aguardando disponibilidade.
    • READY_FOR_PICKUP: cópia disponível para retirada.
    • FULFILLED: convertida em empréstimo.
    • EXPIRED: prazo de retirada vencido.
    • CANCELLED: cancelada pelo usuário ou administrador.

Empréstimos e Atrasos

  • Empréstimo criado com dueAt (data de devolução).
  • Query GET /reservations?overdue=true retorna empréstimos com dueAt < now.
  • Status OVERDUE aplicado automaticamente.

Cálculo de Multas Progressivas

Fórmula implementada:

multa_centavos = FINE_FIXED_CENTS × (1 + dias_atraso × (FINE_DAILY_PERCENT / 100))

Exemplo:

  • FINE_FIXED_CENTS = 500 (R$ 5,00)
  • FINE_DAILY_PERCENT = 10 (10% ao dia)
  • Atraso de 3 dias: 500 × (1 + 3 × 0.1) = 500 × 1.3 = 650 centavos (R$ 6,50)

Características:

  • Multa fixa + percentual progressivo (não linear).
  • Armazenada em centavos para evitar problemas de arredondamento.
  • Status de multa rastreado: OPENPARTIALLY_PAIDPAID.

Controle de Acesso por Roles

  • ADMIN: acesso total (CRUD de livros, clientes, reservas; dashboard; importação de catálogo).
  • USER: acesso restrito (visualizar catálogo, criar próprias reservas, área /me).
  • Guards aplicados via decorators: @UseGuards(JwtAuthGuard, RolesGuard) + @Roles('ADMIN').

6. Dashboard Administrativo

O sistema inclui um dashboard com métricas de negócio, acessível apenas para usuários com role ADMIN.

Endpoint: GET /admin/stats

Retorna:

{
  "overview": {
    "totalBooks": 150,
    "totalMembers": 87,
    "activeMembers": 82,
    "blockedMembers": 5
  },
  "circulation": {
    "activeReservations": 12,
    "activeLoans": 34,
    "overdueLoans": 5,
    "totalFines": 15,
    "openFines": 8
  },
  "nextActions": [
    {
      "type": "overdue_loan",
      "memberId": "...",
      "memberName": "João Silva",
      "dueDate": "2026-01-20T12:00:00Z",
      "daysOverdue": 5
    }
  ]
}

Funcionalidades

  • Contadores em tempo real: livros, clientes ativos, reservas ativas, multas pendentes.
  • Próximas ações: lista de empréstimos atrasados, reservas próximas do vencimento.
  • Métricas de gestão: total de multas aplicadas, taxa de bloqueio de clientes.

Justificativa:

Mesmo não sendo exigido explicitamente pelo desafio, o dashboard facilita a validação visual das regras de negócio e demonstra preocupação com a usabilidade do sistema para o operador final.

Screenshot do Dashboard

Dashboard Administrativo

Dashboard com métricas em tempo real: estatísticas gerais, empréstimos ativos/atrasados, reservas e ações pendentes.


7. Seeds e Cenários de Teste

Para facilitar a avaliação do sistema, foram implementados seeds avançados que simulam cenários reais de operação de uma biblioteca.

Estrutura de Seeds

  • catalog.seed.ts: popula catálogo de livros, autores, categorias, exemplares físicos.
  • circulation.seed.ts: cria membros, reservas em diferentes estados, empréstimos ativos/atrasados/concluídos, multas pagas e pendentes.

Cenários Simulados

  • Dezenas de usuários com status variados (ACTIVE, SUSPENDED, BLOCKED).
  • Reservas em diferentes estados: ACTIVE, READY_FOR_PICKUP, FULFILLED, EXPIRED.
  • Empréstimos completos: ciclo desde reserva → empréstimo → devolução.
  • Multas diversificadas: multas pagas integralmente, parcialmente pagas, e pendentes.
  • Livros com múltiplos exemplares: demonstra controle de disponibilidade por cópia.

Execução

cd apps/api
npm run prisma:seed

Valor para avaliação:

Os seeds permitem testar o sistema imediatamente após o setup, sem necessidade de criar dados manualmente. Facilitam testes exploratórios e validação visual de regras de negócio.


7.1. Galeria de Screenshots

O sistema conta com interface completa para gestão de biblioteca. Veja as principais telas:

Catálogo Público

Catálogo de Livros Catálogo público com busca, filtros e visualização de disponibilidade.

Cadastro de Clientes

Cadastro de Cliente Formulário de cadastro com validação de CPF em tempo real.

Área do Usuário — Minhas Reservas

Minhas Reservas Área do usuário autenticado visualizando suas reservas ativas.

Gestão Administrativa — Reservas

Reservas Admin Painel administrativo para gerenciamento de todas as reservas do sistema.


8. API e Swagger

A API REST está totalmente documentada via Swagger/OpenAPI, acessível em desenvolvimento em:

http://localhost:3000/docs

Rotas Principais

Autenticação (/auth)

  • POST /auth/login — Login (retorna JWT)
    • Body: { email, password }
    • Response: { access_token: "jwt-token" }
  • GET /auth/me — Dados do usuário logado
    • Headers: Authorization: Bearer <token>
    • Response: { id, email, role }

Clientes (/clients)

  • POST /clients — Cadastro de cliente (validação de CPF)
    • Body: { name, cpf, email? }
  • GET /clients — Listagem com paginação e busca
    • Query: ?q=Maria&sort=name&order=asc
  • GET /clients/:id — Detalhes do cliente
  • PATCH /clients/:id — Atualização de dados
  • DELETE /clients/:id — Remoção

Livros (/books)

  • POST /books — Cadastro de livro (ADMIN)
    • Body: { title, authors[], isbn?, coverUrl?, type?, status? }
  • GET /books — Listagem paginada com filtros
    • Query: ?q=Clean Code&author=Robert&status=AVAILABLE
  • GET /books/:id — Detalhes do livro
  • PATCH /books/:id — Atualização
  • DELETE /books/:id — Remoção

Catálogo Público (/public)

  • GET /public/books — Catálogo sem autenticação
    • Suporta mesmos filtros de /books
  • GET /public/books/facets — Facetas para filtros (autores, anos, tipos)
  • POST /public/books/:id/reserve — Reservar do catálogo (requer JWT)
  • GET /public/config — Configurações públicas do sistema
  • GET /public/members/check-cpf — Verificar disponibilidade de CPF
    • Query: ?cpf=529.982.247-25
  • POST /public/members/register — Cadastro público de novo membro
    • Body: { name, email, cpf, password }

Reservas (/reservations)

  • POST /reservations — Criar reserva
    • Body: { memberId, bookId, dueDate }
  • GET /reservations — Listar reservas (com filtros)
    • Query: ?status=ACTIVE&overdue=true&memberId=xxx
  • GET /reservations/overdue — Apenas atrasadas
  • PATCH /reservations/:id/return — Devolver livro

Área do Usuário (/me)

  • GET /me/reservations — Minhas reservas
    • Query: ?status=ACTIVE&sort=reservedAt
  • GET /me/loans — Meus empréstimos
    • Query: ?overdue=true&status=ACTIVE
  • POST /me/reservations/:id/checkout — Finalizar reserva (criar empréstimo)
  • POST /me/reservations/:id/cancel — Cancelar reserva

Administração (/admin)

  • GET /admin/stats — Dashboard de métricas (ADMIN)
    • Response: { overview, circulation, nextActions }
  • POST /admin/books/import — Importar de OpenLibrary/Google Books (ADMIN)
    • Body: { query?, isbn?, limit? }

Total: 30+ endpoints REST documentados

Formato de Resposta Paginada

{
  "items": [...],
  "meta": {
    "page": 1,
    "pageSize": 10,
    "total": 87,
    "pageCount": 9
  }
}

9. Testes

A estratégia de testes prioriza cobertura de regras de negócio críticas e fluxos de integração.

Backend

Testes Unitários

  • Services: validação de CPF, cálculo de multas, lógica de disponibilidade.
  • Isolamento: mocks de Prisma para garantir testes rápidos e determinísticos.

Testes de Integração

  • Fluxos completos: criar cliente → reservar livro → emprestar → devolver → calcular multa.
  • Banco de dados de teste: SQLite em memória ou container Docker efêmero.

Cobertura Mínima

Configuração no package.json:

"coverageThreshold": {
  "global": {
    "branches": 80,
    "functions": 80,
    "lines": 80,
    "statements": 80
  }
}

Execução:

npm run test:cov

Frontend

  • Testes unitários de componentes: validação de formulários, exibição correta de dados.
  • Testes de guards e interceptors: garantir proteção de rotas e injeção de JWT.

10. Como Rodar o Projeto

Pré-requisitos

  • Node.js 18+ e npm
  • Docker e Docker Compose
  • PowerShell 5.1 (Windows) ou bash (Linux/Mac)

Passo 1: Clonar o Repositório

git clone <url-do-repositorio>
cd Biblioteca_api

Passo 2: Subir Infraestrutura (MySQL + Adminer)

docker compose up -d
  • MySQL: localhost:3306, usuário app, senha app, database biblioteca
  • Adminer: http://localhost:8081 (gerenciamento visual do banco)

Passo 3: Configurar Backend

cd apps/api
npm install

Criar .env (se não existir):

DATABASE_URL="mysql://app:app@localhost:3306/biblioteca"
SHADOW_DATABASE_URL="mysql://root:root@localhost:3306/prisma_shadow"
JWT_SECRET="seu-secret-aqui"
FINE_FIXED_CENTS=500
FINE_DAILY_PERCENT=10

Aplicar migrations e popular banco:

npx prisma migrate dev
npx prisma generate
npm run prisma:seed

Subir servidor:

npm run start:dev

API estará em: http://localhost:3000
Swagger: http://localhost:3000/docs

Passo 4: Configurar Frontend

cd apps/web
npm install
npm run dev:web

Frontend estará em: http://localhost:4200

Passo 5: Login Padrão

Após rodar os seeds, use o usuário administrador:

  • Email: admin@biblioteca.local
  • Senha: admin

11. Considerações Finais

Atendimento ao Desafio

Esta solução atende integralmente todos os requisitos especificados no desafio técnico:

✅ CRUD de clientes com validação rigorosa de CPF único
✅ CRUD de livros com controle correto de disponibilidade
✅ Sistema de reservas de livros por clientes
✅ Identificação de reservas em atraso
✅ Cálculo de multa fixa + percentual progressivo por dia de atraso
✅ Autenticação JWT com roles (ADMIN/USER)
✅ Testes unitários e de integração com cobertura mínima de 80% no backend

Decisões Técnicas Defendidas

  1. Separação User/Member: evita acoplamento entre autenticação e domínio, permitindo evolução independente (ex: autenticação OAuth2, clientes sem usuário).
  2. Book vs BookCopy: reflete corretamente a realidade de uma biblioteca (múltiplos exemplares, estados individuais).
  3. Regras no backend: o frontend é "burro" — toda validação crítica ocorre no servidor, garantindo segurança e consistência.
  4. Prisma ORM: tipagem end-to-end elimina bugs de schema mismatch, migrations versionadas facilitam evolução do banco.
  5. Dashboard administrativo: não era obrigatório, mas demonstra preocupação com usabilidade e validação de negócio.
  6. Seeds avançados: facilita avaliação imediata do sistema, simula cenários reais.

Escalabilidade e Manutenibilidade

  • Arquitetura modular (NestJS): novos módulos (ex: notificações, relatórios) podem ser adicionados sem afetar código existente.
  • Testes com alta cobertura: reduz risco de regressão ao evoluir features.
  • Migrations versionadas: deploy em produção sem downtime, rollback seguro.
  • Separação de responsabilidades: frontend e backend podem evoluir independentemente (ex: trocar Angular por React sem impacto no backend).

Próximos Passos (Fora do Escopo)

Se este fosse um projeto real em produção, as próximas evoluções incluiriam:

  • Notificações por email/SMS para atrasos e multas
  • Integração com gateway de pagamento (Stripe, PagSeguro)
  • Logs estruturados (Winston, Pino) para auditoria
  • Deploy containerizado (Kubernetes, AWS ECS)
  • Rate limiting e throttling para proteção contra abuso
  • Internacionalização (i18n) para suporte a múltiplos idiomas

Desenvolvido com foco em clareza, consistência e facilidade de manutenção. Pronto para avaliação técnica.

About

Sistema de biblioteca fullstack desenvolvido como desafio técnico, utilizando Angular, NestJS, Prisma e MySQL, com autenticação JWT, regras de negócio completas e dashboard administrativo.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors