{% raw %} # Development workflow How a change moves from understanding to shipped. The workflow is ordered by data flow because every feature is one data source fanning out into several consumers; the failure mode is updating one consumer while forgetting a connected one. See also [Architecture overview](/docs/architecture.html) and [Conventions and rules](/docs/architecture-conventions.html). > Audience: administrators and maintainers. These pages are hidden from members and guests, in the sidebar, the search index, and the documentation export. ## The feature workflow 1. **Understand.** Read the router for the area (a flat `routers/{area}.py`, or the leaf inside the `routers/{area}/` package that owns the endpoint), the template, the test file, and the matching nested `CLAUDE.md` before writing. Trace the existing input model, router, data helper, and response. 2. **Data layer.** Add query and batch helpers in the `database/` package (never inline N+1). Add the Pydantic `Form` model to `models.py` and the `*Out` response model to the `schemas/` package. Schema auto-syncs via `dataset`; add indexes in `init_db()` with `CREATE INDEX IF NOT EXISTS`. 3. **Server layer.** Write the handler with the right guard (`get_current_user` for public reads, `require_user` for member POSTs, `require_admin` for admin). Declare specific routes before catch-alls. Return HTML and JSON from one handler via `respond(..., model=XOut)`. Register any new router in `main.py`. 4. **View layer.** Import the shared `templates`, extend `base.html`, put page CSS in `{% block extra_head %}` and page JS in `{% block extra_js %}`, and reuse partials and globals. 5. **Agent and docs layer (the most-forgotten step).** If the route is something a user could ask the assistant to do, add an `Action` to the Devii catalog. Add an `endpoint()` entry to the `docs_api/` package, and a prose page to `DOCS_PAGES` where relevant. Set SEO context for any new public page. 6. **Document and validate.** Update the documentation trio, then run the validation gates below. ## The four faces One handler is HTML, JSON, a Devii tool, and an API-docs entry at once. After touching a route, ask of each face whether it needs updating: | Face | Where | Most-forgotten symptom | |------|-------|------------------------| | HTML | the Jinja template | route added but page not rendered | | JSON | the `*Out` schema in the `schemas/` package | new context key silently dropped from JSON | | Devii tool | the catalog `Action` | feature exists for humans but is invisible to the assistant | | API docs | `endpoint()` in the `docs_api/` package | endpoint undocumented | ## The documentation set Two kinds of files are kept current, each with a distinct role: - **`README.md`** is product-facing. Update it when routes, config or env vars, dependencies, or user-visible features change. No development process, no begging, no emoticons. - **`CLAUDE.md`** is split by scope: the root `CLAUDE.md` holds cross-cutting rules and conventions (update it only when a new architectural rule, convention, or workflow step is introduced, not per feature), while a nested `CLAUDE.md` inside a subsystem directory (e.g. `devplacepy/services/devii/CLAUDE.md`) holds that subsystem's domain-specific mechanics, helpers, pitfalls, and cross-layer wiring - it is loaded automatically only when a file in that directory is touched, so update the one nearest the code you changed. This Architecture section in the in-app docs is the browsable, admin-facing reflection of that set: it explains the design and the process, while the `CLAUDE.md` files remain the repository source of truth. ## Validation gates Run these before considering a change done: - **Per-language validation:** check the syntax and structure of each touched language (Python compiles and imports, JavaScript parses, CSS braces and HTML tags balance). - **Clean import:** `python -c "from devplacepy.main import app"` must import without error. - **No em-dash:** grep the touched files for the long dash and its HTML entity; both are forbidden. ## Testing Correctness is verified by the suite in `tests/`, and load behavior by Locust. Every user-facing feature requires an end-to-end Playwright test. The rules, the fixture stack, and the `make` targets are documented in the [Testing overview](/docs/testing.html) section. Do not run the test suite during routine development unless explicitly requested; validate with a clean import and per-language checks instead. {% endraw %}