Software Engineering · Backend

Salus

Backend foundations in TypeScript, Node.js, Express, PostgreSQL and Prisma, with Clean Architecture, domain modeling, TDD, JWT authentication and per-user isolation.

Visit website

Problem

Backend exercises often stop at the happy-path CRUD: no consistent domain rules, no well-isolated persistence, no real authentication, and not enough tests to prevent regressions.

Salus tackles a small but realistic problem: patient management with domain rules plus user authentication. The repository is public, so every decision described here can be inspected in the code.

Engineering decisions

  • Layered architecture, with dependencies pointing toward the domain.
  • Domain free of Express and Prisma; use cases never touch Prisma.
  • Contracts expressed as repository interfaces; Prisma isolated in the infrastructure layer.
  • Use cases depend on ports/interfaces (repositories, PasswordHasher, TokenGenerator), not on infrastructure implementations; in-memory doubles keep the application testable without a database.
  • Composition through factories, with explicit dependency injection.
  • Explicit, readable code: entities guard their own invariants and domain errors map to HTTP without leaking stack traces (Clean Code principles).
  • PostgreSQL for persistence and Docker Compose for the local environment.
  • Passwords with Argon2 + server-side pepper; patient routes require JWTs verified with issuer, audience, subject, and expiry.
  • Global error handling: unexpected errors never leak stack traces to the client.

Implementation

The API’s conceptual flow:

HTTP → Routes / Controllers → Application / Use Cases → Domain → Repository abstraction → Prisma adapter → PostgreSQL.

Entities guard invariants such as name, CPF check digits, phone, and birth date. Infrastructure implements the contracts defined by the inner layers, while the domain stays unaware of framework or database details.

Quality

64 automated tests — 47 unit and 17 integration — covering the domain, use cases, adapters, HTTP, per-user isolation, authorization, pagination, constraint behavior, and a real PostgreSQL database in integration tests. The tests protect domain rules and application decisions against regressions.

Salus was developed using TDD, with tests guiding the implementation and evolution of domain rules and application use cases. The implementation was written manually, without AI-generated code.

The later production-hardening phase was developed with agent-assisted workflows under human review. This does not change how the original core was built manually with TDD.

CI runs, in order:

typecheck → lint → unit tests → build → integration tests.

Security

What the project guarantees today:

  • Password hashing with Argon2 + server-side pepper; hashes never returned in responses.
  • JWT signed with an environment-provided secret; variables validated at boot.
  • .env file kept out of Git.
  • Unexpected errors answered without exposing stack traces to the client.

Security and reliability

Patient routes require verified JWTs. Queries and mutations are scoped by ownerId, isolating each user’s patients; cross-user access returns 404. The API validates requests with Zod, normalizes email and CPF, handles UNIQUE conflicts explicitly, and uses typed errors.

Collections use cursor pagination with a default limit of 20 and a maximum of 100, stable createdAt + id ordering, a matching index, and UNIQUE(ownerId, cpf). Runtime controls include X-Request-Id, structured redacted logs, liveness, database-backed readiness, graceful shutdown, versioned migrations, and a production artifact smoke test.

Trade-offs

  • Modular monolith instead of microservices: a single deploy, without the distributed networking and observability cost for a problem this size.
  • Repository interfaces add a thin mapping layer, but they isolate Prisma and keep use cases testable without a database.
  • Stateless JWT keeps infrastructure simple, but access tokens last 7 days and there is no revocation or refresh.
  • Readiness timeout does not cancel the underlying query; shutdown during a long request still lacks a deterministic test.
  • There is no rate limiting, and dependency advisories remain documented for follow-up.

Limitations

This case does not claim production-ready, enterprise-grade, or fully secure software. Residual risks include no rate limiting, timing differences between an unknown email and a wrong password, 7-day access tokens without revocation, readiness timeout without cancellation of the underlying query, long-request shutdown without a deterministic test, and documented dependency advisories.

Back to projects

LET’S TALK

Good products start with a good conversation.

Professional opportunities, partnerships, or a conversation about AI Engineering, software, and product.

Connect on LinkedIn