Context
SEDUC runs Processos Seletivos Simplificados (PSS) to hire temporary teachers and staff. The system automates candidate scoring and generates the official selection .docx documents, replacing a spreadsheet-and-Word workflow that was error-prone and difficult to audit.
Architecture
Monorepo with three packages: Next.js web app, NestJS API, shared validation schemas.
Next.js — evaluation entry, candidate review, document download
NestJS REST API with hardened input validation on all endpoints
Zod schemas shared between frontend forms and API DTOs
Engineering Decisions
API hardening: security headers, rate limiting, strict validation
The API uses helmet to set secure HTTP headers on every response and @nestjs/throttler to rate-limit public endpoints. All incoming payloads are validated and transformed via class-validator / class-transformer before they reach the service layer — unknown properties are stripped, type coercions are explicit. A government-facing selection API has no tolerance for injection vectors or abuse on unauthenticated routes.
Server-side .docx generation from templates
.docx output is produced server-side using docxtemplater with pizzip. Word templates store the official document structure; the server fills in candidate data and computed scores, then streams the file. This keeps the output consistent with SEDUC's HR format requirements and avoids the layout inconsistencies that arise from client-side PDF rendering across browsers.
Single Zod schema as validation contract
Validation schemas live in packages/shared as Zod definitions. The frontend uses them for form validation; the API uses them as the authoritative input contract. A single source of truth means the frontend cannot accept input the API would reject, and any schema change is immediately visible in both layers during development.