Skip to content

Add account list-detail UIs for values, jobs, memories, and email - #937

Merged
kody-bot merged 4 commits into
mainfrom
cursor/account-list-detail-entities-2b17
Jul 25, 2026
Merged

kody-bot merged 4 commits into
mainfrom
cursor/account-list-detail-entities-2b17

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Jul 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds URL-backed account management list/detail pages for the four user-owned entities that previously had MCP/capability access only:

Entity Path v1 scope
Values /account/values User-scoped CRUD; rejects/hides _integration: / _openapi:; name locked when editing
Jobs /account/jobs List/detail; ad-hoc enable/update/delete; package jobs kill-switch + run-now only (no delete)
Memories /account/memories Browse/search/detail; soft + hard delete (no create/edit); shows newest 100
Email /account/email Inbox + paginated messages + HTML/text detail (no compose); verified-email gated

Follows the existing secrets/MCP-servers/connectors pattern (createListDetailRoute, account management shell, JSON APIs, nav entries).

Test plan

  • npm run validate (format, lint, typecheck, 1303 unit tests, 24 e2e, MCP e2e, primitives, migrations)
  • Handler unit tests for all four APIs (including reserved-value write rejection + package-job delete rejection)
  • E2E smoke for each page (exact heading match, URL selection / empty states)
  • Manual optional: nav links, list→detail URL restore on reload, q filter
System recap — extends existing primitives (medium risk)

Mode: recap · Base: main · Head: cursor/account-list-detail-entities-2b17

Classification: extends — browser app gains four account list/detail surfaces and JSON APIs; values/jobs/memories/email services are composed as-is behind session-auth handlers. No new primitives; per-user isolation unchanged (every read/write binds userId).

Primitives touched

Primitive Group Impact
app-ui surfaces extends — new /account/{values,jobs,memories,email} routes, loaders, nav, document titles
values assistant composes — account UI lists/edits user-scoped values via existing service
jobs assistant composes — account UI inspects/mutates jobs via existing job service
memories assistant composes — account UI browses/deletes via existing memory service/repo
email assistant composes — account UI lists/views user inbox via existing email repo

System map

flowchart LR
  appUi["app-ui<br/>Browser app"]:::extended
  values["values"]:::touched
  jobs["jobs"]:::touched
  memories["memories"]:::touched
  email["email"]:::touched
  appUi -->|"/account/values.json"| values
  appUi -->|"/account/jobs.json"| jobs
  appUi -->|"/account/memories.json"| memories
  appUi -->|"/account/email.json"| email
  classDef touched fill:#1a7f37,color:#fff
  classDef extended fill:#9a6700,color:#fff
Loading

Before / after

New account surfaces:
  /account/values[/new|/:valueId]  + /account/values.json
  /account/jobs[/:jobId]           + /account/jobs.json
  /account/memories[/:memoryId]    + /account/memories.json
  /account/email[/:messageId]      + /account/email.json
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added account pages for managing Values, Jobs, Memories, and Email.
    • Values support creating, editing, searching, and deleting entries.
    • Jobs support viewing schedules and runs, running jobs, toggling status, editing schedules, and deleting eligible jobs.
    • Memories support searching, viewing details, filtering deleted items, and soft or permanent deletion.
    • Email provides a searchable, paginated inbox with message details, previews, attachments, and delivery events.
    • Added navigation links and stable URLs for list and detail views.
  • Tests

    • Added end-to-end and API coverage for the new account features.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@cursor[bot], you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 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: 235125e2-9858-4716-9668-3ce95796c349

📥 Commits

Reviewing files that changed from the base of the PR and between d673503 and b20d6f6.

