# 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<paths>()` 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<paths>()` 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.
