--- id: CSOC-WP-0004 type: workplan title: "App shell entry and Forgejo-backed space content" domain: communication repo: coulomb-social status: active owner: bernd topic_slug: coulomb-social created: "2026-08-10" updated: "2026-08-10" depends_on: - CSOC-WP-0002 related: - CSOC-WP-0001 - CSOC-WP-0003 origin: operator origin_ref: session-2026-08-10-parallel-host-product-path --- # CSOC-WP-0004 — App shell entry and Forgejo-backed space content ## Context Identity is live on **`https://app.coulomb.social`**. After Sign in, members land on an identity **confirmation shell** (“Signed in” + principal dump) with no product surface. Bubble on apex remains the full product until we choose cutover. **Goal for this phase:** build the new implementation toward product usefulness **before** bulk Bubble data migration. Immediate product foundation: 1. Leave the login confirmation shell into a real **app home**. 2. Establish **space** persistence whose **content is markdown**, stored and versioned in close connection with **Forgejo** repositories. Migration of all Bubble spaces is **explicitly later** (`CSOC-WP-0001`). ## Out of scope (this plan) - Apex DNS cutover / Bubble retirement - Full Bubble inventory or bulk import - Public self-registration (CSOC-WP-0003 / NetKingdom) - Full UI parity (Research, marketplace matching, …) beyond space content MVP --- ## T01 — Post-login product entry (leave confirmation shell) ```task id: CSOC-WP-0004-T01 status: todo priority: high ``` Replace the dead-end “Signed in / Principal” page as the primary post-login destination with an **app home** that a member can use: - Clear primary navigation: Spaces (and placeholders for later surfaces). - Principal summary available but secondary (account menu or `/account/`). - Empty state when the member has no spaces yet (“Create space” or “No spaces”). - `LOGIN_REDIRECT_URL` and templates updated; design-extract tokens only as needed. **Done when:** after OIDC login on app.coulomb.social, tegwick lands on app home (not a debug-only principal card) and can navigate without guessing URLs. ## T02 — Space domain model (metadata, tenant-keyed) ```task id: CSOC-WP-0004-T02 status: todo priority: high ``` Introduce `Space` (name pending Bubble vocabulary alignment) as application metadata in the app DB: - `tenant_id`, stable slug, display title, owner/membership linkage to Member - **no** long-form page bodies in Postgres as the system of record - optional pointer fields for content binding (repo, default branch, root path) Migrations + admin + minimal list/detail routes behind auth. **Done when:** authenticated user can list zero-or-more spaces from DB; tests cover tenant isolation basics. ## T03 — Content model ADR: markdown + Forgejo ```task id: CSOC-WP-0004-T03 status: todo priority: high ``` Write `docs/adr/ADR-0002-space-content-forgejo-markdown.md` deciding: - Markdown (and assets) as the **canonical content form** for space pages - Forgejo repo layout (one repo per space vs monorepo paths; branch policy) - How the app **reads** content (clone/cache, raw API, webhook invalidation) - How the app **writes** (direct git push as service account vs user OAuth to Forgejo) - Relationship to Bubble page/chunk model for later CSOC-WP-0001 mapping - Secrets: Forgejo tokens via OpenBao / env secret names only **Done when:** ADR accepted (or explicitly provisional with open questions listed) and linked from INTENT/SCOPE. ## T04 — Read path: render space markdown from bound repo ```task id: CSOC-WP-0004-T04 status: todo priority: high ``` Implement a vertical slice: - Operator or seed binds one space to a Forgejo repo path - App fetches/renders a markdown page (e.g. `README.md` or `pages/index.md`) - Authz: member of tenant/space only (flex-auth or coarse membership check) - Fail closed on missing binding or fetch errors **Done when:** tegwick can open a space on app.coulomb.social and see rendered markdown sourced from Forgejo (not Bubble). ## T05 — Write / sync path (minimal) ```task id: CSOC-WP-0004-T05 status: todo priority: medium ``` Minimal authoring or sync so content is not read-only forever: - either in-app edit → commit to Forgejo, or - documented “edit in Forgejo / pull request” workflow + refresh webhook Prefer the smaller path that keeps git as source of truth. **Done when:** a content change in Forgejo appears in the app without redeploy, and (if in-app write exists) a save produces a commit without secrets in git. ## T06 — Seed and runbook for app.coulomb.social ```task id: CSOC-WP-0004-T06 status: todo priority: medium ``` Document operator steps: create Forgejo org/repo, bind space, credentials env names, smoke checklist on app.coulomb.social. Update `docs/deploy.md` and `docs/identity/smoke.md` pointers as needed. --- ## Sequencing ```text T01 app home entry └─► T02 Space metadata └─► T03 content ADR └─► T04 read path (MVP value) ├─► T05 write/sync └─► T06 runbook ``` T01 can ship alone to fix the “stuck on login confirmation” UX immediately. T03 should land before large T04 investment if write-model choices are unclear; a **provisional** ADR is enough to start T04 against a single seed repo. ## Acceptance (workplan) 1. Post-login journey is product-shaped (app home + spaces), not identity-debug-only. 2. Spaces exist as tenant-keyed app records. 3. Space page content is markdown backed by Forgejo with a working read path. 4. Bubble migration is still not required for demos on app.coulomb.social. 5. CSOC-WP-0001 can map Bubble pages onto the ADR layout when migration starts. ## Related - Live host: `docs/deploy.md` (app.coulomb.social parallel to Bubble) - Identity: CSOC-WP-0002 (done), CSOC-WP-0003 (registration later) - Migration later: CSOC-WP-0001 - Design tokens: `docs/design-extract/`