research/publish: gate approve+reject on Owner role (#4)
ci / gates (push) Successful in 5s
ci / frontend (push) Successful in 24s
ci / rust (push) Successful in 4m5s
ci / e2e (push) Skipped
ci / publish (push) Successful in 4m32s

This commit was merged in pull request #4.
This commit is contained in:
2026-07-15 04:28:01 +00:00
parent dd791061ee
commit 1cb643142c
5 changed files with 149 additions and 5 deletions
+8 -2
View File
@@ -13,8 +13,8 @@
//! POST /api/research/:id/submit-review processing → reviewing
//! POST /api/research/:id/request-publish create pending publish approval
//! GET /api/research/publish-approvals list workspace's pending approvals
//! POST /api/research/publish-approvals/:id/approve reviewing → publishing
//! POST /api/research/publish-approvals/:id/reject stays in reviewing
//! POST /api/research/publish-approvals/:id/approve reviewing → publishing (Owner only)
//! POST /api/research/publish-approvals/:id/reject stays in reviewing (Owner only)
//! POST /api/research/wizard/refine one-shot LLM refine helper
use axum::extract::{Path, State};
@@ -965,6 +965,12 @@ async fn decide_publish(
approve: bool,
notes: Option<String>,
) -> Result<StatusCode, ApiError> {
// Publish gate is workspace-owner-only. Members can request review (via
// POST /api/research/:id/publish) but cannot decide it — mirrors the
// billing/access-policy scope described in Role::is_owner (spec §1).
if !user.role.is_owner() {
return Err(ApiError::Forbidden);
}
let approval =
cm_db::repo::research_publish_approvals::get(&state.pool, id, user.workspace_id.as_uuid())
.await?