Introduces the SDD root: a v1.0.0 constitution and machine-readable AGENTS.md grounded in the project's real conventions; six EARS-aware persona spec-review checklists that cross-reference .claude/personas/; feature-spec/ADR/threat-model/ api-contract templates; a fully worked _example feature; a living RTM; and an adrs/ pointer that reuses the existing docs/adr/ archive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.2 KiB
AGENTS.md
Machine-readable rules for AI coding agents (Claude Code, Copilot, Cursor, …) working in this repository. Read this on every invocation. These are executable constraints, not aspirations. The full rationale lives in constitution.md and the docs it links — this file does not duplicate it, it points to it.
If anything here conflicts with the user's explicit instruction, the user wins. Otherwise, constitution > this file > convenience.
Stack & Versions
| Layer | Tech | Version |
|---|---|---|
| Backend | Spring Boot (Java, Maven, Jetty, JPA/Hibernate, Flyway, Spring Security, Session JDBC) | Boot 4.0.6 / Java 21 |
| API docs | springdoc-openapi (webmvc-ui), served at /v3/api-docs (dev profile only) |
— |
| Frontend | SvelteKit / Svelte | 2.60 / 5.43 |
| Frontend lang/style | TypeScript / Tailwind CSS / Paraglide i18n (de/en/es) | TS 5.9 / TW 4.1 |
| API client | openapi-fetch + openapi-typescript (types generated from the live spec) |
— |
| DB | PostgreSQL | 16 |
| Object storage | MinIO (S3-compatible) | — |
| Sidecars | ocr-service, nlp-service (Python / FastAPI) |
Python 3.11 |
| Tests | JUnit + Mockito + @WebMvcTest + Testcontainers (backend); Vitest + vitest-browser-svelte + Playwright (frontend); Pytest (services) |
— |
| Lint/format | ESLint 9 (+ eslint-plugin-boundaries) + Prettier; Semgrep (backend) |
— |
| CI | Gitea Actions (.gitea/workflows/) |
— |
App port 8080; management port 8081. Backend app id: org.raddatz.familienarchiv / 0.0.1-SNAPSHOT.
Architectural Constraints
- Controllers call services only — never a repository. (constitution §1.2)
- A service uses only its own domain's repository; reach other domains via their service. (constitution §1.3)
- A new backend domain goes in its own package AND is added to
ArchitectureTest's allow-lists in the same change. (constitution §1.7) - Frontend cross-domain imports are allowed only where
frontend/eslint.config.jspermits; otherwise move shared code to$lib/shared/. (constitution §1.4) - Never serialize a lazy-collection entity across the controller boundary — assemble a view in-transaction. (constitution §1.6 / ADR-036)
Person≠AppUser; do not add account guards to Person-domain operations. (constitution §1.5)- Every
POST/PUT/PATCH/DELETEendpoint has@RequirePermission(Permission.X). Use the enum, never@PreAuthorize. (constitution §2.1–2.2) - Throw only
DomainException.notFound/forbidden/conflict/internal()from services, each with anErrorCode. (CONTRIBUTING §Error handling) - Set
createdBy/updatedByfrom the session principal in the service — never bind them from a request body. (constitution §2.4) - Add an
@Schema(requiredMode = REQUIRED)to every always-populated field. (constitution §3.5) - Never introduce a new runtime dependency without an ADR in
Acceptedstatus. (constitution §5.1) - Render untrusted text with
{...}; never{@html}on user/import data. (constitution §2.5) - Build dates from ISO strings with a
T12:00:00suffix. (constitution §3.7)
Workflow Rules
- Always write a failing test before implementation code; confirm it fails, then make it pass, then refactor. (constitution §3.1)
- Run only the specific test file/class locally — never the full suite (it crashes the machine); leave the full sweep to CI.
- Run
npm run generate:api(infrontend/) after ANY backend model or endpoint change — most common cause of TS errors. - Run
npm run lintbefore every commit; a fresh frontend worktree needsnpm installfirst or the pre-commit hook fails. - When adding a new
ErrorCode, update all four sites at once (constitution §3.6). - One logical change per commit; reference the Gitea issue (
Closes #n/Refs #n) on the last line. - Create a git worktree for new issue work — never
git checkout -bin the main repo while another branch has in-flight work. Avoid+in worktree/branch names (breaks vitest browser mode). - Pull
mainas a separate explicit step before creating a branch. - Track work as Gitea issues (
http://192.168.178.71:3005, repomarcel/familienarchiv), not todo files. - Verify ADR and Flyway migration numbers against disk before using one — parallel worktrees make issue-body numbers go stale.
Do Not Touch
- Generated:
frontend/src/lib/generated/api.ts,frontend/src/lib/paraglide/,frontend/.svelte-kit/,frontend/build/,backend/target/. - Shipped Flyway migrations — add a new forward-only migration instead.
- An
AcceptedADR — supersede it with a new one. actions/(upload|download)-artifactversion — stays at@v3(ADR-014).- CI guard steps — do not remove/weaken without an ADR.
main— never commit directly; branch + PR only.- Worktree copies (
familienarchiv-*,.worktrees/) anddata/— never commit.
Spec-Driven Development
Before implementing a feature, read its spec at .specify/features/<name>/spec.md and its
contract at .specify/features/<name>/api-contract.yaml if present. The spec's EARS
requirements (REQ-NNN) are the contract; each maps to a test. Worked reference:
.specify/features/_example/. Full workflow:
SPEC_DRIVEN_DEVELOPMENT.md.