docs(geschichte): annotate GET /api/geschichten query parameters in OpenAPI spec (#794) #810

Merged
marcel merged 4 commits from feat/issue-794-geschichte-openapi-params into feat/issue-750-lesereisen-data-model 2026-06-12 08:44:04 +02:00
Owner

Closes #794

What changed

  • 3 new @WebMvcTest tests in GeschichteControllerTest: list_passesDocumentIdFilterToService, list_passesLimitToService, list_passesStatusFilterToService — pins existing routing behaviour that had no controller-level coverage (AC 5–7)
  • @Parameter annotations on all four query params of GeschichteController.list()status, personId, documentId, limit — with descriptions covering the permission-gated PUBLISHED override, DRAFT author-scoping, AND-filter semantics, and the default/≤0/cap edge cases (AC 1–4)
  • TypeScript types regeneratedapi.ts diff = 4 @description JSDoc lines added, zero type changes

Pre-work

Created two follow-up issues as recommended by reviewers:

  • #808GeschichteServiceTest: list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite (P2-medium/test)
  • #809GeschichteControllerTest: list_passesStatusDraftFilterToService (P3-later/test)

Manual verification required (ACs 1–4)

ACs 1–4 verify annotation content in /v3/api-docs — no automated test covers this at @WebMvcTest level. Verify by starting backend with dev profile and checking GET http://localhost:8080/v3/api-docspaths['/api/geschichten'].get.parameters has non-empty description on all four params.

Test plan

  • GeschichteControllerTest — 29/29 passing
  • Backend build clean (./mvnw clean package -DskipTests)
  • Manual: GET /v3/api-docs with dev profile — confirm 4 params have non-empty descriptions

Side fix

Added /src.main/ to frontend/.prettierignore — this untracked generated artefact was not covered by existing ignore patterns and blocked pre-commit hooks on this branch.

Closes #794 ## What changed - **3 new `@WebMvcTest` tests** in `GeschichteControllerTest`: `list_passesDocumentIdFilterToService`, `list_passesLimitToService`, `list_passesStatusFilterToService` — pins existing routing behaviour that had no controller-level coverage (AC 5–7) - **`@Parameter` annotations** on all four query params of `GeschichteController.list()` — `status`, `personId`, `documentId`, `limit` — with descriptions covering the permission-gated PUBLISHED override, DRAFT author-scoping, AND-filter semantics, and the default/≤0/cap edge cases (AC 1–4) - **TypeScript types regenerated** — `api.ts` diff = 4 `@description` JSDoc lines added, zero type changes ### Pre-work Created two follow-up issues as recommended by reviewers: - #808 — `GeschichteServiceTest: list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite` (P2-medium/test) - #809 — `GeschichteControllerTest: list_passesStatusDraftFilterToService` (P3-later/test) ### Manual verification required (ACs 1–4) ACs 1–4 verify annotation content in `/v3/api-docs` — no automated test covers this at `@WebMvcTest` level. Verify by starting backend with dev profile and checking `GET http://localhost:8080/v3/api-docs` → `paths['/api/geschichten'].get.parameters` has non-empty `description` on all four params. ## Test plan - [x] `GeschichteControllerTest` — 29/29 passing - [x] Backend build clean (`./mvnw clean package -DskipTests`) - [ ] Manual: `GET /v3/api-docs` with dev profile — confirm 4 params have non-empty descriptions ## Side fix Added `/src.main/` to `frontend/.prettierignore` — this untracked generated artefact was not covered by existing ignore patterns and blocked pre-commit hooks on this branch.
marcel added 4 commits 2026-06-12 07:51:26 +02:00
src.main/ is an untracked generated artefact that was not covered by
the existing ignore patterns, causing pre-commit lint failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds list_passesDocumentIdFilterToService, list_passesLimitToService and
list_passesStatusFilterToService — characterisation tests for existing
parameter routing that had no controller-level coverage (refs #794).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds @Parameter descriptions to status, personId, documentId, and limit
on GeschichteController.list() so Swagger UI shows semantics including the
permission-gated PUBLISHED override and DRAFT author-scoping for status,
the AND-filter semantics for personId, and the default/cap for limit (refs #794).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
chore(api): regenerate TypeScript types after GET /api/geschichten annotation
All checks were successful
CI / Unit & Component Tests (pull_request) Successful in 4m9s
CI / OCR Service Tests (pull_request) Successful in 23s
CI / Backend Unit Tests (pull_request) Successful in 4m48s
CI / fail2ban Regex (pull_request) Successful in 44s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m7s
09df6862c0
Adds @description JSDoc strings to status, personId, documentId and limit
query params in api.ts. Types (shapes) are unchanged — only description
strings added (refs #794).

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

👨‍💻 Felix Brandt — Senior Fullstack Developer

Verdict: Approved

I read every changed file at head 09df686. This is exactly the kind of small, disciplined PR I like: it does one thing (annotate four query params + pin the existing routing behaviour with tests) and does it cleanly.

What I checked

  • TDD evidence — the three new tests (list_passesDocumentIdFilterToService, list_passesLimitToService, list_passesStatusFilterToService) follow the existing AAA pattern in GeschichteControllerTest exactly. Each has one logical assertion path: stub → performverify. Names read as sentences. Good.
  • Naming@Parameter descriptions are intent-revealing and accurate against GeschichteService.list(): the ≤0→50 fallback (safeLimit = limit <= 0 ? DEFAULT_LIMIT : Math.min(limit, MAX_LIMIT)) and the currentUserHasBlogWrite() ? status : PUBLISHED override both match the prose. No drift between doc and code.
  • No business logic touched — the controller method body is unchanged; only annotations were added. Zero behavioural risk.
  • Generated api.ts — diff is 4 @description JSDoc lines, no type changes, exactly as the PR claims and the issue predicted.

Suggestions (non-blocking)

  • The three new tests assert only status().isOk() plus a verify(...). That's fine and consistent with the sibling personId test — but note they don't assert the response shape. That's acceptable here since the point is the routing passthrough, not serialization.
  • The status test verifies PUBLISHED passthrough; the DRAFT routing path (and the service-level override) are correctly deferred to #809 / #808. Splitting those out was the right call — keeps this PR atomic.

Clean, atomic, well-tested. No changes requested from me.

## 👨‍💻 Felix Brandt — Senior Fullstack Developer **Verdict: ✅ Approved** I read every changed file at head `09df686`. This is exactly the kind of small, disciplined PR I like: it does one thing (annotate four query params + pin the existing routing behaviour with tests) and does it cleanly. ### What I checked - **TDD evidence** — the three new tests (`list_passesDocumentIdFilterToService`, `list_passesLimitToService`, `list_passesStatusFilterToService`) follow the existing AAA pattern in `GeschichteControllerTest` exactly. Each has one logical assertion path: stub → `perform` → `verify`. Names read as sentences. Good. - **Naming** — `@Parameter` descriptions are intent-revealing and accurate against `GeschichteService.list()`: the ≤0→50 fallback (`safeLimit = limit <= 0 ? DEFAULT_LIMIT : Math.min(limit, MAX_LIMIT)`) and the `currentUserHasBlogWrite() ? status : PUBLISHED` override both match the prose. No drift between doc and code. - **No business logic touched** — the controller method body is unchanged; only annotations were added. Zero behavioural risk. - **Generated `api.ts`** — diff is 4 `@description` JSDoc lines, no type changes, exactly as the PR claims and the issue predicted. ### Suggestions (non-blocking) - The three new tests assert only `status().isOk()` plus a `verify(...)`. That's fine and consistent with the sibling `personId` test — but note they don't assert the *response shape*. That's acceptable here since the point is the routing passthrough, not serialization. - The `status` test verifies `PUBLISHED` passthrough; the DRAFT routing path (and the service-level override) are correctly deferred to #809 / #808. Splitting those out was the right call — keeps this PR atomic. Clean, atomic, well-tested. No changes requested from me.
Author
Owner

🏛️ Markus Keller — Application Architect

Verdict: Approved

A documentation-only PR over the controller boundary, with no structural change. From an architecture standpoint there is nothing to reverse and nothing to extract.

What I checked

  • No layer violations — controller still delegates to geschichteService.list(...); no repository reached into. The @Parameter annotations sit at the API boundary, which is exactly where contract documentation belongs.
  • Boundary respectedpersonIds == null ? List.of() : personIds normalization stays in the controller, the AND-filter sentinel logic stays in the service. The annotation prose documents the contract without leaking service internals (it describes the behaviour, not the 00000000-... sentinel implementation detail). Correct level of abstraction.
  • No new domain conceptGeschichte, GeschichteStatus, BLOG_WRITE all pre-exist. No GLOSSARY, ADR, or C4 diagram update is triggered by this change. I ran my doc-impact table against the diff: no migration, no new route, no new service/controller, no new ErrorCode/Permission. Nothing to flag.
  • Consistency — the PR follows the established inline @Parameter pattern (matching DocumentController/NotificationController) and deliberately avoids @Operation on the list method, preserving codebase-wide annotation consistency. This was the right judgment call.

Note (not a blocker)

The frontend/src.main/ side-fix is interesting: a stray untracked directory mirroring src/ (lib/routes/paraglide). Ignoring it in .prettierignore unblocks the hook, which is pragmatic. But that directory shouldn't exist at all — it smells like a misconfigured codegen output path. Worth a follow-up to find what produces it, but out of scope here and not blocking.

Boring, correct, well-bounded. Approved.

## 🏛️ Markus Keller — Application Architect **Verdict: ✅ Approved** A documentation-only PR over the controller boundary, with no structural change. From an architecture standpoint there is nothing to reverse and nothing to extract. ### What I checked - **No layer violations** — controller still delegates to `geschichteService.list(...)`; no repository reached into. The `@Parameter` annotations sit at the API boundary, which is exactly where contract documentation belongs. - **Boundary respected** — `personIds == null ? List.of() : personIds` normalization stays in the controller, the AND-filter sentinel logic stays in the service. The annotation prose documents the contract without leaking service internals (it describes the *behaviour*, not the `00000000-...` sentinel implementation detail). Correct level of abstraction. - **No new domain concept** — `Geschichte`, `GeschichteStatus`, `BLOG_WRITE` all pre-exist. No GLOSSARY, ADR, or C4 diagram update is triggered by this change. I ran my doc-impact table against the diff: no migration, no new route, no new service/controller, no new ErrorCode/Permission. Nothing to flag. - **Consistency** — the PR follows the established inline `@Parameter` pattern (matching `DocumentController`/`NotificationController`) and deliberately avoids `@Operation` on the list method, preserving codebase-wide annotation consistency. This was the right judgment call. ### Note (not a blocker) The `frontend/src.main/` side-fix is interesting: a stray untracked directory mirroring `src/` (lib/routes/paraglide). Ignoring it in `.prettierignore` unblocks the hook, which is pragmatic. But that directory shouldn't exist at all — it smells like a misconfigured codegen output path. Worth a follow-up to find what produces it, but out of scope here and not blocking. Boring, correct, well-bounded. Approved.
Author
Owner

🧪 Sara Holt — QA Engineer

Verdict: ⚠️ Approved with concerns

The three new @WebMvcTest tests are correctly placed (web-layer slice, not full @SpringBootTest), deterministic, and follow the existing AAA + factory-stub conventions. I'm approving — but I want to be honest about a coverage gap and a verification gap so nobody mistakes this PR for full coverage of the documented behaviour.

What's good

  • Right layer: @WebMvcTest(GeschichteController.class) with mocked GeschichteService — fast, isolated, no DB. Correct for controller routing verification.
  • @WithMockUser(authorities = "READ_ALL") is used consistently, matching the sibling tests.
  • Each test pins exactly one passthrough argument via eq(...) while using any() for the rest — clean isolation of the behaviour under test.

Concerns (not blockers — tracked)

  1. The tests document routing, not the documented behaviour. The @Parameter prose makes three security-relevant claims: (a) non-BLOG_WRITE callers always get PUBLISHED, (b) BLOG_WRITE + DRAFT is author-scoped, (c) limit ≤ 0 → 50, cap 200. None of these are asserted by this PR's tests — they only verify the controller forwards the raw value to the service. The actual override/clamp logic lives in GeschichteService.list() and has no regression guard. This is correctly captured in #808 (service DRAFT override) — that's the most security-sensitive untested path. I'd push for #808 to be P2, not left to drift.
  2. limit edge cases untested anywhere. list_passesLimitToService proves limit=5 reaches the service. It does not prove limit=0 → 50, limit=-1 → 50, or limit=10000 → 200. Those are pure functions in the service — cheap unit tests in GeschichteServiceTest. Recommend a follow-up alongside #808 (the issue's "limit description includes default/fallback/cap" AC is documented but not test-pinned).
  3. AC 1–4 have no automated verification. The PR correctly flags this: the /v3/api-docs description content is only checkable manually. That's an accepted limitation of @WebMvcTest (SpringDoc isn't on the slice), but it means the "non-empty description" ACs ride on a manual checkbox that is still unchecked in the PR body. Please complete that manual GET /v3/api-docs check before merge.

No flaky tests, no H2, no wrong-layer tests. The scope is honest. Approved with the above tracked.

## 🧪 Sara Holt — QA Engineer **Verdict: ⚠️ Approved with concerns** The three new `@WebMvcTest` tests are correctly placed (web-layer slice, not full `@SpringBootTest`), deterministic, and follow the existing AAA + factory-stub conventions. I'm approving — but I want to be honest about a coverage gap and a verification gap so nobody mistakes this PR for full coverage of the documented behaviour. ### What's good - Right layer: `@WebMvcTest(GeschichteController.class)` with mocked `GeschichteService` — fast, isolated, no DB. Correct for controller routing verification. - `@WithMockUser(authorities = "READ_ALL")` is used consistently, matching the sibling tests. - Each test pins exactly one passthrough argument via `eq(...)` while using `any()` for the rest — clean isolation of the behaviour under test. ### Concerns (not blockers — tracked) 1. **The tests document *routing*, not the documented *behaviour*.** The `@Parameter` prose makes three security-relevant claims: (a) non-`BLOG_WRITE` callers always get `PUBLISHED`, (b) `BLOG_WRITE` + DRAFT is author-scoped, (c) `limit ≤ 0 → 50`, cap 200. **None of these are asserted by this PR's tests** — they only verify the controller forwards the raw value to the service. The actual override/clamp logic lives in `GeschichteService.list()` and has *no* regression guard. This is correctly captured in **#808** (service DRAFT override) — that's the most security-sensitive untested path. I'd push for #808 to be P2, not left to drift. 2. **`limit` edge cases untested anywhere.** `list_passesLimitToService` proves `limit=5` reaches the service. It does **not** prove `limit=0 → 50`, `limit=-1 → 50`, or `limit=10000 → 200`. Those are pure functions in the service — cheap unit tests in `GeschichteServiceTest`. Recommend a follow-up alongside #808 (the issue's "limit description includes default/fallback/cap" AC is documented but not test-pinned). 3. **AC 1–4 have no automated verification.** The PR correctly flags this: the `/v3/api-docs` description content is only checkable manually. That's an accepted limitation of `@WebMvcTest` (SpringDoc isn't on the slice), but it means the "non-empty description" ACs ride on a manual checkbox that is still unchecked in the PR body. Please complete that manual `GET /v3/api-docs` check before merge. No flaky tests, no H2, no wrong-layer tests. The scope is honest. Approved with the above tracked.
Author
Owner

🛡️ Nora "NullX" Steiner — Application Security Engineer

Verdict: ⚠️ Approved with concerns

No vulnerability introduced — this PR adds annotations and tests, touching no auth logic. But documenting a security-relevant access-control behaviour without a regression test pinning it is a security smell I want on record.

What I checked

  • No new attack surface. GET /api/geschichten was already @RequestMapping-restricted to GET via @GetMapping. Annotations don't change the method, the permission model, or the SecurityConfig. No injection vector — descriptions are static string literals, not interpolated user input.
  • The DRAFT override is correctly modelled in the service (currentUserHasBlogWrite() ? status : PUBLISHED), and getById correctly returns NOT_FOUND (not FORBIDDEN) for DRAFTs to avoid leaking existence. Good design — the override is a genuine authorization boundary: a READ_ALL reader who passes ?status=DRAFT is silently downgraded to PUBLISHED and cannot enumerate other users' unpublished stories.

Concern (smell, not a confirmed vuln)

That authorization boundary — "non-BLOG_WRITE callers can never receive DRAFT regardless of the status they pass" — is now documented in the public OpenAPI spec but has no test asserting it holds. This is precisely the failure mode in my playbook: a future maintainer reads effective = currentUserHasBlogWrite() ? status : PUBLISHED, thinks "why ignore the caller's status?", and removes it "to simplify" — turning an IDOR-style enumeration guard off, with no test going red.

GeschichteControllerTest only proves the controller forwards status verbatim (list_passesStatusFilterToService asserts PUBLISHED passthrough). The override happens one layer down and is untested.

  • #808 (list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite) is exactly the regression test I'd require. From my chair this isn't "P2-medium nice-to-have" — a documented access-control rule with zero test coverage is a security gap. I'd bump it and land it soon, ideally before anyone touches GeschichteService.list() again.

Approving this PR (it doesn't introduce the gap, it inherits it), but flagging #808 as the security-priority follow-up.

## 🛡️ Nora "NullX" Steiner — Application Security Engineer **Verdict: ⚠️ Approved with concerns** No vulnerability introduced — this PR adds annotations and tests, touching no auth logic. But documenting a security-relevant access-control behaviour *without a regression test pinning it* is a security smell I want on record. ### What I checked - **No new attack surface.** `GET /api/geschichten` was already `@RequestMapping`-restricted to GET via `@GetMapping`. Annotations don't change the method, the permission model, or the SecurityConfig. No injection vector — descriptions are static string literals, not interpolated user input. - **The DRAFT override is correctly modelled in the service** (`currentUserHasBlogWrite() ? status : PUBLISHED`), and `getById` correctly returns `NOT_FOUND` (not `FORBIDDEN`) for DRAFTs to avoid leaking existence. Good design — the override is a genuine authorization boundary: a `READ_ALL` reader who passes `?status=DRAFT` is silently downgraded to `PUBLISHED` and cannot enumerate other users' unpublished stories. ### Concern (smell, not a confirmed vuln) That authorization boundary — "non-`BLOG_WRITE` callers can never receive DRAFT regardless of the `status` they pass" — is now **documented in the public OpenAPI spec** but has **no test asserting it holds**. This is precisely the failure mode in my playbook: a future maintainer reads `effective = currentUserHasBlogWrite() ? status : PUBLISHED`, thinks "why ignore the caller's status?", and removes it "to simplify" — turning an IDOR-style enumeration guard off, with no test going red. `GeschichteControllerTest` only proves the controller forwards `status` verbatim (`list_passesStatusFilterToService` asserts `PUBLISHED` passthrough). The override happens one layer down and is untested. - **#808** (`list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite`) is exactly the regression test I'd require. From my chair this isn't "P2-medium nice-to-have" — a documented access-control rule with zero test coverage is a security gap. I'd bump it and land it soon, ideally before anyone touches `GeschichteService.list()` again. Approving this PR (it doesn't introduce the gap, it inherits it), but flagging #808 as the security-priority follow-up.
Author
Owner

🎨 Leonie Voss — UX & Accessibility

Verdict: Approved (LGTM — nothing in my domain)

This PR is backend OpenAPI annotations, three controller tests, a .prettierignore entry, and a regenerated api.ts whose only diff is JSDoc @description comments. There is no .svelte file, no route, no markup, no CSS, no user-facing string, and no i18n key in the diff.

What I checked (and found nothing to flag)

  • No new or changed UI component, page, or visual region.
  • No color, typography, spacing, or contrast change.
  • No touch-target, focus-indicator, or ARIA surface affected.
  • No user-facing error message or getErrorMessage() mapping touched — the param descriptions are developer-facing Swagger/spec documentation, never rendered to an end user.

The only thing that could be user-adjacent is the generated api.ts, but those @description lines are IDE/devtool documentation, not runtime UI copy.

Nothing for me here. Approved.

## 🎨 Leonie Voss — UX & Accessibility **Verdict: ✅ Approved (LGTM — nothing in my domain)** This PR is backend OpenAPI annotations, three controller tests, a `.prettierignore` entry, and a regenerated `api.ts` whose only diff is JSDoc `@description` comments. There is no `.svelte` file, no route, no markup, no CSS, no user-facing string, and no i18n key in the diff. ### What I checked (and found nothing to flag) - No new or changed UI component, page, or visual region. - No color, typography, spacing, or contrast change. - No touch-target, focus-indicator, or ARIA surface affected. - No user-facing error message or `getErrorMessage()` mapping touched — the param descriptions are developer-facing Swagger/spec documentation, never rendered to an end user. The only thing that *could* be user-adjacent is the generated `api.ts`, but those `@description` lines are IDE/devtool documentation, not runtime UI copy. Nothing for me here. Approved.
Author
Owner

⚙️ Tobias Wendt — DevOps & Platform Engineer

Verdict: Approved

No infrastructure surface in this PR — no Compose file, no CI workflow, no Dockerfile, no env var, no image tag, no secret. The diff is Java annotations, Java tests, a regenerated api.ts, and one .prettierignore line. From an ops standpoint this is a no-op deploy: same JAR shape, same endpoints, same ports.

The one thing in my lane: frontend/.prettierignore

The /src.main/ entry unblocks the pre-commit hook (cd frontend && npm run lint) on this branch, where a stray untracked frontend/src.main/ directory was tripping Prettier. Confirmed it's not tracked in git (git ls-files shows nothing), so this is purely a local/hook concern — correct fix, correct file, zero production impact.

Note (not a blocker)

That src.main/ directory existing at all is the real smell — it mirrors src/ (lib, routes, paraglide) and looks like an accidental codegen output, possibly from a misconfigured generate:api or a path typo (src.main vs src/main). Ignoring it stops the bleeding; finding and fixing the generator that emits it is the actual fix. Worth a quick follow-up issue so it doesn't quietly accumulate on every dev's machine. Out of scope for this PR.

CI impact: three extra fast @WebMvcTest methods — negligible pipeline time. Approved.

## ⚙️ Tobias Wendt — DevOps & Platform Engineer **Verdict: ✅ Approved** No infrastructure surface in this PR — no Compose file, no CI workflow, no Dockerfile, no env var, no image tag, no secret. The diff is Java annotations, Java tests, a regenerated `api.ts`, and one `.prettierignore` line. From an ops standpoint this is a no-op deploy: same JAR shape, same endpoints, same ports. ### The one thing in my lane: `frontend/.prettierignore` The `/src.main/` entry unblocks the pre-commit hook (`cd frontend && npm run lint`) on this branch, where a stray untracked `frontend/src.main/` directory was tripping Prettier. Confirmed it's **not tracked in git** (`git ls-files` shows nothing), so this is purely a local/hook concern — correct fix, correct file, zero production impact. ### Note (not a blocker) That `src.main/` directory existing at all is the real smell — it mirrors `src/` (lib, routes, paraglide) and looks like an accidental codegen output, possibly from a misconfigured `generate:api` or a path typo (`src.main` vs `src/main`). Ignoring it stops the bleeding; finding and fixing the generator that emits it is the actual fix. Worth a quick follow-up issue so it doesn't quietly accumulate on every dev's machine. Out of scope for this PR. CI impact: three extra fast `@WebMvcTest` methods — negligible pipeline time. Approved.
Author
Owner

Implementation verification — Felix Brandt

All five reviewers approved with no code changes requested. I ran the final checks at head 09df686:

Automated checks

  • GeschichteControllerTest — 29/29 passing (includes the three new routing tests from this PR)
  • ./mvnw clean package -DskipTests — BUILD SUCCESS, JAR built cleanly

Open concerns from reviewers

Concern Owner Status
Manual GET /v3/api-docs check (Sara — unchecked checkbox in PR body) Manual verification Pending — requires backend running with dev profile
#808list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite (Sara + Nora, security-priority) Follow-up issue 🔖 Tracked as P2
#809list_passesStatusDraftFilterToService (Sara) Follow-up issue 🔖 Tracked as P3
src.main/ stray directory origin (Markus + Tobias) Follow-up investigation 🔖 Worth a quick issue

Branch status

Branch feat/issue-794-geschichte-openapi-params is already pushed and up to date with remote. No new commits were needed — the PR was complete as submitted.

Suggested next step: complete the manual /v3/api-docs check (start backend with --spring.profiles.active=dev, confirm all four parameters[].description fields are non-empty), then merge.

## Implementation verification — Felix Brandt All five reviewers approved with no code changes requested. I ran the final checks at head `09df686`: ### Automated checks ✅ - **`GeschichteControllerTest`** — 29/29 passing (includes the three new routing tests from this PR) - **`./mvnw clean package -DskipTests`** — BUILD SUCCESS, JAR built cleanly ### Open concerns from reviewers | Concern | Owner | Status | |---------|-------|--------| | Manual `GET /v3/api-docs` check (Sara — unchecked checkbox in PR body) | Manual verification | ⏳ Pending — requires backend running with `dev` profile | | #808 — `list_withDraftRequest_returnsPublished_whenCallerLacksBlogWrite` (Sara + Nora, security-priority) | Follow-up issue | 🔖 Tracked as P2 | | #809 — `list_passesStatusDraftFilterToService` (Sara) | Follow-up issue | 🔖 Tracked as P3 | | `src.main/` stray directory origin (Markus + Tobias) | Follow-up investigation | 🔖 Worth a quick issue | ### Branch status Branch `feat/issue-794-geschichte-openapi-params` is already pushed and up to date with remote. No new commits were needed — the PR was complete as submitted. **Suggested next step:** complete the manual `/v3/api-docs` check (start backend with `--spring.profiles.active=dev`, confirm all four `parameters[].description` fields are non-empty), then merge.
marcel merged commit 09df6862c0 into feat/issue-750-lesereisen-data-model 2026-06-12 08:44:04 +02:00
marcel deleted branch feat/issue-794-geschichte-openapi-params 2026-06-12 08:44:05 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#810