Skip to content

feat: type the remaining closed-set params as enums#508

Merged
pratyush618 merged 11 commits into
masterfrom
feat/enum-remaining-closed-sets
Jul 23, 2026
Merged

feat: type the remaining closed-set params as enums#508
pratyush618 merged 11 commits into
masterfrom
feat/enum-remaining-closed-sets

Conversation

@kartikeya-27

@kartikeya-27 kartikeya-27 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Finishes #503. PR #505 shipped splits 1–6 but deliberately left a long tail of inventory
rows; this closes them. Same non-breaking contract as before — every wire and stored value is
byte-identical and existing string callers keep working (Java keeps its String overloads).

What's typed now

Row Where Change
WorkflowCondition Python + Java New enum. Python builder step()/gate() coerce a string; the tracker/saga compare against the enum. Java gains Step.Builder.condition(WorkflowCondition) beside the String overload.
StorageBackend Python + Java New enum. Queue(backend=…) takes `StorageBackend
Strategy Python register_type(strategy=…) takes `Strategy
DeliveryStatus Python The webhook delivery-log status field and the dashboard filter are typed; write sites pass enum members.
NodeStatus / WorkflowState Python (internal) workflows/tracker/dag.py and workflows/saga/orchestrator.py compare node/run status against the enums instead of string literals.

Notes

  • WorkflowCondition, StorageBackend wire forms are the existing lowercase strings, so
    nothing on the wire or in storage changes. StorageBackend unwraps to its wire value at the
    boundary, so the native layer's aliases (e.g. "postgresql") still work through the raw-string path.
  • Node needs no change. Its WorkflowCondition, backend union, and DeliveryStatus are
    already string-literal unions with runtime sets — the house style. One documented divergence
    stays: pending is a delivery status only Python records (a record exists before its first
    attempt settles); other SDKs record only settled attempts.
  • DeliveryStatus reads fail closed — an unrecognized stored status falls back to pending
    rather than raising, matching feat: replace stringly-typed closed-set params with enums #505's lenient-read treatment for stored enums.

Verification

  • Python: ruff + mypy clean (307 source files); workflow, closed-set-enum, and webhook
    delivery suites green.
  • Java: ./gradlew build green — spotless, checkstyle, strict javadoc, tests.
  • Node: unchanged; already typed.
  • CHANGELOG.md extends the existing closed-set entry under Unreleased.

Summary by CodeRabbit

  • New Features
    • Added type-safe, enum-based workflow conditions and storage backend configuration across Python and Java SDKs.
    • Added enum-based webhook delivery statuses, including status filtering and replay outcome recording.
    • Added validation with clearer errors while preserving compatibility with existing string inputs.
  • Bug Fixes
    • Improved consistency when interpreting node/workflow and webhook delivery statuses by using the shared enum values.
  • Tests
    • Expanded cross-SDK and enum round-trip coverage for workflow conditions, storage backends, and delivery status handling.

Adds a WorkflowCondition enum and a Step.Builder.condition overload; the String overload stays.
Adds a StorageBackend enum and a Builder.backend overload; the String overload stays.
Adds WorkflowCondition; the builder coerces it, and the tracker/saga compare node and run status against the enums instead of string literals.
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@pratyush618, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a971fad-b954-4e8b-ab05-7927099eb886

📥 Commits

Reviewing files that changed from the base of the PR and between 0707a43 and 0724159.

📒 Files selected for processing (2)
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/python/taskito/workflows/builder.py
📝 Walkthrough

Walkthrough

The change introduces enum-backed workflow conditions, storage backends, strategy registration, and webhook delivery statuses across the Java and Python SDKs. Existing wire-string inputs remain supported, while internal workflow and delivery logic uses enum values.

Changes

Closed-set enum typing

