coulomb-social/docs/spaces-content.md
tegwick 3f30bcd340 Add Forgejo edit/refresh sync path for space content (T05)
Keep git as source of truth: deep-link to Forgejo editor, manual refresh to
drop cache, and optional signed push webhook for automatic invalidation.
2026-08-12 03:29:26 +02:00

63 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Space content — Forgejo markdown (read + write path)
See **ADR-0002**. App DB holds metadata; page bodies are markdown in Forgejo.
## Read (T04)
1. Space row has `forgejo_owner`, `forgejo_repo`, `default_branch`, `content_root`.
2. App fetches `{content_root}/index.md` (or `?page=<slug>``{slug}.md`) via Forgejo raw URL.
3. HTML is sanitized and cached in-process (successes only).
Env (non-secret defaults in settings):
| Variable | Purpose |
|----------|---------|
| `FORGEJO_BASE_URL` | default `https://forgejo.coulomb.social` |
| `FORGEJO_TOKEN` | optional; needed for private repos |
| `FORGEJO_WEBHOOK_SECRET` | optional; enables push webhook cache bust |
## Write / sync (T05)
**Git remains the source of truth.** There is no in-app markdown editor in v1.
### Operator / author workflow
1. Open the space on app.coulomb.social.
2. Click **Edit in Forgejo** (file editor) or **View source**.
3. Commit on the spaces `default_branch` (usually `main`).
4. Click **Refresh content** on the space page (or rely on webhook below).
Demo seed (public raw, no token):
```bash
python manage.py seed_demo_space
# binds demo → coulomb/coulomb-social @ docs/space-fixtures/demo/pages
```
### Webhook (optional, recommended)
So authors do not need to click Refresh after every push:
1. Set `FORGEJO_WEBHOOK_SECRET` in the app env Secret (not in git).
2. In Forgejo: repo → **Settings → Webhooks → Add webhook → Gitea**.
3. **Target URL:** `https://app.coulomb.social/app/spaces/hooks/forgejo/`
4. **HTTP Method:** POST, content type JSON.
5. **Secret:** same value as `FORGEJO_WEBHOOK_SECRET` (Forgejo signs with HMAC-SHA256).
6. Trigger: **Push** events.
Auth accepted by the app:
- `X-Gitea-Signature: <hex hmac-sha256 of body>` (Forgejo default when secret set), or
- `X-Coulomb-Webhook-Secret: <shared secret>`
Response JSON: `{ ok, owner, repo, cache_entries_cleared, spaces_matched }`.
### Fail closed
- Missing binding → clear UI error, no Bubble fallback.
- Fetch errors → error card; previous cache entry is not used after Refresh.
## Related
- `docs/adr/ADR-0002-space-content-forgejo-markdown.md`
- `python manage.py seed_demo_space`