Skip to content

46129 frontend [ templates ] Add FieldSets#205

Open
Maria-Lordwill wants to merge 201 commits into
masterfrom
frontend/templates/46129__add_fieldsets
Open

46129 frontend [ templates ] Add FieldSets#205
Maria-Lordwill wants to merge 201 commits into
masterfrom
frontend/templates/46129__add_fieldsets

Conversation

@Maria-Lordwill

@Maria-Lordwill Maria-Lordwill commented Apr 24, 2026

Copy link
Copy Markdown
Collaborator

1. Release notes

Added support for grouped fields (Fieldsets) in templates and running workflows. Users can now create reusable fieldsets in a catalog, add them to kickoff forms and tasks in the template builder, customize their display order alongside individual fields, fill them out during task execution, and view completed fieldset values in the task execution log, workflow modal, and active task cards. Additionally, a sorting dropdown has been added to the fieldsets catalog page.


2. Description (Problem)

Previously, the concept of fieldsets did not exist in the system as an entity. All fields in templates, kickoff forms, and tasks were configured individually as a flat structure. When a template required identical groups of fields across multiple tasks or kickoff configurations (e.g., billing details, company profile, delivery addresses), administrators had to manually recreate those fields repeatedly. This process was error-prone, caused duplicate configurations, and made template updates/maintenance difficult.

A reusable fields grouping mechanism was required to introduce the new Fieldsets Catalog entity with seamless integration across the template editor, runtime task forms, and workflow execution history.


3. Context

  • Related backend task: Task 45773 (backend/fieldsets/45773__fieldsets).
  • Affected screens:
    • Template Editor (Kickoff and Task output flow configuration) — /templates/edit/:id and /templates/new
    • Active Task Card and execution forms — /tasks/:id
    • Workflow Modal and execution logs — /workflows/:id
    • Fieldsets catalog overview page — /fieldsets

4. Solution

  • Fieldset Entity Implementation: Integrated the fieldset catalog CRUD endpoints, created /fieldsets list page with name/date sorting dropdown, and implemented breadcrumb links on the fieldset details view.
  • Template Editor Integration: Supported binding fieldsets to kickoff and task parameters, cloning template bindings, and validating template ownership upon editing.
  • Unified Display Ordering: Centralized fieldset and standalone fields sorting by order inside mergeTaskOutputFlow.ts, and extracted MergedOutputRows.tsx component to unify layout rendering.
  • Runtime Support:
    • Validation: Guarded task completion and workflow startup from proceeding when required fieldset fields are left blank.
    • Template Variables: Updated variable parsing logic in getTaskVariables.tsx to handle nested fieldset properties.
    • File Attachments: Allowed media uploaded within fieldsets to show up in the process-wide attachments list.
  • Redux State Management: Shifted all catalog fetches to the centralized fieldsets Redux slice. Added isCatalogLoaded and current templateId checks to cache catalog items and prevent duplicate API calls during screen swaps.
  • WebSocket Synchronization: Updated realtime event parsers (watchWsEvents.ts, routeRealtimeEvent.ts) to handle fieldset structures in notifications, group adjustments, and completed workflow logs.
  • Label-Left Layout Support: Implemented responsive label-on-the-left positioning for desktop views across both fieldset-enclosed and standalone fields during Process Run, supporting Date, User, File, Checkbox, Radio, Attachment, and Dropdown types.
  • Field Name Overflow Fix: Replaced AutosizeInput with native auto-expanding textareas for Checkbox, Radio, and Attachment components to prevent clipping of long field labels.
  • RichText Editor Enhancements: Introduced responsive scaling for the rich editor toolbar and improved image-loading error handlers along with anchor HTML tag closing.

5. Implementation Details

Before → After

Module / Component Before After
01. Fieldsets Catalog Did not exist in the system. Added /fieldsets catalog page with sorting dropdown and breadcrumbs navigation.
02. Data Contracts & State Supported only flat IExtraField models. Introduced IFieldsetCatalogItem, IFieldsetBindingClient, and IFieldsetRuntime contracts. Catalog logic is handled via Redux with cache controls.
03. Template Builder Fields had to be added individually. Pre-defined fieldsets can be bound and interleaved with standard fields.
04. Runtime Form Views Rendered standard individual fields only. Unified standard fields and fieldset contents into a single sorted list using MergedOutputRows.tsx.
05. Form Guards Audited required standard fields. Blocked task/kickoff submissions if required fields within fieldsets are empty.
06. Media Attachments Extracted files only from individual fields. Files attached inside fieldsets populate the process "Files" viewer.
07. WebSockets Sync Realtime handlers skipped fieldsets. Enhanced WS events to sync fieldset data (notifications, completions, groups).
08. Field Label Alignment All labels were rendered strictly above the input fields. Added desktop-only label-on-the-left (label-left) layout support for fieldset-enclosed and standalone fields in Process Run.
09. Long Field Label Styling Labels were clipped or misaligned due to AutosizeInput boundary limits. Swapped with native auto-expanding textareas to wrap long labels seamlessly without overflow issues.
10. Fieldset Reuse Identical field groups were manually duplicated across every task and template. A single catalog fieldset can be bound to multiple tasks and templates; data is isolated at runtime via unique apiNameBinding.
11. Cloning Task/template cloning did not account for fieldset bindings. Clone logic generates new apiNameBinding values for each copy, ensuring clone data independence from the original.
12. Unified Ordering Fields were rendered as a flat list without grouped element support. Fields and fieldsets are merged by order into a single interleaved stream (Editor, TaskCard, Kickoff, WorkflowLog, Highlights, TuneView).
13. RichText Editor Toolbar Static editor toolbar sizes caused visual wrapping or clunky experience on smaller layouts. Implemented responsive scaling for the rich text editor toolbar.

6. What to Test

6.1 Preconditions

  • Log in as an administrator in the dev environment.
  • Create 2-3 sample fieldsets in the catalog (via Fieldsets menu). Ensure one has a required text field and a file upload field.
  • Set up a test template containing a mix of standalone fields and bound fieldsets in Kickoff and tasks.

