Migrate project artifacts to spec-kit format
- Move cross-cutting docs (personas, design system, implementation phases, Ideen.md) to .specify/memory/ - Move cross-cutting research and plans to .specify/memory/research/ and .specify/memory/plans/ - Extract 5 setup tasks from spec/setup-tasks.md into individual specs/001-005/spec.md files with spec-kit template format - Extract 20 user stories from spec/userstories.md into individual specs/006-026/spec.md files with spec-kit template format - Relocate feature-specific research and plan docs into specs/[feature]/ - Add spec-kit constitution, templates, scripts, and slash commands - Slim down CLAUDE.md to Claude-Code-specific config, delegate principles to .specify/memory/constitution.md - Update ralph.sh with stream-json output and per-iteration logging - Delete old spec/ and docs/agents/ directories - Gitignore Ralph iteration JSONL logs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
179
specs/001-monorepo-setup/plan.md
Normal file
179
specs/001-monorepo-setup/plan.md
Normal 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.
|
||||
477
specs/001-monorepo-setup/research.md
Normal file
477
specs/001-monorepo-setup/research.md
Normal 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
|
||||
```
|
||||
63
specs/001-monorepo-setup/spec.md
Normal file
63
specs/001-monorepo-setup/spec.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Feature Specification: Initialize Monorepo Structure
|
||||
|
||||
**Feature**: `001-monorepo-setup`
|
||||
**Created**: 2026-03-06
|
||||
**Status**: Implemented
|
||||
**Source**: Migrated from spec/setup-tasks.md
|
||||
|
||||
> **Note**: This is a setup task (infrastructure), not a user-facing feature. It establishes the repository structure as a prerequisite for all subsequent development work.
|
||||
|
||||
## User Scenarios & Testing
|
||||
|
||||
### User Story 1 - Developer can scaffold and build the monorepo (Priority: P1)
|
||||
|
||||
A developer cloning the repository for the first time can build both the backend and frontend from a clean checkout with no source code beyond the scaffold.
|
||||
|
||||
**Why this priority**: Without a working monorepo structure, no further development or CI work is possible.
|
||||
|
||||
**Independent Test**: Clone the repository, run `./mvnw verify` in `backend/` and `npm run build` in `frontend/` — both must succeed against the empty scaffold.
|
||||
|
||||
**Acceptance Scenarios**:
|
||||
|
||||
1. **Given** a fresh clone of the repository, **When** the developer inspects the root, **Then** separate `backend/` and `frontend/` directories exist alongside shared top-level files (README, Dockerfile, CLAUDE.md, LICENSE, .gitignore).
|
||||
2. **Given** the `backend/` directory, **When** the developer runs `./mvnw verify`, **Then** the build succeeds with no source code beyond the hexagonal/onion architecture scaffold using Java (latest LTS), Spring Boot, and Maven.
|
||||
3. **Given** the `frontend/` directory, **When** the developer runs `npm run build`, **Then** the build succeeds with the Vue 3 + Vite + TypeScript + Vue Router scaffold.
|
||||
4. **Given** the repository root, **When** the developer inspects `.gitignore`, **Then** build artifacts, IDE files, and dependency directories for both Java/Maven and Node/Vue are covered.
|
||||
|
||||
---
|
||||
|
||||
### Edge Cases
|
||||
|
||||
- What happens when a developer uses an older Java version? [NEEDS EXPANSION]
|
||||
- How does the scaffold behave with no `.env` or environment variables set? [NEEDS EXPANSION]
|
||||
|
||||
## Requirements
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
- **FR-001**: Repository MUST have a `backend/` directory containing a Java Spring Boot Maven project with hexagonal/onion architecture scaffold.
|
||||
- **FR-002**: Repository MUST have a `frontend/` directory containing a Vue 3 project with Vite, TypeScript, and Vue Router.
|
||||
- **FR-003**: Repository MUST include shared top-level files: README, Dockerfile, CLAUDE.md, LICENSE (GPL), and .gitignore.
|
||||
- **FR-004**: Both projects MUST build successfully from an empty scaffold (no application source code required).
|
||||
- **FR-005**: `.gitignore` MUST cover build artifacts, IDE files, and dependency directories for both Java/Maven and Node/Vue.
|
||||
|
||||
### Key Entities
|
||||
|
||||
- **Monorepo**: Single git repository containing both `backend/` and `frontend/` as separate projects sharing a root.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Measurable Outcomes
|
||||
|
||||
- **SC-001**: `cd backend && ./mvnw verify` exits 0 on a clean checkout.
|
||||
- **SC-002**: `cd frontend && npm run build` exits 0 on a clean checkout.
|
||||
- **SC-003**: All six acceptance criteria are checked off (all complete — status: Implemented).
|
||||
|
||||
### Acceptance Criteria (original)
|
||||
|
||||
- [x] Single repository with `backend/` and `frontend/` directories
|
||||
- [x] Backend: Java (latest LTS), Spring Boot, Maven, hexagonal/onion architecture scaffold
|
||||
- [x] Frontend: Vue 3 with Vite as bundler, TypeScript, Vue Router
|
||||
- [x] Shared top-level files: README, Dockerfile, CLAUDE.md, LICENSE (GPL), .gitignore
|
||||
- [x] Both projects build successfully with no source code (empty scaffold)
|
||||
- [x] .gitignore covers build artifacts, IDE files, and dependency directories for both Java/Maven and Node/Vue
|
||||
Reference in New Issue
Block a user