Skip to content

feat(api): Live-State custom procedures — plan §1–§15 (through timeline update)#248

Draft
pedroscosta wants to merge 30 commits into
mainfrom
feat/live-state-pipeline-procedures-qu1
Draft

feat(api): Live-State custom procedures — plan §1–§15 (through timeline update)#248
pedroscosta wants to merge 30 commits into
mainfrom
feat/live-state-pipeline-procedures-qu1

Conversation

@pedroscosta
Copy link
Copy Markdown
Collaborator

@pedroscosta pedroscosta commented Apr 15, 2026

Summary

Rollout for Live-State custom procedures (docs/live-state-custom-procedures-plan.md):

  • Plan §1: pipelineIdempotencyKey and pipelineJob use named procedures; generic collection insert / update are disabled for those tables; worker call sites updated.
  • Plan §2: allowlist uses create / update procedures; generic insert / update disabled; apps/api/src/live-state/router/allowlist.ts added.
  • Plan §3: subscription uses create / update procedures; generic collection update disabled; apps/api/src/live-state/router/subscription.ts added; org bootstrap still uses db.subscription.insert inside organization.create; Dodo webhooks remain on storage outside Live-State.
  • Plan §4: author uses create / update procedures (idempotent get-or-create by userId + organizationId, or metaId + organizationId); generic collection insert / update disabled; apps/api/src/live-state/router/author.ts added; web devtools, deprecated thread input, and Discord/Slack use author.create; optimistic author.create / author.update in apps/web/src/lib/live-state.ts.
  • Plan §5: invite uses create, cancel, accept, and decline procedures; generic collection update disabled; organizationUser.inviteUser removed in favor of invite.create; apps/api/src/live-state/router/invite.ts added; team.tsx uses mutate.invite.create and mutate.invite.cancel; optimistic invite.cancel in apps/web/src/lib/live-state.ts.
  • Plan §6: documentationSource uses withProcedures (validate, create, recrawl, discriminated update); generic insert / update disabled; worker crawl progress uses update with action: "setProgress"; settings UI updated.
  • Plan §7: agentChat uses withProcedures (same RPC names); reads/writes in handlers use typed db.* / trx.* collection APIs; authorize for org membership.
  • Plan §8: onboarding generic insert / update disabled; initialize renamed to create with withProcedures; completeStep / skip / complete unchanged by name; optimistic handlers in live-state.ts.
  • Plan §9: user uses withProcedures update only; generic collection update disabled; apps/api/src/live-state/router/user.ts; profile settings use object payload; optimistic user.update.
  • Plan §10: organizationUser uses withProcedures create and update; generic collection insert / update disabled; apps/api/src/live-state/router/organization-user.ts; org bootstrap uses db.organizationUser.insert; team member role/remove use object payloads; optimistic organizationUser.update.
  • Plan §11: organization extracted to apps/api/src/live-state/router/organization.ts with withProcedures (create, update, createPublicApiKey, revokePublicApiKey, listApiKeys); generic collection insert / update disabled; web org settings and digest worker use mutate.organization.update({ id, ... }); optimistic organization.update in live-state.ts.
  • Plan §12: integration uses apps/api/src/live-state/router/integration.ts with create, update, and fetchSlackChannels; generic collection insert / update disabled; web OAuth flows, activate.ts, Discord/Slack/GitHub apps use object-shaped update and create.
  • Plan §13: label and threadLabel use withProcedures create / update in apps/api/src/live-state/router/labels.ts; generic collection insert / update disabled; web labels UI, thread labels, and quick actions migrated.
  • Plan §14: suggestion uses withProcedures create / update in apps/api/src/live-state/router/suggestions.ts; generic collection insert / update disabled; worker processors, devtools, signal, and thread toolbars use object-shaped updates and create.
  • Plan §15: Timeline update collection uses withProcedures create / update in apps/api/src/live-state/router/update.ts; generic collection insert / update disabled; web thread actions, GitHub webhooks, Discord, and Slack migrated to mutate.update.create / mutate.update.update({ id, ... }).

