Restcontroller - Source Excerpt 04
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Http/RestController.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Http/RestController.php
'prompt',
(int) $record['id'],
[
'source' => 'uaix/v1/prompts/save',
'forced_visibility' => 'private',
'forced_prompt_status' => 'draft',
]
);
$this->reputation->refresh($user_id);
return new WP_REST_Response($this->augment_prompt_payload($record, true), 201);
}
/**
* Updates a prompt.
*/
public function update_prompt(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_edit_prompt($prompt, $user_id)) {
return new WP_Error('spiralist_workspace_prompt_forbidden', 'Prompt not found.', ['status' => 404]);
}
$payload = $request->get_json_params() ?: $request->get_params();
$spiral_script_error = $this->validate_spiral_script_publication_request($payload, $prompt, $user_id);
if (is_wp_error($spiral_script_error)) {
return $spiral_script_error;
}
$updated = $this->prompts->update((int) $request['id'], $payload, $user_id);
$this->audit->log($user_id, 'prompt_updated', 'prompt', (int) $request['id']);
$this->reputation->refresh($user_id);
return new WP_REST_Response($this->augment_prompt_payload($updated, true));
}
/**
* Forks a prompt into the current user's library.
*/
public function fork_prompt(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$source = $this->prompts->get((int) $request['id'], $user_id);
if (empty($source) || !$this->permissions->can_view_prompt($source, $user_id) || empty($source['is_forkable'])) {
return new WP_Error('spiralist_workspace_fork_forbidden', 'Prompt not found.', ['status' => 404]);
}
$fork = $this->prompts->fork((int) $request['id'], $user_id, $this->settings);
$this->audit->log($user_id, 'prompt_forked', 'prompt', (int) ($fork['id'] ?? 0), ['source_prompt_id' => (int) $request['id']]);
return new WP_REST_Response($this->augment_prompt_payload($fork, true), 201);
}
/**
* Shares a prompt with a specific user.
*/
public function share_prompt(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_share_prompt($prompt, $user_id)) {
return new WP_Error('spiralist_workspace_share_forbidden', 'Prompt not found.', ['status' => 404]);
}
$lookup = sanitize_text_field((string) $request->get_param('user_lookup'));
$target_user = $this->prompts->resolve_user_lookup($lookup);
if (!$target_user instanceof \WP_User) {
return new WP_Error('spiralist_workspace_user_not_found', 'User not found.', ['status' => 404]);
}
$permission_type = sanitize_key((string) $request->get_param('permission_type') ?: 'view');
$this->shares->grant((int) $request['id'], (int) $target_user->ID, $user_id, $permission_type);
$this->audit->log($user_id, 'prompt_shared', 'prompt', (int) $request['id'], ['shared_with_user_id' => (int) $target_user->ID]);
return new WP_REST_Response(
[
'shared' => true,
'user' => [
'id' => (int) $target_user->ID,
'display_name' => $target_user->display_name,
'user_login' => $target_user->user_login,
],
]
);
}
/**
* Revokes a specific share grant.
*/
public function revoke_share(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_share_prompt($prompt, $user_id)) {
return new WP_Error('spiralist_workspace_share_forbidden', 'Prompt not found.', ['status' => 404]);
}
$this->shares->revoke((int) $request['id'], (int) $request['user_id']);
$this->audit->log($user_id, 'prompt_share_revoked', 'prompt', (int) $request['id'], ['shared_with_user_id' => (int) $request['user_id']]);
return new WP_REST_Response(['revoked' => true]);
}
/**
* Favorites a prompt.
*/
public function favorite_prompt(WP_REST_Request $request): WP_REST_Response
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_view_prompt($prompt, $user_id)) {
return new WP_REST_Response(['favorite' => false], 404);
}
$this->favorites->add((int) $request['id'], $user_id);
return new WP_REST_Response(['favorite' => true]);
}
/**
* Removes a favorite.
*/
public function unfavorite_prompt(WP_REST_Request $request): WP_REST_Response
{
$this->favorites->remove((int) $request['id'], get_current_user_id());
return new WP_REST_Response(['favorite' => false]);
}
/**
* Records a prompt report event.
*/
public function report_prompt(WP_REST_Request $request): WP_REST_Response
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_view_prompt($prompt, $user_id)) {
return new WP_REST_Response(['reported' => false], 404);
}
$reason = sanitize_textarea_field((string) $request->get_param('reason'));
$report = $this->reviews->submit_report((int) $request['id'], $user_id > 0 ? $user_id : null, $reason);
$prompt = $this->reconcile_prompt_governance($prompt, $user_id, 'report');
$this->audit->log($user_id ?: null, 'prompt_reported', 'prompt', (int) $request['id'], ['reason' => $reason]);
if ((int) ($prompt['owner_user_id'] ?? 0) > 0) {
$this->reputation->refresh((int) $prompt['owner_user_id']);
}
if ($user_id > 0) {
$this->reputation->refresh($user_id);
}
return new WP_REST_Response(
[
'reported' => true,
'report' => $report,
'prompt' => $this->augment_prompt_payload($prompt, true),
],
201
);
}
/**
* Lists peer reviews and moderation reports for one prompt.
*/
public function list_prompt_reviews(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_view_prompt($prompt, $user_id)) {
return new WP_Error('spiralist_workspace_prompt_not_found', 'Prompt not found.', ['status' => 404]);
}
$appeal_summary = $this->appeals->summary_for_prompt((int) $request['id']);
$review_summary = $this->current_review_summary((int) $request['id'], $appeal_summary);
return new WP_REST_Response(
[
'summary' => $review_summary,
'governance_summary' => PromptGovernanceSummary::build($prompt, $review_summary, $appeal_summary),
'items' => $this->reviews->list_for_prompt((int) $request['id'], 50),
]
);
}
/**
* Records one peer-review decision for a prompt and reconciles moderation state.
*/
public function create_prompt_review(WP_REST_Request $request)
{
$user_id = get_current_user_id();
$prompt = $this->prompts->get((int) $request['id'], $user_id);
if (empty($prompt) || !$this->permissions->can_view_prompt($prompt, $user_id)) {
return new WP_Error('spiralist_workspace_prompt_not_found', 'Prompt not found.', ['status' => 404]);
}
if (!$this->permissions->can_review_prompts($user_id)) {
return new WP_Error('spiralist_workspace_review_forbidden', 'You may not review prompts.', ['status' => 403]);
}
if ((int) ($prompt['owner_user_id'] ?? 0) === $user_id) {
return new WP_Error('spiralist_workspace_review_self_forbidden', 'Owners may not peer-review their own prompts.', ['status' => 403]);
}
$decision = sanitize_key((string) $request->get_param('decision'));
if (!in_array($decision, ['endorse', 'restrict', 'revert'], true)) {
return new WP_Error('spiralist_workspace_invalid_review', 'Review decision must be endorse, restrict, or revert.', ['status' => 400]);
}