MySoul · architecture

Retrieval-grounded profile platform in Docker Compose.

This page documents the live three-container runtime, the Next.js application with SSG/ISR profile pages, the retrieval-grounded chat pipeline backed by pgvector, the worker that syncs from Google Drive, and the MCP server that exposes tenant-scoped read-only tools.

Live URL

http://localhost:3005

Stack

Next.js + Compose

Containers

3 running

Runtime

Docker Compose (3 containers)

URL

http://localhost:3005

App

Next.js / React 19 / App Router

Database

PostgreSQL 17 + pgvector

Section 01

Built capabilities and retrieval pipeline

The live build is a three-container Docker Compose stack: a Next.js app, a worker, and a pgvector database. The chat endpoint retrieves from pgvector and synthesizes evidence-grounded answers.

What is built

Three-container Docker Compose: Next.js app (SSG/ISR profiles, chat API, admin sync API, public tenants API), worker (Drive sync, markdown/PDF ingestion, MiniLM-L6-v2 embeddings), and pgvector database. MCP server exposes 3 read-only tools with API key auth over stdio. RLS enforced on profiles, content_chunks, sync_state, and sync_jobs.

Retrieval pipeline

POST /api/chat/[slug] resolves the tenant, embeds the question with local MiniLM-L6-v2, runs pgvector cosine similarity search scoped to tenant_id, then synthesizes an evidence-grounded answer with inline citations. Template mode by default, optional LLM mode via LLM_ENDPOINT.

What the page documents

The page records the live Compose topology, source-of-truth paths, built capabilities, remaining work, and the risks that guide what the build claims.

Chat request flow

POST /api/chat/[slug] → resolve tenant by slug → embedQuery (MiniLM-L6-v2, 384-dim) → searchContent (pgvector cosine, tenant-scoped, top-5) → synthesizeAnswer (template extractive with citations, or LLM mode via LLM_ENDPOINT) → return { answer, sources }.

Section 02

Source-of-truth code paths

These are the source files that implement the live build — not aspirational references, but the actual code paths in the MySoul repository.

  • Source
    src/app/[slug]/page.tsx — SSG/ISR profile pages
  • Source
    src/app/api/chat/[slug]/route.ts — retrieval-grounded chat endpoint
  • Source
    src/app/api/admin/sync/[slug]/route.ts — token-auth Drive sync trigger
  • Source
    src/app/api/tenants/route.ts — public tenant listing
  • Source
    src/worker/index.ts — Drive sync, ingestion, embeddings worker
  • Source
    src/mcp/server.ts — MCP server (API key auth, stdio)
  • Source
    src/lib/retrieval/search.ts — pgvector cosine similarity search
  • Source
    src/lib/synthesis/answer.ts — evidence-grounded answer synthesis
  • Source
    src/lib/embeddings/index.ts — MiniLM-L6-v2 embedding ingestion
  • Source
    docker-compose.yml — mysoul + worker + db (pgvector)

Section 03

Runtime topology

The browser hits the Next.js app container, which serves ISR profile pages and API routes. The worker container syncs from Google Drive and writes embeddings to the pgvector database. Both containers share the same database.

Browserlocalhost:3005/:slugNext.js appSSG/ISR profile pagesPOST /api/chat/[slug]POST /api/admin/sync/[slug]GET /api/tenantsChat widget (client)mysoul containerport 3005 → 3000Docker ComposeWorkerDrive sync (SA auth)Markdown + PDF parseMiniLM-L6-v2 embedISR revalidate triggerPostgreSQL 17pgvector extensioncontent_chunks (384-dim)profiles, sync_jobsRLS on 4 tablesMCP Server (stdio)API key auth · 3 read-only tools · tenant-scopedLegend━ solid: direct request / data flow┄ dashed: retrieval read (pgvector cosine search)

Section 04

How the platform is organized

The page is intentionally linear: hero, runtime facts, built capabilities, source code paths, topology, and remaining work.

Browser

Visits ISR profile pages at /:slug and interacts with the chat widget

Next.js App

SSG/ISR profile pages, API routes (/api/chat, /api/admin/sync, /api/tenants), chat widget

Worker Container

Polls sync_jobs queue, fetches from Google Drive, parses markdown/PDF, embeds with MiniLM-L6-v2

pgvector Database

Tenant-scoped content_chunks (384-dim embeddings), profiles, sync_jobs, sync_state — RLS on 4 tables

MCP Server

stdio transport, API key auth, 3 read-only tools scoped to authenticated tenant

Section 05

Compose and container notes

The app runs in a three-container Compose stack: mysoul (Next.js), worker (Drive sync), and db (pgvector).

services:
  mysoul:
    build: .
    ports:
      - "3005:3000"
    environment:
      DATABASE_URL: postgresql://mysoul:***@db:5432/mysoul
      NODE_ENV: development

  worker:
    build: .
    command: npm run worker
    environment:
      DATABASE_URL: postgresql://mysoul:***@db:5432/mysoul
      GOOGLE_SERVICE_ACCOUNT_EMAIL: ...
      GOOGLE_DRIVE_FOLDER_ID: ...
    depends_on:
      - db

  db:
    image: pgvector/pgvector:pg17
    environment:
      POSTGRES_DB: mysoul
      POSTGRES_USER: mysoul

Three services: the Next.js app on port 3005, the worker that polls sync_jobs and syncs from Google Drive, and a pgvector-enabled PostgreSQL 17 database. Traefik labels are already configured on the mysoul service for future production routing.

What is built

Three-container Docker Compose: Next.js app (SSG/ISR profiles, chat API, admin sync API, public tenants API), worker (Drive sync, markdown/PDF ingestion, MiniLM-L6-v2 embeddings), and pgvector database. MCP server exposes 3 read-only tools with API key auth over stdio. RLS enforced on profiles, content_chunks, sync_state, and sync_jobs.

Retrieval pipeline

POST /api/chat/[slug] resolves the tenant, embeds the question with local MiniLM-L6-v2, runs pgvector cosine similarity search scoped to tenant_id, then synthesizes an evidence-grounded answer with inline citations. Template mode by default, optional LLM mode via LLM_ENDPOINT.

What the page documents

The page records the live Compose topology, source-of-truth paths, built capabilities, remaining work, and the risks that guide what the build claims.

Section 06

Risks and constraints

These are the main reasons the page is careful about what it claims.

  • Drive ingestion E2E has not been verified with live Google service account credentials — the worker code path is complete but unexercised end-to-end.
  • RLS policies exist on 4 tables but the table owner bypasses them; production requires a dedicated non-owner database role for the app connection.
  • Template synthesis is extractive only — natural language synthesis requires configuring LLM_ENDPOINT, which is not yet set in the dev environment.

Section 07

Next implementation steps

What remains to build after the current working state.

  1. 01Complete Drive ingestion end-to-end: verify worker → Drive fetch → parse → embed → pgvector → ISR revalidation cycle with real service account credentials.
  2. 02Add Traefik routing and production Compose target alongside the current dev configuration (labels already in place on the mysoul service).
  3. 03Implement profile diff-and-publish: detect changed profile data, write a new profile version, and revalidate the ISR page.