- In production
- Professional
- 2026
SIGESAC
Request tracking and audit trail for an education provider
Screenshots


Web client
- React 18 SPAVite + Tailwind
- React RouterRole-protected routes
- AxiosAttaches the JWT
- → HTTPS · JSON · JWT
REST API · Spring Boot 3
- 12 controllers@PreAuthorize authorization
- ServicesRules and state machine
- VencimientoSchedulerFlags overdue by SLA
- → JPA / Hibernate
Persistence
- Spring Data JPA14 entities
- PostgreSQL 16Relational store
- FlywayVersioned migrations
Cross-cutting concerns
Security
- JwtAuthenticationFilter
- RBAC, 4 roles
Auditing
- AOP @Auditable
- Historial de negocio
Integrations
- SMTP, correo HTML
- Adjuntos validados
Delivery
- GitHub Actions
- Jenkins + SonarQube
Overview
A web platform that replaces WhatsApp, phone calls, email and spreadsheets with a single system where every request or complaint has a tracking number, an owner, a deadline and an auditable history.
Customer requests arrived through scattered channels, with no clear owner, no response-time control and no reporting.
- Role
- Built end to end as the sole author: domain model, REST API, frontend, security, tests, pipelines, deployment and technical documentation.
- Period
- 2026
- Status
- In production
- Code
- Private, described with permission
- Java 17
- Spring Boot 3
- Spring Security
- JWT
- PostgreSQL
- Flyway
- React 18
- Vite
- Tailwind CSS
- JUnit 5
- Mockito
- Vitest
- Playwright
- Selenium
- GitHub Actions
- Jenkins
- SonarQube
- Docker
Context
Sysdatec Centro de Desarrollo Integral S.A.S. received petitions, complaints, claims, suggestions and compliments from students, applicants and the public through informal channels. There was no way to tell who was handling each case or how long it had been open.
Goals
- A unique tracking number and a public status lookup for the requester.
- A clear owner and a response deadline per category.
- A complete history of actions and metrics computed from the database.
Architecture
A layered modular monolith: controller → service → repository → entity, with DTOs and mappers, plus cross-cutting modules for security, configuration, exceptions and AOP-based auditing. The frontend is a standalone SPA that talks to the API over HTTP/JSON.
I explicitly ruled out microservices and full hexagonal architecture: one team, one cohesive domain and a single database don't justify that complexity. The decision is recorded in an ADR.
Technical decisions
- Dual auditing: a user-readable business history, kept apart from a technical log (IP, before/after JSON) that only administrators can see. A single log would have meant filtering one model for two audiences.
- Stateless JWT authentication with method-level authorization (@PreAuthorize) for four roles.
- Versioned Flyway migrations, applied to the test database too.
- Attachments validated by an extension allow-list and by the file's binary signature, not just its name.
Key features
- Request filing with attachments, including anonymous filing.
- A lifecycle with states such as assigned, in analysis, awaiting information, resolved, response sent, closed and overdue.
- Reassignment with automatic acceptance after 24 hours.
- A scheduler flags overdue requests based on each category's SLA.
- Branded HTML emails for staff and citizens, plus a metrics dashboard.
Challenges and solutions
- Security hardening in dedicated commits: I closed a privilege escalation in public sign-up and an IDOR that exposed internal notes, masked passwords in the audit log and stopped leaking exception messages in 500 errors. The escalation is covered by a unit regression test and an integration test.
- A requester can't read someone else's request, and neither can staff without the central-reception role. Both rules are verified end to end with the real security filters in place.
npm cifailed in CI on Node 20 because of how npm resolves optional binaries. I traced it to an npm version mismatch rather than a corrupt lockfile, and aligned the pipeline's Node version with development.
Quality and testing
- Backend: JUnit 5 + Mockito for the state machine, authentication and storage, plus @SpringBootTest + MockMvc integration tests against a Flyway-migrated PostgreSQL.
- Frontend: ESLint, Vitest + Testing Library (including the modal's focus trap) and Playwright for the main flows.
- GitHub Actions runs
mvn verifyagainst a PostgreSQL 16 service, plus frontend lint, tests and build. - A Jenkins pipeline adds Selenium E2E and SonarQube static analysis.
- A traceability matrix links each requirement to its code and its test.
Outcome
The system is in production at sigesac.sysdatec.edu.co, with public and anonymous filing, tracking-number lookup and role-based internal management.
What I learned
Writing ADRs, even retroactively, forced me to justify each choice against its alternatives. Security tests at the HTTP level caught problems that unit tests alone would have missed.