6.2 Positive Scenarios / Test Report

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
01. Interleaved ordering in Editor 1. Open a template in the editor.
2. Add 2 fields and 1 fieldset to Kickoff.
3. Drag the fieldset between the two fields.
4. Save the template and refresh the page.
→ Expected: the custom layout order is fully preserved.
[ ] [ ] [ ] [ ]
02. Required fieldset fields 1. Start a workflow with a fieldset that contains a required field.
2. Try submitting with the required field empty.
→ Expected: the submit button is disabled, showing a validation warning.
3. Fill the field.
→ Expected: the button becomes active.
[ ] [ ] [ ] [ ]
03. Workflow Log display 1. Complete a task containing filled fieldsets.
2. Open the Workflow Log.
→ Expected: fieldset data is rendered within a distinct grouped container in the correct order.
[ ] [ ] [ ] [ ]
04. Fieldset file attachments 1. Upload a file to a fieldset's File field during execution.
2. Open the process "Files" tab (attachments-only).
→ Expected: the uploaded file is visible in the process files list.
[ ] [ ] [ ] [ ]
05. Fieldset catalog sorting 1. Open /fieldsets page.
2. Select name sorting (Name Asc/Desc) and date sorting in the dropdown.
→ Expected: the list order updates immediately.
[ ] [ ] [ ] [ ]
06. Label-left positioning 1. Configure a fieldset field in the editor with left-label layout enabled.
2. Open the Process Run form on desktop.
→ Expected: the label is rendered to the left of the input field.
3. Resize screen down to mobile viewport.
→ Expected: layout shifts responsively, label moves above the input.
[ ] [ ] [ ] [ ]
07. Long field labels wrap 1. Create a Radio/Checkbox field with a very long label text (100+ chars).
2. Load the task execution form.
→ Expected: the label wraps cleanly using textarea auto-expansion, without clipping.
[ ] [ ] [ ] [ ]
08. Fieldset reuse in tasks 1. Bind the same fieldset from the catalog to two different tasks within the same template.
2. Start a workflow and fill in the fieldset fields in the first task.
→ Expected: the fieldset fields in the second task remain empty (data is isolated per task).
3. Complete both tasks.
→ Expected: Workflow Log displays the correct completed fieldset values for each task independently.
[ ] [ ] [ ] [ ]
09. Fieldset reuse in templates 1. Bind the same fieldset catalog item to Template A and Template B.
2. Start workflows for both templates concurrently and fill in the fieldset values.
→ Expected: process data is completely isolated.
3. Rename or update the fieldset in the catalog.
→ Expected: when editing templates A and B, the updated fieldset structure is reflected correctly in both editors.
[ ] [ ] [ ] [ ]
10. Unified display sequence 1. Create a task output flow with mixed ordering: Field 1, Fieldset 1, Field 2, Fieldset 2.
2. Verify rendering sequence across all project display views:
  a) Active Task Card (/tasks/:id) during execution;
  b) Workflow Log execution history (/workflows/:id) inside task blocks;
  c) Workflow Starter (Kickoff form) in dashboard/modal;
  d) Highlights feed in logs;
  e) Outputs Preview screen in template builder;
  f) Tune View modal (field display configuration).
→ Expected: in all views, elements are rendered in the exact order (Field 1 -> Fieldset 1 -> Field 2 -> Fieldset 2).
[ ] [ ] [ ] [ ]
11. Add fieldset to Kickoff 1. Open the template editor, Kickoff section.
2. Click the add fieldset button → select a fieldset from the catalog.
→ Expected: the fieldset appears in the Kickoff output flow with the full list of fields and drag handles.
3. Save the template.
→ Expected: on reload, the fieldset is persisted with correct order and all fields intact.
[ ] [ ] [ ] [ ]
12. Add fieldset to Task 1. Open the template editor, select a task.
2. Add a fieldset from the catalog to the task's Output flow.
→ Expected: the fieldset is rendered interleaved with regular fields per order.
3. Save and reload.
→ Expected: fieldset is in place with correct order.
[ ] [ ] [ ] [ ]
13. Remove fieldset from task 1. In the template editor, remove a bound fieldset from a task.
→ Expected: the fieldset disappears from the Output flow, regular fields remain, order is recalculated.
2. Save the template.
→ Expected: fieldset is removed; running workflows with this template are unaffected.
[ ] [ ] [ ] [ ]
14. Variables from fieldset fields 1. In the template editor, bind a fieldset to Kickoff.
2. In a task description, insert a variable from a fieldset field via the variables menu.
3. Save and start a workflow, filling in the field.
→ Expected: the variable in the task description is substituted with the filled value.
[ ] [ ] [ ] [ ]
15. Clone task with fieldset 1. In the template editor, clone a task that has a bound fieldset.
→ Expected: the cloned task contains the same fieldset with a unique apiNameBinding.
2. Save the template.
→ Expected: both tasks have independent bindings to the same catalog fieldset.
[ ] [ ] [ ] [ ]
16. Task Card completion 1. Start a workflow, open the active task card (/tasks/:id).
2. Fill in the fieldset fields and complete the task.
→ Expected: the complete button is active only when required fieldset fields are filled. Data is saved.
[ ] [ ] [ ] [ ]
17. Kickoff from modal 1. On the templates page, click "Run" → the Kickoff modal opens.
2. Verify that fieldsets are displayed in the correct order in the modal.
3. Fill in the fields and start the workflow.
→ Expected: workflow is created with all fieldset field values saved.
[ ] [ ] [ ] [ ]
18. Public Form 1. Open the public Kickoff form link for a workflow containing fieldsets.
→ Expected: fieldsets are displayed correctly without auth errors.
2. Fill in and submit the form.
→ Expected: workflow starts with all fieldset values saved.
[ ] [ ] [ ] [ ]
19. Catalog CRUD 1. Create a new fieldset on /fieldsets (name, description, fields).
→ Expected: fieldset is created and appears in the list.
2. Open the fieldset detail page, change the name and save.
→ Expected: name is updated.
3. Delete a fieldset not bound to any template.
→ Expected: fieldset is removed from the list.
[ ] [ ] [ ] [ ]
20. WebSocket: task completion update 1. Open the Workflow Log in one browser tab.
2. In another tab/browser, complete a task with filled fieldset fields.
→ Expected: the first browser updates in real time showing the completed fieldset block.
[ ] [ ] [ ] [ ]
21. Fieldset variables in Conditions and DueDate 1. In the template editor, bind a fieldset with a Date field to a task.
2. Use that field in the DueDate configuration of another task.
3. Use a variable from the fieldset in a task Condition.
4. Save and start a workflow.
→ Expected: DueDate is calculated correctly, the condition triggers based on the fieldset value.
[ ] [ ] [ ] [ ]
22. Remove fieldset with bound variables 1. In the editor, bind a fieldset to a task and insert variables from its fields into task descriptions.
2. Remove (unbind) that fieldset from the task.
→ Expected: dangling variables from the removed fieldset are handled gracefully (no render errors). Template saves without errors.
[ ] [ ] [ ] [ ]
23. Edit Kickoff of running workflow 1. Start a workflow with fieldsets in Kickoff.
2. Open the workflow page → click "Edit Kickoff" (WorkflowEditPopup).
3. Change fieldset field values and save.
→ Expected: values are updated, changes are reflected in the Workflow Log and active tasks.
[ ] [ ] [ ] [ ]
24. Return To (revert task) 1. Complete a task with filled fieldset fields.
2. Use the "Return To" function to send the task back for rework.
→ Expected: task is reverted, previously filled fieldset fields are preserved and available for re-editing.
[ ] [ ] [ ] [ ]
25. Task Events Log 1. Complete a task containing filled fieldset fields.
2. Open the task page → events section (Task Log).
→ Expected: the task completion event displays fieldset fields in the correct order.
[ ] [ ] [ ] [ ]
26. Workflows Grid Page 1. Start several workflows from a template with fieldsets.
2. Open the workflows list page (Workflows Grid).
→ Expected: the page loads without errors, fieldset data is correctly normalized (no crash).
[ ] [ ] [ ] [ ]
27. Clone template 1. Clone a template containing tasks with bound fieldsets.
→ Expected: the new template has all fieldset bindings with unique apiNameBinding values.
2. Open the cloned template and inspect the task Output flow.
→ Expected: fieldsets are in place, variables reference the clone's fieldset, not the original.
[ ] [ ] [ ] [ ]
28. Clone workflow 1. Open a completed or active workflow.
2. Click "Clone" (create a new workflow based on the current one).
→ Expected: the Kickoff form of the new workflow contains fieldsets with values pre-filled from the original.
3. Start the cloned workflow.
→ Expected: workflow is created with correct fieldset data.
[ ] [ ] [ ] [ ]
29. Tune View modal 1. Open a task card or workflow page.
2. Click the display settings icon (Tune View).
3. Verify that fieldset fields appear in the modal's field list with correct names and grouping.
→ Expected: fieldset fields are visible, order matches the template configuration.
[ ] [ ] [ ] [ ]