📒 Files selected for processing (26)
  • e2e/account-email.spec.ts
  • e2e/account-jobs.spec.ts
  • e2e/account-memories.spec.ts
  • e2e/account-values.spec.ts
  • packages/worker/client/routes/account-email.tsx
  • packages/worker/client/routes/account-jobs.tsx
  • packages/worker/client/routes/account-management-components.tsx
  • packages/worker/client/routes/account-memories.tsx
  • packages/worker/client/routes/account-values.tsx
  • packages/worker/client/routes/index.tsx
  • packages/worker/src/app/account-email-data.ts
  • packages/worker/src/app/account-jobs-data.ts
  • packages/worker/src/app/account-memories-data.ts
  • packages/worker/src/app/account-values-data.ts
  • packages/worker/src/app/document-head.ts
  • packages/worker/src/app/handlers/account-email.node.test.ts
  • packages/worker/src/app/handlers/account-email.ts
  • packages/worker/src/app/handlers/account-jobs.node.test.ts
  • packages/worker/src/app/handlers/account-jobs.ts
  • packages/worker/src/app/handlers/account-memories.node.test.ts
  • packages/worker/src/app/handlers/account-memories.ts
  • packages/worker/src/app/handlers/account-values.node.test.ts
  • packages/worker/src/app/handlers/account-values.ts
  • packages/worker/src/app/loader-data.ts
  • packages/worker/src/app/router.ts
  • packages/worker/src/app/routes.ts
📝 Walkthrough

Walkthrough

Adds account Values, Jobs, Memories, and Email pages with typed loaders, authenticated APIs, interactive client routes, navigation and document metadata wiring, unit tests, and end-to-end coverage.

Changes

Account management surfaces

Layer / File(s) Summary
Values data and editing flow
packages/worker/src/app/account-values-data.ts, packages/worker/src/app/handlers/account-values.ts, packages/worker/client/routes/account-values.tsx, packages/worker/src/app/handlers/account-values.node.test.ts, e2e/account-values.spec.ts
Values support URL-backed selection, filtering, creation, editing, deletion, reserved-name validation, and persistence checks.
Jobs inspection and mutation flow
packages/worker/src/app/account-jobs-data.ts, packages/worker/src/app/handlers/account-jobs.ts, packages/worker/client/routes/account-jobs.tsx, packages/worker/src/app/handlers/account-jobs.node.test.ts, e2e/account-jobs.spec.ts
Jobs expose ownership, schedules, runs, detail views, validated mutations, package-job restrictions, and reload-stable selection.
Memories filtering and deletion flow
packages/worker/src/app/account-memories-data.ts, packages/worker/src/app/handlers/account-memories.ts, packages/worker/client/routes/account-memories.tsx, packages/worker/src/app/handlers/account-memories.node.test.ts, e2e/account-memories.spec.ts
Memories support search, deleted-memory filtering, detail selection, soft deletion, permanent deletion, and detail-page rendering.
Email inbox data and message browsing
packages/worker/src/app/account-email-data.ts, packages/worker/src/app/handlers/account-email.ts, packages/worker/client/routes/account-email.tsx, packages/worker/src/app/handlers/account-email.node.test.ts, e2e/account-email.spec.ts
Email provides verification-gated inbox data, pagination and search, selected message details, attachments, delivery events, and HTML/text body views.
Route contracts and application wiring
packages/worker/src/app/loader-data.ts, packages/worker/src/app/routes.ts, packages/worker/src/app/router.ts, packages/worker/client/routes/index.tsx, packages/worker/client/routes/account-management-components.tsx, packages/worker/src/app/document-head.ts
Loader contracts, page/API routes, router actions, client route registries, account navigation, and document titles are extended for the four account sections.

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

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant ClientRoute
  participant AccountApi
  participant AccountData
  participant Storage
  Browser->>ClientRoute: Open account section
  ClientRoute->>AccountApi: GET account JSON endpoint
  AccountApi->>AccountData: Load authenticated data
  AccountData->>Storage: Query account records
  Storage-->>AccountData: Return list and selected detail
  AccountData-->>AccountApi: Return loader payload
  AccountApi-->>ClientRoute: Return JSON data
  ClientRoute-->>Browser: Render list and detail views
Loading

