T-1: initialize monorepo structure with backend and frontend scaffolds

Backend: Spring Boot 3.5.11 on Java 25, Maven with wrapper, hexagonal
architecture package layout (domain/application/adapter/config), health
endpoint with integration test. Originally planned for Spring Boot 4.0
but pivoted due to massive package reorganization in 4.0 (see addenda
in research and plan docs).

Frontend: Vue 3 scaffolded via create-vue with TypeScript, Vue Router,
Vitest, ESLint, Prettier. Pivoted from Svelte due to ecosystem maturity
concerns (broken router ecosystem for Svelte 5).

Also: extended .gitignore for Java/Maven and Node/Vue artifacts, updated
CLAUDE.md with tech stack, build commands, agent documentation sections,
and document integrity rule.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 01:32:18 +01:00
parent 7b460dd322
commit a55174b323
58 changed files with 8933 additions and 9 deletions

View File

@@ -0,0 +1,179 @@
# Implementation Plan: T-1 — Initialize Monorepo Structure
## Context
This is the first setup task for the fete project — a privacy-focused, self-hostable PWA for event announcements and RSVPs. The repository currently contains only documentation, specs, and Ralph loop infrastructure. No application code exists yet.
The tech stack was decided during the research phase (see `docs/agents/research/2026-03-04-t1-monorepo-setup.md`):
- **Backend:** Java 25 (latest LTS), ~~Spring Boot 4.0~~ Spring Boot 3.5.11 (see addendum), Maven, hexagonal architecture, base package `de.fete`
- **Java installation:** Via SDKMAN! (`sdk install java 25-open`), no system-level JDK
- **Frontend:** Vue 3, Vite, TypeScript, Vue Router, Vitest
- **Node.js:** Latest LTS (24)
## Phase 1: Backend Scaffold
### 1.1 Create directory structure
Create `backend/` with the hexagonal architecture package layout:
```
backend/
├── pom.xml
├── mvnw, mvnw.cmd
├── .mvn/wrapper/maven-wrapper.properties
└── src/
├── main/
│ ├── java/de/fete/
│ │ ├── FeteApplication.java
│ │ ├── domain/
│ │ │ ├── model/package-info.java
│ │ │ └── port/
│ │ │ ├── in/package-info.java
│ │ │ └── out/package-info.java
│ │ ├── application/
│ │ │ └── service/package-info.java
│ │ ├── adapter/
│ │ │ ├── in/web/package-info.java
│ │ │ └── out/persistence/package-info.java
│ │ └── config/package-info.java
│ └── resources/
│ └── application.properties
└── test/
└── java/de/fete/
└── FeteApplicationTest.java
```
### 1.2 Create `pom.xml`
- Parent: `spring-boot-starter-parent` (latest 4.0.x, or fall back to 3.5.x if 4.0 is unavailable)
- GroupId: `de.fete`, ArtifactId: `fete-backend`
- Java version: 25
- Dependencies:
- `spring-boot-starter-web` (embedded Tomcat, Spring MVC)
- `spring-boot-starter-test` (scope: test)
- NO JPA yet (deferred to T-4)
### 1.3 Add Maven Wrapper
Generate via `mvn wrapper:wrapper` (or manually create the wrapper files). This ensures contributors and Docker builds don't need a Maven installation.
### 1.4 Create application class
`FeteApplication.java` in `de.fete` — minimal `@SpringBootApplication` with `main()`.
### 1.5 Create a minimal health endpoint
A simple `@RestController` in `adapter/in/web/` that responds to `GET /health` with HTTP 200 and a JSON body like `{"status": "ok"}`. This satisfies:
- The user's requirement that a REST request returns 200
- Prepares for T-2's health-check requirement
### 1.6 Create package-info.java markers
One per leaf package, documenting the package's purpose and architectural constraints. These serve as Git directory markers AND developer documentation.
### 1.7 Write integration test
`FeteApplicationTest.java`:
- `@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)`
- Test 1: Spring context loads successfully
- Test 2: HTTP GET to `/health` returns 200
### 1.8 Verify backend
- [x] `cd backend && ./mvnw test` — tests pass (context loads + health endpoint returns 200)
- [x] `cd backend && ./mvnw spring-boot:run` — app starts on port 8080
- [x] `curl http://localhost:8080/health` — returns 200 with `{"status": "ok"}`
## Phase 2: Frontend Scaffold
### 2.1 Scaffold Vue project
Run `npm create vue@latest` in `frontend/` with these options:
- TypeScript: Yes
- Vue Router: Yes
- Pinia: No
- Vitest: Yes
- ESLint: Yes
- Prettier: Yes
- E2E: No
If the interactive prompts can't be automated, create the project manually based on the `create-vue` template output.
### 2.2 Add `composables/` directory
Create `src/composables/` (empty, with a `.gitkeep` or initial placeholder) — convention for Composition API composables needed later.
### 2.3 Verify frontend builds and tests
- [x] `cd frontend && npm install`
- [x] `cd frontend && npm run build` — builds successfully
- [x] `cd frontend && npm run test:unit` — Vitest runs (sample test passes)
### 2.4 Verify via browser
- [x] `cd frontend && npm run dev` — starts dev server
- [x] Use `browser-interactive-testing` skill to visit the dev server URL and verify the page loads
## Phase 3: Shared Files
### 3.1 Update `.gitignore`
Extend the existing `.gitignore` with sections for:
- Java/Maven (target/, *.class, *.jar, Maven release files, crash logs)
- Node.js/Vue/Vite (node_modules/, dist/, build/, vite temp files)
- Environment files (.env, .env.* but NOT .env.example)
- Editor swap files (*.swp, *.swo, *~)
- Spring Boot (.springBeans, .sts4-cache)
Keep existing entries (IDE, OS, Claude settings) intact.
### 3.2 Verify .gitignore
Run `git status` after building both projects to confirm build artifacts are properly ignored.
- [x] `git status` shows no `target/`, `node_modules/`, `dist/`, or other build artifacts
## Verification Checklist (Done Criteria)
### Backend
- [x] `cd backend && ./mvnw test` passes (integration test: context loads + GET /health → 200)
- [x] `cd backend && ./mvnw spring-boot:run` starts successfully
- [x] `curl http://localhost:8080/health` returns HTTP 200
- [x] Hexagonal package structure exists with package-info.java markers
### Frontend
- [x] `cd frontend && npm run build` succeeds
- [x] `cd frontend && npm run test:unit` runs and passes
- [x] Browser verification via `browser-interactive-testing` skill confirms page loads
### Shared
- [x] `.gitignore` covers Java/Maven + Node/Vue artifacts
- [x] `git status` shows no unintended tracked build artifacts
- [x] T-1 acceptance criteria from `spec/setup-tasks.md` are met
## Files to Create/Modify
**Create:**
- `backend/pom.xml`
- `backend/mvnw`, `backend/mvnw.cmd`, `backend/.mvn/wrapper/maven-wrapper.properties`
- `backend/src/main/java/de/fete/FeteApplication.java`
- `backend/src/main/java/de/fete/adapter/in/web/HealthController.java`
- `backend/src/main/java/de/fete/domain/model/package-info.java`
- `backend/src/main/java/de/fete/domain/port/in/package-info.java`
- `backend/src/main/java/de/fete/domain/port/out/package-info.java`
- `backend/src/main/java/de/fete/application/service/package-info.java`
- `backend/src/main/java/de/fete/adapter/in/web/package-info.java`
- `backend/src/main/java/de/fete/adapter/out/persistence/package-info.java`
- `backend/src/main/java/de/fete/config/package-info.java`
- `backend/src/main/resources/application.properties`
- `backend/src/test/java/de/fete/FeteApplicationTest.java`
- `frontend/` (entire scaffolded project via create-vue)
**Modify:**
- `.gitignore` (extend with Java/Maven + Node/Vue sections)
## Addendum: Spring Boot 4.0 → 3.5 Pivot
During implementation, Spring Boot 4.0.3 was abandoned in favor of **3.5.11**. The 4.0 release reorganized test infrastructure into new modules and packages (`TestRestTemplate``spring-boot-resttestclient`, `AutoConfigureMockMvc` → unknown location) without adequate migration documentation. Multiple attempts to resolve compilation and auto-configuration errors failed, making it impractical for the scaffold phase.
The pivot has no impact on project architecture or future tasks. Migration to 4.x can be revisited once the ecosystem matures. See the research report addendum for full details.