6.3 Negative Scenarios and Edge Cases

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
01. Non-existent fieldset (404) 1. Access /fieldsets/999999 directly.
→ Expected: redirects to the templates overview page, and showing an error notification.
[ ] [ ] [ ] [ ]
02. Duplicate fieldset binding 1. Open a template task in the editor.
2. Attempt to add the same fieldset catalog item twice to the same task.
→ Expected: duplicate addition is disabled or ignored.
[ ] [ ] [ ] [ ]
03. Template ownership validation 1. Attempt to open a fieldset details page belonging to another organization's template.
→ Expected: access is denied; redirects to safety with an error banner.
[ ] [ ] [ ] [ ]

6.4 Verification Points

  • UI: Fieldset blocks are visually enclosed with a header like Fieldset: [Name].
  • UI: Drag-and-drop ordering in the template editor does not cause layout jumps or input focus loss.
  • WebSocket: When another user completes a task, the complete_workflow WS event is processed and the UI updates the fieldset data reactively.
  • API: Queries to /v3/fieldsets include ordering=name or ordering=-created_at.

6.5 Not Tested

  • Locales other than en_US and ru_RU were not tested.
  • Simultaneous template updates by multiple administrators (race conditions) were not tested.

7. Refactoring

Refactoring was carried out to substitute direct API queries with a cached Redux store (redux/fieldsets/slice.ts), caching records based on templateId and isCatalogLoaded. Standardized rendering components by migrating all kickoff and task display files to the new MergedOutputRows.tsx, eliminating layout duplication in the Workflow Log, Task Log, and Kickoff Modal.

Refactoring Verification

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
01. Fast template navigation 1. Click rapidly between different templates in the sidebar.
→ Expected: catalog data is loaded from the Redux cache, preventing multiple API requests.
[ ] [ ] [ ] [ ]
02. State cleanup on template switch 1. View template A, then open template B.
→ Expected: no flashing of stale template A fieldsets occurs.
[ ] [ ] [ ] [ ]

8. Affected Areas (Dependencies)

Scenario Description (Steps & Expected Result) Chrome Desktop Safari Desktop Chrome Mobile Safari Mobile
01. Workflow Starter (Kickoff) Initiating a process from the dashboard or templates page.
→ Expected: the kickoff form correctly displays mixed fields and fieldsets in their configured order.
[ ] [ ] [ ] [ ]
02. Public Forms Filling out a public kickoff form anonymously.
→ Expected: fieldsets render and submit without authorization issues.
[ ] [ ] [ ] [ ]
03. Kickoff Cloning Using the "Clone kickoff" function when setting up a new template.
→ Expected: all bound fieldsets are cloned into the new template kickoff configuration.
[ ] [ ] [ ] [ ]

9. Unit Tests

This branch touches 105 test files, of which 54 are entirely new. Net gain is approximately 390 test cases (it/test).

Category New Files ~Test Cases Coverage Examples
01. Fieldsets Catalog 8 ~103 CRUD sagas, slice/reducers, API clients, validators, catalog page, card, modal, detail page, field mappers
02. Template Editor 20 ~100 KickoffRedux, OutputFormTaskMerged, MergedOutputRows, mergeTaskOutputFlow, FieldsetIconPicker, FieldsetFlowRowDropdown, FieldsetOutputsPreview, TaskItem, TaskRenderExtraFieldsInfo, TemplateControlls, TemplateEdit, TemplateEditVariablesSync, getClonedTask, getRunnableWorkflow, getTaskVariables, getRuleTargetOptions, areExtraFieldsValid, FieldLabel, FieldWithName, ExtraField*
03. Runtime Display 7 ~28 KickoffEdit, KickoffOutputs (Checkbox/Radio), TaskCard, MergedOutputList, Highlights (FeedItemHeader), storageOutputs
04. Workflows 5 ~18 WorkflowLog, WorkflowLogTaskComplete, WorkflowModal, WorkflowsGridPage, WorkflowEditPopup, getClonedKickoff
05. Redux (sagas/slices) 5 ~13 template/saga, fieldsets/saga, fieldsets/slice, dashboard/saga, workflows/saga, runWorkflowModal/reducer, task/saga
06. Utilities & Mappers 7 ~22 mapFieldsetBindingClientToRuntime, mapFieldsetsAPIToClient, mapTemplateFieldsetsToRuntime, tasks (getNormalizedTask), template (mapTemplateRequest), validators.fieldset, mapOutputToCompleteTask
07. Other Components 2 ~29 TuneViewModal, PublicForm, TopNav, Tabs, PageTitle, NotificationsList, TemplateLayout, TemplatesLayout, RichText, realtime WS utilities