Possibly related PRs

  • kentcdodds/kody#601 — Introduced the SSR, loader-data, and route registration patterns used by these account pages.
  • kentcdodds/kody#636 — Added related email message search and LIKE escaping behavior.
  • kentcdodds/kody#807 — Established the document-head registry extended for these account routes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.09% 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 accurately summarizes the main change: new account list-detail UIs for values, jobs, memories, and email.
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 cursor/account-list-detail-entities-2b17

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.

@kody-bot
kody-bot marked this pull request as ready for review July 25, 2026 15:21
@github-actions

github-actions Bot commented Jul 25, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-937.kody-a99.workers.dev

Worker: kody-pr-937
D1: kody-pr-937-db
KV: kody-pr-937-oauth-kv

Mocks:

@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: 3

🧹 Nitpick comments (9)
packages/worker/src/app/loader-data.ts (1)

727-752: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

These shapes are declared twice.

AccountValueListItem, AccountValueDetail, and AccountValuesLoaderData are identical to the exports in packages/worker/src/app/account-values-data.ts (Lines 13-38), and account-memories-data.ts/account-email-data.ts show the same pattern per graph context. Because the client type-checks against this file while the handlers produce the other, drift here goes unnoticed until runtime. Prefer re-exporting the data-module types (or the reverse) so there is one definition per shape.

🤖 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 `@packages/worker/src/app/loader-data.ts` around lines 727 - 752, Remove the
duplicate AccountValueListItem, AccountValueDetail, and AccountValuesLoaderData
declarations from loader-data.ts and reuse the corresponding exports from
account-values-data.ts. Update loader-data.ts imports or exports so consumers
retain the same public types while establishing a single source of truth.
packages/worker/client/routes/account-values.tsx (1)

90-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reserved-name rule is duplicated client/server.

isReservedAccountValueName and reservedAccountValueWriteError already exist server-side (packages/worker/src/app/account-values-data.ts Lines 40-42 and packages/worker/src/app/handlers/account-values.ts). Two copies of the prefix list and the message will drift. Consider extracting them into a shared module both sides import.

🤖 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 `@packages/worker/client/routes/account-values.tsx` around lines 90 - 95,
Extract the reserved account-value prefixes and write-error message used by
isReservedAccountValueName into a shared module, then update both the client
route and server account-values handlers to import and reuse those shared
symbols. Remove the duplicated local definitions while preserving the existing
reserved-name checks and error text.
packages/worker/src/app/handlers/account-jobs.node.test.ts (1)

134-139: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a beforeEach mock reset so assertions don't depend on test order.

not.toHaveBeenCalled() assertions here only hold because prior tests happened not to call those mocks. A beforeEach(() => vi.clearAllMocks()) (re-seeding readAuthenticatedAppUser and resetInspection()) makes each test independent.

Also applies to: 229-229, 247-247, 264-264

🤖 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 `@packages/worker/src/app/handlers/account-jobs.node.test.ts` around lines 134
- 139, Make the tests in account-jobs.node.test.ts independent of execution
order by adding a beforeEach that clears all Vitest mocks, then re-seeds
readAuthenticatedAppUser and invokes resetInspection(). Ensure this setup covers
the affected tests and preserves their expected default mock data.
packages/worker/src/app/handlers/account-jobs.ts (1)

58-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer aligning the two AccountJobsLoaderData types over an as cast.

The cast between #app/account-jobs-data.ts's AccountJobsLoaderData and #app/loader-data.ts's version silences structural drift; if either shape changes the mismatch surfaces only at runtime in the client. Consider having loader-data.ts re-export/reference the loader module's type so the assignment type-checks without a cast.

🤖 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 `@packages/worker/src/app/handlers/account-jobs.ts` around lines 58 - 61, Align
the AccountJobsLoaderData definitions used by `#app/account-jobs-data.ts` and
`#app/loader-data.ts` so they share a single source of truth, preferably by
re-exporting or referencing the loader module’s type. Then remove the `as
AppAccountJobsLoaderData` cast from the `loaderData.accountJobs` assignment in
the account jobs handler and ensure the assignment type-checks directly.
packages/worker/src/app/account-jobs-data.ts (1)

