MySoul · architecture

Retrieval-grounded profile platform in Docker Compose.

This page documents the three-service Compose topology, 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 authenticated MCP process. See the maintained README, BACKLOG, specification, and architecture documents for detail.

Local development URL

http://127.0.0.1:3005

Stack

Next.js + Compose

Containers

3 services

Runtime

Docker Compose (3 services)

Local dev URL

http://127.0.0.1:3005

App

Next.js 16 / App Router

Database

PostgreSQL 17 + pgvector

Section 01

Built capabilities and retrieval pipeline

The build is a three-service 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-service Compose topology: Next.js app, worker (Drive sync, parsing, embeddings), and pgvector database. The MCP process uses stdio and API-key auth; it exposes three read tools and four authenticated write tools. Profile writes now create experimental proposals for owner review. RLS policies cover 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 tenant-scoped pgvector search, then returns a cited evidence-grounded answer. Template mode is the current default; LLM mode is experimental and needs 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/admin/proposals/route.ts — authenticated proposal accept/reject API
  • 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.

BrowserRequest → /: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 · stdio · 3 read + 4 write toolsLegend━ 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/admin/proposals, /api/tenants), chat widget

Worker Container

Polls sync_jobs queue, resolves tenant folders, fetches Google Drive files, 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, three read tools plus four authenticated write tools

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. Production is deployed separately through Hostinger Docker Manager behind existing Traefik; the checked-in Compose labels are local configuration.

What is built

Three-service Compose topology: Next.js app, worker (Drive sync, parsing, embeddings), and pgvector database. The MCP process uses stdio and API-key auth; it exposes three read tools and four authenticated write tools. Profile writes now create experimental proposals for owner review. RLS policies cover 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 tenant-scoped pgvector search, then returns a cited evidence-grounded answer. Template mode is the current default; LLM mode is experimental and needs 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.

  • RLS policies exist on 4 tables but the table owner bypasses them; production requires a dedicated non-owner database role for the app connection.
  • The current worker loop defaults to 5 seconds; there is no SYNC_INTERVAL_MINUTES implementation.
  • Template synthesis is the deployed default; natural-language LLM mode requires configuring LLM_ENDPOINT.

Section 07

Next implementation steps

What remains to build after the current working state.

  1. 01Verify shared-root Drive discovery, all-PDF retrieval ingestion, and proposal acceptance against the live database/deployment.
  2. 02Add the planned non-owner database role and complete RLS hardening proof.
  3. 03Plan external PDF LLM extraction and broader business-document classification without changing the current local-first default.

Section 08

Operator route appendix

Operator-only routes are documented here instead of the public home page. These endpoints remain discoverable for maintainers without making admin flows part of the primary visitor journey.

GET/admin-login

Admin sign-in route that establishes the short-lived HttpOnly admin session.

Access: Admin token

GET/admin

Tenant onboarding surface for creating tenants and viewing one-time MCP key responses.

Access: Admin session

GET/admin/operations

Read-only operations surface for service health and local verification status.

Access: Admin session

POST/api/admin/tenants

Creates a tenant through the admin API.

Access: Admin session or x-admin-sync-token

POST/api/admin/sync/{slug}

Triggers a tenant sync for a registered tenant slug.

Access: Admin session or x-admin-sync-token

GET/status/{slug}

Tenant status page for operators or tenant owners with the status token.

Access: Tenant status token

GET/api/status/{slug}

JSON sync status endpoint for tenant status clients.

Access: x-tenant-status-token

POST/api/status/{slug}/sync

Requests a tenant sync from the status-token flow.

Access: Tenant status token