Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LMendoza70/SSA/llms.txt

Use this file to discover all available pages before exploring further.

The SSA Health Platform is a modular monolith: a single deployable application built from seven independent, self-contained modules. Module boundaries are not a convention — they are an architectural constraint. A module that leaks its internals into a neighbor creates coupling that defeats the purpose of the modular design. When boundaries are respected, each module can be reasoned about in isolation, tested without spinning up the full system, and eventually extracted into an independent service if the operational need arises. This page defines what each module owns, how it is structured internally, and how modules are permitted to communicate.

Modules

The Auth module is the system’s security boundary. All user sessions originate here, and no other module issues or validates credentials.Responsibilities:
  • User login and logout
  • Token refresh flow
  • Password change
  • User profile access
Security design:
  • Issues JWT access tokens with a 15-minute expiry
  • Issues Refresh Tokens with a 7-day expiry
  • All passwords are hashed with Argon2 before storage — never MD5, SHA-1, or bcrypt
  • Both token types are stored in HttpOnly Cookies to prevent JavaScript-based exfiltration
The Auth module never stores session state on the server. Authentication is stateless by design: the JWT is the session. The Refresh Token is the mechanism for renewing it.
The Admin module manages the platform itself — the configuration, structure, and operational record of the system.Responsibilities:
  • Platform-wide configuration and system parameters
  • Navigation menu management
  • Banner and promotional content management
  • User account management
  • Role and permission management
  • Audit log: every write operation (create, update, delete) across the entire platform is recorded with actor identity, timestamp, affected entity, and the nature of the change
The audit log is append-only. Audit records are never soft-deleted. They represent the authoritative history of all administrative actions on the platform.
The CMS module is the core domain of the platform. It manages every type of publishable institutional knowledge produced by the Jurisdicción Sanitaria.Content types managed:
  • News (Noticias)
  • Diseases (Enfermedades)
  • Campaigns (Campañas)
  • Programs (Programas)
  • Events (Eventos)
  • Announcements (Comunicados)
  • Notices (Avisos)
  • Infographics (Infografías)
  • Documents (Documentos)
  • FAQs (Preguntas Frecuentes)
  • Institutional Information (Información Institucional)
Design principles:
  • All content types share a common Content base structure — they are not eleven separate, unrelated tables
  • Rich text bodies are authored and stored as Tiptap JSON (portable, renderer-agnostic)
  • Every content item carries its own SEO metadata (title, description, canonical slug)
  • Content status follows a defined lifecycle: DRAFT → PUBLISHED → ARCHIVED
This is the module that the Chatbot, Social, and Multimedia modules all orbit around. It is the origin of every piece of information the platform distributes.
The Multimedia module is the platform’s single source of truth for binary assets. It owns the full lifecycle of every file: upload, storage, retrieval, and deletion.Supported asset types:
  • Images (JPEG, PNG, WebP, SVG)
  • Videos (MP4, WebM)
  • PDFs
  • Audio (MP3, OGG)
Design principles:
  • Files are stored once and referenced by ID — duplication is prohibited at the architecture level
  • All file access goes through the StorageProvider interface — no module reads from the filesystem or an S3 bucket directly
  • Current implementation: local filesystem
  • Prepared for migration to: Amazon S3, Azure Blob Storage, Google Cloud Storage — swap the StorageProvider implementation with no changes to callers
Bypassing StorageProvider to access files directly is a hard architectural violation. It binds the calling module to a specific storage backend and defeats the portability of the abstraction.
The Timeline module maintains the historical record of the Jurisdicción Sanitaria. Unlike a static page of dates and descriptions, every event is a first-class administrable entity.Each Timeline Event contains:
  • Specific date or date period
  • Title and rich text description
  • Associated multimedia assets
  • Category classification
  • Relationships to other events
Capabilities:
  • Chronological views
  • Filtered views by category, period, or tag
  • Full CRUD administration via the admin interface
The Timeline is not a CMS content type — it is a separate bounded context with its own entity structure and administration lifecycle.
The Social module is the platform’s distribution layer for external social networks. It consumes published CMS content and pushes it to configured social channels.Supported platforms (via adapters):
  • Facebook (FacebookAdapter)
  • Instagram (InstagramAdapter)
  • X / Twitter (XAdapter)
  • TikTok (TikTokAdapter)
  • YouTube (YouTubeAdapter)
Design principles:
  • All adapters implement a common SocialPublisher interface — the module’s core service never calls a platform SDK directly
  • Adding a new social platform means creating a new adapter class; no existing code is modified (Open/Closed Principle)
  • Supports immediate publishing and scheduled publishing
  • Supports republishing existing content to a channel
Each platform adapter is independent. A failure publishing to Instagram does not affect the Facebook publish attempt. Retry logic is handled per-adapter.
The Chatbot module is the platform’s AI-powered information interface. It allows users to ask natural language questions and receive answers grounded exclusively in the CMS content.Architecture: Retrieval Augmented Generation (RAG)
User query

Semantic search (pgvector similarity)

Relevant CMS content retrieved

Context injected into LLM prompt

LLM generates grounded response

Response returned to user
Design principles:
  • No custom model is trained. An external LLM is used via API.
  • All knowledge comes from the CMS. The chatbot cannot invent institutional information.
  • pgvector stores and queries text embeddings for semantic similarity search
  • Embeddings are generated from CMS content at publish time and kept in sync
The Chatbot module reads from the CMS module’s published content via a public service interface — it does not query the CMS database tables directly. This keeps the knowledge boundary clean and ensures only published, reviewed content reaches users.

Internal Structure

Every module follows the same internal directory layout. Consistency here means any developer can navigate any module without a map.
module-name/
├── controllers/    # HTTP handlers — thin, no business logic
├── services/       # Business logic — the only place decisions are made
├── repositories/   # Data access — implements interfaces defined by services
├── dto/            # Request and response shapes — validated with Zod or class-validator
├── entities/       # Domain entities — pure TypeScript, no ORM decorators in domain layer
├── validators/     # Input validation rules — reusable, composable
└── tests/          # Unit tests (services, validators) and integration tests (controllers)
Controllers are intentionally thin. If a controller method contains more than a few lines of logic, that logic belongs in a service. Controllers translate HTTP into service calls — nothing more.

Inter-Module Communication Rules

These rules are non-negotiable. They preserve module independence and prevent the coupling that turns a modular monolith into a distributed ball of mud.
1

Public interfaces only

Module A may only call methods exposed in Module B’s public service. If Module B does not expose a method for what Module A needs, Module B must be extended to add one — after deliberate review.
2

No internal imports

Importing from another module’s repositories/, entities/, or validators/ subdirectories is prohibited. TypeScript path aliases or ESLint import rules should enforce this boundary automatically.
3

Shared types in shared/

Types, interfaces, enums, and constants used by more than one module live in a shared/ package. No module “owns” shared types — they belong to the platform.
4

Side effects via events or injection

When a CMS publish triggers a social post or a chatbot index update, this is handled either through NestJS event emitters (decoupled, asynchronous) or through explicit service injection declared in the module’s dependency graph. Side effects are never implemented as hidden direct calls buried in unrelated services.

Module Boundaries

Understand why boundaries exist and how Clean Architecture enforces them at every layer.

Domain Model

See how the Content abstraction unifies all CMS content types into a single coherent model.

Authentication

Deep dive into the JWT + Refresh Token + Argon2 security design of the Auth module.

Storage

How the StorageProvider interface abstracts local filesystem, S3, Azure Blob, and GCS.

Build docs developers (and LLMs) love