Plan checklist (files cited in the plan)

Cross-cutting / router:

  • apps/api/src/live-state/router.ts
  • apps/api/src/live-state/router/allowlist.ts
  • apps/api/src/live-state/router/subscription.ts
  • apps/api/src/live-state/router/author.ts
  • apps/api/src/live-state/router/invite.ts
  • apps/api/src/live-state/router/documentation-sources.ts
  • apps/api/src/live-state/router/user.ts
  • apps/api/src/live-state/router/organization-user.ts
  • apps/api/src/live-state/router/organization.ts
  • apps/api/src/live-state/router/integration.ts
  • apps/api/src/live-state/router/labels.ts
  • apps/api/src/live-state/router/suggestions.ts
  • apps/api/src/live-state/router/update.ts
  • apps/web/src/lib/live-state.ts
  • apps/api/src/lib/authorize.ts

Worker — pipeline & docs & suggestions:

  • apps/worker/src/pipeline/core/idempotency.ts
  • apps/worker/src/pipeline/core/persistence.ts
  • apps/worker/src/pipeline/processors/suggest-status.ts
  • apps/worker/src/pipeline/processors/suggest-labels.ts
  • apps/worker/src/pipeline/processors/suggest-duplicates.ts
  • apps/worker/src/lib/database/client.ts
  • apps/worker/src/handlers/match-pr-threads.ts
  • apps/worker/src/handlers/digest-scan.ts
  • apps/worker/src/handlers/digest-deliver.ts
  • apps/worker/src/handlers/crawl-documentation.ts

Web — threads, signal, actions, toolbar:

  • apps/web/src/actions/threads.ts
  • apps/web/src/components/threads/properties.tsx
  • apps/web/src/components/threads/issues.tsx
  • apps/web/src/components/threads/pull-requests.tsx
  • apps/web/src/components/threads/linked-pr-suggestions-section.tsx
  • apps/web/src/components/threads/thread-toolbar/quick-actions.tsx
  • apps/web/src/components/threads/thread-toolbar/reply-editor.tsx
  • apps/web/src/routes/app/_workspace/_main/signal/index.tsx
  • apps/web/src/routes/app/_workspace/_main/threads/$id.tsx
  • apps/web/src/routes/app/_workspace/_main/threads/archive/$id.tsx
  • apps/web/src/routes/support/$slug/threads/$id.tsx

Web — labels & org & team & user & integrations:

  • apps/web/src/components/threads/labels.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/labels.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/support-intelligence.tsx
  • apps/web/src/components/threads/thread-input-area-deprecated/support-intelligence.tsx
  • apps/web/src/components/devtools/devtools-menu/add-pr-suggestion-command.tsx
  • apps/web/src/components/devtools/devtools-menu/signals-submenu.tsx
  • apps/web/src/lib/integrations/activate.ts
  • apps/web/src/routes/app/_workspace/settings/organization/index.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/team.tsx
  • apps/web/src/routes/app/_workspace/settings/user/index.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/documentation.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/api-keys.tsx
  • apps/web/src/lib/server-funcs/payment.ts
  • apps/web/src/lib/server-funcs/invitations.tsx

Web — devtools / deprecated / onboarding / playground:

  • apps/web/src/components/devtools/devtools-menu/create-thread-button.tsx
  • apps/web/src/components/devtools/devtools-menu/create-thread-dialog.tsx
  • apps/web/src/components/threads/create-thread-dialog.tsx
  • apps/web/src/components/devtools/devtools-menu/duplicate-thread-command.tsx
  • apps/web/src/components/threads/thread-input-area-deprecated/index.tsx
  • apps/web/src/lib/onboarding/use-onboarding.ts
  • apps/web/src/routes/app/_workspace/_main/playground/index.tsx

