docs(legibility): write CONTRIBUTING.md with three walkthroughs and Testing section (DOC-4) #435

Closed
opened 2026-05-05 21:07:42 +02:00 by marcel · 1 comment
Owner

Part of #394 (Epic 2 — Documentation). Rubric checks: C5.1 (Major), C5.2 (Major), C5.3 (Major). Per Markus, this is the highest-leverage doc in the epic — three walkthroughs are the mental-model compression that lets Anja understand the system in an afternoon.

Problem

Newcomers need a single document that compresses "how to add things." Without it, every contribution starts with grep-archeology. The implementation rules currently live in CLAUDE.md files (LLM-targeted). They need a human-readable home, and the three walkthroughs (per #394 Decision Queue D4) are: add a domain, add an endpoint, add a SvelteKit route.

Scope

  1. Create /CONTRIBUTING.md at the repo root.

  2. Required H2 sections (each linkable from the Gitea TOC):

    • ## Walkthrough: Add a new domain — full vertical slice, worked example Tag:

      • Flyway migration (backend/src/main/resources/db/migration/V{n}__add_tag.sql)
      • Entity (@Entity, @Table, @Data/@Builder/@AllArgsConstructor/@NoArgsConstructor, @Schema(requiredMode = REQUIRED) on every always-populated field)
      • Repository (@Repository, extends JpaRepository)
      • Service (@Service, @RequiredArgsConstructor, @Transactional on writes only, never on reads)
      • Controller (@RestController, @RequirePermission, DomainException static factories)
      • DTO (input only; entities are response shape)
      • Regenerate TypeScript types: cd frontend && npm run generate:api
    • ## Walkthrough: Add an API endpoint to an existing domain — smaller scope, worked example Tag rename:

      • Add controller method with @RequirePermission
      • Add service method (transactional if write)
      • Update OpenAPI schema annotations
      • Regenerate TypeScript types
      • Add @WebMvcTest controller test + @ExtendWith(MockitoExtension.class) service test
    • ## Walkthrough: Add a new SvelteKit route (per Felix) — worked example: a tag detail page:

      • +page.server.ts load function
      • createApiClient(fetch) typed call
      • if (!result.response.ok) guard with getErrorMessage(code) from errors.ts
      • +page.svelte consumes via $props(), never fetch('/api/...') in onMount
      • Loading / empty / error / populated states (per CODESTYLE.md)
      • use:enhance for form actions
    • ## Testing (per Sara — gap not covered by other DOC-* tasks):

      • Test pyramid: Vitest unit · @WebMvcTest slices · Testcontainers integration · Playwright E2E
      • Commands: ./mvnw test · npm run test · npm run test:e2e · ./mvnw test -Dtest=ClassName
      • TDD red/green/refactor expectation
      • Regenerating frontend/e2e/.auth/user.json (run npm run test:e2e -- --headed once)
    • ## Code style — link to docs/STYLEGUIDE.md and CODESTYLE.md. Cover, with one-line each:

      • Backend layering: Controller → Service → Repository (no service touches another domain's repo)
      • Backend @Transactional: write-only, never on a class
      • Backend errors: DomainException static factories with ErrorCode enum
      • Frontend Svelte 5: $derived not $effect, SvelteMap/SvelteSet for reactive collections, keyed {#each}
      • Frontend errors: !result.response.ok + getErrorMessage(code)
    • ## Commit conventions and branching — link to COLLABORATING.md (Conventional Commits, atomic commits, feature-branch + PR workflow).

  3. After CONTRIBUTING.md is written, DOC-7 replaces the migrated CLAUDE.md sections with pointer comments.

References

  • Parent: epic(legibility): documentation — make the codebase self-explaining (#394)
  • Rubric: C5.1, C5.2, C5.3
  • Inputs (sources to migrate from): CLAUDE.md (root), backend/CLAUDE.md, frontend/CLAUDE.md, frontend/e2e/CLAUDE.md, .devcontainer/CLAUDE.md, import/CLAUDE.md
  • Existing docs (link, don't duplicate): docs/STYLEGUIDE.md, CODESTYLE.md, COLLABORATING.md
  • Worked example domain: tag/ (small, complete, full stack — backend tag/ package + frontend lib/tag/)

Acceptance criteria

  • CONTRIBUTING.md exists at the repo root.
  • Three walkthroughs each have an H2 heading (linkable in TOC).
  • Testing section covers all four test layers with run commands.
  • Behavioural test: a developer following Walkthrough 1 against current main produces a passing test for a new domain in ≤2 hours.
  • All rules referenced (not duplicated) from CLAUDE.md sources resolve to a heading after DOC-7 migration.
  • Rubric C5.1, C5.2, C5.3 PASS verified by reviewer.

Definition of Done

CONTRIBUTING.md is on main. Walkthrough 1 verified executable end-to-end. Rubric C5.1, C5.2, C5.3 PASS.

Part of #394 (Epic 2 — Documentation). Rubric checks: C5.1 (Major), C5.2 (Major), C5.3 (Major). Per Markus, this is the **highest-leverage doc in the epic** — three walkthroughs are the mental-model compression that lets Anja understand the system in an afternoon. ## Problem Newcomers need a single document that compresses "how to add things." Without it, every contribution starts with grep-archeology. The implementation rules currently live in CLAUDE.md files (LLM-targeted). They need a human-readable home, and the three walkthroughs (per #394 Decision Queue D4) are: **add a domain**, **add an endpoint**, **add a SvelteKit route**. ## Scope 1. Create `/CONTRIBUTING.md` at the repo root. 2. Required H2 sections (each linkable from the Gitea TOC): - **`## Walkthrough: Add a new domain`** — full vertical slice, worked example `Tag`: - Flyway migration (`backend/src/main/resources/db/migration/V{n}__add_tag.sql`) - Entity (`@Entity`, `@Table`, `@Data`/`@Builder`/`@AllArgsConstructor`/`@NoArgsConstructor`, `@Schema(requiredMode = REQUIRED)` on every always-populated field) - Repository (`@Repository`, extends `JpaRepository`) - Service (`@Service`, `@RequiredArgsConstructor`, `@Transactional` on writes only, never on reads) - Controller (`@RestController`, `@RequirePermission`, `DomainException` static factories) - DTO (input only; entities are response shape) - Regenerate TypeScript types: `cd frontend && npm run generate:api` - **`## Walkthrough: Add an API endpoint to an existing domain`** — smaller scope, worked example `Tag` rename: - Add controller method with `@RequirePermission` - Add service method (transactional if write) - Update OpenAPI schema annotations - Regenerate TypeScript types - Add `@WebMvcTest` controller test + `@ExtendWith(MockitoExtension.class)` service test - **`## Walkthrough: Add a new SvelteKit route`** (per Felix) — worked example: a tag detail page: - `+page.server.ts` `load` function - `createApiClient(fetch)` typed call - `if (!result.response.ok)` guard with `getErrorMessage(code)` from `errors.ts` - `+page.svelte` consumes via `$props()`, never `fetch('/api/...')` in `onMount` - Loading / empty / error / populated states (per CODESTYLE.md) - `use:enhance` for form actions - **`## Testing`** (per Sara — gap not covered by other DOC-* tasks): - Test pyramid: Vitest unit · `@WebMvcTest` slices · Testcontainers integration · Playwright E2E - Commands: `./mvnw test` · `npm run test` · `npm run test:e2e` · `./mvnw test -Dtest=ClassName` - TDD red/green/refactor expectation - Regenerating `frontend/e2e/.auth/user.json` (run `npm run test:e2e -- --headed` once) - **`## Code style`** — link to `docs/STYLEGUIDE.md` and `CODESTYLE.md`. Cover, with one-line each: - Backend layering: Controller → Service → Repository (no service touches another domain's repo) - Backend `@Transactional`: write-only, never on a class - Backend errors: `DomainException` static factories with `ErrorCode` enum - Frontend Svelte 5: `$derived` not `$effect`, `SvelteMap`/`SvelteSet` for reactive collections, keyed `{#each}` - Frontend errors: `!result.response.ok` + `getErrorMessage(code)` - **`## Commit conventions and branching`** — link to `COLLABORATING.md` (Conventional Commits, atomic commits, feature-branch + PR workflow). 3. After CONTRIBUTING.md is written, DOC-7 replaces the migrated CLAUDE.md sections with pointer comments. ## References - Parent: #394 - Rubric: C5.1, C5.2, C5.3 - Inputs (sources to migrate from): `CLAUDE.md` (root), `backend/CLAUDE.md`, `frontend/CLAUDE.md`, `frontend/e2e/CLAUDE.md`, `.devcontainer/CLAUDE.md`, `import/CLAUDE.md` - Existing docs (link, don't duplicate): `docs/STYLEGUIDE.md`, `CODESTYLE.md`, `COLLABORATING.md` - Worked example domain: `tag/` (small, complete, full stack — backend `tag/` package + frontend `lib/tag/`) ## Acceptance criteria - [ ] `CONTRIBUTING.md` exists at the repo root. - [ ] Three walkthroughs each have an H2 heading (linkable in TOC). - [ ] Testing section covers all four test layers with run commands. - [ ] **Behavioural test**: a developer following Walkthrough 1 against current `main` produces a passing test for a new domain in ≤2 hours. - [ ] All rules referenced (not duplicated) from CLAUDE.md sources resolve to a heading after DOC-7 migration. - [ ] Rubric C5.1, C5.2, C5.3 PASS verified by reviewer. ## Definition of Done CONTRIBUTING.md is on `main`. Walkthrough 1 verified executable end-to-end. Rubric C5.1, C5.2, C5.3 PASS.
marcel added this to the (deleted) milestone 2026-05-05 21:07:42 +02:00
marcel added the P0-criticaldocumentationlegibility labels 2026-05-05 21:07:48 +02:00
Author
Owner

Duplicate of #398. I created this in error before noticing #398 already existed. #398 carries the persona reviews and per-child Decision Queue; closing this in favor of the existing issue.

**Duplicate of #398.** I created this in error before noticing #398 already existed. #398 carries the persona reviews and per-child Decision Queue; closing this in favor of the existing issue.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#435