Scaffold pal-e-docs FastAPI service #4

Merged
forgejo_admin merged 7 commits from 1-scaffold-project into main 2026-02-24 14:03:24 +00:00

Summary

  • FastAPI + SQLAlchemy + SQLite (WAL mode) on Kubernetes PVC
  • Full CRUD for projects, notes, tags, bidirectional links, and revision tracking
  • Tag intersection queries (?tags=auth,sop)
  • 11 tests passing, ruff clean
  • Woodpecker CI pipeline (test + build-push to Harbor)
  • K8s manifests (deployment, service, PVC, servicemonitor)
  • No auth in v0.1.0 — behind Tailscale, issue #2 tracks auth integration

Closes #1

Test plan

  • pytest — 11 tests pass
  • ruff check + ruff format --check — clean
  • Woodpecker pipeline builds successfully after merge
  • ArgoCD deploys after tofu apply in pal-e-services
  • GET /healthz returns 200 on deployed instance
## Summary - FastAPI + SQLAlchemy + SQLite (WAL mode) on Kubernetes PVC - Full CRUD for projects, notes, tags, bidirectional links, and revision tracking - Tag intersection queries (`?tags=auth,sop`) - 11 tests passing, ruff clean - Woodpecker CI pipeline (test + build-push to Harbor) - K8s manifests (deployment, service, PVC, servicemonitor) - No auth in v0.1.0 — behind Tailscale, issue #2 tracks auth integration Closes #1 ## Test plan - [x] `pytest` — 11 tests pass - [x] `ruff check` + `ruff format --check` — clean - [ ] Woodpecker pipeline builds successfully after merge - [ ] ArgoCD deploys after `tofu apply` in pal-e-services - [ ] `GET /healthz` returns 200 on deployed instance
Platform knowledge service: SQLite-backed, queryable by AI agents
and humans. Three roles: platform knowledge base (SOPs), planning
continuity (chained plans), project documentation.

Documents how claude-custom connects: hooks enforce behavior,
pal-e-docs defines knowledge. SOPs evolve through note edits,
not commits.

Refs: forgejo_admin/pal-e-docs#1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Notes store HTML rendered from Markdown on write (not raw HTML)
- Add PUT /notes/{slug}/links endpoint for managing cross-links
- Projects are intentionally not deletable (omission is by design)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PUT /notes/{slug}/links sets outgoing links, reverse created automatically
- GET returns both incoming and outgoing
- Single writer = single admin account, matches SQLite's writer lock

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- FastAPI + SQLAlchemy + SQLite (WAL mode) on PVC
- Models: Project, Note, Tag, NoteTag, NoteLink, NoteRevision
- CRUD routes for projects, notes, tags, and bidirectional links
- Revision tracking on note updates
- Tag intersection queries (?tags=auth,sop)
- Alembic initial migration
- 11 tests (health + full CRUD coverage)
- Multi-stage Dockerfile with alembic upgrade on startup
- Woodpecker CI: test + build-and-push to Harbor
- K8s manifests: deployment, service, PVC, servicemonitor
- No auth in v0.1.0 (behind Tailscale, issue #2 tracks auth)

Closes #1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add subqueryload(Note.tags) to list_project_notes endpoint
- Use settings.database_path in alembic/env.py instead of duplicating default
- Remove unused aiosqlite dependency from pyproject.toml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
Owner

Review-Fix Loop

Round 1: 2 blockers (duplicate query from joinedload, metrics returning JSON not text/plain) + 5 nits (links validation order, project update schema, redundant constraint, missing project notes endpoint, memory limit). All fixed in commit 4a92910.

Round 2: 0 blockers, 3 quick-win nits (N+1 query in project notes, duplicated DB path default, unused aiosqlite dep). Fixed in commit 7cd40ce.

Remaining nits deferred to follow-up (self-link prevention, non-root Dockerfile user, HTML sanitization, error path tests, metrics stub).

## Review-Fix Loop **Round 1:** 2 blockers (duplicate query from joinedload, metrics returning JSON not text/plain) + 5 nits (links validation order, project update schema, redundant constraint, missing project notes endpoint, memory limit). All fixed in commit 4a92910. **Round 2:** 0 blockers, 3 quick-win nits (N+1 query in project notes, duplicated DB path default, unused aiosqlite dep). Fixed in commit 7cd40ce. Remaining nits deferred to follow-up (self-link prevention, non-root Dockerfile user, HTML sanitization, error path tests, metrics stub).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.