Discord & Slack:

  • apps/discord/src/index.ts
  • apps/slack/src/index.ts
  • apps/discord/src/lib/utils.ts
  • apps/slack/src/lib/utils.ts
  • apps/slack/src/lib/installation-store.ts

GitHub app:

  • apps/github/src/webhooks/index.ts
  • apps/github/src/routes/setup.ts

Web — integration settings (OAuth / UI; not every file was in the original checklist):

  • apps/web/src/routes/app/_workspace/settings/organization/integration/discord/index.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/integration/discord/redirect.ts
  • apps/web/src/routes/app/_workspace/settings/organization/integration/slack/index.tsx
  • apps/web/src/routes/app/_workspace/settings/organization/integration/slack/redirect.ts
  • apps/web/src/routes/app/_workspace/settings/organization/integration/github/index.tsx

Note: The plan also refers generically to “Discord / Slack / GitHub settings + OAuth redirects” without listing every route file; those can be folded in as you discover additional mutate call sites.

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced detection and handling of database constraint violations for more reliable operations.
  • Infrastructure

    • Refactored pipeline write operations with improved authorization controls.
    • Updated Live-State sync library dependency.

Replace deprecated collection insert/update on pipelineIdempotencyKey and
pipelineJob with internalApiKey-gated procedures (upsert, invalidate,
create, update) and migrate the worker pipeline callers.

Made-with: Cursor
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files

Confidence score: 3/5

  • There is a concrete concurrency risk in apps/api/src/live-state/router.ts: upsert uses a non-atomic find-then-insert/update pattern, which can intermittently fail under parallel requests for the same key.
  • Given the 7/10 severity and high confidence (8/10), this is more than a minor code-quality note and could cause user-visible write failures in production race conditions.
  • Pay close attention to apps/api/src/live-state/router.ts - make the upsert path atomic (or handle unique-key conflicts safely) to avoid intermittent request failures.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/api/src/live-state/router.ts">

<violation number="1" location="apps/api/src/live-state/router.ts:756">
P1: `upsert` is implemented as a non-atomic find-then-insert/update, so concurrent requests for the same key can hit unique-key races and fail intermittently.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread apps/api/src/live-state/router.ts Outdated
Wrap upsert in a short transaction: update when row exists, otherwise insert
and recover from Postgres unique violations on concurrent inserts for the
same key. Invalidate uses the same transactional read-then-update pattern.

Made-with: Cursor
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: Refactors core data persistence logic for pipelines into custom API procedures, modifying business logic for idempotency and job tracking.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Important

Review skipped

Draft detected.

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

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 61da4faa-7b06-4715-8bf3-44e691affed8

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
📝 Walkthrough

Walkthrough

This pull request migrates internal pipeline collections from generic Live-State mutations to explicit procedure-based mutations with built-in authorization and transaction handling. The changes include implementing custom procedures for pipelineIdempotencyKey (upsert, invalidate) and pipelineJob (create, update), updating worker code to invoke these new procedures, and documenting the broader migration policy.

Changes

Cohort / File(s) Summary
API Router Procedure Implementation
apps/api/src/live-state/router.ts
Added isPostgresUniqueViolation() helper for constraint error detection. Disabled direct insert/update mutations for pipelineIdempotencyKey and pipelineJob, replacing them with explicit procedure-based mutations: pipelineIdempotencyKey.upsert() and .invalidate(); pipelineJob.create() and .update(). Each procedure includes authorization, transaction logic, and specific business logic (e.g., upsert retry on unique violation, existence validation for job updates).
Worker Integration
apps/worker/src/pipeline/core/idempotency.ts, apps/worker/src/pipeline/core/persistence.ts
Updated worker code to call the new procedure-based mutations: storeIdempotencyKey and invalidateIdempotencyKey now delegate to pipelineIdempotencyKey.upsert() and .invalidate() respectively; createPipelineJob switched from .insert() to .create() procedure; job status update methods changed to use the new .update() signature with id in the payload.
Migration Documentation
docs/live-state-custom-procedures-plan.md
New reference document outlining the policy for eliminating generic collection mutations across all Live-State collections. Specifies routing-level authorization controls, procedure naming conventions, cross-cutting rules (e.g., mandatory authorize() calls with internalApiKey), and a phased migration plan with implementation order and call-site inventory across multiple apps.
Dependency Update
package.json
Updated @live-state/sync from 0.0.7-canary-7 to 0.0.7-pr-1 in the workspace catalog.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • danielmoural