In addition, mocks and assertions were updated in 51 existing test files to align with the new type contracts (IFieldsetBindingClient, IFieldsetRuntime, apiNameBinding).


10. Related commits

This branch contains 129 commits affecting the frontend part:

Show commit list (129)
  • 75c2310d 46129 test(fieldsets): add factories and update tests for fieldset reuse in templates
  • a355c08b 46129 chore(template): remove obsolete isDiscarding state and fieldsets route redirect
  • 4099803e 46129 fix(fieldsets): remove legacy field order normalization from getNormalizedTask to preserve shared field/fieldset ordering
  • 15cff173 46129 fix(fieldsets): load fieldsets on new template creation
  • 5eb9eb9b 46129 fix(fieldsets): normalize Task API fieldsets to runtime format in getNormalizedTask
  • bf342beb 46129 refactor(fieldsets): remove sharedFieldsetId from IFieldsetRuntime
  • 4dd4bf27 46129 chore: remove legacy ITaskFieldset type, fix stale test mock keys
  • edb20bf0 46129 refactor(fieldsets): rename IFieldsetData → IFieldsetRuntime, fix imports to source module
  • 28909fc6 46129 feat(fieldsets): replace legacy fieldset mapper with binding pipeline, fix fieldset clone uniqueness
  • ff100d79 46129 feat(fieldsets): replace apiName with apiNameBinding in IFieldsetData consumers and tests
  • b798332e 46129 feat(fieldsets): remove legacy id from IFieldsetData, enforce sharedFieldsetId
  • 44fcb9bd 46129 feat(fieldsets): remove getFieldsetsCatalogByApiName selector and all consumers
  • ad8b152d 46129 feat(template-edit): remove fieldsetsByApiName prop from FieldsetIconPicker and OutputFormTaskMerged
  • 2d3f43de 46129 feat(fieldsets): remove catalog lookups from KickoffRedux, TemplateIntegrations; narrow getNormalizedKickoff signature
  • 8917db03 46129 feat(fieldsets): remove fieldsetsByApiName from ExtraFieldsInfo, OutputsPreview, MergedOutputRows
  • e6233d9a 46129 feat(fieldsets): replace catalog fieldset loading with template-embedded data
  • dc99612d 46129 feat(fieldsets): replace catalog API lookup with embedded kickoff fieldsets
  • d424e11b 46129 feat(fieldsets): migrate fieldset types in template editor (part 3) — remove fieldsetsByApiName from template utilities, update cleanTemplateReferences/mapTemplateRequest/collectFieldApiNames signatures
  • aaecad30 46129 feat(fieldsets): unify fieldset removal to use sharedFieldsetId instead of apiName
  • 0b3f0d2a 46129 fest(fieldsets): migrate fieldset creation and binding flow to IFieldsetBindingClient type with apiNameBinding
  • bd92ea59 46129 feat(template) update fieldset catalog loading logic during template fetch
  • 05d1ad8a 46129 feat(fieldsets): migrate fieldset types in template editor (part 2)
  • 323f2f78 46129 feat(fieldsets): migrate fieldset types in template editor (part 1)
  • f3ac87c1 47673 fix(tests): update RichText snapshots
  • 3cb70a7d 46129 fix(fieldsets): show return link on fieldset detail page instead of tabs
  • 91066f70 feat(fieldsets): align frontend types and API layer with fieldsets API contract
  • 573785a4 47616 fix(tasks): insert urgent tasks after urgent block
  • 44156c06 46129 feat(fieldsets): migrate frontend from /templates/:id/fieldsets/:id to /fieldsets/:id
  • 601c5941 47610 chore(tasks): extract workflow rename sync helper
  • 7214f563 47610 fix(tasks): update workflow names after rename
  • 853a445d 8830 refactor(ExtraField): remove unused inputClassName from kickoff field in ExtraFieldCreatable and ExtraFieldUser components
  • 0acee1d1 8830 refactor(FieldWithName): remove unused layout effect and related logic
  • 734bd843 47954 fix(RichText): Enhance image loading error handling in useRichTextContainer
  • 7382029d 47594 fix(RichText): Improve image loading handling and fix anchor tag closure
  • d262e20d 47594 feat(RichText): Enhance RichText component with new features and styling improvements
  • d971733d 47593 refactor(WebSocket): streamline WebSocket event handling and connection management
  • a7d06672 47593 (websocket) Enhance WebSocket error handling: log errors for invalid messages and unhandled events
  • f44ff8d3 47589 fix(workflows): apply class name to workflow ended icon
  • 4bce4663 47589 fix(workflows): show workflow complete events as finished with ended icon
  • ebf29318 46129 feat(fieldsets): migrate POST /templates/:id/fieldsets → POST /fieldsets
  • b6222a9e 46129 feat(fieldsets): migrate fieldsets API from /templates/:id/fieldsets to /fieldsets
  • 26403bf8 47561 refactor(AddGuestsBanner): rename local storage key to reflect groups functionality
  • a6854bba 47561 fix(links): update support article URLs to remove '/en' from paths
  • b9ae7460 47561 fix(Groups): reorder PageTitle component to improve layout
  • 7ca60b25 47328 refactor(WorkflowLog): simplify user ID handling in comments and reactions
  • 1f6bcbc2 47328 fix(WorkflowLog): update comment reaction count to reflect reacted user IDs
  • 536fccf8 47550 fix(interceptor): remove technical JSON payload from InterceptorError message
  • 4850685d 47328 test(realtime): add unit tests for WebSocket utility functions
  • 5712c617 47328 fix(ui): resolve watch list rendering and TaskCard invalid markup
  • 4f5c760a 47328 refactor(realtime): extract WS event routing into dedicated module
  • dc4f16fc 47328 feat(accounts): sync users from WebSocket events
  • 6f546bb9 47328 refactor(groups): migrate groups store to RTK slice
  • 80a1c1b9 47328 fix(realtime): correct WS mappers for notifications and workflow log
  • 75b37e67 47328 refactor(realtime): consolidate WebSocket payload types into types.ts
  • 2b4ac0bd 46129 fix(PublicForm): show backend error message instead of generic fallback on submit failure
  • 787bf6e3 46129 feat(fieldsets): add fieldset support to public form kickoff
  • d7aa5e9f 46129 test(ExtraFields): add label-left coverage and refactor tests to strict types
  • ed7f0461 46129 refactor(tests): add central IExtraField/IFieldsetData factories and migrate all 33 test files to use theM
  • e8758c41 fix(extra-fields): fix field name overflow in Radio, Checkbox and Attachment by switching from AutosizeInput to native textarea
  • b6b39b13 46129 resolve conflicts and merge 45773 into 46129
  • ff4c187c 46129 Add left label support for date/user/file fields in run mode, fix fieldset date conversion, restrict left labels to desktop only, add responsive toolbar scaling for rich editor
  • fda87f4b 46129 feat: add label-left layout support for Checkbox, Radio, and Dropdown fields in Process Run
  • 296f48ec 46129 feat: support left label positioning for checkbox, radio, attachment and dropdown fields in fieldset editor
  • ebc4d07e 46129 feat(fieldsets): Add left label position support for fieldset fields
  • a02cdf37 46129 chore(tests): remove redundant jest reference directives from 74 test files
  • 44300154 46129 test(conditions): add unit tests for skipped and completed_or_skipped operators
  • a290a0a8 46129 test(fieldsets): add unit tests for task, template, templates, workflows, dashboard and runWorkflowModal redux modules
  • 0069b525 feat(nginx): read SSL certificate files from the host
  • 4e7900d1 fix(start.sh) review fixes
  • 5fe83cd5 46129 test(fieldsets): cover API clients, Redux slice/selectors/sagas, mappers and validators
  • cff7011f 46129 test(fieldsets): routing contract for TemplateView, FieldsetsView, TemplateLayout
  • 5e2e65aa 46129 test(fieldsets): cover fieldsets in WorkflowEditPopup, WorkflowModal, TuneViewModal and logs
  • 3e056944 46129 test(fieldsets/runtime): cover kickoff edit, task card outputs, highlights and page title
  • 99b8beda feat(docker): Upgrade installation
  • 5588c695 46129 test(template-edit): add fieldsets coverage for editor (kickoff, task output, runtime, clone)
  • 4288682f 46129 test(fieldsets): cover task variables, item, fields counter, output form merge
  • 64b4dbd3 46129 test(fieldsets/editor): cover TemplateEdit cleanup, variables sync on catalog change, and TemplateControlls fieldsets flows
  • ccf25a76 46129 test(fieldsets): add unit tests for fieldsets in template editor
  • 858962e9 46129 test(fieldsets): add unit tests for Fieldsets, FieldsetCard and FieldsetModal
  • 1811ae18 46129 fix(fieldset details): reset loading state on template mismatch, show skeleton only during loading, add FieldsetDetails tests
  • 15db8dd4 46129 feat(fieldsets): add fieldset rendering to TuneViewModal
  • 48f20a25 46129 fix(fieldsets): align getTaskVariables typings with backend and update function to use proper fieldset data for correct task names in task‑filter on workflow and task pages.
  • 34294785 46129 refactor(template): replace weak param types in collectFieldApiNames with IExtraField/ITaskFieldset and remove redundant null guards
  • 53bd4695 46129 fix(fieldsets): validate URL params on fieldset list and detail pages and redirect when IDs are invalid
  • f19f4236 46129 feat(conditions): add completed_or_skipped operator and fix operator dropdown menu width
  • 8aaf63c6 46129 refactor(fieldsets): make IFieldsetData.order required, remove non-null assertion in KickoffOutputs and fix test mocks
  • 1c6906e2 46129 fix(run) hide Insert variable button in Run workflow name field and add regression tests
  • 784bab83 46129 fix(fieldsets): include kickoff fieldset fields in wfNameTemplate validation and extract collectFieldApiNames helper
  • 94ad8f26 46129 fix(fieldsets): align fieldset preparation with fields logic and fix truncated view rendering
  • 09e0f861 46129 feat(check if): add skipped operator to task conditions in template editor
  • 1aed9e86 46129 fix(fieldsets): pass kickoff fieldsets to KickoffOutputs in Highlights feed
  • c753989d 46129 fix(fieldsets): validate template ownership on fieldset detail page
  • 835ebc38 46129 fix(fieldsets): redirect to templates list when template not found (404)
  • 097575e6 46129 fix(fieldsets): wrap createFieldset and deleteFieldset in call() effect
  • 0617284b 46129 fix(fieldsets): synchronize fieldsets catalog loading before template UI activation, add saga tests
  • 7b7910e9 46129 fix(highlights): show kickoff output fields for WorkflowRun events
  • 54551e3e 46129 fix(fieldsets): disable Save/Start button when fieldset contains empty required fields
  • c7061c71 46129 fix(fieldsets): include fieldset file attachments in attachments-only view
  • 62011cdd 46129 feat(notifications): add complete_workflow notification rendering
  • 59fe7050 46129 fix(fieldsets): persist fieldsets in localStorage via storage factory
  • a7ecb1dc 46129 fix(fieldsets): clear fieldsets list on template switch to prevent stale data flash
  • e02b465c test(fieldsets): add tests for correct fields and fieldsets ordering in workflow run, kickoff edit and task completion
  • e17e8186 46129 fix(fieldsets): correct field/fieldset ordering in KickoffEdit, extract MergedOutputList component
  • 2eb16d62 46129 fix(fieldsets): use kickoff fieldset order in Run form instead of catalog order
  • 0d89feae 46129 fix(datasets): enforce strict datasetOptions typing in ExtraField, fix dataset bug on Fieldset page, add prop propagation test
  • a5f79a5c 46129 refactor(fieldset): unify Kickoff and Task fieldset rendering via shared MergedOutputRows
  • b868db20 46129 refactor(fieldsets): centralize fieldset catalog in Redux, skip redundant loads by templateId
  • 4b52f1b4 46129 refactor(fieldsets): migrate fieldset catalog from React Context to Redux store
  • 2d393931 46129 fix(fieldsets): include fieldsets in output guard check for workflow and task log
  • 28138592 yamaha fix(fildsets): clean up stale fieldset references in cleanTemplateReferences
  • 595d5fae yamaha fix(editor): include fieldset fields in cleanTemplateReferences validation
  • c03df84f 46129 fix(tests): add missing property in TaskPerformers test
  • da96ea35 46129 chore(fieldsets): remove stray word left from refactoring
  • 4a1332ef 46129 fix(datasets): pass datasetOptions to ExtraFieldIntl in OutputFormTaskMerged
  • f05fee2e 46129 fix(fieldsets): fix output display order in workflow log, task log, kickoff modal and fix new field insertion in task editor
  • e93cdc19 46129 feat(fieldsets): display fields and fieldsets in unified order-sorted list across workflow log, task log and kickoff of workflow modal
  • 59443621 46129 feat(fieldsets)!: migrate fieldset identification to apiName in editor scope
  • dfae4827 46129 feat(fieldsets) add sorting SelectMenu to fieldsets list page
  • 87dd5754 46129 feat(fieldsets): add breadcrumb navigation on fieldset detail page
  • c563064d 46129 fix(fieldsets): fix task output fields width narrower than description
  • c0ab52f5 46129 fix(fieldset): fieldsets link visibility for unsaved templates and cloned kickoff test
  • 975d3ee3 45773 feat(fieldsets): frontend init commit
  • 3a3ee10f 8830 style: Enhance FieldWithName component and KickoffRedux styles for improved layout and debugging
  • 21cfd021 8830 style: Add text-small mixin to kickoff-create-field-add-option in Checkbox, Creatable, and Radio components
  • de83dda0 8830 style: Simplify padding and positioning in ExtraFieldCheckbox and KickoffRedux styles
  • 9cf596ad 8830 style: Consolidate margin-top styles for label elements in KickoffRedux.css
  • 648605f3 8830 style: Update ExtraField styles by adding margin-top to kickoff-create-field-options and removing redundant kickoff-dropdown-field margin
  • 065cb5f8 8830 refactor(TaskForm): Remove title prop from TaskDescriptionEditor and TaskForm components for cleaner code
  • c4c158af 8830 refactor: Enhance task view styling: Add text overflow handling for description elements in TemplateEdit.css

