Skip to content
wiki.fftac.org

Restcontroller - Source Excerpt 04

Back to Restcontroller

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]);
        }