# Project: a product-description review workspace

Canonical page: https://yishto.com/en/learn/project-labs/lab-product-description-review/

Author: [Yishto](https://yishto.com/en/about/)

Design versioned drafts, reviewer authority, and evidence checks so AI suggestions require approval before export, with tenant boundaries and stale-version handling.

Published: 2026-11-10
Updated: 2026-11-10

A product-description review workspace receives existing descriptions and supporting material, asks AI for proposed edits, and lets an authorized reviewer approve a specific version. It provides a useful exercise in tenant access, version conflicts, and model-output validation. Generating a suggestion, approving a version, and exporting content are separate operations.

Start with one product, one draft, one model suggestion, and one human review. The tenants, products, and members below are synthetic. Complete this path before adding batches, notifications, or team management.

## Define behavior that can be checked

Authors create drafts, compare original text with suggestions, and submit revisions. Reviewers approve or return versions within their authorized scope. Exports read approved content only. AI has no approval or publishing authority, so receiving a model response must not automatically approve a draft.

Failure requirements include rejecting another tenant's access, preventing authors from impersonating reviewers, and rejecting approval from an outdated page. A model timeout preserves the original. Repeated requests do not create another logical review. Export failure does not undo approval.

Put these rules in interfaces and data constraints, not merely hidden buttons. Tenant, role, and actor fields from the browser are input. The server determines authority from verified identity and membership.

## Model versions and reviews separately

The core entities are tenants, memberships, products, draft versions, reviews, and model runs. Products have stable identifiers. Draft versions contain immutable content and a parent version. A review identifies the exact version and the actor's authorized decision.

An approval Boolean attached to continuously changing text is insufficient. Editing creates a new version. An earlier approval remains historical evidence but cannot authorize exporting the new text. Review records also need reasons, times, and relevant rule versions.

Model runs reference input and source-material versions, output, error category, and processing state. Audit events record actions without copying private text by default. Run model requests outside database transactions to avoid holding locks while waiting.

## Establish access boundaries with Supabase

Configure table privileges and RLS for Data API exposure. Table access and row access are separate questions. `TO authenticated` alone does not restrict tenants or resources; policies must also evaluate trustworthy membership information.

Reading a draft requires membership in its tenant. Writes additionally require the permitted role and action. Update policies must consider access to the existing row, constraints on the new row, and the required read permissions. Prevent reassignment of tenant or ownership fields outside the allowed scope. User-editable metadata must not grant tenant authority.

Keep administrative secret keys and legacy service-role credentials on the server. Current documentation distinguishes management requests without a user access token, which can use service_role to bypass RLS, from requests carrying a user token, which apply that user's policies. Initializing a client with an administrative key is therefore not a complete authorization rule. Privileged services must enforce business authorization explicitly.

## Validate interfaces and model results separately

Draft creation accepts a product identifier, text, and deduplication identifier. The server checks length, identity, and product ownership. Review submission identifies the target and expected version. Approval checks both reviewer authority and version, returning stable permission or conflict errors.

A suggestion may include replacement text, evidence quotations, reasons, and unresolved questions. Structured output constrains fields and format, not the truth of the evidence. Check that quotations belong to permitted material, product identifiers match, and lengths remain bounded before presenting the comparison.

Keep refusals, incomplete output, provider errors, and failed business checks as distinct states. Partial streamed JSON is not a completed suggestion. A successful retry must not erase prior failure evidence. A model adapter exposes the application's result contract so the UI need not understand every provider event.

## Reject approval from an outdated page

This model checks only tenant scope and optimistic version matching. After the version advances from one to two, an approval for version one conflicts. A different tenant is forbidden.

```python
draft = {"tenant": "T-1", "version": 1, "text": "original", "approved": False}
def approve(tenant, version):
    if tenant != draft["tenant"]:
        return "forbidden"
    if version != draft["version"]:
        return "conflict"
    draft["approved"] = True
    return "approved"
assert approve("T-2", 1) == "forbidden"
draft["version"] = 2
assert approve("T-1", 1) == "conflict"
assert approve("T-1", 2) == "approved"
print(draft)
```

The final dictionary has version two and `approved` set to `True`. This code verifies no actual identity, reviewer role, database concurrency, or RLS. It also stores no version history. A real service must coordinate checking and recording through a transaction or conditional update. Sequential memory operations are not a concurrency guarantee.

## Implement one complete path first

Create entities and constraints, then verify access using two synthetic users and two tenants. Implement draft creation, retrieval, and revision. Confirm that refreshing preserves content and version. Add approval and return operations with authority, version checks, and audit recording in one business operation.

Next, connect the interface using fixed suggestion results. Original text, differences, evidence, status, and controls must work before adding a model adapter. Then test timeouts, refusals, and invalid evidence. Fixed results isolate interface problems; they do not establish model quality.

Record each export request as an independent operation bound to the immutable content of a particular approved version. Save its format, version, and state; a retry must not substitute the latest draft. Define how revoked approval affects an export already in progress.

Bound batch size, concurrency, and total budget. Give each item its own state and result so completed work remains visible after partial failure. Retry failures against the original versions instead of reporting incomplete output as total success.

## Exercise: verify both authority and version

Use author, reviewer, and other-tenant identities. Test cross-tenant reads, author approval, stale reviewer submissions, and repeated requests. Rejections must leave content, versions, and approval records free of unauthorized changes.

Then simulate nonexistent model evidence and an interrupted export. Unsupported suggestions must follow a review or failure path. An approved version should remain exportable without approving different text to conceal the error. Record interface expectations and database checks separately from human evaluation of suggestions.

## Sources & further reading

- [Row-level security](https://supabase.com/docs/guides/database/postgres/row-level-security)
- [OpenAPI specification](https://spec.openapis.org/oas/latest.html)
- [Structured outputs guide](https://developers.openai.com/api/docs/guides/structured-outputs)
- [PostgreSQL transactions](https://www.postgresql.org/docs/current/tutorial-transactions.html)

Sources checked on 2026-11-10. Examples are teaching data, not production measurements.

## Related guides

- [Streaming and structured output solve different problems](https://yishto.com/en/learn/models/streaming-and-structured-output/)
- [Find product problems in real work](https://yishto.com/en/learn/product-building/needs-interviews-and-product-discovery/)