85-105: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the shared selected-id URL decoder. Both loaders reimplement identical logic (path-prefix match, single-segment guard, decodeURIComponent with raw fallback, selected query fallback), differing only in base path and param name — so hardening or bug fixes must be applied in every copy.

  • packages/worker/src/app/account-jobs-data.ts#L85-L105: replace the body of readAccountJobsSelectedJobId with a call to a shared readSelectedIdFromUrl({ requestUrl, basePath, pathId }) helper.
  • packages/worker/src/app/account-memories-data.ts#L42-L62: replace readAccountMemoriesSelectedMemoryId's body with the same shared helper, passing /account/memories.
🤖 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 `@packages/worker/src/app/account-jobs-data.ts` around lines 85 - 105, Extract
the duplicated URL selected-ID parsing into a shared readSelectedIdFromUrl({
requestUrl, basePath, pathId }) helper, preserving path-prefix matching,
single-segment validation, decoded-ID handling with raw fallback, and the
selected query fallback. In packages/worker/src/app/account-jobs-data.ts lines
85-105, replace readAccountJobsSelectedJobId’s body with the helper using its
jobs base path and parameter name; in
packages/worker/src/app/account-memories-data.ts lines 42-62, replace
readAccountMemoriesSelectedMemoryId’s body with the same helper using
/account/memories.
packages/worker/src/app/handlers/account-memories.node.test.ts (1)

253-265: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Same untyped null mock override.

