Feat/tier settings rev - #184
Conversation
|
| Filename | Overview |
|---|---|
| apps/tradinggoose/hooks/queries/private-tier-access.ts | The previous error-mapping defect is fixed by preserving server guidance for rate-limit and dependency-failure responses while retaining generic invalid-code copy for validation failures. |
| apps/tradinggoose/app/api/billing/private-tier-access/route.ts | Adds an authenticated private-tier discovery and grant endpoint with rate limiting, no-store responses, and explicit temporary-unavailability handling. |
| apps/tradinggoose/lib/execution/workflow-execution-time-policy.ts | Introduces tier-derived workflow execution-time policy capture for the execution pipeline. |
| apps/tradinggoose/background/workflow-execution.ts | Integrates attempt-scoped execution deadlines and durable timeout handling into background workflow processing. |
| apps/tradinggoose/executor/index.ts | Propagates and enforces execution budgets while suppressing results completed after the deadline. |
Sequence Diagram
sequenceDiagram
participant User
participant UI as Subscription UI
participant API as Private-tier API
participant Limiter as Rate limiter
participant Billing as Billing helpers
User->>UI: Submit access code
UI->>API: POST access code
API->>Limiter: Check user attempt budget
alt Limiter unavailable
Limiter-->>API: Dependency failure
API-->>UI: 503 temporary unavailable
UI-->>User: Server unavailability message
else Attempt allowed
API->>Billing: Validate code and persist grant
Billing-->>API: Granted or invalid
API-->>UI: Updated tiers or generic invalid response
end
Reviews (2): Last reviewed commit: "fix: surface private access service erro..." | Re-trigger Greptile
📝 WalkthroughWalkthroughThis change adds private billing-tier access, tier archiving, subscription policy handling, workflow execution time budgets, deadline propagation, cancellation signals, and related persistence, UI, API, localization, test, and SDK updates. ChangesBilling and private-tier access
Workflow execution time budgets
Cancellation and supporting behavior
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant executeWorkflowJob
participant AttemptTimeBudget
participant Executor
participant WorkflowRunner
participant ExecutionLog
Client->>executeWorkflowJob: submit workflow execution
executeWorkflowJob->>AttemptTimeBudget: create execution policy and budget
executeWorkflowJob->>WorkflowRunner: run with time policy and start timestamp
WorkflowRunner->>Executor: execute blocks with abort signal
AttemptTimeBudget-->>WorkflowRunner: deadline expiration
WorkflowRunner->>Executor: stopForDeadline()
Executor-->>WorkflowRunner: snapshot timed-out block logs
WorkflowRunner->>ExecutionLog: persist timeout result and deadline metadata
ExecutionLog-->>Client: return failed execution result
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 17
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/tradinggoose/lib/logs/execution/logger.ts (1)
283-290: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winThe whole
ExecutionResultis persisted intoworkflowExecutionLogs.executionData. The root cause is the merge at the logger, which writes the complete result next totraceSpansandfinalOutput. The result repeatsoutputand adds everyBlockLogwith itsinputandoutput, so the row stores the same payloads twice and widens the sensitive surface of the durable log.
apps/tradinggoose/lib/logs/execution/logger.ts#L283-L290: narrow the persisted value to the deadline diagnostics (code,deadline,error) instead of spreading the fullresult, and type the parameter as that narrowed shape rather thanobject.apps/tradinggoose/lib/logs/execution/logging-session.ts#L44-L59: changeresult?: ExecutionResultonSessionCompleteParamsandSessionErrorCompleteParamsto the same narrowed type.apps/tradinggoose/lib/workflows/execution-runner.ts#L528-L555: project the result before passing it tocompleteWithErrorandcomplete.🤖 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 `@apps/tradinggoose/lib/logs/execution/logger.ts` around lines 283 - 290, Stop persisting the full ExecutionResult in logger.ts#L283-L290: define and use a narrowed type containing only deadline diagnostics (code, deadline, and error), and persist only those fields alongside traceSpans and finalOutput. Update SessionCompleteParams and SessionErrorCompleteParams in apps/tradinggoose/lib/logs/execution/logging-session.ts#L44-L59 to use the same narrowed result type instead of ExecutionResult, and project those fields before passing the result to completeWithError and complete in apps/tradinggoose/lib/workflows/execution-runner.ts#L528-L555.apps/tradinggoose/tools/index.ts (1)
52-73: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy liftPropagate the captured workflow time policy through nested tool calls.
resolveExecutionScopeonly captures the policy fromexecutionContext. Every provider site passesundefinedfor that argument. When a limited workflow invokes a provider tool,workflowExecutionTimePolicyis therefore absent. The abort signal cancels the current request, but a nested internal workflow cannot receive the original tier policy or deadline.MCP execution has an execution context, but it creates a generic internal token. Use the scoped token path there so that MCP child execution also receives the captured policy.
apps/tradinggoose/tools/index.ts#L52-L73: support a captured policy supplied by provider-driven tool execution.apps/tradinggoose/providers/ai/anthropic/core.ts#L554-L556: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/anthropic/core.ts#L972-L974: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/anthropic/index.ts#L466-L468: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/anthropic/index.ts#L818-L820: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/azure-openai/index.ts#L391-L393: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/bedrock/index.ts#L504-L506: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/cerebras/index.ts#L295-L297: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/deepseek/index.ts#L297-L299: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/fireworks/index.ts#L303-L305: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/mistral/index.ts#L333-L335: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/ollama/index.ts#L399-L401: pass the captured policy or an equivalent execution context.apps/tradinggoose/providers/ai/openai/index.ts#L340-L342: pass the captured policy or an equivalent execution context.apps/tradinggoose/tools/index.ts#L1103-L1104: resolve the scope before authentication and use the scoped internal token generator.apps/tradinggoose/tools/index.ts#L1188-L1188: retain abort propagation after adding scoped policy propagation.🤖 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 `@apps/tradinggoose/tools/index.ts` around lines 52 - 73, Propagate the captured workflow execution-time policy through provider tool calls so nested internal workflows retain the original tier policy and deadline. Update resolveExecutionScope in apps/tradinggoose/tools/index.ts and every listed provider site to accept and pass the captured policy or equivalent execution context; in apps/tradinggoose/tools/index.ts lines 1103-1104 resolve the scope before authentication and use the scoped internal-token generator, while preserving abort propagation at lines 1188-1188. Apply the corresponding changes at all listed provider file ranges.
🧹 Nitpick comments (21)
apps/tradinggoose/lib/billing/webhooks/subscription.ts (1)
142-142: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winLog the skipped overage calculation.
When
subscription.tieris null, the final overage becomes0and no invoice is created. Real unbilled usage is then dropped without any signal. The existing log at line 235 only reports "No overage to bill". Add a warning that distinguishes a missing tier from a genuine zero overage.♻️ Proposed change
- // Calculate overage for the final billing period - const totalOverage = subscription.tier ? await calculateSubscriptionOverage(subscription) : 0 + // Calculate overage for the final billing period + if (!subscription.tier) { + logger.warn('Skipping final overage calculation for a subscription without a tier', { + subscriptionId: subscription.id, + stripeSubscriptionId, + }) + } + const totalOverage = subscription.tier ? await calculateSubscriptionOverage(subscription) : 0🤖 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 `@apps/tradinggoose/lib/billing/webhooks/subscription.ts` at line 142, Add a warning in the subscription overage flow around the `totalOverage` assignment when `subscription.tier` is missing, explicitly recording that overage calculation was skipped; keep the zero fallback, and ensure the existing “No overage to bill” log remains reserved for genuine zero-overage cases.apps/tradinggoose/lib/billing/webhooks/subscription.test.ts (1)
344-346: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRestore coverage for the settlement-failure path.
handleStripeSubscriptionDeletedstill implements the settlement-failure branch. It recordssettlementError, skips final settlement, restoresstripeSubscriptionIdon the replacement subscription, and rethrows. The removed tests were the only coverage for that branch. Add a test that forcessyncSubscriptionBillingTierFromStripeSubscriptionto reject, then assert the Stripe ID restore and the rethrow.Also applies to: 410-410
🤖 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 `@apps/tradinggoose/lib/billing/webhooks/subscription.test.ts` around lines 344 - 346, Restore a test for the settlement-failure branch of handleStripeSubscriptionDeleted by mocking syncSubscriptionBillingTierFromStripeSubscription to reject. Assert that settlement is skipped, the replacement subscription restores stripeSubscriptionId, and the original error is rethrown.apps/tradinggoose/lib/billing/webhooks/invoices.ts (1)
74-77: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low valueRemove the
idempotencyKeyfromstripe.invoices.del. Stripe Node accepts and forwards the key, but Stripe ignoresIdempotency-Keyon/v1DELETErequests becauseDELETEis idempotent by definition. The key provides no replay protection here.🤖 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 `@apps/tradinggoose/lib/billing/webhooks/invoices.ts` around lines 74 - 77, Remove the idempotencyKey option from the stripe.invoices.del call in the invoice webhook handling flow, leaving the invoice ID and existing control flow unchanged.apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts (1)
5-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftReplace source-text assertions with behavior tests.
These tests only verify that identifiers occur in source text. They do not verify normalization, persistence, uniqueness handling, or tier-query behavior.
apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts#L5-L11: invoke the create route with mocked persistence and assert normalized access-code storage plus duplicate-code handling.apps/tradinggoose/lib/billing/tiers.test.ts#L5-L12: invoke the exported tier helpers with mocked persistence and assert the Stripe-backed and private-access query results.🤖 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 `@apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts` around lines 5 - 11, Replace source-text assertions in apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts:5-11 with behavior tests that invoke the create route using mocked persistence, asserting access-code normalization, persistence, and duplicate-code handling through the route’s uniqueness backstop. Update apps/tradinggoose/lib/billing/tiers.test.ts:5-12 to invoke the exported tier helpers with mocked persistence and assert both Stripe-backed and private-access query results.apps/tradinggoose/lib/workflows/workflow-execution-time-budget.test.ts (1)
1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider co-locating this test with its subject.
This file tests
AttemptTimeBudgetfrom@/lib/execution/workflow-execution-time-budget, but it lives underlib/workflows/. The sibling test added in this PR,apps/tradinggoose/lib/execution/workflow-execution-events.test.ts, sits next to its subject. Moving this file toapps/tradinggoose/lib/execution/workflow-execution-time-budget.test.tskeeps discovery consistent.🤖 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 `@apps/tradinggoose/lib/workflows/workflow-execution-time-budget.test.ts` around lines 1 - 3, Move the test file containing the AttemptTimeBudget tests from the workflows test location to the execution directory beside workflow-execution-time-budget, matching the co-located placement used by workflow-execution-events.test.ts; preserve the test contents unchanged.apps/tradinggoose/lib/execution/workflow-execution-time-budget.ts (2)
103-105: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueMark the budget disposed so a late call cannot re-arm a timer.
disposeclears the timer but keepsthis.timerset and leaves the instance usable. A latecloseActivityormergeChildRemainingcallsarm()and creates a new timer that nothing clears. The runner disposes at the end of an attempt, so this is defensive hardening rather than a live leak.♻️ Proposed hardening
private arm() { if (this.timer) clearTimeout(this.timer) this.timer = undefined + if (this.disposed) return const remaining = this.currentRemaining()+ private disposed = false + dispose() { + this.disposed = true if (this.timer) clearTimeout(this.timer) + this.timer = undefined }🤖 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 `@apps/tradinggoose/lib/execution/workflow-execution-time-budget.ts` around lines 103 - 105, Update dispose() in the workflow execution time budget to mark the instance disposed after clearing its timer, and ensure arm() rejects or no-ops once disposed so late closeActivity or mergeChildRemaining calls cannot create another timer. Preserve normal timer behavior before disposal.
68-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider surfacing an unknown slot id in
markQueuedChildWait.
markQueuedChildWaitignores a slot id that is not registered. If a caller ever marks before it registers, the budget keeps charging during the queued child wait and no signal is produced. A debug log or an assertion makes that caller error visible.🤖 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 `@apps/tradinggoose/lib/execution/workflow-execution-time-budget.ts` around lines 68 - 71, Update markQueuedChildWait to detect when slotId is absent from this.activities and surface that caller error through the existing project-appropriate debug log or assertion mechanism; retain the queued-child-wait state update and syncPause behavior for registered slots.apps/tradinggoose/lib/execution/workflow-execution-time-policy.ts (1)
117-161: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueConsider validating
processingStartedAtat construction.
createWorkflowExecutionTimePolicyvalidateslimitSecondsthoroughly but acceptsprocessingStartedAtunchecked. An unparsable value passes through into aremainingpolicy and only fails later inisWorkflowExecutionTimePolicy. In theabsolutebranch at Line 156,new Date(NaN).toISOString()throws a RangeError. That branch is currently unreachable becauseNESTED_WORKFLOW_QUEUE_WAIT_COUNTS_TOWARD_DEADLINEisfalse. A single guard makes the failure local and consistent with the rest of the file.🤖 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 `@apps/tradinggoose/lib/execution/workflow-execution-time-policy.ts` around lines 117 - 161, Validate processingStartedAt at the start of createWorkflowExecutionTimePolicy by confirming it parses to a finite timestamp, and throw a clear error when invalid. Perform this before the tier and accounting branches so both unlimited and bounded policies reject invalid input consistently.apps/tradinggoose/components/ui/dropdown-menu.test.tsx (1)
31-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the portal boundary.
Line 43 passes when the menu renders inline because
containeris insidedocument.body. Assert thatcontainerdoes not containOption, then assert thatdocument.bodydoes contain it.🤖 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 `@apps/tradinggoose/components/ui/dropdown-menu.test.tsx` around lines 31 - 44, Update the open-menu test around the DropdownMenu render to first assert that the local container does not contain “Option,” then assert that document.body contains it, confirming the menu renders through the required Base UI portal.apps/tradinggoose/background/workflow-execution.test.ts (1)
107-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest the inherited-budget path.
The policy at Line 124 exceeds its own 10-second limit.
isWorkflowExecutionTimePolicyrejects it before any parent allowance comparison.Rename this test to describe malformed policy validation, or add a nested execution test that propagates a real parent remaining budget and verifies that the child cannot increase it.
🤖 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 `@apps/tradinggoose/background/workflow-execution.test.ts` around lines 107 - 131, The test named “rejects a nested policy that expands the inherited allowance” currently exercises malformed policy validation because remainingMilliseconds exceeds limitSeconds, so it never reaches inherited-budget comparison. Rename the test to describe malformed policy rejection, or update it to provide a valid bounded policy and a real parent remaining budget, then verify the nested child cannot increase that allowance while preserving the existing no-execution assertions.apps/tradinggoose/lib/admin/billing/snapshot.test.ts (1)
5-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the snapshot output instead of the source text.
This test reads
snapshot.tsas a string and checks for substrings. It passes when a symbol appears in a comment or unreachable code, and it fails after a harmless rename. It verifies no behavior of the snapshot builder.Replace it with a test that calls the snapshot function with a stubbed database and asserts the returned object contains
entitledSubscriptionCount,archiveAction, andaccessCode. That gives real coverage of the contract this test intends to protect.🤖 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 `@apps/tradinggoose/lib/admin/billing/snapshot.test.ts` around lines 5 - 11, Replace the source-text assertions in the test with an invocation of the snapshot function using a stubbed database. Assert the returned snapshot object contains the expected entitledSubscriptionCount, archiveAction, and accessCode values, and remove checks for symbol names such as BILLING_ENTITLED_SUBSCRIPTION_STATUSES.apps/tradinggoose/lib/workflows/execution-runner.ts (1)
476-493: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winThe deadline handler duplicates
deadlineResultIfExpired, and the losing attempt keeps mutating shared state.Two points on this block:
Lines 480-485 repeat the body of
deadlineResultIfExpired(lines 386-391). After the handler setsattemptClosed = true,deadlineResultIfExpired()returns exactly the same value. Reuse it so the terminal-result shape stays defined in one place.When the deadline wins the race, the
attemptpromise continues to run. Its remaining startup steps are not abortable. It can still assign the outerencryptedEnvVarsat line 417 after line 542 has already read that variable forloggingSession.complete. Thevariablesrecorded on the terminal log then depend on timing. ThedeadlineResultIfExpiredguards do prevent dispatch, so no execution occurs; only the logged variables are nondeterministic.♻️ Proposed dedup for point 1
if (executionPolicy.kind === 'bounded') { const deadline = timeBudget.expired.then(() => { attemptClosed = true executor?.stopForDeadline() - const terminatedAt = new Date().toISOString() - return createWorkflowExecutionDeadlineResult( - executionPolicy, - terminatedAt, - executor?.snapshotBlockLogsForDeadline(terminatedAt) ?? [] - ) + return deadlineResultIfExpired()! })For point 2, capture
encryptedEnvVarsinto a local constant once the race settles, so the logged variables reflect the state at termination time.🤖 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 `@apps/tradinggoose/lib/workflows/execution-runner.ts` around lines 476 - 493, In the bounded execution branch around deadlineResultIfExpired and the Promise.race, replace the duplicated deadline-result construction with the existing deadlineResultIfExpired() helper after setting attemptClosed. Once the race settles, capture encryptedEnvVars into a local constant before completing logging, and use that snapshot for the terminal log’s variables so the losing attempt cannot change them.apps/tradinggoose/lib/admin/billing/access-code.ts (1)
22-30: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueThe violation check inspects only one
causelevel.
isAccessCodeUniqueViolationreadserror.causeonce. Drizzle wraps driver errors inDrizzleQueryError, and the depth of the wrapping can change between driver or ORM versions. If the postgres-js error is nested deeper, the helper returnsfalseand the route returns HTTP 500 instead of 409. Consider walking thecausechain.♻️ Optional: walk the cause chain
export function isAccessCodeUniqueViolation(error: unknown): boolean { - const cause = (error as { cause?: unknown })?.cause as { - code?: unknown - constraint_name?: unknown - } - return ( - cause?.code === '23505' && cause?.constraint_name === 'system_billing_tier_access_code_unique' - ) + let current: unknown = error + for (let depth = 0; depth < 5 && current; depth++) { + const candidate = current as { code?: unknown; constraint_name?: unknown; cause?: unknown } + if ( + candidate.code === '23505' && + candidate.constraint_name === 'system_billing_tier_access_code_unique' + ) { + return true + } + current = candidate.cause + } + return false }Note: the current unit test asserts that an unwrapped error returns
false. Update that case if you accept this change.🤖 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 `@apps/tradinggoose/lib/admin/billing/access-code.ts` around lines 22 - 30, Update isAccessCodeUniqueViolation to traverse the full error.cause chain, checking each wrapped error for code 23505 and constraint_name system_billing_tier_access_code_unique, while safely handling unknown or cyclic causes. Preserve false for errors without a matching cause and update the related unwrapped-error test only if its expected behavior changes.</code>apps/tradinggoose/executor/handlers/function/function-handler.ts (1)
69-70: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse the optional fifth parameter of
executeTooldirectly.Pass
context.abortSignal ? { signal: context.abortSignal } : undefinedto keep the call arity stable.🤖 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 `@apps/tradinggoose/executor/handlers/function/function-handler.ts` around lines 69 - 70, Update the executeTool call in the function handler to pass the optional fifth parameter directly as context.abortSignal ? { signal: context.abortSignal } : undefined, preserving stable call arity instead of conditionally spreading an array argument.apps/tradinggoose/providers/ai/xai/index.ts (1)
334-336: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winTool calls honor the abort signal; the xAI completion calls do not.
executeToolnow receivesrequest.abortSignal, butxai.chat.completions.create(...)in this file is called without the OpenAI request-options argument, so model calls ignore cancellation. See the consolidated comment for the shared fix.🤖 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 `@apps/tradinggoose/providers/ai/xai/index.ts` around lines 334 - 336, Update the xAI completion calls in the surrounding request flow to pass request.abortSignal through the OpenAI request-options argument of xai.chat.completions.create(...), matching the existing executeTool cancellation behavior. Apply this to every completion call in the file while preserving the current completion parameters.apps/tradinggoose/providers/ai/openrouter/index.ts (1)
258-260: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winTool calls honor the abort signal; the OpenRouter completion calls do not.
executeToolnow receivesrequest.abortSignal, butclient.chat.completions.create(...)in this file is called without the OpenAI request-options argument, so model calls ignore cancellation. See the consolidated comment for the shared fix.🤖 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 `@apps/tradinggoose/providers/ai/openrouter/index.ts` around lines 258 - 260, Update the OpenRouter completion calls in the relevant request flow to pass request options containing request.abortSignal as the OpenAI client’s final argument to client.chat.completions.create(...). Apply this consistently to every completion call in the file while preserving the existing request payloads.apps/tradinggoose/executor/handlers/workflow/workflow-handler.ts (1)
96-181: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winCreate the child-execution promise lazily, or attach a no-op rejection handler.
The IIFE at Line 102 starts the child workflow immediately and stores the promise. If any caller receives the deferred value but never calls
wait(), the rejection stays unobserved and Node reports an unhandled rejection.Executor.executeLayercurrently always awaits deferred results, so this is a latent risk rather than a present failure. A one-line guard removes the risk without changing the eager-start semantics.♻️ Proposed guard
})() + wait.catch(() => {}) return { kind: 'deferred', wait: () => wait }🤖 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 `@apps/tradinggoose/executor/handlers/workflow/workflow-handler.ts` around lines 96 - 181, Add a no-op rejection handler immediately after creating the eager child-execution promise in the IIFE assigned to wait, while keeping the existing wait() accessor and eager-start behavior unchanged. Ensure the handled promise does not alter the original rejection observed when wait() is called.apps/tradinggoose/providers/ai/groq/index.ts (1)
264-266: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winTool calls honor the abort signal; the Groq completion calls do not.
executeToolnow receivesrequest.abortSignal. Thegroq.chat.completions.create(...)calls in this file are issued without a request-options object, so they ignore cancellation. The groq-sdk accepts a second request-options argument withsignal. See the consolidated comment for the shared fix.🤖 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 `@apps/tradinggoose/providers/ai/groq/index.ts` around lines 264 - 266, Update every groq.chat.completions.create call in this file to pass a second request-options argument containing request.abortSignal, matching the signal already supplied to executeTool. Ensure all Groq completion calls honor cancellation without changing their existing request payloads.apps/tradinggoose/providers/ai/google/index.ts (2)
528-530: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winTool calls now honor the abort signal, but the Gemini HTTP calls in this provider still do not.
executeToolreceivesrequest.abortSignal, so tool work stops at the deadline. Thefetchcalls togenerativelanguage.googleapis.comin this sameexecuteRequestdo not passsignal, so a long model call keeps running after the workflow deadline fires. The vLLM provider passesrequest.abortSignalto every completion call. Consider aligning this provider so deadline cancellation covers model requests too.🤖 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 `@apps/tradinggoose/providers/ai/google/index.ts` around lines 528 - 530, Update the Gemini HTTP requests within executeRequest to pass request.abortSignal through their fetch options, matching the cancellation behavior already used by executeTool and the vLLM completion calls. Ensure every generativelanguage.googleapis.com request in this provider honors the workflow deadline.
1-1: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winCancellation reaches
executeToolin four providers but not their model API calls. Each provider now forwardsrequest.abortSignaltoexecuteTool, so tool work stops at the workflow deadline. The model requests in the sameexecuteRequestfunctions still run without a signal, so a slow completion continues afterstopForDeadlineaborts the execution.apps/tradinggoose/providers/ai/vllm/index.tsalready passesrequest.abortSignal ? { signal: request.abortSignal } : undefinedto everychat.completions.createcall; apply that same pattern.
apps/tradinggoose/providers/ai/google/index.ts#L528-530: addsignal: request.abortSignalto thefetchoptions for the initial, check, streaming, and follow-up calls togenerativelanguage.googleapis.com.apps/tradinggoose/providers/ai/groq/index.ts#L264-266: pass a request-options second argument containingsignal: request.abortSignalto everygroq.chat.completions.create(...)call.apps/tradinggoose/providers/ai/openrouter/index.ts#L258-260: pass a request-options second argument containingsignal: request.abortSignalto everyclient.chat.completions.create(...)call.apps/tradinggoose/providers/ai/xai/index.ts#L334-336: pass a request-options second argument containingsignal: request.abortSignalto everyxai.chat.completions.create(...)call.🤖 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 `@apps/tradinggoose/providers/ai/google/index.ts` at line 1, Propagate request.abortSignal to all model API calls in the executeRequest flows for Google, Groq, OpenRouter, and xAI. Add signal: request.abortSignal to Google fetch options for initial, check, streaming, and follow-up requests, and pass the corresponding request-options object to every chat.completions.create call in Groq, OpenRouter, and xAI, matching the existing vLLM pattern.apps/tradinggoose/lib/auth/internal.ts (1)
40-45: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winValidate
timePolicyCapturedAtwith the same strictness as the policy timestamps.
isWorkflowExecutionTimePolicyrequires an exact ISO round-trip forprocessingStartedAtandexpiresAt. This guard only requiresDate.parseto return a finite value, so values such as"2026"or"Jan 1 2026"pass. The producer always emitsnew Date().toISOString(), so aligning the check costs nothing and keeps the claim format stable for downstream elapsed-time math.♻️ Proposed change
- typeof (value as Record<string, unknown>).timePolicyCapturedAt === 'string' && - Number.isFinite( - Date.parse((value as Record<string, unknown>).timePolicyCapturedAt as string) - ) && + typeof (value as Record<string, unknown>).timePolicyCapturedAt === 'string' && + new Date( + Date.parse((value as Record<string, unknown>).timePolicyCapturedAt as string) + ).toISOString() === (value as Record<string, unknown>).timePolicyCapturedAt &&🤖 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 `@apps/tradinggoose/lib/auth/internal.ts` around lines 40 - 45, Update the timePolicyCapturedAt validation in the surrounding auth claim guard to require the same exact ISO round-trip format as processingStartedAt and expiresAt, rather than only checking that Date.parse returns a finite value. Reuse the existing timestamp-validation approach from isWorkflowExecutionTimePolicy while preserving the surrounding type and policy checks.
🤖 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 `@apps/tradinggoose/app/admin/billing/billing-admin.tsx`:
- Around line 486-489: Make the dynamic feedback messages accessible to screen
readers by adding polite live-region semantics around the save-success Notice
rendered by the billing admin component; likewise add a polite live region for
the access-code success and validation feedback in subscription.tsx at lines
636-639. Preserve the existing Notice content and feedback behavior at both
sites.
In `@apps/tradinggoose/app/admin/billing/tier-editor.tsx`:
- Around line 1446-1463: Update the Input for workflowExecutionTimeLimitSeconds
in the tier editor to reject zero by requiring values greater than 0, aligning
client-side validation with the server and database constraints while preserving
the existing numeric input behavior.
In `@apps/tradinggoose/app/api/auth/`[...all]/route.ts:
- Line 86: Normalize pathname by removing a trailing slash before the guard
comparison in the route handler, so both `/api/auth/subscription/upgrade` and
its slash-suffixed form enter the session, reference authorization, and tier
availability checks. Preserve the existing POST-method requirement and exact
subscription upgrade path matching after normalization.
In `@apps/tradinggoose/executor/index.ts`:
- Around line 662-665: Update the shouldCancelExecution callback in the
execution options to abort this.abortController when either this.isCancelled or
the external contextExtensions.shouldCancelExecution callback returns true. Keep
deadlineExceeded handling separate and unchanged, and continue returning the
cancellation result.
In `@apps/tradinggoose/i18n/messages/en.json`:
- Around line 1463-1468: Implement the non-test renderer for
workspace.logs.details.deadline, mapping limitSeconds to the limit message’s
seconds placeholder and appliedTierName to the tier message’s tierName
placeholder. Ensure the deadline title, reason, limit, and tier translations are
consumed when rendering this log detail.
In `@apps/tradinggoose/i18n/messages/es.json`:
- Line 22160: Update the activeSubscriptionsWarning translation to replace
“suscripciones con derecho” with clear Spanish wording such as “suscripciones
con acceso vigente,” while preserving the message’s existing meaning about
archiving, the paid period, and renewal cancellation.
In `@apps/tradinggoose/i18n/messages/zh.json`:
- Line 22147: Update the activeSubscriptionsWarning translation to clearly state
that the tier has active subscriptions and that archiving preserves the current
paid period while canceling subsequent renewals.
In `@apps/tradinggoose/lib/auth/internal.test.ts`:
- Line 7: Replace the process.env assignments with deletion so the variables are
truly unset: use delete for INTERNAL_API_SECRET in
apps/tradinggoose/lib/auth/internal.test.ts:7-7 and for NEXT_PHASE in
apps/tradinggoose/lib/billing/plans.test.ts:29-29, including its assignments
inside the runtime-phase tests.
In `@apps/tradinggoose/lib/auth/internal.ts`:
- Around line 23-24: Update the child-workflow token validation and queue flow
around timePolicy and timePolicyCapturedAt to support a compatibility window for
pre-deploy tokens that verify as valid but lack the new fields. Delay
enforcement of the workflow execution policy until those legacy tokens can
expire, while ensuring missing policy data is never treated as a safe fallback.
In `@apps/tradinggoose/lib/billing/webhooks/invoices.ts`:
- Around line 46-54: Update the missing-subscription branch in the renewal
handler around getSubscriptionByStripeSubscriptionId to log the absence and
return immediately. Ensure the subsequent eligibility check and Stripe
cancellation path run only when a local subscription record exists, while
preserving cancellation for confirmed non-renewable local subscriptions.
- Around line 409-415: Update the cancellation/default-restoration flow around
handleStripeSubscriptionDeleted and ensureDefaultUserSubscription to clear
billingBlocked for both userStats and organizationBillingLedger before the early
return, ensuring canceled subscriptions settled through this path do not retain
the blocked state.
In `@apps/tradinggoose/lib/execution/workflow-execution-events.ts`:
- Around line 234-240: Update the isExecutionResult(storedResult) branch to
merge executionData.traceSpans into the returned stored-result object before
constructing result, preserving any existing stored trace spans while retaining
the current status, metadata, and failureReason behavior.
In `@apps/tradinggoose/lib/logs/execution/logger.ts`:
- Line 227: Replace the broad result?: object persisted by the execution logger
with a narrowed diagnostic-only type containing only the failure fields needed
for durable diagnostics, excluding output and BlockLog input/output payloads.
Apply the same type to SessionCompleteParams and SessionErrorCompleteParams in
logging-session.ts, then project results to that shape at the
execution-runner.ts call sites before persistence; preserve the existing
mergedExecutionData fields.
In `@apps/tradinggoose/providers/ai/gemini/core.ts`:
- Around line 126-128: Update executeToolCallsBatch to rethrow the caught error
when request.abortSignal.aborted is true, instead of converting an aborted
execution into a normal tool failure; preserve existing handling for non-abort
errors. Add a test that aborts every tool call and verifies executeGeminiRequest
rejects.
In `@apps/tradinggoose/services/queue/ExecutionLimiter.test.ts`:
- Around line 296-415: Ensure the tests using fake timers in the added
rate-limiter cases always restore real timers when assertions or setup fail.
Prefer adding an afterEach cleanup for this test suite that calls
vi.useRealTimers(), rather than relying only on each test’s final statement;
remove redundant per-test restoration only if appropriate.
In
`@apps/tradinggoose/widgets/widgets/workflow_console/components/terminal/components/status-display.test.tsx`:
- Around line 1-31: Set globalThis.IS_REACT_ACT_ENVIRONMENT to true at the start
of the StatusDisplay test setup, before either act call executes, so React
recognizes the Vitest jsdom environment and avoids the act-environment warning.
In `@packages/db/migrations/0040_wet_psylocke.sql`:
- Around line 13-16: Update the migration around
system_billing_tier_access_code_unique to create the unique index concurrently
through a separate non-transactional migration step or custom runner, avoiding
Drizzle’s transactional execution for that statement. Add the three CHECK
constraints with NOT VALID, then validate each constraint in a separate step
while preserving their existing conditions.
---
Outside diff comments:
In `@apps/tradinggoose/lib/logs/execution/logger.ts`:
- Around line 283-290: Stop persisting the full ExecutionResult in
logger.ts#L283-L290: define and use a narrowed type containing only deadline
diagnostics (code, deadline, and error), and persist only those fields alongside
traceSpans and finalOutput. Update SessionCompleteParams and
SessionErrorCompleteParams in
apps/tradinggoose/lib/logs/execution/logging-session.ts#L44-L59 to use the same
narrowed result type instead of ExecutionResult, and project those fields before
passing the result to completeWithError and complete in
apps/tradinggoose/lib/workflows/execution-runner.ts#L528-L555.
In `@apps/tradinggoose/tools/index.ts`:
- Around line 52-73: Propagate the captured workflow execution-time policy
through provider tool calls so nested internal workflows retain the original
tier policy and deadline. Update resolveExecutionScope in
apps/tradinggoose/tools/index.ts and every listed provider site to accept and
pass the captured policy or equivalent execution context; in
apps/tradinggoose/tools/index.ts lines 1103-1104 resolve the scope before
authentication and use the scoped internal-token generator, while preserving
abort propagation at lines 1188-1188. Apply the corresponding changes at all
listed provider file ranges.
---
Nitpick comments:
In `@apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts`:
- Around line 5-11: Replace source-text assertions in
apps/tradinggoose/app/api/admin/billing/tiers/route.test.ts:5-11 with behavior
tests that invoke the create route using mocked persistence, asserting
access-code normalization, persistence, and duplicate-code handling through the
route’s uniqueness backstop. Update
apps/tradinggoose/lib/billing/tiers.test.ts:5-12 to invoke the exported tier
helpers with mocked persistence and assert both Stripe-backed and private-access
query results.
In `@apps/tradinggoose/background/workflow-execution.test.ts`:
- Around line 107-131: The test named “rejects a nested policy that expands the
inherited allowance” currently exercises malformed policy validation because
remainingMilliseconds exceeds limitSeconds, so it never reaches inherited-budget
comparison. Rename the test to describe malformed policy rejection, or update it
to provide a valid bounded policy and a real parent remaining budget, then
verify the nested child cannot increase that allowance while preserving the
existing no-execution assertions.
In `@apps/tradinggoose/components/ui/dropdown-menu.test.tsx`:
- Around line 31-44: Update the open-menu test around the DropdownMenu render to
first assert that the local container does not contain “Option,” then assert
that document.body contains it, confirming the menu renders through the required
Base UI portal.
In `@apps/tradinggoose/executor/handlers/function/function-handler.ts`:
- Around line 69-70: Update the executeTool call in the function handler to pass
the optional fifth parameter directly as context.abortSignal ? { signal:
context.abortSignal } : undefined, preserving stable call arity instead of
conditionally spreading an array argument.
In `@apps/tradinggoose/executor/handlers/workflow/workflow-handler.ts`:
- Around line 96-181: Add a no-op rejection handler immediately after creating
the eager child-execution promise in the IIFE assigned to wait, while keeping
the existing wait() accessor and eager-start behavior unchanged. Ensure the
handled promise does not alter the original rejection observed when wait() is
called.
In `@apps/tradinggoose/lib/admin/billing/access-code.ts`:
- Around line 22-30: Update isAccessCodeUniqueViolation to traverse the full
error.cause chain, checking each wrapped error for code 23505 and
constraint_name system_billing_tier_access_code_unique, while safely handling
unknown or cyclic causes. Preserve false for errors without a matching cause and
update the related unwrapped-error test only if its expected behavior
changes.</code>
In `@apps/tradinggoose/lib/admin/billing/snapshot.test.ts`:
- Around line 5-11: Replace the source-text assertions in the test with an
invocation of the snapshot function using a stubbed database. Assert the
returned snapshot object contains the expected entitledSubscriptionCount,
archiveAction, and accessCode values, and remove checks for symbol names such as
BILLING_ENTITLED_SUBSCRIPTION_STATUSES.
In `@apps/tradinggoose/lib/auth/internal.ts`:
- Around line 40-45: Update the timePolicyCapturedAt validation in the
surrounding auth claim guard to require the same exact ISO round-trip format as
processingStartedAt and expiresAt, rather than only checking that Date.parse
returns a finite value. Reuse the existing timestamp-validation approach from
isWorkflowExecutionTimePolicy while preserving the surrounding type and policy
checks.
In `@apps/tradinggoose/lib/billing/webhooks/invoices.ts`:
- Around line 74-77: Remove the idempotencyKey option from the
stripe.invoices.del call in the invoice webhook handling flow, leaving the
invoice ID and existing control flow unchanged.
In `@apps/tradinggoose/lib/billing/webhooks/subscription.test.ts`:
- Around line 344-346: Restore a test for the settlement-failure branch of
handleStripeSubscriptionDeleted by mocking
syncSubscriptionBillingTierFromStripeSubscription to reject. Assert that
settlement is skipped, the replacement subscription restores
stripeSubscriptionId, and the original error is rethrown.
In `@apps/tradinggoose/lib/billing/webhooks/subscription.ts`:
- Line 142: Add a warning in the subscription overage flow around the
`totalOverage` assignment when `subscription.tier` is missing, explicitly
recording that overage calculation was skipped; keep the zero fallback, and
ensure the existing “No overage to bill” log remains reserved for genuine
zero-overage cases.
In `@apps/tradinggoose/lib/execution/workflow-execution-time-budget.ts`:
- Around line 103-105: Update dispose() in the workflow execution time budget to
mark the instance disposed after clearing its timer, and ensure arm() rejects or
no-ops once disposed so late closeActivity or mergeChildRemaining calls cannot
create another timer. Preserve normal timer behavior before disposal.
- Around line 68-71: Update markQueuedChildWait to detect when slotId is absent
from this.activities and surface that caller error through the existing
project-appropriate debug log or assertion mechanism; retain the
queued-child-wait state update and syncPause behavior for registered slots.
In `@apps/tradinggoose/lib/execution/workflow-execution-time-policy.ts`:
- Around line 117-161: Validate processingStartedAt at the start of
createWorkflowExecutionTimePolicy by confirming it parses to a finite timestamp,
and throw a clear error when invalid. Perform this before the tier and
accounting branches so both unlimited and bounded policies reject invalid input
consistently.
In `@apps/tradinggoose/lib/workflows/execution-runner.ts`:
- Around line 476-493: In the bounded execution branch around
deadlineResultIfExpired and the Promise.race, replace the duplicated
deadline-result construction with the existing deadlineResultIfExpired() helper
after setting attemptClosed. Once the race settles, capture encryptedEnvVars
into a local constant before completing logging, and use that snapshot for the
terminal log’s variables so the losing attempt cannot change them.
In `@apps/tradinggoose/lib/workflows/workflow-execution-time-budget.test.ts`:
- Around line 1-3: Move the test file containing the AttemptTimeBudget tests
from the workflows test location to the execution directory beside
workflow-execution-time-budget, matching the co-located placement used by
workflow-execution-events.test.ts; preserve the test contents unchanged.
In `@apps/tradinggoose/providers/ai/google/index.ts`:
- Around line 528-530: Update the Gemini HTTP requests within executeRequest to
pass request.abortSignal through their fetch options, matching the cancellation
behavior already used by executeTool and the vLLM completion calls. Ensure every
generativelanguage.googleapis.com request in this provider honors the workflow
deadline.
- Line 1: Propagate request.abortSignal to all model API calls in the
executeRequest flows for Google, Groq, OpenRouter, and xAI. Add signal:
request.abortSignal to Google fetch options for initial, check, streaming, and
follow-up requests, and pass the corresponding request-options object to every
chat.completions.create call in Groq, OpenRouter, and xAI, matching the existing
vLLM pattern.
In `@apps/tradinggoose/providers/ai/groq/index.ts`:
- Around line 264-266: Update every groq.chat.completions.create call in this
file to pass a second request-options argument containing request.abortSignal,
matching the signal already supplied to executeTool. Ensure all Groq completion
calls honor cancellation without changing their existing request payloads.
In `@apps/tradinggoose/providers/ai/openrouter/index.ts`:
- Around line 258-260: Update the OpenRouter completion calls in the relevant
request flow to pass request options containing request.abortSignal as the
OpenAI client’s final argument to client.chat.completions.create(...). Apply
this consistently to every completion call in the file while preserving the
existing request payloads.
In `@apps/tradinggoose/providers/ai/xai/index.ts`:
- Around line 334-336: Update the xAI completion calls in the surrounding
request flow to pass request.abortSignal through the OpenAI request-options
argument of xai.chat.completions.create(...), matching the existing executeTool
cancellation behavior. Apply this to every completion call in the file while
preserving the current completion parameters.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 991217e0-f4ea-45b3-8733-09cb782e1bb6
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (146)
apps/tradinggoose/app/(landing)/components/monitor-preview/fetch-listings.test.tsapps/tradinggoose/app/(landing)/components/monitor-preview/fetch-listings.tsapps/tradinggoose/app/admin/billing/billing-admin.test.tsxapps/tradinggoose/app/admin/billing/billing-admin.tsxapps/tradinggoose/app/admin/billing/tier-detail.test.tsxapps/tradinggoose/app/admin/billing/tier-detail.tsxapps/tradinggoose/app/admin/billing/tier-editor.test.tsxapps/tradinggoose/app/admin/billing/tier-editor.tsxapps/tradinggoose/app/api/admin/billing/tiers/[id]/route.test.tsapps/tradinggoose/app/api/admin/billing/tiers/[id]/route.tsapps/tradinggoose/app/api/admin/billing/tiers/route.test.tsapps/tradinggoose/app/api/admin/billing/tiers/route.tsapps/tradinggoose/app/api/auth/[...all]/route.test.tsapps/tradinggoose/app/api/auth/[...all]/route.tsapps/tradinggoose/app/api/billing/payg/activate/route.tsapps/tradinggoose/app/api/billing/private-tier-access/route.test.tsapps/tradinggoose/app/api/billing/private-tier-access/route.tsapps/tradinggoose/app/api/billing/public-catalog/route.test.tsapps/tradinggoose/app/api/logs/log-utils.test.tsapps/tradinggoose/app/api/organizations/[id]/seats/route.test.tsapps/tradinggoose/app/api/webhooks/test/route.test.tsapps/tradinggoose/app/api/webhooks/test/route.tsapps/tradinggoose/app/api/workflows/[id]/queue/route.test.tsapps/tradinggoose/app/api/workflows/[id]/queue/route.tsapps/tradinggoose/background/pending-execution-drain.test.tsapps/tradinggoose/background/pending-execution-drain.tsapps/tradinggoose/background/portfolio-monitor-execution.tsapps/tradinggoose/background/schedule-execution.tsapps/tradinggoose/background/webhook-execution.tsapps/tradinggoose/background/workflow-execution.test.tsapps/tradinggoose/background/workflow-execution.tsapps/tradinggoose/components/ui/dropdown-menu.test.tsxapps/tradinggoose/components/ui/dropdown-menu.tsxapps/tradinggoose/executor/handlers/agent/agent-handler.tsapps/tradinggoose/executor/handlers/api/api-handler.tsapps/tradinggoose/executor/handlers/evaluator/evaluator-handler.tsapps/tradinggoose/executor/handlers/function/function-handler.tsapps/tradinggoose/executor/handlers/generic/generic-handler.tsapps/tradinggoose/executor/handlers/router/router-handler.tsapps/tradinggoose/executor/handlers/workflow/workflow-handler.test.tsapps/tradinggoose/executor/handlers/workflow/workflow-handler.tsapps/tradinggoose/executor/index.test.tsapps/tradinggoose/executor/index.tsapps/tradinggoose/executor/types.tsapps/tradinggoose/global-navbar/settings-modal/components/subscription/subscription-permissions.test.tsapps/tradinggoose/global-navbar/settings-modal/components/subscription/subscription-permissions.tsapps/tradinggoose/global-navbar/settings-modal/components/subscription/subscription.test.tsxapps/tradinggoose/global-navbar/settings-modal/components/subscription/subscription.tsxapps/tradinggoose/hooks/queries/admin-billing.test.tsxapps/tradinggoose/hooks/queries/admin-billing.tsapps/tradinggoose/hooks/queries/private-tier-access.test.tsxapps/tradinggoose/hooks/queries/private-tier-access.tsapps/tradinggoose/i18n/messages/en.jsonapps/tradinggoose/i18n/messages/es.jsonapps/tradinggoose/i18n/messages/zh.jsonapps/tradinggoose/i18n/request-locale.test.tsapps/tradinggoose/i18n/request-locale.tsapps/tradinggoose/lib/admin/billing/access-code.test.tsapps/tradinggoose/lib/admin/billing/access-code.tsapps/tradinggoose/lib/admin/billing/snapshot.test.tsapps/tradinggoose/lib/admin/billing/snapshot.tsapps/tradinggoose/lib/admin/billing/tier-mutations.test.tsapps/tradinggoose/lib/admin/billing/tier-mutations.tsapps/tradinggoose/lib/admin/billing/types.tsapps/tradinggoose/lib/api/rate-limit.test.tsapps/tradinggoose/lib/api/rate-limit.tsapps/tradinggoose/lib/auth.tsapps/tradinggoose/lib/auth/internal.test.tsapps/tradinggoose/lib/auth/internal.tsapps/tradinggoose/lib/billing/authorization.tsapps/tradinggoose/lib/billing/catalog.test.tsapps/tradinggoose/lib/billing/catalog.tsapps/tradinggoose/lib/billing/core/subscription.test.tsapps/tradinggoose/lib/billing/core/subscription.tsapps/tradinggoose/lib/billing/plans.test.tsapps/tradinggoose/lib/billing/plans.tsapps/tradinggoose/lib/billing/private-tier-access.tsapps/tradinggoose/lib/billing/public-catalog.tsapps/tradinggoose/lib/billing/subscription-tier-display.test.tsapps/tradinggoose/lib/billing/subscription-tier-display.tsapps/tradinggoose/lib/billing/tier-availability-policy.test.tsapps/tradinggoose/lib/billing/tier-availability-policy.tsapps/tradinggoose/lib/billing/tier-summary.tsapps/tradinggoose/lib/billing/tiers.test.tsapps/tradinggoose/lib/billing/tiers.tsapps/tradinggoose/lib/billing/types/index.tsapps/tradinggoose/lib/billing/webhooks/invoices.test.tsapps/tradinggoose/lib/billing/webhooks/invoices.tsapps/tradinggoose/lib/billing/webhooks/subscription.test.tsapps/tradinggoose/lib/billing/webhooks/subscription.tsapps/tradinggoose/lib/execution/pending-execution.test.tsapps/tradinggoose/lib/execution/pending-execution.tsapps/tradinggoose/lib/execution/workflow-execution-events.test.tsapps/tradinggoose/lib/execution/workflow-execution-events.tsapps/tradinggoose/lib/execution/workflow-execution-time-budget.tsapps/tradinggoose/lib/execution/workflow-execution-time-policy.test.tsapps/tradinggoose/lib/execution/workflow-execution-time-policy.tsapps/tradinggoose/lib/logs/execution/logger.tsapps/tradinggoose/lib/logs/execution/logging-session.tsapps/tradinggoose/lib/logs/execution/trace-spans/trace-spans.test.tsapps/tradinggoose/lib/logs/execution/trace-spans/trace-spans.tsapps/tradinggoose/lib/logs/types.tsapps/tradinggoose/lib/subscription/upgrade.tsapps/tradinggoose/lib/workflows/execution-result.test.tsapps/tradinggoose/lib/workflows/execution-result.tsapps/tradinggoose/lib/workflows/execution-runner.test.tsapps/tradinggoose/lib/workflows/execution-runner.tsapps/tradinggoose/lib/workflows/workflow-execution-time-budget.test.tsapps/tradinggoose/package.jsonapps/tradinggoose/providers/ai/anthropic/core.tsapps/tradinggoose/providers/ai/anthropic/index.tsapps/tradinggoose/providers/ai/azure-openai/index.tsapps/tradinggoose/providers/ai/bedrock/index.tsapps/tradinggoose/providers/ai/cerebras/index.tsapps/tradinggoose/providers/ai/deepseek/index.tsapps/tradinggoose/providers/ai/fireworks/index.tsapps/tradinggoose/providers/ai/gemini/core.tsapps/tradinggoose/providers/ai/google/index.tsapps/tradinggoose/providers/ai/groq/index.tsapps/tradinggoose/providers/ai/mistral/index.tsapps/tradinggoose/providers/ai/ollama/index.tsapps/tradinggoose/providers/ai/openai/index.tsapps/tradinggoose/providers/ai/openrouter/index.tsapps/tradinggoose/providers/ai/vllm/index.tsapps/tradinggoose/providers/ai/xai/index.tsapps/tradinggoose/proxy.tsapps/tradinggoose/scripts/test-billing-suite.tsapps/tradinggoose/services/queue/ExecutionLimiter.test.tsapps/tradinggoose/services/queue/ExecutionLimiter.tsapps/tradinggoose/stores/console/store.test.tsapps/tradinggoose/stores/console/store.tsapps/tradinggoose/stores/organization/store.tsapps/tradinggoose/stores/organization/types.tsapps/tradinggoose/tools/index.test.tsapps/tradinggoose/tools/index.tsapps/tradinggoose/widgets/widgets/editor_workflow/components/workflow-block/components/sub-block/components/dropdown.tsxapps/tradinggoose/widgets/widgets/workflow_console/components/terminal/components/status-display.test.tsxapps/tradinggoose/widgets/widgets/workflow_console/components/terminal/components/status-display.tsxapps/tradinggoose/widgets/widgets/workflow_console/components/terminal/terminal.tsxpackages/db/migrations/0040_wet_psylocke.sqlpackages/db/migrations/meta/0040_snapshot.jsonpackages/db/migrations/meta/_journal.jsonpackages/db/schema/billing.tspackages/db/schema/system.tspackages/python-sdk/tradinggoose/__init__.pypackages/ts-sdk/src/index.ts
💤 Files with no reviewable changes (3)
- apps/tradinggoose/widgets/widgets/editor_workflow/components/workflow-block/components/sub-block/components/dropdown.tsx
- apps/tradinggoose/stores/organization/types.ts
- apps/tradinggoose/stores/organization/store.ts
Summary
Adds two related billing-tier capabilities:
Type of Change
Why
Private tiers need secure, non-enumerating access control without creating a separate subscription path. Workflow executions also need tier-controlled time limits that work consistently across triggers and nested workflows while preserving the existing execution lifecycle.
This change keeps Better Auth, Stripe, workflow execution, logging, and shared rate limiting as the canonical owners.
Affected Areas
Validation
The following validation passed:
A final independent branch review against staging reported no goal-blocking findings.
Reviewer Focus
Risk / Rollout Notes
Config / Data Changes
Screenshots / Video
Not attached. Visible changes are contained within existing billing administration and subscription-modal surfaces.
Checklist
Summary by CodeRabbit