Skip to content

Record Feedback

Method

This API follows the REST methodology.

HTTP Method

POST: Record designer feedback on a completed wf2des generation.

Feedback is bookkeeping only. It stamps feedbackStatus on the wf2des row so consumers can see how the generated design was received โ€” whether it was hand-fixed before use or adopted as-is. It emits no SQS message, fires no webhook, and triggers no follow-on generation run. The generation itself is unchanged.

Naming Convention

To ensure consistency and readability, JSON nodes in requests and responses use camelCase. SQS payload nodes use snake_case.

Request and Response

Headers

Meta information is set in HTTP headers, not in the response body.

Request Headers

  • Authorization
  • Content-Type
  • Accept
  • Accept-language

Response Headers

  • Content-Type

Record Feedback

URI

POST /api/v1/organizations/{organization_id}/projects/{project_id}/wf2des/{wf2des_id}/feedback

Path Parameters

Name Type Required Description
organization_id integer Required Organization ID
project_id integer Required Project ID
wf2des_id string Required wf2des ID

Request Body

The request body is JSON.

{
  "feedbackStatus": "0"
}

Request Parameters

Name Type Required Description
feedbackStatus string (enum) Required How the generated design was received. "0" fixed (adopted after manual correction) / "1" adopted (used as-is). Any other value is 400.

This endpoint carries only the flag. The feedback detail ({status, changed_nodes[], diff_url, at, by}) is written by the plugin directly to wf2des-api (POST /internal/wf2des/{wf2des_id}/feedback) before this endpoint is called โ€” detail first, flag last. The detail never travels through this endpoint (the backend's service token is read-only on the data plane). See Processing Flow.

Response

The response is JSON (HTTP status: 200 OK).

{
  "wf2desId": "8f14e45f-ceea-467d-9a3e-1b2c3d4e5f60",
  "status": "1",
  "phase": null,
  "feedbackStatus": "0",
  "attempt": 1,
  "recordedAt": "2026-07-10T09:30:00Z"
}

Response Fields

Name Type Description
wf2desId string wf2des ID
status string (enum) Generation status โ€” unchanged by feedback. Feedback is recorded only on a completed run ("1").
phase string | null Generation phase โ€” null on a completed run (feedback does not touch it).
feedbackStatus string (enum) The stamped value โ€” "0" fixed / "1" adopted.
attempt integer Fencing counter of the run (unchanged by feedback).
recordedAt string ISO 8601 timestamp when feedback_status was stamped (updatedAt mirror).

Status / phase enums (wf2des row):

  • status: "0" processing ยท "1" completed ยท "2" failed ยท "3" rejected ยท "4" cancelled
  • phase (inside status "0", null once terminal): "0" parse ยท "1" awaiting_confirm ยท "2" assemble
  • feedbackStatus: "0" fixed ยท "1" adopted

Feedback is idempotent by last-write. Re-recording feedback overwrites the prior feedbackStatus (the plugin re-writes the detail via wf2des-api the same way) and returns 200 OK with the current value.

Authentication

Authentication is performed using JSON Web Tokens (JWT) issued by Amazon Cognito.

Any authenticated session with Write access to the project may record feedback โ€” it is not restricted to the session that triggered the generation. The feedback detail is written by the plugin to the design_generation_result document via the wf2des-api data plane before this endpoint stamps the row.

Error Handling

The following status codes are returned for errors.

Description Status Code Status Name
Missing or invalid feedbackStatus (absent, or not "0" / "1") 400 Bad Request
Missing authentication credentials 401 Unauthorized
Insufficient permissions 403 Forbidden
wf2des, project, or organization not found 404 Not Found
Internal server error 500 Internal Server Error

Feedback is accepted only on a completed run (status "1"). A row that is not completed is treated as not found for feedback purposes and returns 404 โ€” feedback has no meaning on a processing, failed, rejected, or cancelled generation.

Processing Flow

The backend owns the wf2des PostgreSQL row and is the sole writer. Recording feedback is a single detail-first-flag-last sequence applied backend-side โ€” the worker holds no PostgreSQL credentials and never participates. No SQS message is emitted, no webhook fires, and no follow-on run is triggered; the endpoint only annotates a completed row and its result document.

  1. Extract organization ID, project ID, and wf2des_id from path parameters; extract feedbackStatus from the request body.
  2. Verify the user has Write access to the project.
  3. Validate feedbackStatus ("0" fixed / "1" adopted); on an absent or unknown value, return 400.
  4. Load the wf2des row; if it does not exist, is soft-deleted, or its organization_id / project_id does not match the path, return 404.
  5. Confirm the row is status "1" completed; if it is in any other state, return 404 (feedback applies only to a completed run).
  6. Detail first (precondition). The feedback detail โ€” the feedback block ({status, changed_nodes[], diff_url, at, by}, referenced from artifact_urls.feedback_diff) โ€” has already been written by the plugin directly to wf2des-api before this call. Detail before flag guarantees a flagged row always has its feedback detail present; this endpoint neither accepts nor persists the detail.
  7. Flag last. Stamp feedback_status on the wf2des row in one PostgreSQL transaction (also stamping updated_at / updated_by). status, phase, and attempt are untouched.
  8. Return the row with the stamped feedbackStatus.

Re-recording overwrites the prior detail document and re-stamps feedback_status (last-write-wins). Because feedback is bookkeeping only, there is no compare-and-set on attempt โ€” the flag simply reflects the most recent feedback recorded against the completed run.

Detailed Flowchart

flowchart TD
    Start([POST /feedback]) --> Auth[Auth & Parameter Extraction]
    Auth --> Service[Service Layer]

    Service --> AccessCheck[Access Check]
    AccessCheck --> HasAccess{Write Access?}
    HasAccess -->|No| Err403[403 Forbidden]
    HasAccess -->|Yes| Validate[Validate Body<br/>feedbackStatus '0' fixed / '1' adopted]

    Validate --> BodyValid{Valid?}
    BodyValid -->|No| Err400[400 Bad Request]
    BodyValid -->|Yes| LoadRow[Load wf2des Row<br/>WHERE id = :wf2des_id]

    LoadRow --> RowExists{Exists &<br/>org/project match?}
    RowExists -->|No| Err404[404 Not Found]
    RowExists -->|Yes| Completed{status '1'<br/>completed?}

    Completed -->|No| Err404
    Completed -->|Yes| DetailNote[Detail precondition<br/>the plugin has already written the<br/>feedback detail via wf2des-api]

    DetailNote --> FlagLast[Flag last<br/>stamp feedback_status in one PG txn<br/>status / phase / attempt untouched]

    FlagLast --> FlagResult{Success?}
    FlagResult -->|No| Err500[500 Internal Server Error]
    FlagResult -->|Yes| Success[200 OK<br/>row with feedbackStatus stamped]