Poem

🐰 Hopping through transactions with care so true,
Old mutations fade, procedures bloom anew,
Authorization guards each database dance,
Pipeline jobs safe in transactions' trance,
From insert and update, we've made our stance!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective: implementing Live-State custom procedures for the pipeline-related collections (pipelineIdempotencyKey and pipelineJob) as the first phase of a broader migration plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/live-state-pipeline-procedures-qu1

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
docs/live-state-custom-procedures-plan.md (1)

9-9: Clean up MD037 emphasis spacing to keep markdownlint green.

There are many inline emphasis spans with spaces inside marker boundaries (for example around inline code). Normalizing those will remove the repeated MD037 warnings.

Also applies to: 21-23, 32-32, 44-45, 59-59, 74-74, 92-92, 105-105, 124-124, 128-128, 144-145, 157-157, 161-161, 172-172, 176-176, 188-188, 193-193, 206-206, 212-213, 234-234, 247-247, 254-254, 273-274, 278-278, 293-294, 298-298, 314-315, 319-320, 325-325, 335-337, 373-373

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/live-state-custom-procedures-plan.md` at line 9, Normalize inline
emphasis spacing across the document by removing spaces between emphasis markers
and their content (e.g., change " `**insert: () => false`** " to "`**insert: ()
=> false**`" and similarly for "`**update: false**`"); scan occurrences listed
(including the example snippets `insert: () => false` and `update: false`) and
update each inline code/emphasis span so there are no spaces inside the markdown
emphasis/backtick markers to satisfy MD037.
apps/worker/src/pipeline/core/idempotency.ts (1)

169-173: Batch upserts are currently serialized; this can slow larger runs.

Line 169 performs one network mutation per key sequentially. If ordering is not required, parallelizing these upserts will reduce latency.

⚡ Suggested refactor
   try {
-    for (const { key, hash } of keyHashPairs) {
-      await fetchClient.mutate.pipelineIdempotencyKey.upsert({
-        key,
-        hash,
-      });
-    }
+    await Promise.all(
+      keyHashPairs.map(({ key, hash }) =>
+        fetchClient.mutate.pipelineIdempotencyKey.upsert({
+          key,
+          hash,
+        }),
+      ),
+    );
 
     return true;
   } catch (error) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/worker/src/pipeline/core/idempotency.ts` around lines 169 - 173, The
