docs(cleanup): archief verouderde plannen, backlog en root-duplicaten (#191)

* docs(cleanup): archief verouderde plannen, backlog en root-duplicaten

- 6 plans naar docs/old/plans/ (PBI-11/75/78, user-settings-store, Local github setup, lees-de-readme — laatste was verkeerde repo)
- docs/backlog/ naar docs/old/backlog/ (pre-MCP statische registry; live werk loopt via Scrum4Me-MCP)
- 6 root-level duplicaten naar docs/old/ (functional, {pbi,story,task}-dialog, product-backlog, backlog)
- 2 landing plans (niet uitgevoerd) krijgen archived: true frontmatter — blijven op plek maar uit INDEX
- scripts/generate-docs-index.mjs: skip docs/old/** + skip archived: true
- CLAUDE.md: rijen docs/backlog/, docs/plans/<key>-*.md, docs/manual/ weg; Track B-sectie verwijderd
- README.md / CHANGELOG.md / docs/plans/v1-readiness.md: link-fixes naar nieuwe locaties

Verify groen (lint + typecheck + 718 tests). docs/INDEX.md geregenereerd.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(cleanup): registreer handmatige verplaatsingen en fix referenties

- 4 plans verplaatst naar docs/old/plans/ (M10-qr-pairing-login, auto-pr-deploy-sync, docs-restructure-ai-lookup, v1-readiness)
- 3 archive-plans verplaatst naar docs/old/plans/ (archive-map nu leeg)
- ST-1114-copilot-reviews + 3 research-docs naar nieuwe docs/Ideas/ map
- Duplicaat docs/old/2026-04-27-m8-realtime-solo.md verwijderd (origineel zit in docs/old/plans/)
- Link-fixes naar nieuwe locaties:
  - CHANGELOG.md → docs/old/plans/v1-readiness.md
  - docs/runbooks/deploy-control.md → docs/old/plans/auto-pr-deploy-sync.md (2x)
  - docs/runbooks/worker-idempotency.md → docs/old/plans/auto-pr-deploy-sync.md
  - docs/plans/docs-restructure-pbi-spec.md → docs/old/plans/docs-restructure-ai-lookup.md (4x text + 2x href)
- docs/INDEX.md geregenereerd (96 docs, was 100)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-11 19:46:00 +02:00 committed by GitHub
parent d587be2fb3
commit b39c3ec2e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 1068 additions and 49 deletions

View file

@ -0,0 +1,605 @@
---
title: "Installatieplan — Beelink Ubuntu Scrum4Me server en worker-aanpassingen"
status: draft
audience: [maintainer, operator, ai-agent]
language: nl
last_updated: 2026-05-10
---
# Installatieplan — Beelink Ubuntu Scrum4Me server en worker-aanpassingen
## Doel
Deze notitie beschrijft de huidige Beelink-installatie en het vervolgplan om de Scrum4Me workers geschikt te maken voor drie rollen:
```text
worker-idea
worker-implementation
worker-orchestrator
```
De server draait nu als LAN-host voor Scrum4Me. Productie-internettoegang met domein en HTTPS is nog een latere stap.
## Hardware
| Onderdeel | Waarde |
|---|---|
| Machine | Beelink mini-PC |
| CPU | Intel Core i5-12450H |
| RAM zichtbaar in Ubuntu | 16 GB |
| Max RAM volgens hardware | 32 GB |
| Disk | 468 GB bruikbaar na Ubuntu-installatie |
| IP | `192.168.0.154` |
Opmerking: Ubuntu ziet momenteel ongeveer 16 GB RAM. De hardware meldt een maximum van 32 GB, maar dat betekent niet dat 32 GB bruikbaar/geplaatst is.
## Huidige Installatie
### Ubuntu
Ubuntu Server is geïnstalleerd op de hele disk.
Belangrijke keuzes:
- Ubuntu Server 24.04 LTS.
- Geen Ubuntu Desktop.
- Geen LVM.
- Geen aparte GPU-drivers.
- Geen Windows dual boot meer.
- Hostname: `scrum4me-server`.
- Sleep/hibernate uitgeschakeld.
- Swapfile vergroot naar 16 GB.
Controle:
```bash
hostnamectl
free -h
swapon --show
df -h
```
### Directorystructuur
Alle service-data staat onder:
```text
/srv/scrum4me
```
Structuur:
```text
/srv/scrum4me/postgres database data
/srv/scrum4me/repos GitHub clones
/srv/scrum4me/worker-cache worker caches
/srv/scrum4me/worker-logs worker logs
/srv/scrum4me/worker-state worker state
/srv/scrum4me/backups Postgres backups
/srv/scrum4me/compose Docker Compose files
/srv/scrum4me/caddy Caddy config/data
```
### Docker
Docker Engine draait native op Ubuntu.
Controle:
```bash
docker run hello-world
docker compose version
```
### Postgres
Postgres draait als Docker container:
```text
container: scrum4me-postgres
image: postgres:17
```
Host mapping:
```text
127.0.0.1:5432 -> postgres:5432
```
Host-app gebruikt:
```env
DATABASE_URL="postgresql://scrum4me:<password>@127.0.0.1:5432/scrum4me"
DIRECT_URL="postgresql://scrum4me:<password>@127.0.0.1:5432/scrum4me"
```
Containers gebruiken:
```env
DATABASE_URL=postgresql://scrum4me:<password>@postgres:5432/scrum4me
DIRECT_URL=postgresql://scrum4me:<password>@postgres:5432/scrum4me
```
DB-test:
```bash
docker exec -e PGPASSWORD="$DBPASS" scrum4me-postgres \
psql -h 127.0.0.1 -U scrum4me -d scrum4me \
-c "select current_user, current_database();"
```
### Scrum4Me Web
Repo:
```text
/srv/scrum4me/repos/Scrum4Me
```
Build:
```bash
cd /srv/scrum4me/repos/Scrum4Me
rm -rf .next
npm run build
```
Runtime:
```text
systemd service: scrum4me-web
```
Service startcommand:
```bash
npm run start -- -H 0.0.0.0
```
Controle:
```bash
systemctl status scrum4me-web --no-pager
curl -I http://127.0.0.1:3000/login
```
### Caddy
Caddy draait als Docker container:
```text
container: scrum4me-caddy
```
Caddy reverse proxyt:
```text
http://192.168.0.154 -> Caddy -> 172.18.0.1:3000 -> Scrum4Me web
```
Caddyfile:
```caddyfile
:80 {
reverse_proxy 172.18.0.1:3000
}
```
Controle:
```bash
curl -I http://192.168.0.154/login
docker logs --tail=50 scrum4me-caddy
```
### LAN Session Config
Omdat de server nu via HTTP op LAN draait, is secure session cookie tijdelijk uitgezet.
Env:
```env
SESSION_COOKIE_SECURE="false"
```
Code-aanpassing:
```ts
secure: process.env.SESSION_COOKIE_SECURE === 'true',
```
Later, bij domein + HTTPS:
```env
SESSION_COOKIE_SECURE="true"
```
Daarna:
```bash
rm -rf .next
npm run build
sudo systemctl restart scrum4me-web
```
### Migrations
De database is gemigreerd.
Belangrijke migration-notitie:
`20260506101436_restore_todos_table` kan op een bestaande DB falen met:
```text
relation "todos" already exists
```
Voor deze server is de juiste aanpak:
```bash
npx prisma migrate resolve --applied 20260506101436_restore_todos_table
npx prisma migrate deploy
```
Controle:
```bash
npx prisma migrate status
docker exec -it scrum4me-postgres psql -U scrum4me -d scrum4me -c "\dt public.users"
```
### Admin en Product
Admin user is aangemaakt via:
```bash
npx tsx scripts/create-admin.ts janpeter '<password>'
```
Login werkt.
Product aanmaken werkt.
### Backups
Backup-script:
```text
/srv/scrum4me/backup-postgres.sh
```
Script:
```bash
#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/srv/scrum4me/backups"
STAMP="$(date +%Y%m%d-%H%M%S)"
FILE="$BACKUP_DIR/scrum4me-$STAMP.sql.gz"
mkdir -p "$BACKUP_DIR"
docker exec scrum4me-postgres pg_dump -U scrum4me scrum4me | gzip > "$FILE"
find "$BACKUP_DIR" -type f -name 'scrum4me-*.sql.gz' -mtime +14 -delete
echo "backup written: $FILE"
```
Test:
```bash
/srv/scrum4me/backup-postgres.sh
ls -lh /srv/scrum4me/backups
```
Cron:
```cron
15 3 * * * /srv/scrum4me/backup-postgres.sh >> /srv/scrum4me/backups/backup.log 2>&1
```
## Worker-Idea Installatie
Worker compose-service:
```text
worker-idea
container: scrum4me-worker-idea
health: http://127.0.0.1:18081/health
```
Belangrijke env-waarden:
```env
SCRUM4ME_BASE_URL=http://caddy
SCRUM4ME_TOKEN=<raw Scrum4Me API token>
DATABASE_URL=postgresql://scrum4me:<password>@postgres:5432/scrum4me
DIRECT_URL=postgresql://scrum4me:<password>@postgres:5432/scrum4me
GH_TOKEN=<GitHub token>
GH_PRECLONE_REPOS=madhura68/Scrum4Me,madhura68/scrum4me-mcp,madhura68/scrum4me-docker
CLAUDE_CODE_OAUTH_TOKEN=<Claude Code OAuth token>
```
Token-validatie:
```bash
read -s -p "Scrum4Me token: " TOKEN; echo
curl -i -H "Authorization: Bearer $TOKEN" http://127.0.0.1:3000/api/products
unset TOKEN
```
Verwacht:
```text
HTTP/1.1 200 OK
```
Worker health:
```bash
curl http://127.0.0.1:18081/health
```
Gezonde idle-output bevat:
```json
{
"status": "idle",
"heartbeatAgeSeconds": 1,
"consecutiveFailures": 0
}
```
## Huidige Worker-Beperking
De Docker worker is gezond, maar Scrum4Me UI toont mogelijk nog:
```text
geen Claude worker actief
```
Oorzaak:
- De Docker health-server draait altijd.
- De daemon-loop draait altijd.
- Maar de DB-tabel `claude_workers` wordt nu alleen bijgewerkt door de MCP stdio-server.
- Die MCP stdio-server start pas binnen een echte Claude/MCP job-run.
- Bij een lege queue is de Docker worker dus idle en gezond, maar verschijnt hij niet als actieve worker in de UI.
Controle:
```bash
docker exec -it scrum4me-postgres psql -U scrum4me -d scrum4me \
-c "select t.id, t.label, w.id as worker_id, w.last_seen_at from api_tokens t left join claude_workers w on w.token_id=t.id order by t.created_at desc;"
```
Gezonde Docker-worker maar lege presence:
```text
label | worker_id | last_seen_at
worker-idea | |
```
## Worker Aanpassingsplan
### Doelrollen
```text
worker-idea
IDEA_GRILL
IDEA_MAKE_PLAN
PLAN_CHAT
worker-implementation
TASK_IMPLEMENTATION
SPRINT_IMPLEMENTATION
later STORY_IMPLEMENTATION
worker-orchestrator
PR_REVIEW
CI_TRIAGE
MERGE_CONFLICT_RESOLUTION
REPAIR_FAILED_JOB
CONTEXT_SUMMARY
```
## Fase 1 — Presence Fix
### Probleem
Worker-health is nu container-lokaal, maar UI-presence is DB-gebaseerd.
Nu:
```text
curl :18081/health -> online
claude_workers -> leeg
UI -> offline
```
### Gewenst gedrag
Zolang de Docker daemon-loop draait, moet `claude_workers.last_seen_at` vers blijven, ook als de queue leeg is.
### Aanpassing
Verplaats worker-presence naar `scrum4me-docker/bin/run-one-job.ts` of naar een kleine runner-level heartbeat naast `run-agent.sh`.
Aanbevolen: in `run-one-job.ts`, direct na `getAuth()`:
```ts
const { userId, tokenId } = await getAuth()
await registerWorker({ userId, tokenId })
const heartbeat = startHeartbeat({ userId, tokenId, intervalMs: 10_000 })
```
In `finally`:
```ts
heartbeat.stop()
```
Niet unregisteren bij normale idle-exit. Anders gaat de UI-indicator flikkeren tussen iteraties.
### Acceptatie
Bij lege queue:
```bash
curl http://127.0.0.1:18081/health
```
toont:
```text
status idle
```
En:
```sql
select token_id, last_seen_at, now() - last_seen_at from claude_workers;
```
toont een recente `last_seen_at`.
## Fase 2 — Role-Aware Workers
### Probleem
De huidige worker claimt elke job die beschikbaar is. Daardoor kan `worker-idea` ook implementation jobs claimen.
### Nieuwe env
```env
SCRUM4ME_WORKER_ROLE=idea
```
Toegestane waarden:
```text
idea
implementation
orchestrator
```
### Claimfilter
`tryClaimJob` krijgt een role/capability-filter.
Mapping:
```text
idea:
IDEA_GRILL
IDEA_MAKE_PLAN
PLAN_CHAT
implementation:
TASK_IMPLEMENTATION
SPRINT_IMPLEMENTATION
orchestrator:
PR_REVIEW
CI_TRIAGE
MERGE_CONFLICT_RESOLUTION
REPAIR_FAILED_JOB
CONTEXT_SUMMARY
```
### Acceptatie
Test:
- Queue bevat één `IDEA_GRILL` en één `TASK_IMPLEMENTATION`.
- Alleen `worker-idea` actief: claimt alleen `IDEA_GRILL`.
- Alleen `worker-implementation` actief: claimt alleen `TASK_IMPLEMENTATION`.
- Beide actief: ieder claimt eigen jobtype.
## Fase 3 — DB/UI Uitbreiding
Breid `claude_workers` uit met:
```text
role
worker_name
container_name
last_status
last_job_id
last_error
```
UI toont dan:
```text
Idea worker online / idle
Implementation worker offline
Orchestrator online / idle
```
## Fase 4 — Orchestrator Jobs
Nieuwe job kinds:
```text
PR_REVIEW
CI_TRIAGE
MERGE_CONFLICT_RESOLUTION
REPAIR_FAILED_JOB
CONTEXT_SUMMARY
```
Orchestrator mag:
- PR's inspecteren.
- CI-fouten samenvatten.
- Merge conflicts analyseren.
- Repair jobs aanmaken.
- Context capsules schrijven.
- Human escalation vragen.
- Draft PR naar ready begeleiden.
Orchestrator mag niet:
- Vrij featurewerk implementeren.
- Dezelfde branch tegelijk wijzigen als implementation-worker.
- Auto-mergen zonder checks.
- Secrets of tokens loggen.
## Fase 5 — Deployment
Na code-aanpassing:
```bash
cd /srv/scrum4me/repos/scrum4me-docker
git pull
cd /srv/scrum4me/compose
docker compose build worker-idea
docker compose up -d --force-recreate worker-idea
```
Checks:
```bash
curl http://127.0.0.1:18081/health
docker logs -f scrum4me-worker-idea
docker exec -it scrum4me-postgres psql -U scrum4me -d scrum4me \
-c "select token_id, last_seen_at from claude_workers;"
```
## Aanbevolen Volgorde Vanaf Nu
1. Test één `IDEA_GRILL` job met de huidige worker.
2. Implementeer Fase 1: runner-level presence.
3. Rebuild `worker-idea`.
4. Verifieer UI online/idle bij lege queue.
5. Implementeer Fase 2: role-aware claiming.
6. Voeg `worker-implementation` toe.
7. Voeg pas daarna `worker-orchestrator` toe.
Niet meteen drie workers starten zonder role-aware claimfilter.