deleteMemory is inferred to resolve to a memory row, so mockResolvedValueOnce(null) may not type-check. Consider null as never (or widen the hoisted mock's return type) for consistency with the email test 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 `@packages/worker/src/app/handlers/account-memories.node.test.ts` around lines
253 - 265, Update the deleteMemory mock setup in the not-found test to use the
established type-safe null override, such as casting null to never, or widen the
hoisted mock return type consistently with the email test. Preserve the existing
404 assertion and handler behavior.
packages/worker/src/app/handlers/account-email.ts (1)

41-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Drop the cast by having one source of truth for AccountEmailLoaderData.

account-email-data.ts declares its own AccountEmailLoaderData (with a comment saying it lives there "until the integrator adds accountEmail to AppLoaderData"), and this file imports a second definition from #app/loader-data.ts. The as cast silences any future divergence between the two. Prefer having loader-data.ts re-export the loader's type and remove the cast.

🤖 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 `@packages/worker/src/app/handlers/account-email.ts` around lines 41 - 44, The
account email loader uses duplicate AccountEmailLoaderData definitions, with a
cast masking divergence. Remove the local duplicate type in
account-email-data.ts, have `#app/loader-data.ts` re-export the loader’s
AccountEmailLoaderData, and update the account-email handler’s loaderData
assignment to use the shared type without an `as` cast.
packages/worker/src/app/handlers/account-email.node.test.ts (1)

235-250: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Dispatch the prepare mock on SQL text instead of call parity.

The prepareCall % 2 heuristic silently breaks if the loader ever adds/reorders a query, and it produces wrong results rather than a clear failure. Matching COUNT(*) in the SQL argument is both self-documenting and order-independent.

♻️ Suggested change
-	let prepareCall = 0
-	mockModule.prepare.mockImplementation(() => {
-		prepareCall += 1
-		// countAndListMessages issues COUNT then SELECT in Promise.all order.
-		if (prepareCall % 2 === 1) return createCountResult(1)
-		return createListResult([messageRow])
-	})
+	mockModule.prepare.mockImplementation((sql: unknown) =>
+		String(sql).includes('COUNT(*)')
+			? createCountResult(1)
+			: createListResult([messageRow]),
+	)
🤖 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 `@packages/worker/src/app/handlers/account-email.node.test.ts` around lines 235
- 250, The prepare mock in createEnv should dispatch based on the SQL text
passed to mockModule.prepare rather than the prepareCall parity counter. Return
createCountResult for statements containing COUNT(*) and createListResult for
the message-list query, with an explicit failure for unexpected SQL so query
changes are detected clearly.
packages/worker/src/app/account-email-data.ts (1)

253-303: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

Leading-wildcard LIKE plus COUNT(*) on every page load will full-scan email_messages.

Both the search and unfiltered paths run a COUNT(*) alongside the page query; LIKE '%term%' on subject/from_address cannot use an index. Worth confirming a (user_id, created_at DESC, id DESC) index exists for the list path, and consider FTS or dropping the exact total (e.g. fetch pageSize + 1 to infer "has more") if message volumes grow.

🤖 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 `@packages/worker/src/app/account-email-data.ts` around lines 253 - 303, The
countAndListMessages function performs an expensive COUNT(*) on every page and
uses leading-wildcard LIKE searches that cannot use ordinary indexes. Confirm or
add the (user_id, created_at DESC, id DESC) index for list ordering, and replace
exact totals with pageSize + 1 fetching to expose whether more messages exist;
for scalable search, use the project’s existing FTS mechanism instead of
leading-wildcard LIKE where available.
🤖 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 `@packages/worker/client/routes/account-memories.tsx`:
- Around line 313-316: Update the showMemoryNotFound calculation near
detailMemory to also require that the detail payload is not pending, using the
same pending-load flag and guard pattern as the jobs and values routes. Preserve
the existing selectedId, detailMemory, and ready-status checks.

In `@packages/worker/src/app/account-memories-data.ts`:
- Around line 135-157: Update the memory search flow around listMemoriesByUserId
and memoryMatchesQuery so query filtering occurs before limiting results, or
otherwise expose that only the newest 100 rows were searched in the returned
payload. Ensure older matching memories are discoverable when the query is
applied server-side.

In `@packages/worker/src/app/handlers/account-values.node.test.ts`:
- Around line 345-349: Update the readAuthenticatedAppUser mock override in
packages/worker/src/app/handlers/account-values.node.test.ts:345-349 to use null
as never, or widen the hoisted mock type to allow null. Apply the same treatment
to the deleteMemory override in
packages/worker/src/app/handlers/account-memories.node.test.ts:253-265,
preserving the existing unauthorized behavior.

---

Nitpick comments:
In `@packages/worker/client/routes/account-values.tsx`:
- Around line 90-95: Extract the reserved account-value prefixes and write-error
message used by isReservedAccountValueName into a shared module, then update
both the client route and server account-values handlers to import and reuse
those shared symbols. Remove the duplicated local definitions while preserving
the existing reserved-name checks and error text.

In `@packages/worker/src/app/account-email-data.ts`:
- Around line 253-303: The countAndListMessages function performs an expensive
COUNT(*) on every page and uses leading-wildcard LIKE searches that cannot use
ordinary indexes. Confirm or add the (user_id, created_at DESC, id DESC) index
for list ordering, and replace exact totals with pageSize + 1 fetching to expose
whether more messages exist; for scalable search, use the project’s existing FTS
mechanism instead of leading-wildcard LIKE where available.

In `@packages/worker/src/app/account-jobs-data.ts`:
- Around line 85-105: Extract the duplicated URL selected-ID parsing into a
shared readSelectedIdFromUrl({ requestUrl, basePath, pathId }) helper,
preserving path-prefix matching, single-segment validation, decoded-ID handling
with raw fallback, and the selected query fallback. In
packages/worker/src/app/account-jobs-data.ts lines 85-105, replace
readAccountJobsSelectedJobId’s body with the helper using its jobs base path and
parameter name; in packages/worker/src/app/account-memories-data.ts lines 42-62,
replace readAccountMemoriesSelectedMemoryId’s body with the same helper using
/account/memories.

In `@packages/worker/src/app/handlers/account-email.node.test.ts`:
- Around line 235-250: The prepare mock in createEnv should dispatch based on
the SQL text passed to mockModule.prepare rather than the prepareCall parity
counter. Return createCountResult for statements containing COUNT(*) and
createListResult for the message-list query, with an explicit failure for
unexpected SQL so query changes are detected clearly.

In `@packages/worker/src/app/handlers/account-email.ts`:
- Around line 41-44: The account email loader uses duplicate
AccountEmailLoaderData definitions, with a cast masking divergence. Remove the
local duplicate type in account-email-data.ts, have `#app/loader-data.ts`
re-export the loader’s AccountEmailLoaderData, and update the account-email
handler’s loaderData assignment to use the shared type without an `as` cast.

In `@packages/worker/src/app/handlers/account-jobs.node.test.ts`:
- Around line 134-139: Make the tests in account-jobs.node.test.ts independent
of execution order by adding a beforeEach that clears all Vitest mocks, then
re-seeds readAuthenticatedAppUser and invokes resetInspection(). Ensure this
setup covers the affected tests and preserves their expected default mock data.

In `@packages/worker/src/app/handlers/account-jobs.ts`:
- Around line 58-61: Align the AccountJobsLoaderData definitions used by
`#app/account-jobs-data.ts` and `#app/loader-data.ts` so they share a single source
of truth, preferably by re-exporting or referencing the loader module’s type.
Then remove the `as AppAccountJobsLoaderData` cast from the
`loaderData.accountJobs` assignment in the account jobs handler and ensure the
assignment type-checks directly.

In `@packages/worker/src/app/handlers/account-memories.node.test.ts`:
- Around line 253-265: Update the deleteMemory mock setup in the not-found test
to use the established type-safe null override, such as casting null to never,
or widen the hoisted mock return type consistently with the email test. Preserve
the existing 404 assertion and handler behavior.

In `@packages/worker/src/app/loader-data.ts`:
- Around line 727-752: Remove the duplicate AccountValueListItem,
AccountValueDetail, and AccountValuesLoaderData declarations from loader-data.ts
and reuse the corresponding exports from account-values-data.ts. Update
loader-data.ts imports or exports so consumers retain the same public types
while establishing a single source of truth.
🪄 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: 8f9ca377-3e80-4e80-8ff0-715daa42c50b

📥 Commits

Reviewing files that changed from the base of the PR and between 7d88928 and d673503.

📒 Files selected for processing (26)
  • e2e/account-email.spec.ts
  • e2e/account-jobs.spec.ts
  • e2e/account-memories.spec.ts
  • e2e/account-values.spec.ts
  • packages/worker/client/routes/account-email.tsx
  • packages/worker/client/routes/account-jobs.tsx
  • packages/worker/client/routes/account-management-components.tsx
  • packages/worker/client/routes/account-memories.tsx
  • packages/worker/client/routes/account-values.tsx
  • packages/worker/client/routes/index.tsx
  • packages/worker/src/app/account-email-data.ts
  • packages/worker/src/app/account-jobs-data.ts
  • packages/worker/src/app/account-memories-data.ts
  • packages/worker/src/app/account-values-data.ts
  • packages/worker/src/app/document-head.ts
  • packages/worker/src/app/handlers/account-email.node.test.ts
  • packages/worker/src/app/handlers/account-email.ts
  • packages/worker/src/app/handlers/account-jobs.node.test.ts
  • packages/worker/src/app/handlers/account-jobs.ts
  • packages/worker/src/app/handlers/account-memories.node.test.ts
  • packages/worker/src/app/handlers/account-memories.ts
  • packages/worker/src/app/handlers/account-values.node.test.ts
  • packages/worker/src/app/handlers/account-values.ts
  • packages/worker/src/app/loader-data.ts
  • packages/worker/src/app/router.ts
  • packages/worker/src/app/routes.ts

Comment thread packages/worker/client/routes/account-memories.tsx Outdated
Comment on lines +135 to +157
const rows = await listMemoriesByUserId(input.env.APP_DB, userId, {
statuses,
limit: 100,
})
const memories = rows
.map((row) =>
toListItem({
id: row.id,
category: row.category,
status: row.status,
subject: row.subject,
summary: row.summary,
details: row.details,
tags: parseJsonStringArray(row.tags_json),
sourceUris: parseJsonStringArray(row.source_uris_json),
dedupeKey: row.dedupe_key,
createdAt: row.created_at,
updatedAt: row.updated_at,
lastAccessedAt: row.last_accessed_at,
deletedAt: row.deleted_at,
}),
)
.filter((memory) => memoryMatchesQuery(memory, query))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Search filters only within the newest 100 rows.

The limit: 100 fetch happens before memoryMatchesQuery, so a query matching an older memory returns nothing even though the record exists. Either push the query into listMemoriesByUserId (or a search path) or make the cap explicit in the returned payload so the UI can say results are limited to the newest 100.

🤖 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 `@packages/worker/src/app/account-memories-data.ts` around lines 135 - 157,
Update the memory search flow around listMemoriesByUserId and memoryMatchesQuery
so query filtering occurs before limiting results, or otherwise expose that only
the newest 100 rows were searched in the returned payload. Ensure older matching
memories are discoverable when the query is applied server-side.

Comment on lines +345 to +349
mockModule.readAuthenticatedAppUser.mockResolvedValueOnce(null)
const unauthorized = await handler.handler({
request: new Request('https://example.com/account/values.json'),
})
expect(unauthorized.status).toBe(401)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Hoisted mocks infer non-nullable return types, so null overrides may not type-check. Both files declare vi.fn(async () => ({ ... })) and later override with mockResolvedValueOnce(null); the email test avoids this with null as never.

  • packages/worker/src/app/handlers/account-values.node.test.ts#L345-L349: use null as never for the readAuthenticatedAppUser override (or type the hoisted mock to include null).
  • packages/worker/src/app/handlers/account-memories.node.test.ts#L253-L265: apply the same treatment to the deleteMemory override.
📍 Affects 2 files
  • packages/worker/src/app/handlers/account-values.node.test.ts#L345-L349 (this comment)
  • packages/worker/src/app/handlers/account-memories.node.test.ts#L253-L265
🤖 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 `@packages/worker/src/app/handlers/account-values.node.test.ts` around lines
345 - 349, Update the readAuthenticatedAppUser mock override in
packages/worker/src/app/handlers/account-values.node.test.ts:345-349 to use null
as never, or widen the hoisted mock type to allow null. Apply the same treatment
to the deleteMemory override in
packages/worker/src/app/handlers/account-memories.node.test.ts:253-265,
preserving the existing unauthorized behavior.

Pick a memory from the list to inspect its details, sources,
and timestamps.
</p>
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Memories detail loading state missing

Medium Severity

While a memory detail fetch is in flight, the main panel falls through to the empty “Select a memory” state even though the URL already selects a memory. waitingForDetail is computed but never used in the detail ternary, unlike the jobs page.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 378955d. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

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

Reviewed by Cursor Bugbot for commit 49c131e. Configure here.

env: input.env,
request: input.request,
user: input.user,
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Delete reload drops memory filters

Medium Severity

After a successful memory delete, the API reloads list data using the POST request URL (/account/memories.json), so q and includeDeleted from the user’s inbox view are ignored. The client applies that payload before navigating, briefly showing the wrong list versus the URL filters.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 49c131e. Configure here.

cursoragent and others added 4 commits July 25, 2026 15:44
Give users the same URL-backed list/detail management pattern already used
for secrets, packages, and connectors for the four user-owned entities that
previously had MCP/capability access only.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Reject reserved value names and package-job deletes from the account UI,
lock value names while editing, harden selected-id decoding, and make
Playwright heading assertions exact so format/validate gates pass.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Match the jobs/values pending-load guard so selecting a memory no longer
briefly shows "Memory not found" before the detail payload arrives.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
The previous commit ran prettier instead of the repo oxfmt formatter,
which failed CI format:check.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@cursor
cursor Bot force-pushed the cursor/account-list-detail-entities-2b17 branch from 49c131e to b20d6f6 Compare July 25, 2026 15:44
@kody-bot
kody-bot merged commit 49c11fd into main Jul 25, 2026
5 checks passed
@kody-bot
kody-bot deleted the cursor/account-list-detail-entities-2b17 branch July 25, 2026 15:51
cursor Bot pushed a commit that referenced this pull request Jul 26, 2026
Fold post-#937/#939/#940 account verification tests into fewer workflow
journeys and drop low-signal Playwright coverage.

- account-values handler: list/select/save/delete + rejection matrix
- account-memories handler: list/filter/select + soft/force delete
- activity-data helpers + load/cursor; billing refresh workflow without
  instructional error-copy pins
- auth-session password-change matrix; auth-denial and email-delivery
  alert cron/threshold/cooldown journeys
- trim activity e2e instructional empty-state copy; drop memories e2e
  (values e2e + memories handler cover the pattern); drop jobs schedule
  text pin

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
kody-bot pushed a commit that referenced this pull request Jul 26, 2026
…#958)

* test: consolidate low-signal workers tests into workflow journeys

Collapses 32 tests across four files down to 15, following the
'fewer longer workflow tests' principle from testing-principles.md.

run-records.workers.test.ts (20 → 9):
- Merge eager-begin/finish, finish-only upsert, one-shot recordRunRecord,
  waitUntil non-blocking, and execute on-failure policy into a single
  'write surfaces journey' test.
- Delete 'sandbox level markers become structured log levels' — covered
  by the existing sandbox e2e test which already asserts structured
  log levels on each entry.
- Merge retention-priority, cap-protect-running, stale-reconcile,
  stale-cap-evict, and age-cap scenarios into 'cap and stale retention
  journey' (each with its own userId for DO isolation).
- Extend 'write after idle re-arms alarm and age-prunes' into a full
  'alarm lifecycle' narrative that also covers the fresh-arm far-future
  deadline assertion and the self-termination assertion from the two
  standalone alarm tests.

runs.workers.test.ts (5 → 2):
- Keep the auth guard test unchanged.
- Merge run_list filter smoke, run_get with logs/foreign/missing
  rejection, run_summary counts, and run_list/run_summary tenant
  isolation into a single 'run capabilities smoke' test. Filter/
  pagination matrix remains in run-records.workers.test.ts.

execute-console-capture.workers.test.ts (4 → 2):
- Merge success-levels, throw-capture, and unshimmed-methods into
  'console capture contract'; keep 'reused dynamic workers' separate.

stripe-webhooks.workers.test.ts (3 → 2):
- Fold the 503-when-secret-unset guard into the main journey test as
  an upfront check before any seeding.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

* test: fold Sentry, D1 retry, and small unit microtests into journeys

Collapse post-#934 one-string-per-filter and sibling unit cases toward
fewer longer workflow tests.

- sentry-options: fold UserCodeError hint + platform keep into the main
  filter journey; delete standalone user-code-error.node.test.ts
- d1-retry: keep representative matchers and one retry/fail path
- observability: fold conversationId/storageId/detail context into the
  platform-bug reporting journey
- activation: merge twice-same-package, HTTP ignore, sticky timestamp,
  fast path, and never-throw degradation
- fold stripe signature fixture, package-workflow sentry tags,
  invocation surface/name helpers, and package_service_states count +
  entitlement boundary

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

* test: consolidate account list/detail and alert suites

Fold post-#937/#939/#940 account verification tests into fewer workflow
journeys and drop low-signal Playwright coverage.

- account-values handler: list/select/save/delete + rejection matrix
- account-memories handler: list/filter/select + soft/force delete
- activity-data helpers + load/cursor; billing refresh workflow without
  instructional error-copy pins
- auth-session password-change matrix; auth-denial and email-delivery
  alert cron/threshold/cooldown journeys
- trim activity e2e instructional empty-state copy; drop memories e2e
  (values e2e + memories handler cover the pattern); drop jobs schedule
  text pin

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

* style: apply oxfmt after mistaken prettier pass

CI format:check uses oxfmt (tabs/single quotes). A Prettier pass had
rewritten touched test files to spaces/double quotes.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
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.

3 participants