View File

@@ -0,0 +1,477 @@
---
date: 2026-03-04T00:19:03+01:00
git_commit: 7b460dd322359dc1fa3ca0dc950a91c607163977
branch: master
topic: "T-1: Initialize monorepo structure — Tech stack research"
tags: [research, codebase, t-1, scaffolding, spring-boot, vue, maven, vite, hexagonal-architecture]
status: complete
---
# Research: T-1 — Initialize Monorepo Structure
## Research Question
What are the current versions, scaffolding approaches, and architectural patterns needed to implement T-1 (Initialize monorepo structure) with the specified tech stack: Java (latest LTS), Spring Boot, Maven, hexagonal/onion architecture backend + Svelte with Vite frontend?
## Summary
This research covers all technical aspects needed for T-1. The spec requires a monorepo with `backend/` and `frontend/` directories, both building successfully as empty scaffolds. The key findings and open decisions are:
1. **Java 25** is the current LTS (Sep 2025). Spring Boot **4.0.3** is the latest stable — but **3.5.x** is more battle-tested. This is an architectural decision.
2. **Svelte 5** is stable (since Oct 2024). The SPA router ecosystem for plain Svelte 5 is weak — **SvelteKit in SPA mode** is the pragmatic alternative.
3. **Hexagonal architecture**: Single Maven module with package-level separation + ArchUnit enforcement. Base package `com.fete`.
4. **TypeScript** for the frontend is recommended but is a decision point.
## Detailed Findings
### 1. Java Version
**Java 25 (LTS)** — released September 16, 2025.
- Premier support through Sep 2030, extended support through Sep 2033.
- Supersedes Java 21 (Sep 2023) as the current LTS.
- Java 21 is still supported but free updates end Sep 2026.
- Next LTS: Java 29 (Sep 2027).
**Recommendation:** Java 25. Longest support runway, both Spring Boot 3.5 and 4.0 support it.
### 2. Spring Boot Version
Two actively supported lines as of March 2026:
| Version | Latest Patch | OSS Support Ends | Java Baseline | Key Dependencies |
|---------|-------------|-------------------|---------------|-----------------|
| **4.0.x** | 4.0.3 | Dec 2026 | Java 17+ (up to 25) | Spring Framework 7.0, Jakarta EE 11, Hibernate 7.1, Jackson 3.0, Tomcat 11.0 |
| **3.5.x** | 3.5.11 | Jun 2026 | Java 17+ (up to 25) | Spring Framework 6.x, Jakarta EE 10, Hibernate 6.x, Jackson 2.x, Tomcat 10.x |
**Trade-offs:**
| Factor | Spring Boot 4.0 | Spring Boot 3.5 |
|--------|----------------|-----------------|
| Support runway | Dec 2026 (longer) | Jun 2026 (shorter) |
| Ecosystem maturity | Jackson 3.0 + Hibernate 7.1 are new major versions; fewer community examples | Battle-tested, large ecosystem of examples |
| Migration burden | None (greenfield) | None (greenfield) |
| Forward-looking | Yes | Will need migration to 4.x eventually |
**Decision needed:** Spring Boot 4.0 (forward-looking) vs. 3.5 (more battle-tested). Both support Java 25.
### 3. Maven
- **Maven version:** 3.9.12 (latest stable; Maven 4.0.0 is still RC).
- **Maven Wrapper:** Yes, include it. Modern "only-script" distribution — no binary JAR in repo. Scripts `mvnw`/`mvnw.cmd` + `.mvn/wrapper/maven-wrapper.properties` are committed.
- Benefits: deterministic builds in Docker, no Maven pre-install requirement for contributors or CI.
**Minimal dependencies for Spring Boot + PostgreSQL:**
```xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.3</version> <!-- or 3.5.11 -->
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
```
Note: For the empty scaffold (T-1), JPA autoconfig must be excluded or deferred since there's no DB yet. Either omit `spring-boot-starter-data-jpa` until T-4, or add `spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration` to `application.properties`.
### 4. Svelte + Vite Frontend
**Current versions:**
- Svelte: **5.53.6** (stable since Oct 2024, runes-based reactivity)
- Vite: **7.3.1** (stable; Vite 8 is in beta)
**Svelte 5 key changes from Svelte 4:**
- Reactive state: `let count = $state(0)` (explicit rune) instead of implicit `let count = 0`
- Derived values: `$derived()` replaces `$:` blocks
- Props: `$props()` replaces `export let`
- Reactivity works in `.svelte.ts` files too (not just components)
### 5. SvelteKit vs. Plain Svelte — Decision Point
The spec says "Svelte with Vite as bundler" for an SPA with a separate REST backend.
**Option A: Plain Svelte + Vite + third-party router**
| Pro | Con |
|-----|-----|
| Simpler mental model | Router ecosystem broken for Svelte 5: `svelte-spa-router` has no Svelte 5 support (issue #318) |
| Literal spec wording | Only unmaintained/low-adoption alternatives exist |
| No unused SSR concepts | Violates dependency statute ("actively maintained") |
**Option B: SvelteKit in SPA mode (adapter-static + `ssr: false`)**
| Pro | Con |
|-----|-----|
| Built-in file-based routing (maintained by Svelte team) | Has SSR concepts that exist but are unused |
| First-class Vitest integration (T-4 requirement) | Slightly larger framework footprint |
| SPA config is 3 lines of code | SEO concerns (irrelevant for this app) |
| Output is static HTML/JS/CSS — no Node.js runtime needed | |
| `npx sv create` scaffolds TS/ESLint/Vitest in one step | |
**SPA configuration (total effort):**
1. `npm i -D @sveltejs/adapter-static`
2. `svelte.config.js`: `adapter: adapter({ fallback: '200.html' })`
3. `src/routes/+layout.js`: `export const ssr = false;`
**Decision needed:** SvelteKit in SPA mode (pragmatic, solves the router problem) vs. plain Svelte + Vite (minimalist, but router ecosystem is a real problem).
### 6. TypeScript vs. JavaScript — Decision Point
**Arguments for TypeScript:**
- Java backend is strongly typed; TS catches API contract drift at compile time.
- Svelte 5 has first-class TS support, including TS in markup.
- The API client layer (T-4) benefits most from type safety.
- Zero-config in both SvelteKit and the `svelte-ts` Vite template.
- Rich Harris: "TypeScript for apps, JSDoc for libraries." This is an app.
**Arguments against:**
- KISS/grugbrain principle — TS adds cognitive overhead.
- Svelte's compiler already catches many errors.
**Verdict from research:** TS overhead in Svelte 5 is minimal (`let count: number = $state(0)` vs. `let count = $state(0)`). The real value is in the API client layer and shared types.
### 7. Node.js Version
| Version | Status | End of Life |
|---------|--------|-------------|
| Node.js 24 | Active LTS | ~April 2028 |
| Node.js 22 | Active LTS | April 2027 |
| Node.js 20 | Maintenance LTS | April 2026 (EOL imminent) |
**Recommendation:** Target Node.js 22 LTS as minimum. Docker image should use `node:22-alpine`.
### 8. Hexagonal Architecture — Package Structure
**Approach:** Single Maven module with package-level separation. Multi-module Maven is overkill for a small app. ArchUnit test enforces dependency rules.
**Package structure:**
```
com.fete
├── FeteApplication.java # @SpringBootApplication
├── domain/
│ ├── model/ # Entities, value objects (plain Java, no framework annotations)
│ └── port/
│ ├── in/ # Driving port interfaces (use cases)
│ └── out/ # Driven port interfaces (repositories)
├── application/
│ └── service/ # Use case implementations (@Service)
├── adapter/
│ ├── in/
│ │ └── web/ # REST controllers, DTOs, mappers
│ └── out/
│ └── persistence/ # JPA entities, Spring Data repos, mappers
└── config/ # @Configuration classes
```
**Dependency flow (strict):**
```
domain → nothing
application → domain only
adapter → application + domain
config → everything (wiring)
```
**Spring annotations by layer:**
| Layer | Annotations | Rationale |
|-------|-------------|-----------|
| `domain.model` | None | Plain Java — no framework coupling |
| `domain.port` | None | Plain Java interfaces |
| `application.service` | `@Service` only | Pragmatic compromise for component scanning |
| `adapter.in.web` | `@RestController`, `@GetMapping`, etc. | Framework adapter layer |
| `adapter.out.persistence` | `@Entity`, `@Repository`, `@Table`, etc. | Framework adapter layer |
| `config` | `@Configuration`, `@Bean` | Wiring layer |
**Domain purity:** Persistence has its own JPA entity classes (e.g., `EventJpaEntity`) separate from domain model classes. Mappers convert between them.
**Empty directory markers:** Use `package-info.java` in each leaf package. Documents package purpose, allows Git to track the directory, and aids component scanning.
**Base package:** `com.fete` (Maven convention, clean, short).
### 9. .gitignore
The existing `.gitignore` covers IDE files (`.idea/`, `.vscode/`, `*.iml`), OS files (`.DS_Store`, `Thumbs.db`), and Claude settings. The following sections need to be added:
**Java/Maven:**
- `*.class`, `*.jar`, `*.war`, `*.ear`, `*.nar` — compiled artifacts
- `target/` — Maven build output
- Maven release plugin files (`pom.xml.tag`, `pom.xml.releaseBackup`, etc.)
- `.mvn/wrapper/maven-wrapper.jar` — downloaded automatically
- Eclipse files (`.classpath`, `.project`, `.settings/`, `.factorypath`)
- Spring Boot (`.springBeans`, `.sts4-cache`)
- Java crash logs (`hs_err_pid*`, `replay_pid*`)
- `*.log`
**Node.js/Svelte/Vite:**
- `node_modules/`
- `dist/`, `build/` — build output
- `.svelte-kit/` — SvelteKit generated files
- `vite.config.js.timestamp-*`, `vite.config.ts.timestamp-*` — Vite temp files
- `.env`, `.env.*` (but NOT `.env.example`)
- `npm-debug.log*`
**Editor files:**
- `*.swp`, `*.swo`, `*~` — Vim/editor backup files
- `\#*\#`, `.#*` — Emacs
**Committed (NOT ignored):**
- `mvnw`, `mvnw.cmd`, `.mvn/wrapper/maven-wrapper.properties`
- `package-lock.json`
### 10. Existing Repository State
The repository currently contains:
- `CLAUDE.md` — Project statutes
- `README.md` — With tech stack docs and docker-compose example
- `LICENSE` — GPL
- `.gitignore` — Partial (IDE + OS only)
- `Ideen.md` — German idea document
- `spec/` — User stories, personas, setup tasks, implementation phases
- `.ralph/` — Ralph loop infrastructure
- `ralph.sh` — Ralph loop runner
- `review-findings.md` — Review notes
No `backend/` or `frontend/` directories exist yet. No `Dockerfile` exists yet (listed in README project structure, but deferred to T-2).
## Decisions Required Before Implementation
These are architectural decisions that require approval per CLAUDE.md governance statutes:
| # | Decision | Options | Recommendation |
|---|----------|---------|----------------|
| 1 | Spring Boot version | 4.0.3 (latest, longer support) vs. 3.5.11 (battle-tested, shorter support) | 4.0.3 — greenfield project, no migration burden, longer support |
| 2 | SvelteKit vs. plain Svelte | SvelteKit SPA mode vs. plain Svelte + third-party router | SvelteKit SPA mode — router ecosystem for plain Svelte 5 is broken |
| 3 | TypeScript vs. JavaScript | TypeScript (type safety on API boundary) vs. JavaScript (simpler) | TypeScript — minimal overhead in Svelte 5, catches API contract drift |
| 4 | Spring Boot JPA in T-1? | Include `spring-boot-starter-data-jpa` now (exclude autoconfig) vs. add it in T-4 | Defer to T-4 — T-1 is "empty scaffold", JPA needs a datasource |
## Code References
- `spec/setup-tasks.md` — T-1 acceptance criteria
- `spec/implementation-phases.md:9-14` — Phase 0 task order
- `CLAUDE.md:36-43` — Dependency statutes
- `Ideen.md:76-78` — Tech stack decisions (already made)
- `.gitignore` — Current state (needs extension)
- `README.md:112-119` — Documented project structure (target)
## Architecture Documentation
### Target Repository Layout (after T-1)
```
fete/
├── backend/
│ ├── pom.xml
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── .mvn/wrapper/maven-wrapper.properties
│ └── src/
│ ├── main/
│ │ ├── java/com/fete/
│ │ │ ├── FeteApplication.java
│ │ │ ├── domain/model/ (package-info.java)
│ │ │ ├── domain/port/in/ (package-info.java)
│ │ │ ├── domain/port/out/ (package-info.java)
│ │ │ ├── application/service/ (package-info.java)
│ │ │ ├── adapter/in/web/ (package-info.java)
│ │ │ ├── adapter/out/persistence/(package-info.java)
│ │ │ └── config/ (package-info.java)
│ │ └── resources/
│ │ └── application.properties
│ └── test/java/com/fete/
│ └── FeteApplicationTest.java
├── frontend/
│ ├── package.json
│ ├── package-lock.json
│ ├── svelte.config.js
│ ├── vite.config.ts
│ ├── tsconfig.json
│ ├── src/
│ │ ├── app.html
│ │ ├── routes/
│ │ │ ├── +layout.js (ssr = false)
│ │ │ └── +page.svelte
│ │ └── lib/
│ └── static/
├── spec/
├── .gitignore (extended)
├── CLAUDE.md
├── README.md
├── LICENSE
└── Ideen.md
```
### Build Commands (Target State)
| What | Command |
|------|---------|
| Backend build | `cd backend && ./mvnw package` |
| Backend test | `cd backend && ./mvnw test` |
| Frontend install | `cd frontend && npm install` |
| Frontend build | `cd frontend && npm run build` |
| Frontend test | `cd frontend && npm test` |
| Frontend dev | `cd frontend && npm run dev` |
## Open Questions
All resolved — see Follow-up Research below.
## Follow-up Research: Frontend Pivot to Vue 3 (2026-03-04)
### Context
During decision review, the developer raised concerns about the Svelte 5 ecosystem maturity (specifically the broken third-party router situation signaling a smaller, less mature ecosystem). After comparing Svelte 5 vs Vue 3 on ecosystem size, community support, team size, and stability, the decision was made to pivot from Svelte to **Vue 3**.
### Rationale
- Vue 3 has a significantly larger ecosystem and community
- Official, battle-tested packages for all needs (Vue Router, Pinia, Vitest)
- Vite was created by Evan You (Vue's creator) — first-class integration
- Vue 3 Composition API is modern and elegant while being mature (stable since 2020)
- Larger team, broader funding, more StackOverflow answers and tutorials
### Vue 3 Stack — Research Findings
**Current versions (March 2026):**
| Package | Version | Notes |
|---------|---------|-------|
| Vue | 3.5.29 | Stable. Vue 3.6 (Vapor Mode) is in beta |
| Vue Router | 5.0.3 | Includes file-based routing from unplugin-vue-router. Drop-in from v4 for manual routes |
| Vite | 7.3.1 | Stable. Vite 8 (Rolldown) is in beta |
| Vitest | 4.0.18 | Stable. Browser Mode graduated from experimental |
| @vue/test-utils | 2.4.6 | Official component testing utilities |
| create-vue | 3.22.0 | Official scaffolding tool |
| Node.js | 24 LTS | Latest LTS, support through ~April 2028 |
**Scaffolding:** `npm create vue@latest` (official Vue CLI scaffolding). Interactive prompts offer TypeScript, Vue Router, Pinia, Vitest, ESLint, Prettier out of the box.
**Selected options for fete:**
- TypeScript: **Yes**
- Vue Router: **Yes**
- Pinia: **No** — Composition API (`ref`/`reactive`) + localStorage is sufficient for this app's simple state
- Vitest: **Yes**
- ESLint: **Yes**
- Prettier: **Yes**
- E2E testing: **No** (not needed for T-1)
**Project structure (scaffolded by create-vue):**
```
frontend/
├── public/
│ └── favicon.ico
├── src/
│ ├── assets/ # Static assets (CSS, images)
│ ├── components/ # Reusable components
│ ├── composables/ # Composition API composables (added manually)
│ ├── router/ # Vue Router config (index.ts)
│ ├── views/ # Route-level page components
│ ├── App.vue # Root component
│ └── main.ts # Entry point
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── vite.config.ts
├── eslint.config.js
├── .prettierrc.json
├── env.d.ts
└── README.md
```
**Key conventions:**
- `src/views/` for route page components (not `src/pages/` — that's Nuxt)
- `src/components/` for reusable components
- `src/composables/` for Composition API composables (e.g., `useStorage.ts`)
- `src/router/index.ts` for route definitions
### Resolved Decisions
| # | Decision | Resolution |
|---|----------|------------|
| 1 | Spring Boot version | ~~**4.0.3**~~**3.5.11** — see addendum below |
| 2 | Frontend framework | **Vue 3** — pivot from Svelte due to ecosystem maturity concerns |
| 3 | TypeScript | **Yes** — confirmed by developer |
| 4 | Node.js version | **24 LTS** (latest LTS) |
| 5 | Base package | **`de.fete`** (not `com.fete`) |
| 6 | JPA in T-1 | **Defer to T-4** — T-1 is empty scaffold, JPA needs a datasource |
| 7 | State management | **No Pinia** — Composition API + localStorage sufficient |
### Addendum: Spring Boot 4.0 → 3.5 Pivot (2026-03-04)
During T-1 implementation, Spring Boot 4.0.3 proved unworkable for the scaffold phase. The 4.0 release massively reorganized internal packages — test infrastructure classes (`TestRestTemplate`, `AutoConfigureMockMvc`, etc.) were moved into new modules with different package paths. The Spring Boot 4.0 Migration Guide did not cover these changes adequately, and resolving the issues required extensive trial-and-error with undocumented class locations and missing transitive dependencies.
**Decision:** Pivot to **Spring Boot 3.5.11** (latest 3.5.x patch). This is the battle-tested line with OSS support through June 2026. Since this is a greenfield project, migrating to 4.x later (once the ecosystem and documentation have matured) is straightforward.
**Impact:** None on architecture or feature scope. The hexagonal package structure, dependency choices, and all other decisions remain unchanged. Only the Spring Boot parent version in `pom.xml` changed.
### Updated Target Repository Layout
```
fete/
├── backend/
│ ├── pom.xml
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── .mvn/wrapper/maven-wrapper.properties
│ └── src/
│ ├── main/
│ │ ├── java/de/fete/
│ │ │ ├── FeteApplication.java
│ │ │ ├── domain/model/ (package-info.java)
│ │ │ ├── domain/port/in/ (package-info.java)
│ │ │ ├── domain/port/out/ (package-info.java)
│ │ │ ├── application/service/ (package-info.java)
│ │ │ ├── adapter/in/web/ (package-info.java)
│ │ │ ├── adapter/out/persistence/(package-info.java)
│ │ │ └── config/ (package-info.java)
│ │ └── resources/
│ │ └── application.properties
│ └── test/java/de/fete/
│ └── FeteApplicationTest.java
├── frontend/
│ ├── public/
│ ├── src/
│ │ ├── assets/
│ │ ├── components/
│ │ ├── composables/
│ │ ├── router/index.ts
│ │ ├── views/
│ │ ├── App.vue
│ │ └── main.ts
│ ├── index.html
│ ├── package.json
│ ├── package-lock.json
│ ├── tsconfig.json
│ ├── vite.config.ts
│ └── eslint.config.js
├── spec/
├── .gitignore (extended)
├── CLAUDE.md
├── README.md
├── LICENSE
└── Ideen.md
```