max / makenotwork
1 file changed,
+56 insertions,
-0 deletions
| @@ -312,6 +312,62 @@ All four Run #1 deferred items closed by Run #2 sweeps; pointers below. | |||
| 312 | 312 | ||
| 313 | 313 | --- | |
| 314 | 314 | ||
| 315 | + | ## Creator applications restructure (replaces waitlist) | |
| 316 | + | ||
| 317 | + | Discussed and scoped 2026-06-03; no implementation yet. Rename and generalize the existing waitlist into a creator-applications system that lives inside the join wizard, replaces the standalone `/admin/waitlist` surface, and gives fans a settings-page path to apply after the fact. The trigger to start: when the founder cohort fill is no longer well-served by the current waitlist UX, or before opening signup beyond hand-picked invitations — whichever comes first. | |
| 318 | + | ||
| 319 | + | ### Model | |
| 320 | + | ||
| 321 | + | Three branches in the wizard, decided up front by the signing-up account: | |
| 322 | + | ||
| 323 | + | - **Free trial** — short pitch (1–2 sentences: what you make, why MNW). Account exists, `can_create_projects = false`, application status `pending`. Operator approval flips it. | |
| 324 | + | - **Benefits account** — longer disclosure (community / mission alignment, the binding-mission-statement framing from the program docs). Same `pending` state, different `application_type` so the admin queue can sort them. | |
| 325 | + | - **Just pay** — skip the application entirely, route to Stripe checkout. **No approval required** — paying is the signal. On subscription activation, `can_create_projects = true` immediately. No `creator_applications` row written. | |
| 326 | + | ||
| 327 | + | Founder rate (50% off, locked for life when window closes) is available on **any** branch during the cohort window — free-trial seats get $0, benefits seats may be subsidized, paid seats get the standard founder discount. | |
| 328 | + | ||
| 329 | + | ### Schema migration | |
| 330 | + | ||
| 331 | + | - [ ] Replace `creator_waitlist` with `creator_applications`. Either rename the table + add columns, or create a sibling and migrate rows. Add `application_type` enum column (`free_trial` | `benefits_account`). Normalize `status` values to `pending` | `approved` | `declined` | `spam`. | |
| 332 | + | - [ ] Backfill existing waitlist rows as `application_type = 'free_trial'` (preserve `pitch`, `created_at`, decision metadata, `selection_method`, `invited_by_user_id`). | |
| 333 | + | - [ ] Drop the `db::waitlist` module + its consumers once nothing references it. The `grant_creator_access` helper is the right primitive to keep — move it under `db::creator_applications`. | |
| 334 | + | ||
| 335 | + | ### Wizard | |
| 336 | + | ||
| 337 | + | - [ ] Insert a new "Choose your entry" step in `join_wizard.rs` flow after profile, before pitch. Three radio options + short descriptions. The chosen branch threads through to the next step. | |
| 338 | + | - [ ] Rebuild `wizards/steps/join/pitch.html` to branch on `application_type` — different prompt text, different length limits (free-trial short, benefits longer). | |
| 339 | + | - [ ] Route the paid branch around the application step entirely: profile → Stripe checkout → complete. On webhook activation, no `creator_applications` row is written; `can_create_projects` is granted on `creator_subscriptions.status = 'active'`. | |
| 340 | + | - [ ] Rewrite `wizards/steps/join/complete.html` so the "Apply for creator access" framing is gone (the question was already answered upstream). Free-trial / benefits accounts see "Application under review"; paid accounts see "Welcome — create your first project." | |
| 341 | + | ||
| 342 | + | ### Dashboard / settings | |
| 343 | + | ||
| 344 | + | - [ ] New `/settings/creator-access` page for fan-only accounts to submit an application after the fact. Same three branches, same pitch requirements. Lives in the dashboard tab rail, not a marketing page. | |
| 345 | + | - [ ] Strip the five existing "Apply for Creator Access" CTAs (`partials/tabs/user_projects.html` x2, `partials/tabs/user_creator.html` heading, `pages/creators.html` step list, `wizards/steps/join/complete.html` card). Replace dashboard surfaces with a small "Apply for creator access" link that routes to `/settings/creator-access`. Marketing page (`creators.html`) drops the "apply from your dashboard" framing in favor of "start your free trial during signup." | |
| 346 | + | ||
| 347 | + | ### Pending UX | |
| 348 | + | ||
| 349 | + | - [ ] Accounts in `pending` status can browse, buy items as a fan, manage profile and settings — they just can't reach creator dashboards. Existing `can_create_projects` guards already block project creation; new behavior is to render an "Application under review" panel (with submitted pitch + submission date) instead of returning 404 or redirecting away. | |
| 350 | + | - [ ] Email notification on approve / decline, distinct templates per `application_type`. Decline template names the reason; approval template points at the dashboard. | |
| 351 | + | ||
| 352 | + | ### Admin | |
| 353 | + | ||
| 354 | + | - [ ] Rename `routes/admin/waitlist.rs` → `routes/admin/applications.rs`. Generalize the approve / decline / spam handlers to read `application_type`. The `grant_creator_access` call on approve stays as-is. | |
| 355 | + | - [ ] Rename `dashboards/admin-waitlist.html` → `dashboards/admin-applications.html`. Add an `application_type` column and a type filter (free_trial / benefits_account / all). The existing stats block (pending / approved / spam / total_creators counts) stays; queries adjust to read the new table. | |
| 356 | + | - [ ] Update admin navigation (`admin_active_page: "waitlist"` → `"applications"`) and any cross-links in the admin shell. | |
| 357 | + | - [ ] Sitemap entry update, breadcrumb update. | |
| 358 | + | ||
| 359 | + | ### Tests + acceptance | |
| 360 | + | ||
| 361 | + | - [ ] Pin: a `pending` account cannot create projects (the existing `can_create_projects` guard already enforces this; verify the rendered panel works). | |
| 362 | + | - [ ] Pin: a "just pay" signup lands at `can_create_projects = true` AND an active Stripe subscription AND **no** `creator_applications` row. | |
| 363 | + | - [ ] Pin: admin queue lists pending applications sorted by `application_type` then `created_at`. | |
| 364 | + | - [ ] Pin: every removed "Apply for Creator Access" string is gone from `templates/` (grep test in `tests/regression/`). | |
| 365 | + | - [ ] Pin: founder rate applies regardless of branch during the cohort window (existing founder-pricing logic; new test asserts the multiplier doesn't depend on `application_type`). | |
| 366 | + | ||
| 367 | + | ### Out of scope (this restructure) | |
| 368 | + | ||
| 369 | + | - Partnership / sponsorship / residency / fellow-led-project applications — those continue via email, no form surface built. If we ever build them, the same `creator_applications` table can host them as additional `application_type` variants. | |
| 370 | + | ||
| 315 | 371 | ## PoM contract guard (landed 2026-05-25) | |
| 316 | 372 | ||
| 317 | 373 | Schema-drift guard test wired against `shared/pom-contract/`: `src/routes/pages/public/health/mod.rs::tests::pom_hetzner_health_expectations_resolve`. `health_json` body builder extracted as pure `health_json_body(overall, db_ok)` for the test. Catches the v0.5.16-class drift where a field is removed from `/api/health` without updating PoM's expectations. See `MNW/CLAUDE.md` § PoM Health Contract. |