diff --git a/Sprint-1-Plan.md b/Sprint-1-Plan.md
new file mode 100644
index 0000000..a0a5f54
--- /dev/null
+++ b/Sprint-1-Plan.md
@@ -0,0 +1,374 @@
+# Sprint 1 — Plan ("Spark")
+
+**Date:** Pre-Sprint 1 planning
+**Module:** Sparkboard (greenfield)
+**Author:** Patrick Plate / Lumen (Planner)
+**Status:** Entwurf v1
+**Basis:** [Sprint 1 Assessment](Sprint-1-Assessment.md) — Option A approved
+**Predecessor:** [plate-auth v0.1.0](https://git.plate-software.de/pplate/plate-auth/wiki/Roadmap#v010--ship-sprint-0-deliverable) must be published before W2.
+
+---
+
+## 0. How to read this plan
+
+The plan is broken into **seven workstreams** (W0–W6). They are partially parallel — W0/W1 must complete before W2, but W2/W3/W4 can be developed in parallel by the same human, and W5/W6 are tail-end. Each workstream lists:
+
+- **Goal** — what the workstream produces
+- **Deliverables** — files / artifacts that must exist
+- **Acceptance gate** — what proves the workstream is done
+- **Code sketches** — illustrative, not final
+
+The acceptance criteria A1–A6 from the [Assessment](Sprint-1-Assessment.md#7-acceptance-criteria-a1a6) are mapped to workstreams in the [implementation order](Sprint-1-Plan-Part-4.md#implementation-order) section at the end.
+
+Code paths shown as `[`backend/...`](../backend/...)` will resolve once the `sparkboard` code repo is cloned alongside this wiki.
+
+---
+
+## 1. Background
+
+Sparkboard does not exist yet. There is no codebase, no DB, no DNS. Sprint 1 builds the walking skeleton: a Spring Boot 4.1 + Java 25 backend consuming `plate-auth-starter:0.1.0`, a Next.js 15 frontend consuming `@platesoft/auth:0.1.0`, a Postgres database, and a deployment to `sparkboard.plate-software.de`.
+
+The whole sprint is an integration exercise. The product surface (one entity, two endpoints, two pages) is intentionally tiny so that all the difficulty surfaces in the integration. See [Assessment §1](Sprint-1-Assessment.md#1-problem-analysis) for the strategic reasoning.
+
+---
+
+## 2. Architecture summary
+
+See [Architecture](Architecture.md) for the full picture. Sprint 1 instantiates exactly one section of it:
+
+- One Spring Boot app: `de.plate.sparkboard.SparkboardApplication` — embeds plate-auth's auto-config.
+- One Postgres database: `sparkboard` — with two Flyway histories side-by-side (`flyway_schema_history` for Sparkboard's tables, `flyway_schema_history_auth` for plate-auth's).
+- One Next.js app: `frontend/` — embeds `@platesoft/auth/next-auth` factory + `@platesoft/auth/proxy` handlers.
+- One Sparkboard SPI implementation: `SparkboardOnboardingHook`.
+- One Sparkboard domain table: `ideas` (and one Sparkboard-owned reference table: `spark_org`).
+- Deployed to TrueNAS via Gitea Actions, exposed via frps port 30011 + IONOS Apache.
+
+---
+
+## 3. Repository layout
+
+```
+sparkboard/
+├── README.md
+├── docker-compose.yml # local dev: backend + frontend + postgres
+├── docker-compose.prod.yml # TrueNAS: backend + frontend + postgres + caddy/apache
+├── .gitea/workflows/
+│ ├── ci.yml # build + test on every push
+│ └── deploy.yml # SSH deploy to TrueNAS on main
+├── deploy/
+│ ├── caddy/Caddyfile # internal reverse proxy on TrueNAS
+│ ├── deploy.sh # SSH-driven deploy
+│ └── smoke-test.sh # post-deploy health checks
+├── backend/
+│ ├── pom.xml
+│ ├── Dockerfile
+│ └── src/main/
+│ ├── java/de/plate/sparkboard/
+│ │ ├── SparkboardApplication.java
+│ │ ├── onboarding/{SparkboardOnboardingHook, SparkboardAdminProperties}.java
+│ │ ├── idea/{Idea, IdeaStatus, IdeaRepository, IdeaService, IdeaController, IdeaDto, CreateIdeaRequest}.java
+│ │ └── config/SparkboardSecurityCustomizations.java # optional
+│ └── resources/
+│ ├── application.yml
+│ ├── application-prod.yml
+│ └── db/migration/
+│ ├── V1__init.sql # ideas + spark_org tables
+│ └── V2__seed_family_spark_org.sql
+└── frontend/
+ ├── package.json # depends on @platesoft/auth: 0.1.0
+ ├── next.config.ts
+ ├── auth.ts # createAuthConfig from @platesoft/auth/next-auth
+ ├── middleware.ts # optional re-export
+ ├── Dockerfile
+ └── app/
+ ├── layout.tsx
+ ├── globals.css
+ ├── api/
+ │ ├── auth/[...nextauth]/route.ts # exports handlers from auth.ts
+ │ └── backend/[...path]/route.ts # createProxyHandlers
+ ├── (auth)/login/page.tsx
+ └── (app)/
+ ├── layout.tsx
+ ├── page.tsx # redirect to /ideas
+ └── ideas/
+ ├── page.tsx # list (server component)
+ ├── new/page.tsx # create form
+ └── components/{idea-form, idea-list, idea-card}.tsx
+```
+
+---
+
+## 4. Workstreams
+
+### W0 — Skeleton
+
+**Goal:** an empty but buildable Sparkboard. `mvn package` produces a runnable JAR. `pnpm build` produces a Next.js standalone build. CI runs both on every push.
+
+**Deliverables:**
+
+1. Gitea repo `pplate/sparkboard` created.
+2. `backend/pom.xml` declaring Spring Boot 4.1.0 parent, Java 25 source/target, Maven build.
+3. `backend/src/main/java/de/plate/sparkboard/SparkboardApplication.java` — empty `@SpringBootApplication`.
+4. `frontend/package.json` declaring Next.js 15, React 19, TypeScript 5.
+5. `frontend/app/page.tsx` — placeholder "Sparkboard" string.
+6. `docker-compose.yml` for local dev.
+7. `.gitea/workflows/ci.yml` building both subprojects.
+8. `README.md` with quick-start.
+
+**Acceptance gate:**
+- `git push` triggers CI; CI builds backend + frontend in < 5 min wall-clock; CI is **green**.
+
+**Code sketch — backend `pom.xml` excerpt:**
+
+```xml
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 4.1.0
+
+
+
+ de.plate
+ sparkboard-backend
+ 0.1.0-SNAPSHOT
+
+
+ 25
+ 25
+
+
+
+
+ plate-software-gitea
+ https://git.plate-software.de/api/packages/platesoft/maven
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.postgresql
+ postgresql
+
+
+ org.flywaydb
+ flyway-database-postgresql
+
+
+
+
+ de.platesoft
+ plate-auth-starter
+ 0.1.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.testcontainers
+ postgresql
+ 1.20.6
+ test
+
+
+
+```
+
+**Code sketch — frontend `package.json` excerpt:**
+
+```json
+{
+ "name": "sparkboard-frontend",
+ "version": "0.1.0",
+ "scripts": {
+ "dev": "next dev --port 3000",
+ "build": "next build",
+ "start": "node .next/standalone/server.js",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "@platesoft/auth": "0.1.0",
+ "next": "15.1.0",
+ "next-auth": "5.0.0-beta.25",
+ "react": "19.0.0",
+ "react-dom": "19.0.0"
+ },
+ "devDependencies": {
+ "@playwright/test": "1.50.0",
+ "tailwindcss": "3.4.17",
+ "typescript": "5.6.3"
+ }
+}
+```
+
+**Code sketch — `.gitea/workflows/ci.yml`:**
+
+```yaml
+name: CI
+on:
+ push:
+ branches: [main, '**']
+ pull_request:
+
+jobs:
+ backend:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ java-version: '25'
+ distribution: 'temurin'
+ - run: mvn -B verify
+ working-directory: backend
+ frontend:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+ - uses: pnpm/action-setup@v4
+ - run: pnpm install --frozen-lockfile
+ working-directory: frontend
+ - run: pnpm build
+ working-directory: frontend
+```
+
+---
+
+### W1 — plate-auth wire-up
+
+**Goal:** the four allowlisted Google users can sign in. Sparkboard has not yet implemented `OnboardingHook`, so a successful login leaves them with `auth_identities` row but no `memberships` row — they are signed in but "homeless". The list page will look empty until W2 ships the hook.
+
+**Pre-requisite:** [plate-auth v0.1.0](https://git.plate-software.de/pplate/plate-auth/wiki/Roadmap) is **published and pullable** from `https://git.plate-software.de/api/packages/platesoft/maven` and `https://git.plate-software.de/api/packages/platesoft/npm`. If this is not the case at the start of W1, **stop and ping plate-auth Sprint 0**.
+
+**Deliverables:**
+
+1. `backend/src/main/resources/application.yml` with `plate.auth.*` block — see [Architecture §10.1](Architecture.md#101-backend-applicationyml) for the full block.
+2. `backend/src/main/resources/application-prod.yml` overriding env-derived values for production.
+3. `frontend/auth.ts` calling `createAuthConfig({ ... })` from `@platesoft/auth/next-auth`.
+4. `frontend/app/api/auth/[...nextauth]/route.ts` exporting the NextAuth handlers from `auth.ts`.
+5. `frontend/app/api/backend/[...path]/route.ts` calling `createProxyHandlers({ ... })` from `@platesoft/auth/proxy`.
+6. `frontend/app/(auth)/login/page.tsx` with a "Sign in with Google" button (calls `signIn('google')`).
+7. Google Cloud Console: OAuth client with redirect URIs:
+ - `http://localhost:3000/api/auth/callback/google` (dev)
+ - `https://sparkboard.plate-software.de/api/auth/callback/google` (prod)
+8. Local `.env.local` and TrueNAS `/mnt/tank/sparkboard/.env` with all required secrets — see [Integration Guide §2](Integration-Guide.md#2-secrets-and-env-vars).
+
+**Acceptance gate:**
+- A Gmail account in `plate.auth.allowlist.emails` can sign in **locally** (`http://localhost:3000`) and reach `/ideas` (which is still placeholder content).
+- A Gmail account NOT in the allowlist gets a "not authorised" message and **no row is created** in `auth_identities`.
+- The `auth_identities` table contains one row per successful login (idempotent on subsequent logins).
+- The `memberships` table is **empty** (W2 will fill it).
+- This satisfies **A1** (allowlisted user can sign in) and **A2** (non-allowlisted user is rejected) **except** for the post-login `/ideas` page being meaningful — that part of A1 lands in W4.
+
+**Code sketch — `frontend/auth.ts`:**
+
+```typescript
+import NextAuth from "next-auth";
+import { createAuthConfig } from "@platesoft/auth/next-auth";
+
+export const { handlers, auth, signIn, signOut } = NextAuth(
+ createAuthConfig({
+ backendUrl: process.env.PLATE_AUTH_BACKEND_URL!, // http://backend:8080
+ exchangeSecret: process.env.PLATE_AUTH_EXCHANGE_SECRET!,
+ nextAuthSecret: process.env.NEXTAUTH_SECRET!,
+ providers: {
+ google: {
+ clientId: process.env.GOOGLE_CLIENT_ID!,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
+ },
+ },
+ pages: { signIn: "/login" },
+ })
+);
+```
+
+**Code sketch — `frontend/app/api/auth/[...nextauth]/route.ts`:**
+
+```typescript
+export { handlers as GET, handlers as POST } from "@/auth";
+```
+
+**Code sketch — `frontend/app/api/backend/[...path]/route.ts`:**
+
+```typescript
+import { createProxyHandlers } from "@platesoft/auth/proxy";
+
+export const { GET, POST, PUT, PATCH, DELETE } = createProxyHandlers({
+ backendUrl: process.env.PLATE_AUTH_BACKEND_URL!,
+ exchangeSecret: process.env.PLATE_AUTH_EXCHANGE_SECRET!,
+});
+
+export const runtime = "nodejs"; // proxy requires Node runtime (duplex: 'half')
+```
+
+**Code sketch — `frontend/app/(auth)/login/page.tsx`:**
+
+```tsx
+"use client";
+import { signIn } from "next-auth/react";
+
+export default function LoginPage() {
+ return (
+
+
+
+ );
+}
+```
+
+**Code sketch — `backend/src/main/resources/application.yml` (plate.auth excerpt only):**
+
+```yaml
+plate:
+ auth:
+ jwt:
+ secret: ${PLATE_AUTH_JWT_SECRET}
+ access-expiration: PT15M
+ refresh-expiration: P30D
+ exchange:
+ secret: ${PLATE_AUTH_EXCHANGE_SECRET}
+ registration:
+ enabled: false
+ allowlist:
+ enabled: true
+ emails: ${PLATE_AUTH_ALLOWLIST_EMAILS} # comma-separated env var
+ providers:
+ google:
+ enabled: true
+ client-id: ${GOOGLE_CLIENT_ID}
+ client-secret: ${GOOGLE_CLIENT_SECRET}
+```
+
+Note: zero Java code is written in W1. Everything is configuration and frontend wiring. **That is the win.**
+
+---
+
+_Continued in [Sprint-1-Plan-Part-2](Sprint-1-Plan-Part-2.md): W2 (domain) and W3 (API)._
+_Continued in [Sprint-1-Plan-Part-3](Sprint-1-Plan-Part-3.md): W4 (frontend), W5 (seed data), W6 (deploy + CI/CD)._
+_Continued in [Sprint-1-Plan-Part-4](Sprint-1-Plan-Part-4.md): implementation order, acceptance mapping, open questions._