Add document converter, seeder data structure, and project wiki

- ai-service/convert.py: converts Office/PDF files to markdown with frontmatter
- database/seeders/data/: folder structure for themas, projects, documents, etc.
- database/seeders/data/raw/: drop zone for Office/PDF files to convert
- wiki/: project architecture, concepts, and knowledge graph documentation
- Remove unused Laravel example tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
znetsixe
2026-04-08 08:33:30 +02:00
parent 302c790c13
commit 926872a082
23 changed files with 1785 additions and 76 deletions

View File

@@ -0,0 +1,109 @@
---
title: System Architecture
created: 2026-04-08
updated: 2026-04-08
status: evolving
tags: [architecture, stack, docker, layers]
sources: [docker-compose.yml, composer.json, package.json, ai-service/app/main.py]
---
# System Architecture
## Stack
| Layer | Technology | Version |
|---|---|---|
| Backend | Laravel (PHP) | 13.0 / PHP 8.3+ |
| Frontend | Vue 3 + Inertia.js | Vue 3.5, Inertia 3 |
| Build | Vite | 8.0 |
| Styling | Tailwind CSS | 4.2 |
| Visualization | D3.js | 7.9 |
| Database | PostgreSQL + pgvector | 16 |
| Cache / Queue | Redis | alpine |
| AI Service | Python FastAPI | 0.1.0 |
| Auth | Laravel Fortify + Sanctum | Fortify 1.36, Sanctum 4.0 |
| Fonts | VT323, Press Start 2P, IBM Plex Mono | — |
## Architecture Principles
1. **Service-oriented** — domain logic lives in service classes (`app/Services/`), not controllers
2. **Event-driven** — status transitions go through transactional methods with audit logging
3. **API-first** — all functionality reachable via REST endpoints
4. **Audit trail** — all mutations logged to `audit_logs` table (append-only)
5. **AI content labeled** — AI-generated content marked and requires human confirmation
6. **Inertia SPA** — server-side routing (Laravel) with client-side rendering (Vue 3), no separate API layer needed for pages
## Docker Topology
```
┌─────────────────────────────────────────────────────────┐
│ nginx:alpine ─────────────────────────────→ :80 │
│ │ │
│ ▼ │
│ laravel-app (PHP 8.4-FPM) │
│ │ │
│ ├── laravel-worker (queue:work) │
│ ├── laravel-scheduler (cron) │
│ │ │
│ ┌───▼────────────┐ ┌─────────────────┐ │
│ │ postgresql:16 │ │ redis:alpine │ │
│ │ + pgvector │ │ cache/queue │ │
│ │ :5432 │ │ :6379 │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ai-service (Python FastAPI) ──────────────→ :8000 │
│ └── connects to postgresql for embeddings │
└─────────────────────────────────────────────────────────┘
```
7 services total. All on `innovatieplatform` bridge network.
## Data Flow
### Page Rendering (Inertia)
```
Browser → nginx → PHP-FPM → Laravel Router → Controller
→ Service (business logic)
→ Inertia::render('Page', $data)
→ Vue component receives props
→ D3.js renders metro map canvas
```
### API Calls (Map data)
```
Vue component → axios GET /api/map/strategy
→ MapController::apiStrategy()
→ MapDataService::getStrategyMap()
→ Eloquent queries (Thema → Speerpunten → Projects)
→ JSON response {lines, nodes, connections, level}
→ D3 re-renders canvas
```
### AI Integration (planned)
```
CliBar.vue → POST /api/chat
→ Laravel proxy → ai-service:8000/api/chat
→ LangGraph agent → Anthropic Claude
→ RAG: pgvector similarity search on documents
→ Response with source attribution
→ CliBar displays with [AI] prefix
```
## Key Service Classes
| Service | LOC | Responsibility |
|---|---|---|
| `ProjectService` | 186 | Project CRUD, lifecycle transitions, park/stop, audit logging |
| `MapDataService` | 165 | Build metro map data structures (Level 1: strategy, Level 2: project) |
| `ThemaService` | 60 | Theme CRUD operations |
## Configuration
- **Session/Cache/Queue**: All Redis-backed (`config/session.php`, `config/cache.php`, `config/queue.php`)
- **Database**: PostgreSQL with pgvector extension for embedding vectors
- **Auth**: Fortify handles registration/login/password flows, Sanctum for API tokens
- **OPcache**: Production-optimized (`docker/php/opcache.ini`)
- **Gzip**: Enabled in nginx config