current loop in idempotency.ts is performing sequential network upserts via
fetchClient.mutate.pipelineIdempotencyKey.upsert which slows large runs; change
the logic to fire the upserts in parallel (e.g., map the keys to calls to
fetchClient.mutate.pipelineIdempotencyKey.upsert and await Promise.all) when
ordering is not required, or use a bounded concurrency helper (p-map or a simple
limit) if you need to cap concurrent requests; ensure you preserve existing
error handling semantics by collecting/rethrowing/reporting errors from the
parallel calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/live-state/router.ts`:
- Around line 872-879: The insert into pipelineJob using
db.insert(schema.pipelineJob, ...) must be made idempotent: wrap that call in a
try/catch, and on a duplicate-key/unique-constraint error (e.g., Postgres
'23505' or error message containing 'duplicate'/'unique') treat it as a success
path instead of throwing—either return the existing row (by selecting where id =
req.input.id) or proceed as if the insert succeeded; ensure this logic is
applied around the code that constructs/invokes db.insert(schema.pipelineJob,
...) so transient retries with the same id do not produce hard failures.

In `@docs/live-state-custom-procedures-plan.md`:
- Line 5: The document uses "github" in two places; update both occurrences to
use the official product capitalization "GitHub" (specifically change the
instance inside the bolded app list that currently reads `**apps/github**` and
the other occurrence on line 17) so the text consistently uses "GitHub" across
the file.

---

Nitpick comments:
In `@apps/worker/src/pipeline/core/idempotency.ts`:
- Around line 169-173: The current loop in idempotency.ts is performing
sequential network upserts via fetchClient.mutate.pipelineIdempotencyKey.upsert
which slows large runs; change the logic to fire the upserts in parallel (e.g.,
map the keys to calls to fetchClient.mutate.pipelineIdempotencyKey.upsert and
await Promise.all) when ordering is not required, or use a bounded concurrency
helper (p-map or a simple limit) if you need to cap concurrent requests; ensure
you preserve existing error handling semantics by
collecting/rethrowing/reporting errors from the parallel calls.

In `@docs/live-state-custom-procedures-plan.md`:
- Line 9: Normalize inline emphasis spacing across the document by removing
spaces between emphasis markers and their content (e.g., change " `**insert: ()
=> false`** " to "`**insert: () => false**`" and similarly for "`**update:
false**`"); scan occurrences listed (including the example snippets `insert: ()
=> false` and `update: false`) and update each inline code/emphasis span so
there are no spaces inside the markdown emphasis/backtick markers to satisfy
MD037.
🪄 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

Run ID: b93f5193-6a9f-4804-bd16-8994c49bcba4

📥 Commits

Reviewing files that changed from the base of the PR and between bd8feb9 and e408307.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • apps/api/src/live-state/router.ts
  • apps/worker/src/pipeline/core/idempotency.ts
  • apps/worker/src/pipeline/core/persistence.ts
  • docs/live-state-custom-procedures-plan.md
  • package.json

Comment on lines +872 to +879
await db.insert(schema.pipelineJob, {
id: req.input.id,
name: req.input.name,
status: req.input.status,
metadataStr: req.input.metadataStr,
createdAt: req.input.createdAt,
updatedAt: req.input.updatedAt,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

pipelineJob.create should be retry-safe (idempotent) to avoid duplicate-key hard failures.

A transient timeout/retry with the same id can hit a unique constraint and fail even though the job row already exists. Please handle duplicate-key as an idempotent success path.

🛡️ Suggested retry-safe create pattern
         ).handler(async ({ req, db }) => {
           if (!req.context?.internalApiKey) {
             throw new Error("UNAUTHORIZED");
           }
 
-          await db.insert(schema.pipelineJob, {
-            id: req.input.id,
-            name: req.input.name,
-            status: req.input.status,
-            metadataStr: req.input.metadataStr,
-            createdAt: req.input.createdAt,
-            updatedAt: req.input.updatedAt,
-          });
+          try {
+            await db.insert(schema.pipelineJob, {
+              id: req.input.id,
+              name: req.input.name,
+              status: req.input.status,
+              metadataStr: req.input.metadataStr,
+              createdAt: req.input.createdAt,
+              updatedAt: req.input.updatedAt,
+            });
+          } catch (error: unknown) {
+            if (!isPostgresUniqueViolation(error)) {
+              throw error;
+            }
+            const existing = await db.findOne(schema.pipelineJob, req.input.id);
+            if (!existing) {
+              throw error;
+            }
+          }
 
           return { success: true as const };
         }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/live-state/router.ts` around lines 872 - 879, The insert into
pipelineJob using db.insert(schema.pipelineJob, ...) must be made idempotent:
wrap that call in a try/catch, and on a duplicate-key/unique-constraint error
(e.g., Postgres '23505' or error message containing 'duplicate'/'unique') treat
it as a success path instead of throwing—either return the existing row (by
selecting where id = req.input.id) or proceed as if the insert succeeded; ensure
this logic is applied around the code that constructs/invokes
db.insert(schema.pipelineJob, ...) so transient retries with the same id do not
produce hard failures.

