Final project status: - 328 files, 26.357 lines of code - 23 views + client portal (5 tabs) - 69 API routes (30 AOS + 5 public v1 + 1 MCP + 1 health + 32 nested) - 39 Prisma models - 29 MCP tools (16 read + 13 write) for Claude Code - 0 TypeScript errors, ESLint clean - All 30 AOS endpoints + 6 public endpoints returning correct status codes - Health endpoint: ok, DB connected
6.0 KiB
6.0 KiB
AOS — Agency Operating System
Project Overview
Self-hosted platform for German software agencies. Full lifecycle: Lead → Deal → Quote → Project → Invoice → License → Renewal. GoBD-compliant accounting (SKR04, EÜR, UStVA, DATEV). Client Portal. MCP Server for Claude Code.
Tech Stack
- Framework: Next.js 16 (App Router, Turbopack)
- Language: TypeScript 5 (strict, 0 errors)
- Database: Prisma ORM (SQLite for dev)
- UI: shadcn/ui + Tailwind CSS 4 (monochrome design)
- State: Zustand + custom useFetch hook
- AI: z-ai-web-dev-sdk (server-side only, 3 AI flows)
- i18n: DE/EN/TR
Commands
bun run dev # Start dev server (port 3000)
bun run lint # ESLint check
bun run db:push # Push Prisma schema to DB
bun run db:generate # Generate Prisma Client
bun run src/lib/seed.ts # Seed database with realistic data
Architecture
- Modular monolith — one deployable, strict module boundaries
- Money: integer cents, tax in basis points (1900 = 19%). No floats.
- GoBD: immutable after Festschreibung, corrections via Storno (new row)
- Audit: SHA-256 hash-chain on all business operations
- Auth: Bearer token (SHA-256 hashed at rest) with scoped permissions
- No mocks — real implementations only (TCP mail test, CAMT.053 parser, ELSTER XML)
Key Directories
src/app/api/aos/ # Internal API (28+ endpoints)
src/app/api/v1/ # Public REST API (scoped tokens)
src/app/api/mcp/ # MCP Server (29 JSON-RPC tools)
src/app/api/health/ # Health check endpoint
src/components/aos/ # All UI components (23 views)
src/lib/ # Shared logic (db, format, i18n, api-auth, webhook)
prisma/ # Schema (30+ models)
.mcp.json # Claude Code auto-detection
MCP Server (29 Tools)
Claude Code auto-detects .mcp.json and connects with the seed admin token.
Read Tools (16)
| Tool | Description |
|---|---|
search_companies |
Search CRM companies by name/city/website |
get_pipeline |
Sales pipeline deals by stage |
get_invoice |
Single invoice by number with E-Rechnung status |
list_leads |
Leads Finder queue with scores |
get_dashboard |
Agency KPIs (pipeline, MRR, projects) |
list_tickets |
Support tickets with SLA info |
get_buchhaltung |
SKR04 Konten, Journal, EÜR summary |
get_anlagen |
Anlagenverzeichnis with AfA depreciation |
get_kassenbuch |
Cash book entries, running balance |
get_belege |
Receipts with SHA-256 content hashes |
get_finanzamt |
VAT returns, Jahreserklärungen, Jahresarchive |
get_contracts |
Verträge (AVV, NDA, SLA, Werkvertrag) |
get_projects |
Projects with progress, budget, task counts |
get_timesheet |
Weekly timesheet grid with lock status |
get_notifications |
All alerts (overdue, expiring, SLA breaches) |
get_calendar |
Upcoming deadlines (30-day look-ahead) |
Write Tools (13)
| Tool | Description |
|---|---|
approve_lead |
Approve a lead in the review queue |
create_ticket |
Create a support ticket |
create_deal |
Create a deal with value/stage/probability |
update_deal_stage |
Move deal through pipeline |
create_task |
Create a task with priority/assignee/estimate |
log_time |
Log billable time with rate |
create_invoice |
Create draft invoice with line items |
finalize_invoice |
Lock + send invoice (GoBD Festschreibung) |
run_recurring |
Run recurring invoice scheduler + license suspend |
create_buchung |
SKR04 Buchungssatz (Soll an Haben) |
create_beleg |
Register receipt (SHA-256, GoBD retention) |
create_pauschale |
Homeoffice/Kilometer/Verpflegung (auto-computed) |
create_kassenbuch_entry |
Cash book entry (§ 146 AO, immutable) |
Usage Examples
// Search companies
{"name": "search_companies", "arguments": {"query": "Hamburg"}}
// Create a deal
{"name": "create_deal", "arguments": {"companyId": "abc123", "title": "Website Relaunch", "valueCents": 980000, "stage": "proposal"}}
// Log time
{"name": "log_time", "arguments": {"projectId": "xyz789", "description": "SSO integration", "minutes": 180, "rateCentsPerHour": 9500}}
// Create invoice + finalize
{"name": "create_invoice", "arguments": {"companyId": "abc123", "lines": [{"description": "Website Audit", "quantity": 1, "unitCents": 45000}]}}
{"name": "finalize_invoice", "arguments": {"invoiceId": "inv123", "zugferd": true}}
// Book a Buchungssatz (SKR04)
{"name": "create_buchung", "arguments": {"belegdatum": "2026-10-27", "sollKontoNummer": "4930", "habenKontoNummer": "1200", "betragCents": 89900, "buchungstext": "JetBrains Lizenz"}}
// Create a Kilometerpauschale
{"name": "create_pauschale", "arguments": {"type": "kilometer", "date": "2026-10-27", "km": 140, "vehicleType": "auto", "description": "Kundentermin Berlin"}}
Compliance
- GoBD: Festschreibung (SHA-256), immutable Buchungssätze, 8/6 year retention
- DSGVO: Art. 15/17/20/30, consent log, data export with checksum
- E-Rechnung: ZUGFeRD/XRechnung (EN 16931)
- SKR04: Kontenrahmen, doppelte Buchführung, Saldenliste
- EÜR: Anlage EÜR with AVEÜR line numbers (§ 4 Abs. 3 EStG)
- UStVA: Kennzahlen 81/86/66/83/65/37, ELSTER XML
- DATEV: EXTF v5.0 Buchungsstapel export
- AfA: GWG (§ 6 Abs. 2), Sammelposten (§ 6 Abs. 2a), lineare AfA (§ 7)
- Kassenbuch: § 146 AO, § 22 UStG — immutable
- Pauschalen: EStG § 4 Abs. 5, § 9 Abs. 1 (Homeoffice, KM, Verpflegung)
- Mahnwesen: § 288 BGB Verzugszinsen, 3-stufig + license suspend
Important Rules
- No mocks — real implementations only
- No
anytypes — all interfaces explicitly typed - All API routes: try/catch error handling
- All icon-only buttons:
aria-label(WCAG 2.1 AA) - Client Portal: no agency-internal details visible to clients
- German UI by default (i18n: DE/EN/TR)
- Money: cents (integer), tax: basis points. Never floats.
Seed Token
Pre-built admin MCP token for Claude Code:
aos_admin_seed_token_for_claude_code_2026
Created by bun run src/lib/seed.ts. All read + write scopes.