Layer / File(s) Summary
Java enum contracts and overloads
sdks/java/src/main/java/org/byteveda/taskito/..., sdks/java/src/test/java/org/byteveda/taskito/...
Adds StorageBackend and WorkflowCondition enums with wire parsing, plus type-safe builder overloads and tests.
Python workflow condition handling
sdks/python/taskito/workflows/..., sdks/python/tests/python/test_closed_set_enums.py
Adds WorkflowCondition, supports enum or string conditions in steps and gates, serializes enum values, and replaces workflow status literals with enum-backed values.
Python backend and strategy entry points
sdks/python/taskito/enums.py, sdks/python/taskito/app.py, sdks/python/taskito/mixins/runtime_config.py, sdks/python/tests/python/test_closed_set_enums.py
Adds public StorageBackend support and coerces enum or string values for queue backends and strategy registration.
Python delivery status persistence and handlers
sdks/python/taskito/dashboard/..., sdks/python/taskito/webhooks.py, sdks/python/tests/dashboard/..., sdks/python/tests/python/test_closed_set_enums.py
Uses DeliveryStatus for persistence, replay outcomes, webhook outcomes, filtering, parsing, and validation.
Cross-surface compatibility validation
CHANGELOG.md, sdks/python/tests/python/test_closed_set_enums.py
Expands wire-value, compatibility, invalid-input, and integration coverage for the enum-based APIs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested labels: dashboard, storage

Suggested reviewers: pratyush618

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main change: typing remaining closed-set parameters as enums across Python and Java.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/enum-remaining-closed-sets

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.

ruff 0.16 flags None not at the end of a type union; reorder the compensates annotations. Annotation-only, no behavior change.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdks/python/taskito/dashboard/delivery_store.py (1)

169-214: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Normalize statuses before persistence and filtering.

A legacy status="pending" bypasses enum normalization, so Line 194 sets completed_at; unknown stored statuses likewise fall back to PENDING only after Line 214 has already filtered them out. Normalize accepted string inputs and compare filters against _parse_status(row.get("status")).

Proposed fix
-        status: DeliveryStatus,
+        status: DeliveryStatus | str,
@@
     ) -> DeliveryRecord:
         """Append a delivery row and trim to the per-webhook cap."""
+        status = DeliveryStatus(status)
         now = _now_ms()
@@
-        if status:
-            rows = [r for r in rows if r.get("status") == status]
+        if status:
+            status = DeliveryStatus(status)
+            rows = [r for r in rows if _parse_status(r.get("status")) is status]

Add coverage for a string "pending" write and an unrecognized persisted status filtered as PENDING.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdks/python/taskito/dashboard/delivery_store.py` around lines 169 - 214,
Update the delivery-record write path around DeliveryStore’s append method to
normalize string status inputs through the existing status parser before
constructing DeliveryRecord, ensuring `"pending"` produces no completed_at and
unknown values resolve consistently. In list_for, compare the requested status
against _parse_status(row.get("status")) so persisted unrecognized statuses are
treated as PENDING during filtering. Add coverage for both string pending writes
and filtering an unrecognized persisted status as PENDING.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sdks/java/src/main/java/org/byteveda/taskito/Taskito.java`:
- Around line 663-669: Rename the new type-safe Builder.backend(StorageBackend)
method to a distinct name so Taskito.builder().backend(null) continues resolving
to the existing String overload. Update its documentation and callers as needed,
and add a compile-compatibility test covering backend(null).

---

Outside diff comments:
In `@sdks/python/taskito/dashboard/delivery_store.py`:
- Around line 169-214: Update the delivery-record write path around
DeliveryStore’s append method to normalize string status inputs through the
existing status parser before constructing DeliveryRecord, ensuring `"pending"`
produces no completed_at and unknown values resolve consistently. In list_for,
compare the requested status against _parse_status(row.get("status")) so
persisted unrecognized statuses are treated as PENDING during filtering. Add
coverage for both string pending writes and filtering an unrecognized persisted
status as PENDING.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 602cd0ff-c73a-44f0-9835-355e76293a1e

📥 Commits

Reviewing files that changed from the base of the PR and between 840415a and 0707a43.

📒 Files selected for processing (21)
  • CHANGELOG.md
  • sdks/java/src/main/java/org/byteveda/taskito/Taskito.java
  • sdks/java/src/main/java/org/byteveda/taskito/model/StorageBackend.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowCondition.java
  • sdks/java/src/test/java/org/byteveda/taskito/model/ClosedSetEnumTest.java
  • sdks/java/src/test/java/org/byteveda/taskito/workflows/WorkflowConditionTest.java
  • sdks/python/taskito/__init__.py
  • sdks/python/taskito/app.py
  • sdks/python/taskito/dashboard/delivery_store.py
  • sdks/python/taskito/dashboard/handlers/webhook_deliveries.py
  • sdks/python/taskito/enums.py
  • sdks/python/taskito/mixins/runtime_config.py
  • sdks/python/taskito/webhooks.py
  • sdks/python/taskito/workflows/__init__.py
  • sdks/python/taskito/workflows/builder.py
  • sdks/python/taskito/workflows/saga/orchestrator.py
  • sdks/python/taskito/workflows/tracker/dag.py
  • sdks/python/taskito/workflows/types.py
  • sdks/python/tests/dashboard/test_webhook_deliveries.py
  • sdks/python/tests/python/test_closed_set_enums.py

