# Feature Specification: API-First Tooling Setup **Feature**: `005-api-first-tooling` **Created**: 2026-03-06 **Status**: Implemented **Source**: Migrated from spec/setup-tasks.md (setup task — infrastructure, not user-facing) ## User Scenarios & Testing ### Setup Story 1 - Backend OpenAPI Code Generation (Priority: P1) The development toolchain generates Java server interfaces and model classes from the OpenAPI spec so that the backend implementation always matches the API contract. **Why this priority**: Code generation from the spec is the foundation of API-first development. Without it, backend implementation can diverge from the contract. **Independent Test**: Run `./mvnw compile` and verify that generated sources appear in `target/generated-sources/openapi/`. **Acceptance Scenarios**: 1. **Given** the OpenAPI spec exists at `backend/src/main/resources/openapi/api.yaml`, **When** `./mvnw compile` is run, **Then** Java interfaces and model classes are generated into `target/generated-sources/openapi/` with packages `de.fete.adapter.in.web.api` and `de.fete.adapter.in.web.model`. 2. **Given** the generator is configured with `interfaceOnly: true`, **When** compilation completes, **Then** only interfaces (not implementations) are generated, keeping implementation separate from contract. --- ### Setup Story 2 - Frontend TypeScript Type Generation (Priority: P1) The development toolchain generates TypeScript types from the OpenAPI spec so that the frontend is always type-safe against the API contract. **Why this priority**: Type generation ensures frontend-backend contract alignment at compile time. **Independent Test**: Run `npm run generate:api` and verify that `frontend/src/api/schema.d.ts` is created with types matching the spec. **Acceptance Scenarios**: 1. **Given** `openapi-typescript` is installed as a devDependency and `openapi-fetch` as a dependency, **When** `npm run generate:api` is run, **Then** TypeScript types are generated into `frontend/src/api/schema.d.ts`. 2. **Given** the `dev` and `build` scripts include type generation as a pre-step, **When** `npm run dev` or `npm run build` is run, **Then** types are regenerated automatically before the build proceeds. --- ### Setup Story 3 - Minimal API Client (Priority: P2) A minimal API client using `openapi-fetch` is wired up so that frontend code can call the backend with full type safety. **Why this priority**: The client is needed before any user story can make API calls, but can be a thin wrapper initially. **Independent Test**: Verify `frontend/src/api/client.ts` exists and uses `createClient()` from `openapi-fetch`. **Acceptance Scenarios**: 1. **Given** the generated `schema.d.ts` exists, **When** a developer imports the API client, **Then** all request/response types are fully inferred from the OpenAPI spec. --- ### Setup Story 4 - Minimal OpenAPI Spec (Priority: P1) A minimal OpenAPI 3.1 spec exists at the canonical location and is sufficient to prove the tooling works end-to-end. **Why this priority**: The spec is the prerequisite for all code generation. It must exist before any other story can proceed. **Independent Test**: Run both generation steps (backend + frontend) and verify both succeed without errors. **Acceptance Scenarios**: 1. **Given** a minimal spec at `backend/src/main/resources/openapi/api.yaml`, **When** both generation steps run, **Then** both complete successfully and the project compiles cleanly (backend + frontend). --- ### Edge Cases - What happens when the OpenAPI spec contains a syntax error? Generation should fail with a clear error message. - What happens when the spec is updated with a breaking change? Generated types and interfaces reflect the change, causing compile errors that force the developer to update implementations. ## Requirements ### Functional Requirements - **FR-001**: `openapi-generator-maven-plugin` (v7.20.x, `spring` generator, `interfaceOnly: true`) MUST be configured in `backend/pom.xml`. - **FR-002**: A minimal OpenAPI 3.1 spec MUST exist at `backend/src/main/resources/openapi/api.yaml`. - **FR-003**: `./mvnw compile` MUST generate Java interfaces and model classes into `target/generated-sources/openapi/` with packages `de.fete.adapter.in.web.api` and `de.fete.adapter.in.web.model`. - **FR-004**: `openapi-typescript` MUST be installed as a devDependency in the frontend. - **FR-005**: `openapi-fetch` MUST be installed as a runtime dependency in the frontend. - **FR-006**: `npm run generate:api` MUST generate TypeScript types from the spec into `frontend/src/api/schema.d.ts`. - **FR-007**: Frontend `dev` and `build` scripts MUST include type generation as a pre-step. - **FR-008**: A minimal API client at `frontend/src/api/client.ts` MUST use `createClient()` from `openapi-fetch`. - **FR-009**: Both generation steps MUST succeed and the project MUST compile cleanly (backend + frontend). ### Key Entities - **OpenAPI Spec**: The single source of truth for the REST API contract, located at `backend/src/main/resources/openapi/api.yaml`. A living document that grows with each user story. - **Generated Sources**: Backend Java interfaces/models in `target/generated-sources/openapi/`; frontend TypeScript types in `frontend/src/api/schema.d.ts`. ## Success Criteria ### Measurable Outcomes - **SC-001**: `./mvnw compile` succeeds and generated sources exist in `target/generated-sources/openapi/`. - **SC-002**: `npm run generate:api` succeeds and `frontend/src/api/schema.d.ts` is created. - **SC-003**: Frontend `npm run dev` and `npm run build` automatically regenerate types before building. - **SC-004**: The project compiles cleanly end-to-end (backend + frontend) with the generated code. - **SC-005**: A working API client exists at `frontend/src/api/client.ts` using the generated types.