2026-08-10 09:40:25 +02:00
|
|
|
|
---
|
|
|
|
|
|
id: CSOC-WP-0004
|
|
|
|
|
|
type: workplan
|
|
|
|
|
|
title: "App shell entry and Forgejo-backed space content"
|
|
|
|
|
|
domain: communication
|
|
|
|
|
|
repo: coulomb-social
|
2026-08-12 10:59:25 +02:00
|
|
|
|
status: finished
|
2026-08-10 09:40:25 +02:00
|
|
|
|
owner: bernd
|
|
|
|
|
|
topic_slug: coulomb-social
|
|
|
|
|
|
created: "2026-08-10"
|
2026-08-12 10:59:25 +02:00
|
|
|
|
updated: "2026-08-12"
|
2026-08-11 02:31:55 +02:00
|
|
|
|
# note: T07 added same day — principal diagnostics via profile menu
|
2026-08-10 09:40:25 +02:00
|
|
|
|
depends_on:
|
|
|
|
|
|
- CSOC-WP-0002
|
|
|
|
|
|
related:
|
|
|
|
|
|
- CSOC-WP-0001
|
|
|
|
|
|
- CSOC-WP-0003
|
|
|
|
|
|
origin: operator
|
|
|
|
|
|
origin_ref: session-2026-08-10-parallel-host-product-path
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_workstream_id: "d10427aa-02d9-4ec9-a466-d7cdb1a9167e"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 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`).
|
|
|
|
|
|
|
2026-08-12 10:59:25 +02:00
|
|
|
|
**Finished 2026-08-12:** T01–T07 complete. Operator runbook and smoke pointers
|
|
|
|
|
|
in `docs/deploy.md` and `docs/identity/smoke.md`.
|
|
|
|
|
|
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## Out of scope (this plan)
|
|
|
|
|
|
|
|
|
|
|
|
- Apex DNS cutover / Bubble retirement
|
|
|
|
|
|
- Full Bubble inventory or bulk import
|
2026-08-12 10:59:25 +02:00
|
|
|
|
- Public self-registration (CSOC-WP-0003 residuals / NetKingdom)
|
2026-08-10 09:40:25 +02:00
|
|
|
|
- Full UI parity (Research, marketplace matching, …) beyond space content MVP
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## T01 — Post-login product entry (leave confirmation shell)
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T01
|
2026-08-11 02:31:55 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: high
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "7cce67c0-6234-4ef4-ad67-de952f5f4519"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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).
|
2026-08-11 02:31:55 +02:00
|
|
|
|
- Compact account control (display name / avatar) opening a **profile menu**
|
|
|
|
|
|
(full principal diagnostics live under **T07**, not on the home body).
|
2026-08-10 09:40:25 +02:00
|
|
|
|
- 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.
|
|
|
|
|
|
|
2026-08-11 02:31:55 +02:00
|
|
|
|
2026-08-11: App home is Spaces empty state; header nav + profile menu; principal
|
|
|
|
|
|
dump removed from home body. Deploy with next image for app.coulomb.social.
|
|
|
|
|
|
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## T02 — Space domain model (metadata, tenant-keyed)
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T02
|
2026-08-12 01:30:05 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: high
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "5fd91718-151d-4216-acf2-2104a45cddf9"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
2026-08-12 01:30:05 +02:00
|
|
|
|
2026-08-12: `spaces` app — `Space` + `SpaceMembership`, tenant-scoped list on
|
|
|
|
|
|
`/app/`, detail `/app/spaces/<slug>/`, admin seed path. Tests cover isolation.
|
|
|
|
|
|
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## T03 — Content model ADR: markdown + Forgejo
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T03
|
2026-08-12 01:30:05 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: high
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "628243e0-732f-42c1-b4e3-9b8cd82ea530"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
2026-08-12 01:30:05 +02:00
|
|
|
|
2026-08-12: Provisional ADR-0002 committed; linked from INTENT/SCOPE. One repo
|
|
|
|
|
|
per space, `pages/` root, Forgejo API read for T04; write-in-Forgejo for T05.
|
|
|
|
|
|
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## T04 — Read path: render space markdown from bound repo
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T04
|
2026-08-12 01:56:30 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: high
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "77fa3454-6f2e-4a76-8a0c-ff7e13ca4b6a"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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).
|
|
|
|
|
|
|
2026-08-12 01:56:30 +02:00
|
|
|
|
2026-08-12: Forgejo raw fetch + bleach-sanitized markdown render; demo fixture
|
|
|
|
|
|
at `docs/space-fixtures/demo/pages/index.md`; `seed_demo_space` management
|
|
|
|
|
|
command; env `FORGEJO_BASE_URL` / optional `FORGEJO_TOKEN`.
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## T05 — Write / sync path (minimal)
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T05
|
2026-08-12 03:29:26 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: medium
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "30ed5def-2718-4379-834c-920e751e4d0b"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
2026-08-12 03:29:26 +02:00
|
|
|
|
2026-08-12: **Edit in Forgejo** + **View source** + **Refresh content** on space
|
|
|
|
|
|
detail; repo-scoped cache invalidate; optional push webhook
|
|
|
|
|
|
`POST /app/spaces/hooks/forgejo/` (HMAC or shared secret). Docs:
|
|
|
|
|
|
`docs/spaces-content.md`. No in-app editor (git remains SoR).
|
2026-08-10 09:40:25 +02:00
|
|
|
|
## T06 — Seed and runbook for app.coulomb.social
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T06
|
2026-08-12 10:59:25 +02:00
|
|
|
|
status: done
|
2026-08-10 09:40:25 +02:00
|
|
|
|
priority: medium
|
2026-08-11 02:31:55 +02:00
|
|
|
|
state_hub_task_id: "40a880d0-62b9-4ae4-ab3e-074e8901462a"
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
2026-08-12 10:59:25 +02:00
|
|
|
|
2026-08-12: Full operator runbook in `docs/deploy.md` (demo seed, dedicated
|
|
|
|
|
|
repo, webhook, env table, smoke table). Product smoke section in
|
|
|
|
|
|
`docs/identity/smoke.md`. FORGEJO_* names in `.env.example` and `docs/dev.md`.
|
|
|
|
|
|
Content detail remains `docs/spaces-content.md`.
|
|
|
|
|
|
|
2026-08-11 02:31:55 +02:00
|
|
|
|
## T07 — Principal diagnostics via user profile menu
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: CSOC-WP-0004-T07
|
|
|
|
|
|
status: done
|
|
|
|
|
|
priority: high
|
2026-08-12 01:30:05 +02:00
|
|
|
|
state_hub_task_id: "8487443a-dfd2-4220-a90b-bca2b5b04c4c"
|
2026-08-11 02:31:55 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Keep the current principal card fields available as **detail information**
|
|
|
|
|
|
reachable from the **user profile menu** in the app chrome (not as the primary
|
|
|
|
|
|
post-login page body). Purpose: refine and diagnose identity wiring during
|
|
|
|
|
|
ongoing user, group, role, and tenant management work.
|
|
|
|
|
|
|
|
|
|
|
|
Include at least the present shell fields (and extend as claims become available):
|
|
|
|
|
|
|
|
|
|
|
|
| Area | Examples |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| Identity | display name, username, issuer, subject |
|
|
|
|
|
|
| Platform user | user-engine id, user-engine source |
|
|
|
|
|
|
| Tenancy | tenant id / claims |
|
|
|
|
|
|
| Roles & groups | OIDC/groups/roles claims when present |
|
|
|
|
|
|
| Authz | flex-auth / shell decision reason + decision id |
|
|
|
|
|
|
| Session | assurance / AAL hints when present |
|
|
|
|
|
|
|
|
|
|
|
|
UX:
|
|
|
|
|
|
|
|
|
|
|
|
- Profile menu entry e.g. **Account** / **Session details** / **Identity**
|
|
|
|
|
|
- Detail view at a stable path (e.g. `/account/` or `/account/session/`)
|
|
|
|
|
|
- Readable for operators; no secrets (tokens, proxy secrets) ever rendered
|
|
|
|
|
|
- Sign out remains on the menu
|
|
|
|
|
|
|
|
|
|
|
|
**Done when:** after T01 app chrome exists, tegwick can open the profile menu →
|
|
|
|
|
|
principal/session detail page and see the same diagnostic surface formerly on
|
|
|
|
|
|
the signed-in card, without that card being the home page.
|
|
|
|
|
|
|
|
|
|
|
|
Ship with or immediately after **T01** (same PR is fine).
|
|
|
|
|
|
|
|
|
|
|
|
2026-08-11: `/account/session/` holds principal diagnostics (identity, UE,
|
|
|
|
|
|
tenant, roles/groups, assurance, authz). Profile menu → **Session details**.
|
|
|
|
|
|
Session stashes groups/roles/assurance at login (no secrets).
|
|
|
|
|
|
|
2026-08-10 09:40:25 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Sequencing
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
2026-08-11 02:31:55 +02:00
|
|
|
|
T01 app home entry ──┬─► T07 profile menu principal diagnostics
|
|
|
|
|
|
└─► T02 Space metadata
|
|
|
|
|
|
└─► T03 content ADR
|
|
|
|
|
|
└─► T04 read path (MVP value)
|
|
|
|
|
|
├─► T05 write/sync
|
|
|
|
|
|
└─► T06 runbook
|
2026-08-10 09:40:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Acceptance (workplan)
|
|
|
|
|
|
|
|
|
|
|
|
1. Post-login journey is product-shaped (app home + spaces), not identity-debug-only.
|
2026-08-11 02:31:55 +02:00
|
|
|
|
2. Principal/session diagnostics remain available from the user profile menu (T07).
|
|
|
|
|
|
3. Spaces exist as tenant-keyed app records.
|
|
|
|
|
|
4. Space page content is markdown backed by Forgejo with a working read path.
|
|
|
|
|
|
5. Bubble migration is still not required for demos on app.coulomb.social.
|
|
|
|
|
|
6. CSOC-WP-0001 can map Bubble pages onto the ADR layout when migration starts.
|
2026-08-12 10:59:25 +02:00
|
|
|
|
7. Operator runbook documents seed, bind, secrets (names), and smoke (T06).
|
2026-08-10 09:40:25 +02:00
|
|
|
|
|
|
|
|
|
|
## Related
|
|
|
|
|
|
|
|
|
|
|
|
- Live host: `docs/deploy.md` (app.coulomb.social parallel to Bubble)
|
2026-08-12 10:59:25 +02:00
|
|
|
|
- Identity: CSOC-WP-0002 (done), CSOC-WP-0003 residuals for public registration
|
2026-08-10 09:40:25 +02:00
|
|
|
|
- Migration later: CSOC-WP-0001
|
|
|
|
|
|
- Design tokens: `docs/design-extract/`
|