Skip to content

fix: policy version API content bug + published version protection#2130

Merged
tofikwest merged 4 commits intomainfrom
tofik/fix-policy-version-api-content
Feb 12, 2026
Merged

fix: policy version API content bug + published version protection#2130
tofikwest merged 4 commits intomainfrom
tofik/fix-policy-version-api-content

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Feb 12, 2026

Summary

  • Fix policy version content stored as empty arrays via APIclass-transformer with enableImplicitConversion was converting TipTap node objects to [] when processing content: unknown[] DTO fields. Added @Transform decorator to preserve raw values. This fixes the customer-reported issue where PATCH always returned 200 but content showed empty in the UI.
  • Add GET /policies/:id/versions/:versionId — new endpoint so API users can fetch a single version by ID (previously returned 404).
  • Protect published versions consistently — aligned all mutation paths (API + UI) to only block edits on the current version when the policy is actually published. Draft policies can freely edit their current version (v1).
  • Sync content to current version via PATCH /policies/:id — previously this endpoint updated Policy.content but not the current PolicyVersion.content, causing them to go out of sync.
  • Fix false success toast on PDF upload/deletePdfViewer now checks result.data.success before showing the success toast. Previously showed "PDF uploaded successfully" even when the server action returned { success: false }.

Test plan

  • API: Create a draft policy via API, PATCH version content with TipTap JSON → verify content is stored correctly (not empty arrays)
  • API: GET /policies/:id/versions/:versionId returns the version with content
  • API: Cannot PATCH content on the current version of a published policy (returns 400)
  • API: Can PATCH content on the current version of a draft policy
  • API: PATCH /policies/:id with content on a draft policy → verify both Policy.content and current version content are updated
  • UI: Upload PDF to a draft policy (v1) → verify it succeeds and displays
  • UI: Upload PDF to the published version → verify error toast is shown (not success)
  • UI: Existing policy editing in the UI still works as before (no regressions)

🤖 Generated with Claude Code

tofikwest and others added 2 commits February 12, 2026 15:54
class-transformer with enableImplicitConversion was converting TipTap node
objects to empty arrays when processing content: unknown[] DTO fields.
Added @Transform decorator to preserve raw values.

Also:
- Block content updates on published policies via PATCH /policies/:id
- Align updateVersionContent guard with UI (only block current version when published)
- Sync content to current version when updating via PATCH /policies/:id
- Add GET /policies/:id/versions/:versionId endpoint
- Add Swagger docs for new endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lse success toast

The upload and delete PDF guards blocked all operations on the current version
regardless of policy status. Now only blocks when policy is actually published
(matching the pattern used everywhere else).

Also fixed PdfViewer onSuccess handlers to check result.data.success before
showing the success toast — previously showed "PDF uploaded successfully"
even when the server action returned { success: false }.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Feb 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped Feb 12, 2026 9:46pm
portal Skipped Skipped Feb 12, 2026 9:46pm

Request Review

@cursor
Copy link

cursor bot commented Feb 12, 2026

PR Summary

Medium Risk
Touches policy update/version mutation rules and wraps updates in a DB transaction, which could change client behavior and error cases for non-draft policies. Also adds a new read endpoint and adjusts UI feedback, so risk is mostly around correctness/regressions in policy editing flows.

Overview
Fixes API request DTO handling for TipTap JSON fields by adding @Transform(({ value }) => value) on content/chatHistory, preventing class-transformer from coercing rich objects into empty arrays.

Adds GET /v1/policies/:id/versions/:versionId (with Swagger/OpenAPI updates) to fetch a single version including metadata.

Hardens mutation paths: PATCH /policies/:id now runs in a transaction, blocks content updates unless the policy is draft, and keeps PolicyVersion.content synced with Policy.content; version-content updates and PDF upload/delete actions now also treat the current version as immutable unless the policy is draft (covering published and needs_review). UI PdfViewer now only shows success toasts when server actions return success: true.

Written by Cursor Bugbot for commit 425bacf. This will update automatically on new commits. Configure here.

