Skip to content

feat(api-workflows): domain - #6037

Open
brunozoric wants to merge 26 commits into
bruno/feat/workflows-umbrellafrom
bruno/feat/workflows-api-workflows-domain
Open

brunozoric wants to merge 26 commits into
bruno/feat/workflows-umbrellafrom
bruno/feat/workflows-api-workflows-domain

Conversation

@brunozoric

@brunozoric brunozoric commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Domain model of the workflows engine: workflows, steps, rules, review entries, routing and notifications.

Part of the workflows split (117 files). Merges into bruno/feat/workflows-umbrella; builds only together with the other parts.

🤖 Generated with Claude Code

Split from bruno/refactor/workflows-flow for review.

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

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 54b2f52a-308a-48ea-910f-f03072c37104

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

🚓 Slop Cop

✅ Nothing worth flagging. The diff looks consistent with the PR's stated intent and the code-style rules.

PR is a large but coherent, intentional slice of a stated multi-part domain-model split; no integrity red flags or clear style violations found in the sampled diff.

Automated, non-blocking heads-up from an LLM. It can be wrong — use your judgment. Regenerates on every push.

brunozoric and others added 6 commits October 21, 2026 14:00
…en matching and the rule inspector

matchRoutingRuleConditions, matchRoutingRuleLocalConditions and getFailedRoutingConditions now decide each condition through the same predicate (requester, requester team, folder type, folder), so the inspector cannot drift from live routing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…class

PersistenceError keeps the fixed client message, the storage code in data and the non-enumerable raw source in one place (R146). The review, workflow, assignment, settings and routing dependency errors extend it; their codes, messages and payloads are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e as none

Reject already trims its comment. A whitespace-only approve comment no longer shows up as an empty comment in the steps popover or the notifications.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e wrong type

reach is for review steps and reachRun for run steps (automation, AI). The aggregate now checks the current step's type itself instead of trusting every registered step type, and fails with ReviewInvalidStateError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he domain

Websocket action names, send concurrency, the BCC chunk size, HTML escaping and error log fields are transport and logging concerns, so they move from domain/notifications to features/notifications/shared. The comment length limit stays in the domain: it shapes the message text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the inline { id: string } generic constraint with the DropActorRecipient interface.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brunozoric brunozoric changed the title feat(api-workflows): domain feat(api-workflows): domain [skip ci] Oct 21, 2026
…update

ReviewRepository.save read the entry and created it when missing, so a review deleted between a load and its save (content trashed while an approve or the stuck-step check was in flight) came back as an active review. The repository now has create and update; update fails with ReviewNotFoundError for a missing review, and ReviewSaver creates only a review whose facts include requested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brunozoric brunozoric changed the title feat(api-workflows): domain [skip ci] feat(api-workflows): domain Oct 21, 2026
brunozoric and others added 7 commits October 21, 2026 19:02
… its tasks

The running task (the current step's task while it is in review) and the task of every attempt are rules about the review's own data. Review.getRunningTaskId and Review.getTaskIds now hold them; CancelReview and DeleteTargetReviews call them instead of each repeating the running-task rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eave ids out

The review list cursor kept a repository page cursor and a row offset into it. When a row earlier on that page left the list between calls (an approve, a reassign), the rows after it shifted up and the next call skipped one. The cursor now holds the lastChangedOn of the last examined row and the ids examined at exactly that time; the next call resumes there with lastChangedOn_gte (ascending) or _lte (descending) and leaves those ids out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…filter

Part of removing queries in loops (docs/.bruno/plans/2026-10-21-workflows-no-n-plus-one.md, Phase 1 and Phase 2 item 1). The review lists turn the viewer's read access into query filters (readable models, own-only models by author, denied folders) built once per request, confirm each storage page with one batch read, and never read a target per row. Folder rules load only for models with active reviews (one distinct-values query).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…repositories

Part of removing queries in loops (docs/.bruno/plans/2026-10-21-workflows-no-n-plus-one.md, Phase 3): the delete cascade lists all records of a batch of reviews at once and deletes in batches with one task-abort call; assignment records are written with a concurrency limit; least-loaded ties read one userId_in list; cancel-for-delete no longer lists twice; saving a workflow reads its user targets with one ListUsers call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of removing queries in loops (docs/.bruno/plans/2026-10-21-workflows-no-n-plus-one.md, Phase 3): the review and assignment repositories delete with CMS DeleteMultipleEntriesUseCase in chunks of 50 instead of one delete per entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed user, team, transport or permission lookup in the workflow editor's config use cases was reported as WorkflowPersistenceError ("The workflow could not be read or saved."), pointing at the workflow storage. It is now WorkflowLookupError (Workflows/Workflow/Lookup) with the raw cause kept off the client the same way. A step id missing from a review in NotificationRecipientService.listPool is a ReviewValidationError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of #6039: the workflow editor access check (signed in, editor permission, a failing permission load as WorkflowLookupError) lives in one WorkflowEditorAccess service used by the eight config use cases; routing loads step members (team members, exclusions, read adapter) in one place for evaluate, listMembers and checkUser, and toStepMembersParams builds the members params for the candidates list and pool notifications.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brunozoric brunozoric changed the title feat(api-workflows): domain feat(api-workflows): domain [skip ci] Oct 22, 2026
brunozoric and others added 2 commits October 23, 2026 09:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brunozoric brunozoric changed the title feat(api-workflows): domain [skip ci] feat(api-workflows): domain Oct 23, 2026
brunozoric and others added 6 commits October 23, 2026 10:31
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rror message

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… error is wrapped again

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…om the review repository

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ithout a features import

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brunozoric and others added 3 commits October 24, 2026 14:37
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…user

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… folder captured at request

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

This branch has not been deployed

No deployments
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