Note

High Risk
Large schema and workflow-path changes (kickoff start, task complete, field resolution) plus a one-off data migration command; mistakes could break templates, validation, or existing field data.

Overview
Introduces grouped fields (fieldsets) end-to-end on the backend: new template models (FieldsetTemplate, rules, shared vs per-template bindings) and workflow models (FieldSet, FieldSetRule), with migrations and a migrate_fieldsets management command to reshape legacy shared fieldset data.

Catalog & template editing: FieldSetTemplateService supports shared CRUD, cloning from shared definitions via shared_fieldset_id, and guards against deleting/editing catalog fieldsets still referenced by templates. Kickoff and task serializers gain fieldsets, with FieldsetMixin syncing bindings on create/update and draft normalization. New DRF helpers (RelatedApiNameField, RelatedApiNameListField) resolve nested field/rule references by api_name within account/template context.

Runtime: Workflows instantiate fieldsets from templates (FieldSetService on task/kickoff start). Kickoff create/update and task completion now read/write values for fields inside fieldsets and run sum_equal rule validation. Template/workflow helpers for output fields include fields attached via fieldsets, not only top-level kickoff/task fields.

Supporting changes: BaseModelService gains optional account, default delete(), and looser _create_related; dedicated FieldTemplateService for template fields. Versioning schemas and task version updates persist fieldsets. Minor: SystemVariable.TASK_VARS expanded, TemplateFilter removed from filters (replaced by FieldSetFilter), locale POT refresh, sample .env logging default.

Reviewed by Cursor Bugbot for commit 5e73dbe. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add FieldSets support to templates, workflows, tasks, and the public UI

  • Introduces FieldsetTemplate and FieldSet Django models with associated rules, linking fieldsets to templates, kickoffs, and tasks; adds migrations and service layers (FieldSetTemplateService, FieldSetService, FieldSetRuleService) for full CRUD and rule validation.
  • Exposes a new /fieldsets/ REST API (SharedFieldsetTemplateViewSet) for managing shared fieldset templates, and updates template/kickoff/task serializers to include fieldsets in all relevant API responses.
  • Adds frontend Redux slice, sagas, selectors, and API clients for fieldsets; registers the fieldsets reducer and saga in the root store.
  • Adds Fieldsets list and detail pages (Fieldsets, FieldsetDetails, FieldsetCard, FieldsetModal) behind an admin/owner-gated route at /fieldsets/.
  • Updates KickoffRedux, TaskForm, WorkflowEditPopup, PublicForm, TaskCard, KickoffOutputs, and WorkflowModal to render, edit, validate, and submit fieldset fields alongside regular fields via a shared MergedOutputList component.
  • Extends task/kickoff version services (TaskUpdateVersionService, KickoffUpdateVersionService) to synchronize fieldset rules and fields during version updates.
  • Adds fieldsetsStorage to localStorage task persistence alongside existing outputStorage, and clears both on task completion.
  • Propagates fieldsets into webhook payloads, event serializers, highlights, workflow log, and TuneViewModal.
  • Risk: TaskUpdateVersionService and KickoffUpdateVersionService now delete fieldsets/rules not present in incoming payloads during version updates, which is destructive if callers omit fieldsets unintentionally.

Macroscope summarized 5e73dbe.

@Maria-Lordwill Maria-Lordwill added bug Something isn't working Frontend Web client changes request labels Apr 24, 2026
Comment thread backend/src/processes/services/tasks/task_version.py
Comment thread backend/src/processes/services/fieldsets/fieldset_rule.py
Comment thread backend/src/processes/services/workflows/fieldsets/fieldset_rule.py
Comment thread backend/src/processes/models/templates/fieldset.py
Comment thread backend/src/processes/serializers/templates/task.py Outdated
Comment thread backend/src/processes/services/workflows/fieldsets/fieldset.py
for field in self.instance.fields.all():
if field.value not in self.NULL_VALUES:
total += float(field.value)
if total != float(self.instance.value):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium fieldsets/fieldset_rule.py:22

