porchlight/CLAUDE.md
2026-06-29 09:18:37 +02:00

155 lines
6.5 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Format
make reformat # uv run ruff format src/ tests/
# Lint (with auto-fix)
make lint # uv run ruff check src/ tests/ --fix
# Type checking
make typecheck # uv run ty check src/
# Tests
make test # uv run python -m pytest -v
uv run pytest tests/test_foo.py::test_specific # single test
# All checks
make check
# Dev server
OIDC_OP_ISSUER=http://localhost:8000 OIDC_OP_DEBUG=true \
uv run uvicorn porchlight.app:create_app \
--factory --host 127.0.0.1 --port 8000 --reload --reload-dir src
```
### End-to-end tests (Playwright/Node)
```bash
# One-time setup
cd tests/e2e && npm install && npm run setup && cd ../..
# Run e2e tests (starts/stops the server automatically)
./tests/e2e/run.sh
# Run a specific spec
./tests/e2e/run.sh tests/e2e/login.spec.js
# Run with visible browser
E2E_HEADLESS=0 ./tests/e2e/run.sh
```
## Architecture
Porchlight is an OpenID Connect (OIDC) Provider + user management app built on **FastAPI** with **idpyoidc** for the OIDC protocol layer. UI is server-side **Jinja2** templates with **HTMX** for interactivity. Storage defaults to **SQLite** via `aiosqlite`.
### Request flow
```
Browser/RP → FastAPI routes → Service classes → Repository layer → SQLite
idpyoidc (OIDC protocol)
```
### Module layout
- `src/porchlight/app.py` — FastAPI app factory (`create_app()`), lifespan, middleware stack
- `src/porchlight/config.py` — Settings loaded from env vars (`OIDC_OP_*` prefix) and optional TOML file
- `src/porchlight/models.py` — Pydantic domain models (`User`, `WebAuthnCredential`, `MagicLink`, `Consent`)
- `src/porchlight/validation.py` — Form-validation models (`ProfileUpdate` with email/phone/URL validation)
- `src/porchlight/dependencies.py` — FastAPI dependency injection helpers
- `src/porchlight/csrf.py` — Synchronizer-token CSRF middleware (exempt: `/token`, `/userinfo`)
- `src/porchlight/authn/` — Password (`argon2`) and WebAuthn (`fido2`) authentication services + routes
- `src/porchlight/manage/` — Authenticated user credential & profile management routes
- `src/porchlight/admin/` — Admin user management routes (user list, invite creation, profile editing)
- `src/porchlight/invite/` — Magic-link invitation service (proquint tokens, time-limited)
- `src/porchlight/oidc/` — OIDC endpoints (discovery, JWKS, `/authorization`, `/token`, `/userinfo`)
- `src/porchlight/store/` — Repository pattern: `protocols.py` defines interfaces; `sqlite/` has the concrete implementation; `mongodb/` is a stub
- `src/porchlight/cli.py` — Typer CLI (`create-invite`, `initial-admin`)
### Storage layer
`store/protocols.py` defines `UserRepository`, `CredentialRepository`, `MagicLinkRepository`, and `ConsentRepository` as Protocol classes. The SQLite implementation lives in `store/sqlite/repositories.py`. Migrations run automatically on startup from `store/sqlite/migrations/*.sql`.
### Configuration
All settings use the `OIDC_OP_` env-var prefix (see `config.py`). Key vars:
| Variable | Notes |
|---|---|
| `OIDC_OP_ISSUER` | **Required.** Must match the public-facing URL. |
| `OIDC_OP_SESSION_SECRET` | Session signing key |
| `OIDC_OP_DEBUG` | Enables Swagger UI |
| `OIDC_OP_SQLITE_PATH` | DB file path (default `data/oidc_op.db`) |
| `OIDC_OP_CONFIG_FILE` | Optional TOML file for clients and advanced config |
OIDC relying parties (clients) are defined in the TOML config file under `[clients.<id>]`.
### Test fixtures
`tests/conftest.py` provides:
- `settings` — in-memory SQLite, test issuer
- `client` — async `httpx.AsyncClient` with ASGI transport
- CSRF token extraction helper
Unit and integration tests use in-memory SQLite; e2e tests use a seeded file-based DB (`tests/e2e/setup_db.py`).
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:6cd5cc61 -->
## Beads Issue Tracker
This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
### Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
```
### Rules
- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
- Run `bd prime` for detailed command reference and session close protocol
- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
**Architecture in one line:** issues live in a local Dolt DB; sync uses `refs/dolt/data` on your git remote; `.beads/issues.jsonl` is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
## Agent Context Profiles
The managed Beads block is task-tracking guidance, not permission to override repository, user, or orchestrator instructions.
- **Conservative (default)**: Use `bd` for task tracking. Do not run git commits, git pushes, or Dolt remote sync unless explicitly asked. At handoff, report changed files, validation, and suggested next commands.
- **Minimal**: Keep tool instruction files as pointers to `bd prime`; use the same conservative git policy unless active instructions say otherwise.
- **Team-maintainer**: Only when the repository explicitly opts in, agents may close beads, run quality gates, commit, and push as part of session close. A current "do not commit" or "do not push" instruction still wins.
## Session Completion
This protocol applies when ending a Beads implementation workflow. It is subordinate to explicit user, repository, and orchestrator instructions.
1. **File issues for remaining work** - Create beads for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **Handle git/sync by active profile**:
```bash
# Conservative/minimal/default: report status and proposed commands; wait for approval.
git status
# Team-maintainer opt-in only, unless current instructions forbid it:
git pull --rebase
git push
git status
```
5. **Hand off** - Summarize changes, validation, issue status, and any blocked sync/commit/push step
**Critical rules:**
- Explicit user or orchestrator instructions override this Beads block.
- Do not commit or push without clear authority from the active profile or the current user request.
- If a required sync or push is blocked, stop and report the exact command and error.
<!-- END BEADS INTEGRATION -->