Skip to content

[Fix] Persist field removals with full PUT form updates - #9

Merged
nilzzzzzz merged 2 commits into
mainfrom
codex/fix-full-put-form-update
Apr 13, 2026
Merged

[Fix] Persist field removals with full PUT form updates#9
nilzzzzzz merged 2 commits into
mainfrom
codex/fix-full-put-form-update

Conversation

@nilzzzzzz

@nilzzzzzz nilzzzzzz commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Reference: n/a

Description

Form editor removals (e.g. task tag, awork mappings/select fields, description) were not always persisted because update payloads omitted cleared values.

Solution

  • Switch form updates to full PUT semantics and send all update fields from frontend.
  • Send explicit null for cleared optional values.
  • Update backend form update logic to apply full replacement semantics for incoming DTO values.
  • Add payload regression tests for serializer + page save flow.
  • Update backend tests/integration tests to send full update payloads.

Preview (screenshots/screencasts)

n/a (backend + payload behavior change)

How has this been tested?

  • Unit Tests / Storybook / E2E / Manually

Commands:

  • npm run test
  • npm run lint
  • npm run build
  • dotnet test backend.Tests/backend.Tests.csproj

awork Runner config

Default

…rm-update

# Conflicts:
#	backend/Forms/FormsService.cs
#	frontend/src/components/form-editor/AworkIntegrationSettings.tsx
#	frontend/src/lib/api.ts
@nilzzzzzz
nilzzzzzz merged commit 9e80c41 into main Apr 13, 2026
1 check passed
Comment on lines +196 to +201
form.AworkProjectId = dto.AworkProjectId;
form.AworkProjectTypeId = dto.AworkProjectTypeId;
form.AworkTaskListId = dto.AworkTaskListId;
form.AworkTaskStatusId = dto.AworkTaskStatusId;
form.AworkTypeOfWorkId = dto.AworkTypeOfWorkId;
form.AworkAssigneeId = dto.AworkAssigneeId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The UpdateForm method unconditionally overwrites fields with null when a partial payload is sent, which can silently delete Awork integration settings.
Severity: CRITICAL

Suggested Fix

To prevent data loss from partial updates, apply null-coalescing to all property assignments in the UpdateForm method. For example, change form.AworkProjectId = dto.AworkProjectId; to form.AworkProjectId = dto.AworkProjectId ?? form.AworkProjectId;. This ensures that fields not present in the request payload retain their existing values in the database.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: backend/Forms/FormsService.cs#L196-L201

Potential issue: The `UpdateForm` endpoint accepts partial JSON payloads. When a client
sends an update for only a subset of fields (e.g., just the form `name`), the other
properties in the `UpdateFormDto` deserialize to `null`. The service then
unconditionally assigns these `null` values to the database entity, for example, via
`form.AworkProjectId = dto.AworkProjectId;`. This silently wipes out existing Awork
integration configurations, causing permanent data loss. While some properties use
null-coalescing to prevent this, the Awork-related fields do not, creating a dangerous
inconsistency.

Did we get this right? 👍 / 👎 to inform future reviews.

Comment on lines +207 to +208
form.LogoUrl = string.IsNullOrWhiteSpace(dto.LogoUrl) ? null : dto.LogoUrl;
form.IsSharedWithWorkspace = dto.IsSharedWithWorkspace ?? form.IsSharedWithWorkspace;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The UpdateForm method incorrectly uses PATCH semantics for IsSharedWithWorkspace and IsActive, preserving nulls instead of applying the intended full PUT semantics.
Severity: MEDIUM

Suggested Fix

In backend/Forms/FormsService.cs, change the assignments for form.IsSharedWithWorkspace and form.IsActive to use direct assignment from the DTO. Additionally, update the backend UpdateFormDto to use non-nullable bool for these properties to match the frontend contract.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: backend/Forms/FormsService.cs#L207-L208

Potential issue: The `UpdateForm` method implements inconsistent update semantics. While
most fields are updated using full PUT semantics (direct assignment), the
`IsSharedWithWorkspace` and `IsActive` properties use PATCH-style semantics via the
null-coalescing operator (`??`). This means if a client sends `null` for these boolean
fields, their existing values are silently preserved instead of being updated. This
contradicts the PR's stated goal of applying full replacement semantics for all incoming
DTO values and can lead to silent data inconsistencies, as a client's intent to clear or
reset a value is ignored without error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant