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 follows a domain-first design philosophy: the business domain is modeled and fully understood before any database schema is written. This means tables and columns are a consequence of the domain model, not its driver. Prisma ORM sits between the application and PostgreSQL, acting as the single source of truth for the schema — every structural change flows through a Prisma migration, never through manual SQL edits. On top of the relational foundation, the pgvector extension adds native vector similarity search to PostgreSQL, enabling the AI chatbot to perform semantic retrieval over CMS content without an external vector database.

Technology Choices

PostgreSQL 14+

The primary relational database. Chosen for its reliability, rich extension ecosystem, and first-class support for JSON, full-text search, and the pgvector extension.

pgvector

A PostgreSQL extension that adds a native vector column type and approximate nearest-neighbor (ANN) operators. Powers semantic search for the RAG-based chatbot without requiring a separate vector store.

Prisma ORM

A type-safe, migration-managed ORM. The schema.prisma file is the canonical definition of the database structure. TypeScript types for all models are generated automatically from the schema.
The schema is the single source of truth. If the schema says a field exists, it exists. If it does not appear in the schema, it does not belong in the database.

Prisma Setup

Use the following commands to manage the database during development and production deployments:
# Create and apply a new migration in development
npx prisma migrate dev

# Apply pending migrations in production (no schema drift check)
npx prisma migrate deploy

# Seed the database with initial data (roles, admin user, config)
npx prisma db seed

# Open the visual database browser (development only)
npx prisma studio
Always run npx prisma migrate deploy as part of your CI/CD pipeline before starting the application server in production. This ensures the database schema is always in sync with the running code.

Universal Table Fields

Every table in the SSA schema includes the following audit fields. These fields are defined once and applied consistently across all models, ensuring a uniform audit trail throughout the system.
// Illustrative base shape — applied to every model in schema.prisma
model BaseFields {
  id        String    @id @default(uuid())
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  deletedAt DateTime? // Soft delete — null means the record is active
  createdBy String?   // UUID of the user who created the record
  updatedBy String?   // UUID of the user who last modified the record
}
FieldTypePurpose
idString (UUID)Globally unique primary key, never reused
createdAtDateTimeTimestamp of record creation, set automatically
updatedAtDateTimeTimestamp of last update, maintained by Prisma
deletedAtDateTime?Soft-delete marker — null means active
createdByString?ID of the creating user, for audit logging
updatedByString?ID of the last modifying user, for audit logging

Soft Delete Strategy

The platform never permanently removes data. All delete operations are implemented as soft deletes, setting deletedAt to the current timestamp instead of issuing a SQL DELETE.
1

Delete request arrives

A DELETE /resource/:id request is authenticated and authorized by the Guards pipeline.
2

Service sets deletedAt

The service layer calls prisma.resource.update({ where: { id }, data: { deletedAt: new Date() } }). No row is physically removed.
3

All reads filter deleted records

Every query in every repository includes WHERE deletedAt IS NULL (or the Prisma equivalent where: { deletedAt: null }). Soft-deleted records are invisible to normal operations.
4

Audit trail preserved

The record remains in the database indefinitely, with its full history intact. Administrators with database access can recover data or produce audit reports at any time.
Every repository query must explicitly filter deletedAt: null. Forgetting this filter will cause deleted records to appear in API responses and is considered a data integrity bug.

pgvector for AI

The Chatbot Module uses a RAG (Retrieval Augmented Generation) architecture. When a user asks a question, the system performs semantic search over CMS content — finding the most relevant articles, disease pages, and campaigns — and passes that context to the LLM to generate a grounded, factual answer. This semantic search is powered by pgvector, which lives inside the same PostgreSQL instance as the rest of the data. No separate vector database is required. Enable the extension:
CREATE EXTENSION IF NOT EXISTS vector;
Embedding storage model:
model ContentEmbedding {
  id        String                     @id @default(uuid())
  contentId String
  embedding Unsupported("vector(384)") // dimension matches the chosen embedding model
  createdAt DateTime                   @default(now())
}
1

Content is published

An editor publishes a news article, disease page, or campaign through the CMS.
2

Embedding is generated

The publishing workflow calls an external embedding model via API to convert the content into a dense vector representation.
3

Vector is stored

The vector is persisted in the ContentEmbedding table, linked to the content record by contentId.
4

User asks a question

The chatbot converts the user’s query into a vector using the same embedding model and queries pgvector for the nearest neighbors.
5

LLM generates a response

The top matching content records are passed as context to the LLM, which generates a response grounded in the actual CMS content.
The platform never trains its own model. All intelligence comes from combining CMS-managed content with a hosted LLM through the RAG pattern. This keeps the system maintainable and ensures answers always reflect the latest published information.

Connection String

DATABASE_URL="postgresql://user:password@localhost:5432/ssa_db"
In production, the connection string should reference a managed PostgreSQL instance with SSL enabled:
DATABASE_URL="postgresql://user:password@your-db-host:5432/ssa_db?sslmode=require"

Schema Design Principles

These principles govern every schema decision in the platform:
  • Domain first — No schema work begins until the domain model is fully understood and agreed upon
  • Migrations only — Schema changes are made exclusively through prisma migrate dev; direct SQL edits to production are prohibited
  • UUID primary keys — All tables use UUID keys generated by the database, never sequential integers
  • Nullable over absent — When a field’s presence is uncertain for future use cases, prefer String? (nullable) over omitting it entirely; this avoids additive migrations later
  • No cross-module direct queries — Modules do not query other modules’ tables directly; they call the owning module’s service or repository
  • Indexes on foreign keys — All foreign key columns carry an index to prevent full-table scans in join-heavy operations

Architecture Overview

How the database layer fits into the modular monolith and Clean Architecture.

Domain Model

Entity relationships and the Content abstraction that drives the schema design.

Chatbot Module

How pgvector powers semantic similarity search in the RAG pipeline.

Development Stack

Full technology decisions, versions, and rationale for the platform.

Build docs developers (and LLMs) love