@tofikwest tofikwest changed the title [dev] [tofikwest] tofik/fix-policy-version-api-content fix: policy version API content bug + published version protection Feb 12, 2026
…fix stale pointer

Change version mutation guards from `status === 'published'` to `status !== 'draft'`
so that the current version is also protected when the policy is in needs_review state.
Fix stale currentVersionId in updateById by reading it inside the transaction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

…publish bypass

The draft-only content guard was reading policy status before the
transaction, allowing a concurrent publish to bypass the check. Now
the existence check and status guard both run inside the transaction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel vercel bot temporarily deployed to Preview – app February 12, 2026 21:46 Inactive
@vercel vercel bot temporarily deployed to Preview – portal February 12, 2026 21:46 Inactive
@tofikwest tofikwest merged commit 7f79351 into main Feb 12, 2026
12 of 13 checks passed
@tofikwest tofikwest deleted the tofik/fix-policy-version-api-content branch February 12, 2026 21:51
claudfuen pushed a commit that referenced this pull request Feb 12, 2026
## [1.82.3](v1.82.2...v1.82.3) (2026-02-12)

### Bug Fixes

* **app:** check DNS records using Node's built-in DNS instead of using external APIs ([#2126](#2126)) ([5fab9bd](5fab9bd))
* **app:** enable capitalized text for role in csv when adding users ([#2123](#2123)) ([5fdb448](5fdb448))
* **automation:** clarify automation agent's data retrieval capabilities ([#2129](#2129)) ([eb2957f](eb2957f))
* policy version API content bug + published version protection ([#2130](#2130)) ([7f79351](7f79351))
@claudfuen
Copy link
Contributor

🎉 This PR is included in version 1.82.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

carhartlewis pushed a commit to carhartlewis/comp that referenced this pull request Feb 13, 2026
…rycompai#2130)

* fix(api): fix policy version content stored as empty arrays via API

class-transformer with enableImplicitConversion was converting TipTap node
objects to empty arrays when processing content: unknown[] DTO fields.
Added @Transform decorator to preserve raw values.

Also:
- Block content updates on published policies via PATCH /policies/:id
- Align updateVersionContent guard with UI (only block current version when published)
- Sync content to current version when updating via PATCH /policies/:id
- Add GET /policies/:id/versions/:versionId endpoint
- Add Swagger docs for new endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(app): allow PDF upload/delete on draft policy versions and fix false success toast

The upload and delete PDF guards blocked all operations on the current version
regardless of policy status. Now only blocks when policy is actually published
(matching the pattern used everywhere else).

Also fixed PdfViewer onSuccess handlers to check result.data.success before
showing the success toast — previously showed "PDF uploaded successfully"
even when the server action returned { success: false }.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(api,app): protect current version during needs_review status and fix stale pointer

Change version mutation guards from `status === 'published'` to `status !== 'draft'`
so that the current version is also protected when the policy is in needs_review state.
Fix stale currentVersionId in updateById by reading it inside the transaction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(api): move status guard inside transaction to prevent concurrent publish bypass

The draft-only content guard was reading policy status before the
transaction, allowing a concurrent publish to bypass the check. Now
the existence check and status guard both run inside the transaction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Tofik Hasanov <annexcies@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
carhartlewis pushed a commit to carhartlewis/comp that referenced this pull request Feb 13, 2026
## [1.82.3](trycompai/comp@v1.82.2...v1.82.3) (2026-02-12)

### Bug Fixes

* **app:** check DNS records using Node's built-in DNS instead of using external APIs ([trycompai#2126](trycompai#2126)) ([5fab9bd](trycompai@5fab9bd))
* **app:** enable capitalized text for role in csv when adding users ([trycompai#2123](trycompai#2123)) ([5fdb448](trycompai@5fdb448))
* **automation:** clarify automation agent's data retrieval capabilities ([trycompai#2129](trycompai#2129)) ([eb2957f](trycompai@eb2957f))
* policy version API content bug + published version protection ([trycompai#2130](trycompai#2130)) ([7f79351](trycompai@7f79351))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants