diff --git a/Home.md b/Home.md index 425d839..252a6cd 100644 --- a/Home.md +++ b/Home.md @@ -18,7 +18,7 @@ A web app at `sparkboard.plate-software.de` with a Spring Boot 4.1 + Java 25 bac **Sprint 0 — Waiting.** Sparkboard cannot start coding until `plate-auth v0.1.0` is published to the Gitea Package Registry. Sparkboard's entire auth/multi-tenancy story is **outsourced** to that library. Sprint 1 ("Spark") begins the moment `de.platesoft:plate-auth-starter:0.1.0` and `@platesoft/auth:0.1.0` are pullable. -**Sprint 1 — Spark.** Walking skeleton that imports `plate-auth`, configures it for single-org mode ("Family Spark"), implements one [`SparkboardOnboardingHook.afterFirstLogin()`](Architecture.md#single-org-mode-and-onboardinghook), adds a single `ideas` table, and ships to TrueNAS. Acceptance A1–A6. +**Sprint 1 — Spark.** Walking skeleton that imports `plate-auth`, configures it for single-org mode ("Family Spark"), implements one [`SparkboardOnboardingHook.onFirstSignIn()`](Architecture.md#single-org-mode-and-onboardinghook), adds a single `ideas` table, and ships to TrueNAS. Acceptance A1–A6. See [Roadmap](Roadmap.md) for the full multi-sprint arc. @@ -52,6 +52,21 @@ What Sparkboard inherits from the wider `plate-software` family: --- +## 📜 Decisions log + +| Date | ID | Decision | +|------|----|----------| +| 2026-06-24 | Q01 | Single-org ID: hardcode `FAMILY_SPARK_ID = UUID.fromString("00000000-0000-0000-0000-000000000001")` on `SparkboardOnboardingHook` | +| 2026-06-24 | Q02 | Allowlist: `plate.auth.allowlist[]` in `application.yml` (YAML edit + redeploy via Gitea Actions) | +| 2026-06-24 | Q03 | Admin promotion: `sparkboard.admins[]` YAML list; `onFirstSignIn` writes ADMIN vs MEMBER | +| 2026-06-24 | Q07 | PWA icons: hand-crafted 192×192 + 512×512 PNGs in `frontend/public/icons/`; no build-time generator | +| 2026-06-24 | F3 | Onboarding hook renamed `afterFirstLogin(OnboardingContext)` → `onFirstSignIn(AuthenticatedUser)` (plate-auth spelling wins) | +| 2026-06-24 | F4 | UT-06 test class moved to `de.plate.sparkboard.onboarding.SparkboardOnboardingHookTest` | + +Full rationale lives in [Open Questions](Open-Questions.md). Sprint-1-Plan-Part-4 § 9 carries the per-decision Sprint 1 impact. + +--- + ## 🔗 External links | Link | What | diff --git a/Open-Questions.md b/Open-Questions.md index 632e06a..2a24a51 100644 --- a/Open-Questions.md +++ b/Open-Questions.md @@ -12,18 +12,18 @@ ## Question Map -| ID | Topic | Blocks Sprint | Decision needed by | -|----|-------|--------------|-------------------| -| Q01 | Single-org name and ID strategy | Sprint 1 (W2) | Sprint 1 kickoff | -| Q02 | Allowlist management UX | Sprint 1 (W1) — light; Sprint 4 — heavy | Sprint 1 kickoff | -| Q03 | Admin promotion model | Sprint 1 (W2) | Sprint 1 kickoff | -| Q04 | Idea status workflow | Sprint 2 (Kindling) | Sprint 2 kickoff | -| Q05 | Reaction model | Sprint 2 (Kindling) | Sprint 2 kickoff | -| Q06 | Security customisation: do we need any beyond plate-auth? | Sprint 1 (W1) — confirm "no"; Sprint 2 — re-check | Sprint 1 kickoff | -| Q07 | PWA assets pipeline (icons, splash) | Sprint 1 (W4) | Sprint 1 mid-sprint | -| Q08 | Mobile strategy: PWA-only vs native APK | Sprint 5 (Wildfire) | Sprint 4 retro | -| Q09 | Real-time updates (live list refresh) | Sprint 4 (Ember) | Sprint 3 retro | -| Q10 | Notifications: email, push, or none | Sprint 4 (Ember) | Sprint 3 retro | +| ID | Topic | Status | Blocks Sprint | Decision needed by | +|----|-------|--------|--------------|-------------------| +| Q01 | Single-org name and ID strategy | ✅ Decided 2026-06-24 — **A** | Sprint 1 (W2) | Sprint 1 kickoff | +| Q02 | Allowlist management UX | ✅ Decided 2026-06-24 — **A** | Sprint 1 (W1) — light; Sprint 4 — heavy | Sprint 1 kickoff | +| Q03 | Admin promotion model | ✅ Decided 2026-06-24 — **A** | Sprint 1 (W2) | Sprint 1 kickoff | +| Q04 | Idea status workflow | ⏳ Open | Sprint 2 (Kindling) | Sprint 2 kickoff | +| Q05 | Reaction model | ⏳ Open | Sprint 2 (Kindling) | Sprint 2 kickoff | +| Q06 | Security customisation: do we need any beyond plate-auth? | ⏳ Open | Sprint 1 (W1) — confirm "no"; Sprint 2 — re-check | Sprint 1 kickoff | +| Q07 | PWA assets pipeline (icons, splash) | ✅ Decided 2026-06-24 — **A** | Sprint 1 (W4) | Sprint 1 mid-sprint | +| Q08 | Mobile strategy: PWA-only vs native APK | ⏳ Open | Sprint 5 (Wildfire) | Sprint 4 retro | +| Q09 | Real-time updates (live list refresh) | ⏳ Open | Sprint 4 (Ember) | Sprint 3 retro | +| Q10 | Notifications: email, push, or none | ⏳ Open | Sprint 4 (Ember) | Sprint 3 retro | --- @@ -46,7 +46,7 @@ This decision shows up in `IdeaController` (the `FAMILY_SPARK_ID` constant), the - Trivial to refactor to option C the moment a second org appears (which is "never" for Sparkboard, but might be relevant if the pattern is lifted into a different app). - Option B costs a DB roundtrip per request for no value. Option C costs configuration ceremony for no value. -**Decision:** _Pending._ +**Decision:** ✅ **Decided 2026-06-24 — Option A.** Hardcode `FAMILY_SPARK_ID = UUID.fromString("00000000-0000-0000-0000-000000000001")` as a `public static final` on `SparkboardOnboardingHook`. Used by `IdeaController`, the hook, and the `V2__seed_family_spark_org.sql` migration. Refactor to option C only when a second org appears (not in Sprint 1–5). --- @@ -68,7 +68,7 @@ Affects W1 config shape, Sprint 4 admin-panel scope, and how forgiving the syste - DB-backed allowlist (B) adds an entire CRUD surface; not worth it in Sprint 1. - Admin UI (C) is multi-week work; explicitly scheduled in Sprint 4 (Ember) on the [Roadmap](Roadmap.md). -**Decision:** _Pending._ +**Decision:** ✅ **Decided 2026-06-24 — Option A.** Allowlist lives in `application.yml` under `plate.auth.allowlist[]` (bound by plate-auth's `PlateAuthProperties`). Adding/removing a family member is a YAML edit + Gitea Actions deploy. DB-backed allowlist (B) and admin UI (C) deferred to Sprint 4 (Ember) at the earliest. --- @@ -92,7 +92,7 @@ Affects W2 (`SparkboardOnboardingHook` impl) and the bootstrap story for new fam - Idempotent (re-running the hook against the same user with same admin list = no diff). - Option D (all ADMIN) is tempting for simplicity, but Sprint 2+ will care about MEMBER vs ADMIN (e.g., admin-only delete), so introducing the distinction now costs almost nothing. -**Decision:** _Pending._ +**Decision:** ✅ **Decided 2026-06-24 — Option A.** Admin list lives in `application.yml` under `sparkboard.admins[]` (bound by `SparkboardAdminProperties`). `SparkboardOnboardingHook.onFirstSignIn(user)` reads it and writes `Role.ADMIN` if `user.email()` is in the list, otherwise `Role.MEMBER`. Initial seed list (placeholders — replace before first deploy): ``, ``, ``, ``. --- @@ -178,7 +178,7 @@ Affects A5 acceptance ("installable PWA with correct icon"). Default browser ico - Asset-generator tooling (B) is Sprint 4+ when we care about iOS splash screens, maskable icons, dark-mode variants. - C fails the spirit of A5. -**Decision:** _Pending. Sprint 1 blocker if no icon → A5 fails MT-01/MT-02._ +**Decision:** ✅ **Decided 2026-06-24 — Option A.** Hand-craft 2 PNGs (192×192 and 512×512), commit to `frontend/public/icons/icon-192.png` and `frontend/public/icons/icon-512.png`, reference both from `frontend/public/manifest.json`. No build-time generator in Sprint 1. Asset-generator tooling (Option B) revisited in Sprint 4+ when iOS splash / maskable / dark-mode variants are needed. --- @@ -248,9 +248,16 @@ Affects Sprint 4 architecture (SMTP integration vs Web Push API + VAPID keys). ## Resolved Questions (Archive) -> When a question is decided, move it here with the resolution and date. Keeps Q01–Q10 numbering stable. +> When a question is decided, the full text stays in place (numbering stays stable). This section is a quick-reference log of decisions. -_None yet._ +| ID | Topic | Decision | Date | +|----|-------|----------|------| +| Q01 | Single-org name and ID strategy | **A** — Hardcode `FAMILY_SPARK_ID = 00000000-0000-0000-0000-000000000001` | 2026-06-24 | +| Q02 | Allowlist management UX | **A** — `plate.auth.allowlist[]` in `application.yml` | 2026-06-24 | +| Q03 | Admin promotion model | **A** — `sparkboard.admins[]` YAML list, read by `SparkboardOnboardingHook.onFirstSignIn` | 2026-06-24 | +| Q07 | PWA assets pipeline | **A** — Hand-crafted 192×192 + 512×512 PNGs in `frontend/public/icons/` | 2026-06-24 | +| F3 | Reviewer finding — hook method spelling | Renamed `afterFirstLogin(OnboardingContext)` → `onFirstSignIn(AuthenticatedUser)` across all sparkboard docs (plate-auth spelling wins) | 2026-06-24 | +| F4 | Reviewer finding — UT-06 package typo | `de.plate.sparkboard.auth.SparkboardOnboardingHookTest` → `de.plate.sparkboard.onboarding.SparkboardOnboardingHookTest` | 2026-06-24 | --- @@ -263,4 +270,4 @@ _None yet._ --- -_End of Open Questions. Status: **10 open, 0 resolved.**_ +_End of Open Questions. Status: **6 open, 4 resolved.** (Q01, Q02, Q03, Q07 decided 2026-06-24.)_ diff --git a/Sprint-1-Plan-Part-4.md b/Sprint-1-Plan-Part-4.md index 3051d99..b814778 100644 --- a/Sprint-1-Plan-Part-4.md +++ b/Sprint-1-Plan-Part-4.md @@ -94,14 +94,14 @@ Each acceptance criterion from [Sprint-1-Assessment §7](Sprint-1-Assessment.md# ## 9. Open Questions (Sprint-1-Specific) -These questions block or change Sprint 1 if answered "differently than the leaning." The full list of Sparkboard open questions lives in [Open-Questions](Open-Questions.md) — this section only highlights the ones Sprint 1 touches. +All Sprint-1-blocking questions have been **decided 2026-06-24**. The full list of Sparkboard open questions lives in [Open-Questions](Open-Questions.md) — this section only logs the Sprint 1 decisions. -| ID | Question | Sprint 1 Impact | Leaning | -|----|----------|----------------|---------| -| **Q01** | Single-org name + ID strategy: hardcode `00000000-0000-0000-0000-000000000001` or compute? | High — affects W2 SQL + `IdeaController.FAMILY_SPARK_ID` constant. | Hardcode the all-zeros-with-trailing-1 magic UUID. Trivial to refactor to a `@ConfigurationProperties` lookup later. | -| **Q02** | Allowlist management: edit `application.yml` and redeploy, or admin UI? | Medium — affects W1 config shape and W6 deploy story. | YAML + redeploy in v1. Admin UI is Sprint 4+. | -| **Q03** | Admin promotion model: bootstrap admins via `sparkboard.admins[]` config, or DB seed? | Medium — affects W2 (`SparkboardOnboardingHook` logic). | Config-driven (`sparkboard.admins[]`). Hook reads it at hook time and writes `ADMIN` vs `MEMBER`. | -| **Q07** | PWA assets pipeline: hand-crafted SVGs/PNGs in `frontend/public/` or generated? | Low — affects W4 + manifest. | Hand-crafted for v1 (4 humans, no app-store presence). Generated assets are Sprint 4. | +| ID | Question | Sprint 1 Impact | ✅ Decision (2026-06-24) | +|----|----------|----------------|--------------------------| +| **Q01** | Single-org name + ID strategy | High — affects W2 SQL + `IdeaController.FAMILY_SPARK_ID` constant. | **Option A.** Hardcode `FAMILY_SPARK_ID = UUID.fromString("00000000-0000-0000-0000-000000000001")` as a `public static final` on `SparkboardOnboardingHook`. | +| **Q02** | Allowlist management | Medium — affects W1 config shape and W6 deploy story. | **Option A.** `plate.auth.allowlist[]` in `application.yml`. YAML edit + Gitea Actions deploy. Admin UI deferred to Sprint 4. | +| **Q03** | Admin promotion model | Medium — affects W2 (`SparkboardOnboardingHook` logic). | **Option A.** `sparkboard.admins[]` YAML list (bound by `SparkboardAdminProperties`). `onFirstSignIn(user)` reads it and writes `ADMIN` vs `MEMBER`. Initial seed (placeholders — replace before first deploy): ``, ``, ``, ``. | +| **Q07** | PWA assets pipeline | Low — affects W4 + manifest. | **Option A.** Hand-craft 192×192 + 512×512 PNGs in `frontend/public/icons/`. No build-time generator in Sprint 1. | > **Non-blocking but worth noting:** Q04 (idea status workflow), Q05 (reaction model), Q06 (security customisation), Q08 (mobile PWA vs native), Q09 (real-time updates), Q10 (notifications) are all Sprint 2+. They do **not** affect Sprint 1's surface.