Comment thread sdks/java/src/main/java/org/byteveda/taskito/Taskito.java
@kartikeya-27

Copy link
Copy Markdown
Contributor Author

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
sdks/python/taskito/dashboard/delivery_store.py (1)

169-194: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Normalize legacy string statuses before setting completed_at.

Line 194 treats a valid existing status="pending" caller as terminal because it is not the enum singleton, persisting a pending record with completed_at=now. Accept DeliveryStatus | str and normalize with DeliveryStatus(status) before constructing the record; add coverage for raw "pending".

Proposed fix
-        status: DeliveryStatus,
+        status: DeliveryStatus | str,
         attempts: int,
@@
-        now = _now_ms()
+        status = DeliveryStatus(status)
+        now = _now_ms()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdks/python/taskito/dashboard/delivery_store.py` around lines 169 - 194,
Update the delivery-record creation method around DeliveryRecord to accept
DeliveryStatus | str and normalize status with DeliveryStatus(status) before
constructing the record. Use the normalized enum for both the record’s status
and the completed_at pending check, preserving correct behavior for raw
"pending" values. Add coverage verifying that a string "pending" status leaves
completed_at unset.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java`:
- Around line 163-170: Update the invalid-condition validation message in
Step.Builder’s string condition path to direct callers to
condition(WorkflowCondition) instead of condition(Condition). Leave the new
Builder.condition(WorkflowCondition) overload and other validation behavior
unchanged.

In `@sdks/python/taskito/workflows/builder.py`:
- Around line 147-148: Align the compensates parameter annotation with the
runtime lookup used by the workflow builder: either resolve HasTaskName objects
through _task_name in the compensator handling, or replace HasTaskName with a
protocol/type requiring name. Ensure every value accepted by the annotation is
accepted by the runtime resolution path.

---

Outside diff comments:
In `@sdks/python/taskito/dashboard/delivery_store.py`:
- Around line 169-194: Update the delivery-record creation method around
DeliveryRecord to accept DeliveryStatus | str and normalize status with
DeliveryStatus(status) before constructing the record. Use the normalized enum
for both the record’s status and the completed_at pending check, preserving
correct behavior for raw "pending" values. Add coverage verifying that a string
"pending" status leaves completed_at unset.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bd21fb5-a1ea-4969-b955-bc56b65c8667

📥 Commits

Reviewing files that changed from the base of the PR and between 840415a and 0707a43.

📒 Files selected for processing (21)
  • CHANGELOG.md
  • sdks/java/src/main/java/org/byteveda/taskito/Taskito.java
  • sdks/java/src/main/java/org/byteveda/taskito/model/StorageBackend.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowCondition.java
  • sdks/java/src/test/java/org/byteveda/taskito/model/ClosedSetEnumTest.java
  • sdks/java/src/test/java/org/byteveda/taskito/workflows/WorkflowConditionTest.java
  • sdks/python/taskito/__init__.py
  • sdks/python/taskito/app.py
  • sdks/python/taskito/dashboard/delivery_store.py
  • sdks/python/taskito/dashboard/handlers/webhook_deliveries.py
  • sdks/python/taskito/enums.py
  • sdks/python/taskito/mixins/runtime_config.py
  • sdks/python/taskito/webhooks.py
  • sdks/python/taskito/workflows/__init__.py
  • sdks/python/taskito/workflows/builder.py
  • sdks/python/taskito/workflows/saga/orchestrator.py
  • sdks/python/taskito/workflows/tracker/dag.py
  • sdks/python/taskito/workflows/types.py
  • sdks/python/tests/dashboard/test_webhook_deliveries.py
  • sdks/python/tests/python/test_closed_set_enums.py

Comment thread sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
Comment thread sdks/python/taskito/workflows/builder.py
@pratyush618
pratyush618 merged commit 21fa2fe into master Jul 23, 2026
22 checks passed
@pratyush618
pratyush618 deleted the feat/enum-remaining-closed-sets branch July 23, 2026 20:45
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