managarten/apps/context/CLAUDE.md
Till JS ea4b585f37 feat(context): add NestJS backend, PostgreSQL database, and migrate web app from Supabase to API
- Create NestJS backend on port 3020 with 4 modules (space, document, ai, token)
- Add Drizzle schema with 5 tables (spaces, documents, token_transactions, model_prices, user_tokens)
- Rewrite web services (spaces, documents, tokens, ai) to use shared API client instead of Supabase
- Move AI API keys server-side (Azure OpenAI, Google Gemini)
- Add seed script for model prices (gpt-4.1, gemini-pro, gemini-flash)
- Add 70 unit tests across 4 test suites (space, document, token, ai services)
- Add monorepo integration (setup-databases.sh, generate-env.mjs, docker init-db, root scripts)
- Remove @supabase/supabase-js dependency and delete supabase.ts from web app
- Update CLAUDE.md with full API documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:28:01 +01:00

7.5 KiB

Context App

AI-powered document management and context system for knowledge organization.

App Port URL
Backend 3020 http://localhost:3020
Web App 5192 http://localhost:5192
Mobile 8081 Expo Go

Structure

apps/context/
├── apps/
│   ├── backend/     # NestJS API server (@context/backend)
│   │   └── src/
│   │       ├── main.ts
│   │       ├── app.module.ts
│   │       ├── db/           # Drizzle schemas + migrations
│   │       │   ├── schema/
│   │       │   │   ├── spaces.schema.ts
│   │       │   │   ├── documents.schema.ts
│   │       │   │   ├── token-transactions.schema.ts
│   │       │   │   ├── model-prices.schema.ts
│   │       │   │   └── user-tokens.schema.ts
│   │       │   ├── connection.ts
│   │       │   ├── database.module.ts
│   │       │   ├── migrate.ts
│   │       │   └── seed.ts
│   │       ├── space/        # Space CRUD
│   │       ├── document/     # Document CRUD + versions + tags
│   │       ├── ai/           # AI generation (Azure + Google)
│   │       ├── token/        # Token balance + stats
│   │       └── common/
│   ├── web/         # SvelteKit web application (@context/web)
│   ├── mobile/      # Expo React Native app (@context/mobile)
│   └── landing/     # (Planned) Astro Landing Page
├── packages/        # Project-specific shared code
└── package.json     # Workspace root

Development Commands

# From monorepo root
pnpm dev:context:full          # Start auth + backend + web (with DB setup)
pnpm dev:context:backend       # Start backend only (port 3020)
pnpm dev:context:web           # Start web only (port 5192)
pnpm dev:context:app           # Start web + backend together
pnpm dev:context:mobile        # Start mobile app

# Database
pnpm context:db:push           # Push schema to database
pnpm context:db:studio         # Open Drizzle Studio
pnpm context:db:seed           # Seed model prices
pnpm setup:db:context          # Create DB + push schema

Tech Stack

Layer Technology
Backend NestJS 10, Drizzle ORM, PostgreSQL
Web SvelteKit 2.x, Svelte 5 (runes mode), Tailwind CSS 4
Mobile React Native 0.76 + Expo SDK 52, NativeWind
Auth Mana Core Auth (JWT)
AI Azure OpenAI (GPT-4.1), Google Gemini (Pro, Flash)
i18n svelte-i18n (DE, EN)

Core Features

  • Spaces: Organize documents into collections with prefix-based short IDs
  • Documents: Text, context references, and AI prompts with versioning
  • AI Generation: Multi-model support (Azure OpenAI, Google Gemini)
  • Token Economy: Track and manage AI usage credits per user
  • Document Versioning: AI-generated summaries, continuations, rewrites

Backend API Endpoints

Health

Endpoint Method Description
/health GET Health check

Spaces

Endpoint Method Description
/api/v1/spaces GET List user's spaces
/api/v1/spaces POST Create space
/api/v1/spaces/:id GET Get space details
/api/v1/spaces/:id PUT Update space
/api/v1/spaces/:id DELETE Delete space (cascades documents)

Documents

Endpoint Method Description
/api/v1/documents GET List documents (?spaceId=&preview=true&limit=)
/api/v1/documents/recent GET Recent documents (?limit=)
/api/v1/documents POST Create document
/api/v1/documents/:id GET Get document
/api/v1/documents/:id PUT Update document
/api/v1/documents/:id DELETE Delete document
/api/v1/documents/:id/tags PUT Update document tags
/api/v1/documents/:id/pinned PUT Toggle pinned
/api/v1/documents/:id/versions GET Get document versions
/api/v1/documents/:id/versions POST Create AI version

AI

Endpoint Method Description
/api/v1/ai/generate POST Generate text (server-side AI)
/api/v1/ai/estimate POST Estimate token cost

Tokens

Endpoint Method Description
/api/v1/tokens/balance GET Get user token balance
/api/v1/tokens/stats GET Usage stats (?timeframe=day|week|month|year)
/api/v1/tokens/transactions GET Transaction history (?limit=&offset=)
/api/v1/tokens/models GET Available model prices

Database Schema

spaces

Column Type Description
id UUID Primary key
user_id TEXT Owner
name VARCHAR(255) Space name
description TEXT Optional description
settings JSONB Space settings
pinned BOOLEAN Pinned in sidebar
prefix VARCHAR(10) Short ID prefix (e.g. "A")
text_doc_counter INTEGER Counter for text docs
context_doc_counter INTEGER Counter for context docs
prompt_doc_counter INTEGER Counter for prompt docs

documents

Column Type Description
id UUID Primary key
user_id TEXT Owner
space_id UUID FK to spaces (cascade delete)
title VARCHAR(500) Document title
content TEXT Document content
type VARCHAR(20) text / context / prompt
short_id VARCHAR(20) Short ID (e.g. "AD1")
pinned BOOLEAN Pinned flag
metadata JSONB Tags, word count, version info

token_transactions

Column Type Description
id UUID Primary key
user_id TEXT User
amount INTEGER Tokens used (negative for usage)
transaction_type VARCHAR(50) usage / bonus / purchase
model_used VARCHAR(100) AI model name
prompt_tokens INTEGER Input tokens
completion_tokens INTEGER Output tokens
cost_usd NUMERIC(10,6) Actual USD cost

model_prices

Column Type Description
model_name VARCHAR(100) Unique model name
input_price_per_1k_tokens NUMERIC(10,6) Input price
output_price_per_1k_tokens NUMERIC(10,6) Output price
tokens_per_dollar INTEGER App tokens per USD

user_tokens

Column Type Description
user_id TEXT Primary key
token_balance INTEGER Current balance
monthly_free_tokens INTEGER Free monthly allocation

Environment Variables

Backend (.env)

NODE_ENV=development
PORT=3020
DATABASE_URL=postgresql://manacore:devpassword@localhost:5432/context
MANA_CORE_AUTH_URL=http://localhost:3001
AZURE_OPENAI_API_KEY=your-key
AZURE_OPENAI_ENDPOINT=https://your-endpoint.openai.azure.com/
GOOGLE_API_KEY=your-key

Web (.env)

PUBLIC_BACKEND_URL=http://localhost:3020
PUBLIC_MANA_CORE_AUTH_URL=http://localhost:3001

Important Patterns

  1. API Client pattern - All web services use @manacore/shared-api-client (Go-style { data, error })
  2. Svelte 5 runes - $state, $derived, $effect throughout
  3. Server-side AI keys - API keys only on backend, never in frontend
  4. Auto word/token count - Backend calculates on create/update
  5. Optimistic updates - Immediate UI feedback in stores
  6. Document versioning - AI generations linked via parent_document in metadata