Floating-point comparison total != float(self.instance.value) incorrectly rejects valid field sets due to precision loss. For example, when fields sum to 0.3 via 0.1 + 0.2, the strict equality check fails because 0.1 + 0.2 != 0.3 in IEEE 754 arithmetic. Consider using a tolerance-based comparison like abs(total - float(self.instance.value)) > epsilon.

-        if total != float(self.instance.value):
+        if abs(total - float(self.instance.value)) > 1e-9:
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file backend/src/processes/services/workflows/fieldsets/fieldset_rule.py around line 22:

Floating-point comparison `total != float(self.instance.value)` incorrectly rejects valid field sets due to precision loss. For example, when fields sum to `0.3` via `0.1 + 0.2`, the strict equality check fails because `0.1 + 0.2 != 0.3` in IEEE 754 arithmetic. Consider using a tolerance-based comparison like `abs(total - float(self.instance.value)) > epsilon`.

Evidence trail:
backend/src/processes/services/workflows/fieldsets/fieldset_rule.py lines 16-24 at REVIEWED_COMMIT - shows the `_validate_sum_equal` method with `total != float(self.instance.value)` comparison on line 22. IEEE 754 floating-point precision issues are well-documented (e.g., Python docs on floating point: https://docs.python.org/3/tutorial/floatingpoint.html).

Comment thread backend/src/processes/services/templates/field_template.py
Comment thread backend/src/processes/services/fieldsets/fieldset_rule.py
Comment thread frontend/src/public/components/KickoffEdit/KickoffEdit.tsx
}
"""

if data.get('fields'):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Low workflows/kickoff_version.py:180

When data contains {'fields': [], 'fieldsets': []}, the empty fields list is skipped due to truthiness check on line 180, but empty fieldsets is processed via is not None check on line 182. This causes _update_fieldsets to delete all fieldsets while _update_fields leaves orphaned fields intact — inconsistent behavior for empty list inputs. Consider changing line 180 to if data.get('fields') is not None: to match the fieldsets handling.

Also found in 1 other location(s)

backend/src/processes/services/tasks/task_version.py:66

If field_data.get('selections') returns an empty list [], the condition on line 66 evaluates to falsy, so the method exits without deleting existing selections. This means when a field previously had selections but the new data has 'selections': [], the old selections will incorrectly remain in the database instead of being cleared.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file backend/src/processes/services/workflows/kickoff_version.py around line 180:

When `data` contains `{'fields': [], 'fieldsets': []}`, the empty `fields` list is skipped due to truthiness check on line 180, but empty `fieldsets` is processed via `is not None` check on line 182. This causes `_update_fieldsets` to delete all fieldsets while `_update_fields` leaves orphaned fields intact — inconsistent behavior for empty list inputs. Consider changing line 180 to `if data.get('fields') is not None:` to match the fieldsets handling.

Evidence trail:
backend/src/processes/services/workflows/kickoff_version.py lines 180-183 (condition checks), lines 63-77 (_update_fields with delete at line 76-78), lines 136-163 (_update_fieldsets with delete at lines 161-163). Verified at REVIEWED_COMMIT.

Also found in 1 other location(s):
- backend/src/processes/services/tasks/task_version.py:66 -- If `field_data.get('selections')` returns an empty list `[]`, the condition on line 66 evaluates to falsy, so the method exits without deleting existing selections. This means when a field previously had selections but the new data has `'selections': []`, the old selections will incorrectly remain in the database instead of being cleared.

Comment thread frontend/src/public/components/TemplateEdit/FieldsetPicker/FieldsetPicker.tsx Outdated
Comment thread backend/src/processes/services/fieldsets/fieldset.py
Comment thread backend/src/processes/services/workflows/fieldsets/fieldset_rule.py
Comment thread backend/src/processes/models/templates/fieldset.py
Comment thread backend/src/processes/serializers/workflows/kickoff_value.py
Comment thread backend/src/processes/models/workflows/workflow.py
Comment thread backend/src/processes/services/workflow_action.py
Comment thread backend/src/processes/models/templates/fieldset.py
selection_ids.add(selection.id)
field.selections.exclude(id__in=selection_ids).delete()
self._update_field_selections(field, field_data)
self.instance.output.exclude(id__in=field_ids).delete()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High tasks/task_version.py:94

In _update_fields, the deletion at line 94 removes ALL TaskField objects with task=self.instance, including fields that belong to fieldsets. Since _update_fields runs before _update_fieldsets (lines 531-532), and field_ids only tracks non-fieldset fields, existing fieldset fields are deleted before _update_fieldsets can recreate them. The deletion should filter to only remove fields without a fieldset using self.instance.output.filter(fieldset__isnull=True).exclude(id__in=field_ids).delete().

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file backend/src/processes/services/tasks/task_version.py around line 94:

In `_update_fields`, the deletion at line 94 removes ALL `TaskField` objects with `task=self.instance`, including fields that belong to fieldsets. Since `_update_fields` runs before `_update_fieldsets` (lines 531-532), and `field_ids` only tracks non-fieldset fields, existing fieldset fields are deleted before `_update_fieldsets` can recreate them. The deletion should filter to only remove fields without a fieldset using `self.instance.output.filter(fieldset__isnull=True).exclude(id__in=field_ids).delete()`.

Evidence trail:
backend/src/processes/services/tasks/task_version.py lines 82-94 (_update_fields: field_ids only collects non-fieldset fields, then deletes all output not in field_ids), lines 91 (fieldset=None), line 94 (self.instance.output.exclude(id__in=field_ids).delete()), lines 531-532 (_update_fields called before _update_fieldsets), lines 167-187 (_update_field uses TaskField.objects.update_or_create with fieldset in lookup), lines 231-244 (_update_fieldset_fields), lines 246-276 (_update_fieldsets). backend/src/processes/models/workflows/fields.py lines 47-53 (TaskField.task FK with related_name='output'), lines 60-65 (TaskField.fieldset FK nullable), line 76 (objects = BaseSoftDeleteManager). backend/src/generics/managers.py lines 6-8 (BaseSoftDeleteManager filters is_deleted=False). backend/src/generics/querysets.py lines 59-61 (BaseQuerySet.delete does soft delete via update is_deleted=True).

Comment thread backend/src/processes/services/fieldsets/fieldset.py
Comment thread backend/src/processes/services/tasks/task_version.py Outdated
service.validate_rules()
except FieldsetServiceException as ex:
self.raise_validation_error(message=ex.message)
for field_template in kickoff.fields.filter(fieldset__isnull=True):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Low workflows/kickoff_value.py:113

When creating fields without a fieldset at lines 113-120, fieldset_id is not passed to TaskFieldService.create(). If the field template has rules, _link_rules accesses kwargs['fieldset_id'] with direct key access and raises KeyError, which escapes the except (TaskFieldException, FieldsetServiceException) block at line 121. Pass fieldset_id=None for fields without a fieldset.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file backend/src/processes/serializers/workflows/kickoff_value.py around line 113:

When creating fields without a fieldset at lines 113-120, `fieldset_id` is not passed to `TaskFieldService.create()`. If the field template has rules, `_link_rules` accesses `kwargs['fieldset_id']` with direct key access and raises `KeyError`, which escapes the `except (TaskFieldException, FieldsetServiceException)` block at line 121. Pass `fieldset_id=None` for fields without a fieldset.

Evidence trail:
backend/src/processes/serializers/workflows/kickoff_value.py lines 113-121 (REVIEWED_COMMIT): `service.create()` called without `fieldset_id`; except block catches only `TaskFieldException, FieldsetServiceException`.
backend/src/generics/base/service.py lines 65-70: `BaseModelService.create(**kwargs)` passes kwargs to `_create_related(**kwargs)`.
backend/src/processes/services/tasks/field.py line 326: `_create_related` calls `_link_rules(instance_template, **kwargs)` if rules exist.
backend/src/processes/services/tasks/field.py line 375: `_link_rules` uses `kwargs['fieldset_id']` (direct key access, raises KeyError if missing).
backend/src/processes/models/templates/fields.py lines 59-68: `FieldTemplate.fieldset` is nullable, and `rules` M2M has no constraint preventing association on fieldset-less fields.

Comment thread backend/src/processes/models/templates/fieldset.py Outdated
if field.value not in self.NULL_VALUES:
total += float(field.value)
if total != float(self.instance.value):
raise FieldsetServiceException(MSG_FS_0002(self.instance.value))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Floating-point equality check in sum validation is unreliable

Medium Severity

_validate_sum_equal accumulates field values using float() addition and then compares the total with exact equality (!=). Floating-point arithmetic can produce rounding errors (e.g., 0.1 + 0.2 != 0.3), causing valid inputs to fail validation spuriously. Using Decimal or an epsilon-based comparison would be more reliable.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5944362. Configure here.

Comment thread frontend/src/public/components/TemplateEdit/FieldsetPicker/FieldsetPicker.tsx Outdated
…sorted list across workflow log, task log and kickoff of workflow modal
Comment thread frontend/src/public/components/KickoffOutputs/KickoffOutputs.tsx Outdated
values_exists = True
else:
total += float(field.value)
values_exists = True

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sum rule rejects invalid numbers poorly

Medium Severity

Runtime sum_equal validation in FieldSetRuleService._validate_sum_equal uses float(field.value) with no handling for non-numeric values. Invalid stored or submitted values raise ValueError instead of a fieldset validation error, which can surface as an unhandled server error during kickoff updates or task completion when validate_rules() runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5eb9eb9. Configure here.

('is_shared', models.BooleanField(default=True)),
('account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='accounts.Account')),
('kickoff', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='fieldsets', to='processes.Kickoff')),
('shared_fieldset', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_fieldsets', to='processes.FieldsetTemplate')),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shared fieldset FK on_delete mismatch

Medium Severity

Migration 0254 defines shared_fieldset with on_delete=CASCADE, while the model uses on_delete=SET_NULL. Deleting a shared catalog fieldset can cascade-delete template bindings in the database even though application code expects bindings to remain with a null reference.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a355c08. Configure here.

order=fieldset_data['order'],
title=fieldset_data.get('title'),
description=fieldset_data.get('description'),
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fieldset update clears title

High Severity

When an existing kickoff or task fieldset binding only needs an order change, create_or_update_fieldsets still calls partial_update_instance with title and description from fieldset_data.get(...). Omitted keys become None, which overwrites stored title/description on the binding even though those fields were not part of the intended update.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 75c2310. Configure here.

fields=['api_name', 'fieldset'],
condition=Q(is_deleted=False),
name='fieldsettemplate_api_name_template_unique',
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicate DB constraint name

Medium Severity

FieldsetTemplateRule declares a UniqueConstraint named fieldsettemplate_api_name_template_unique, identical to the constraint on FieldsetTemplate. Migration 0255 creates the rule constraint as fieldsettemplate_rule_api_name_template_unique, so the model Meta no longer matches the database and duplicate names can break future migrations or checks.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 75c2310. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 using default effort and found 3 potential issues.

There are 9 total unresolved issues (including 6 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5e73dbe. Configure here.

del task_fieldsets[i]
else:
new_task_fieldsets.append(task_fieldsets[i])
task['fieldsets'] = new_kickoff_fieldsets

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Task drafts get kickoff fieldsets

High Severity

In update_draft_fieldset, task draft updates build new_task_fieldsets but assign task['fieldsets'] from new_kickoff_fieldsets. Task output flows can receive kickoff bindings or the wrong list, and matched task fieldsets are appended to task_fieldsets instead of the new list.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e73dbe. Configure here.

)
else:
print('--- duplicate task fieldset - removed')
link.delete()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Migration skips task fieldset links

High Severity

The migrate_fieldsets handler reuses one updated flag for kickoff M2M links and task M2M links. After the first kickoff link creates a template fieldset, task links are deleted without creating replacements, dropping task fieldset bindings.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e73dbe. Configure here.

f'---|--- new task fieldset: '
f'task: "{task["name"]}"',
)
updated = True

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Draft flag blocks task updates

Medium Severity

update_draft_fieldset uses a single updated flag for kickoff and every task. After kickoff fieldset data is applied, task sections treat later updates as duplicates and skip inserting migrated fieldset payloads into task drafts.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e73dbe. Configure here.

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

Labels

Frontend Web client changes request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants