§22 M3-backend Plan B (write path, propose): project-scoped propose (v0.38.0)
A new entry can be proposed into a specific project; it lands in that project's
content repo and shows under that project's proposals. A non-default project is
no longer read-only.
- api.py: POST /api/projects/{pid}/rfcs/propose (propose body extracted into a
project-parameterized helper; unscoped /api/rfcs/propose kept as default
compat). Slug uniqueness, idea-PR reservation, landing state, and the
proposed_use_cases row scoped to the target project. GET
/api/projects/{pid}/proposals.
- cache.py: refresh_meta_pulls loops every project's content_repo, stamping
cached_prs.project_id; projects.content_repo(pid) helper.
- frontend: proposeRFC(projectId,…)/listProposals(projectId); ProposeModal
takes projectId; App resolves current project from the /p/<id>/ URL; Catalog
lists that project's proposals.
- tests: test_project_scoped_propose.py (lands scoped + gated 404). 447 backend
+ 11 Vitest green; clean build.
Known limitation: branch/PR/graduation edit flows + default-id re-stamp not yet
scoped (next slice). Per docs/superpowers/specs/2026-06-04-m3-backend-planb-design.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,42 @@ skip versions are the composition of each intervening adjacent
|
||||
release's steps in order — no A-to-B path is pre-computed beyond
|
||||
that.
|
||||
|
||||
## 0.38.0 — 2026-06-04
|
||||
|
||||
**Minor — §22 M3-backend Plan B (write path, propose): a new entry can be
|
||||
proposed *into a specific project*, landing in that project's content repo and
|
||||
surfacing under that project's proposals. A non-default project is no longer
|
||||
read-only. No upgrade steps; single-project deployments are unaffected.**
|
||||
|
||||
Added:
|
||||
|
||||
- **`POST /api/projects/{pid}/rfcs/propose`** — propose into a chosen project
|
||||
(read-gated, then project-level contribute-gated, §22.6/§22.7). The propose
|
||||
body is now a project-parameterized helper; the unscoped `/api/rfcs/propose`
|
||||
stays as the default-project compat path. Slug uniqueness, the idea-PR
|
||||
reservation, the landing state (§22.4b), and the `proposed_use_cases` row are
|
||||
all scoped to the target project.
|
||||
- **`GET /api/projects/{pid}/proposals`** — pending idea-PRs scoped to one
|
||||
project.
|
||||
- **Per-project PR mirror** (`app/cache.py`): `refresh_meta_pulls` iterates
|
||||
every project's `content_repo`, stamping `cached_prs.project_id` (was: the
|
||||
default project only). `projects.content_repo(pid)` helper added.
|
||||
- **Tests:** `test_project_scoped_propose.py` — propose into a second project
|
||||
lands in its content repo + shows only under its proposals (not the
|
||||
default's); gated-project propose 404s a non-member. 447 backend green.
|
||||
|
||||
Changed:
|
||||
|
||||
- **Frontend:** `api.proposeRFC(projectId, …)` / `listProposals(projectId)`;
|
||||
`ProposeModal` takes a `projectId`; `App` resolves the current project from
|
||||
the `/p/<id>/` URL so the propose modal targets it; `Catalog` lists that
|
||||
project's proposals.
|
||||
|
||||
Known limitation (next slice): the **edit** write flows — branch / PR /
|
||||
graduation — and the **default-project-id re-stamp** (§22.13 step 1) are not
|
||||
yet project-scoped (they still target the default project's content repo). Per
|
||||
`docs/superpowers/specs/2026-06-04-m3-backend-planb-design.md` §1 + §3.
|
||||
|
||||
## 0.37.0 — 2026-06-04
|
||||
|
||||
**Minor — §22 M3-backend Plan B (2/2, read path): per-project RFC serving. A
|
||||
|
||||
Reference in New Issue
Block a user