Comment thread docs/live-state-custom-procedures-plan.md
@pedroscosta pedroscosta marked this pull request as draft April 15, 2026 20:31
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 3 files (changes from recent commits).

Requires human review: This is a significant structural refactor that migrates core pipeline idempotency and job logic into API procedures, requiring human review of the new transaction logic and auth checks.

@pedroscosta pedroscosta changed the title feat(api): Live-State procedures for pipeline idempotency & jobs (plan §1) feat(api): Live-State custom procedures — pipeline & allowlist (plan §1–§2) Apr 15, 2026
@pedroscosta pedroscosta changed the title feat(api): Live-State custom procedures — pipeline & allowlist (plan §1–§2) feat(api): Live-State custom procedures — pipeline, allowlist & subscription (plan §1–§3) Apr 15, 2026
Add author.create (idempotent) and author.update procedures, disable generic
author insert/update, and migrate web/devtools, Discord, and Slack call sites.
Extend web optimistic mutations for standalone author flows.

Made-with: Cursor
@pedroscosta pedroscosta changed the title feat(api): Live-State custom procedures — pipeline, allowlist & subscription (plan §1–§3) feat(api): Live-State custom procedures — pipeline, allowlist, subscription & author (plan §1–§4) Apr 15, 2026
Add invite.create, cancel, accept, and decline with withProcedures; disable
generic invite update. Move bulk invite flow from organizationUser.inviteUser
to invite.create. Team settings uses WebSocket mutate for create/cancel with
optimistic cancel. Remove unused resend import from router.ts.

Made-with: Cursor
@pedroscosta pedroscosta changed the title feat(api): Live-State custom procedures — pipeline, allowlist, subscription & author (plan §1–§4) feat(api): Live-State custom procedures — pipeline through invite (plan §1–§5) Apr 16, 2026
… §6)

Replace generic collection writes with withProcedures: validate, create,
recrawl, and discriminated update (setProgress for the worker, patch/delete
for owners). Point web and crawl-documentation call sites at the new API.

Made-with: Cursor
…an §7)

Use withProcedures on agentChat, authorize for org checks, and typed
db.* / trx.* collection entry points instead of schema-level helpers.

Made-with: Cursor
…edures (plan §8–§10)

Disable generic collection writes; add withProcedures (onboarding create plus
step flows; user.update; organizationUser.update). Wire router imports,
rename onboarding.initialize to create, use object payloads for user and
member updates, and extend optimistic mutations for onboarding, user, and
organizationUser.

Made-with: Cursor
@pedroscosta pedroscosta changed the title feat(api): Live-State custom procedures — pipeline through invite (plan §1–§5) feat(api): Live-State custom procedures — plan §1–§10 (docs through org user) Apr 16, 2026
…ootstrap inserts

Plan §10: add create procedure for membership rows (owner/internalApiKey);
use db.organization/db.organizationUser.insert in organization create.

Made-with: Cursor
Plan §11: extract organization route with withProcedures (create, update,
API key helpers); block generic insert/update; migrate web and digest
worker to mutate.organization.update({ id, ... }); add optimistic org patch.

Made-with: Cursor
Plan §12: disable generic integration insert/update; add create, update,
and fetchSlackChannels procedures with authorize; migrate web, Discord,
Slack, and GitHub call sites to object-shaped updates.

Made-with: Cursor
Plan §13: label/threadLabel create+update procedures with authorize; migrate
web label flows off collection insert/update.

Plan §14: suggestion create+update procedures (worker + devtools + UI);
migrate fetchClient and mutate call sites to object-shaped updates.

Plan §15: timeline update create+update procedures; migrate web, GitHub
webhooks, Discord, Slack, and thread actions off raw collection writes.

Made-with: Cursor
@pedroscosta pedroscosta changed the title feat(api): Live-State custom procedures — plan §1–§10 (docs through org user) feat(api): Live-State custom procedures — plan §1–§15 (through timeline update) Apr 16, 2026
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