Skip to content

feat(admin): user search by email/ID, remove table border - #3646

Merged
waleedlatif1 merged 6 commits into
mainfrom
waleedlatif1/hangzhou-v2
Mar 18, 2026
Merged

feat(admin): user search by email/ID, remove table border#3646
waleedlatif1 merged 6 commits into
mainfrom
waleedlatif1/hangzhou-v2

Conversation

@waleedlatif1

@waleedlatif1waleedlatif1 commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Search: Replaces the Load Users button with a live search input. Email search uses listUsers with a contains operator; pasting a UUID switches to admin.getUser for exact ID lookup. Pagination resets on each new search.
  • Border fix: Removes the outer border-[var(--border-secondary)] on the user table container, which was rendering white in dark mode.

Test plan

  • Search by partial email returns matching users
  • Paste a full user UUID returns exactly that user
  • No white border around the user table in dark mode
  • Pagination still works across email search results

Sg312and others added 5 commits March 17, 2026 16:19
* feat(csp): allow chat UI to be embedded in iframes
Mirror the existing form embed CSP pattern for chat pages: add
getChatEmbedCSPPolicy() with frame-ancestors *, configure /chat/:path*
headers in next.config.ts without X-Frame-Options, and early-return in
proxy.ts so chat routes skip the strict runtime CSP.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(csp): extract shared getEmbedCSPPolicy helper
Deduplicate getChatEmbedCSPPolicy and getFormEmbedCSPPolicy into a
shared private helper to prevent future divergence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(logs): persist execution diagnostics markers
Store last-started and last-completed block markers with finalization metadata so later read surfaces can explain how a run ended without reconstructing executor state.
* fix(executor): preserve durable diagnostics ordering
Await only the persistence needed to keep diagnostics durable before terminal completion while keeping callback failures from changing execution behavior.
* fix(logs): preserve fallback diagnostics semantics
Keep successful fallback output and accumulated cost intact while tightening progress-write draining and deduplicating trace span counting for diagnostics helpers.
* fix(api): restore async execute route test mock
Add the missing AuthType export to the hybrid auth mock so the async execution route test exercises the 202 queueing path instead of crashing with a 500 in CI.
* fix(executor): align async block error handling
* fix(logs): tighten marker ordering scope
Allow same-millisecond marker writes to replace prior markers and drop the unused diagnostics read helper so this PR stays focused on persistence rather than unread foundation code.
* fix(logs): remove unused finalization type guard
Drop the unused helper so this PR only ships the persistence-side status types it actually uses.
* fix(executor): await subflow diagnostics callbacks
Ensure empty-subflow and subflow-error lifecycle callbacks participate in progress-write draining before terminal finalization while still swallowing callback failures.
---------
Co-authored-by: test <test@example.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
- Replace Load Users button with a live search input; query fires on any input
- Email search uses listUsers with contains operator
- User ID search (UUID format) uses admin.getUser directly for exact lookup
- Remove outer border on user table that rendered white in dark mode
- Reset pagination to page 0 on new search
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cursor

cursorBot commented Mar 18, 2026

Copy link
Copy Markdown

You have used all Bugbot PR reviews included in your free trial for your GitHub account on this workspace.

To continue using Bugbot reviews, enable Bugbot for your team in the Cursor dashboard.

@vercel

vercelBot commented Mar 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
docsSkippedSkippedMar 18, 2026 0:46am

Request Review

@greptile-apps

greptile-appsBot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR ships two user-visible features (admin user search by email/UUID and a dark-mode border fix) alongside a substantial batch of infrastructure improvements across the executor, logging session, and CSP layers.

Admin search (primary feature)

  • admin.tsx replaces the "Load Users" toggle with a committed-search UX: the live input updates searchInput, but only Enter/button press commits to searchQuery, which drives the query's enabled flag and controls table visibility. Pagination resets correctly on every new search.
  • admin-users.ts routes UUID-shaped queries through admin.getUser (exact ID lookup) and all other non-empty strings through listUsers with a contains operator on the email field. The shared mapUser helper removes the duplicated field mapping.

Block lifecycle persistence (logging-session.ts, execution-core.ts)

  • Every onBlockStart / onBlockComplete now writes a monotonic lastStartedBlock / lastCompletedBlock marker directly to execution_data using conditional jsonb_set SQL (only advances when the new timestamp is ≥ the stored one).
  • A pendingProgressWritesSet<Promise<void>> tracks in-flight DB writes; drainPendingProgressWrites loops until the set is empty, so terminal completion always awaits all side-effect writes before finalizing.
  • wrappedOnBlockStart (mirroring the existing wrappedOnBlockComplete) awaits persistence synchronously while firing the user-supplied streaming callback fire-and-forget — consistent with the existing design for onBlockComplete.
  • All execution paths (completed, force_failed, cancelled, paused, fallback_completed) now record a finalizationPath discriminant plus optional completionFailure string for diagnostics.

Executor async propagation (block-executor.ts, loop.ts, parallel.ts, node.ts, subflow-utils.ts)

  • Lifecycle callbacks (onBlockStart, onBlockComplete) are now await-ed throughout the executor tree; each call site is wrapped in try/catch so a failing callback cannot abort execution.

Other fixes

  • workspace-file-manager.ts: trackChatUpload now tries an UPDATE first to link an existing file record to the chat before falling back to INSERT, preventing duplicate rows.
  • hooks/queries/workflows.ts: isPlaceholderData is added to effect deps and gates completeMetadataLoad so placeholder data is never surfaced as real results.
  • next.config.ts / proxy.ts: Chat embed pages (/chat/:path*) get their own permissive CSP block; the runtime CSP injection in the proxy is removed for chat routes; the fallback exclusion regex is corrected from (?!chat$) (only excluded bare /chat) to (?!chat) (correctly excludes all /chat/* paths).

Confidence Score: 5/5

  • This PR is safe to merge — all changes are well-tested, error paths are properly guarded, and the executor async refactor follows consistent patterns throughout.
  • All significant logic is covered by new or updated unit tests (parallel.test.ts, logging-session.test.ts, execution-core.test.ts, logger.test.ts). The async propagation across the executor is mechanical and consistent; error swallowing is deliberate (warns rather than throws). The admin search UX is straightforward and correct. No SQL injection risks (Drizzle's sql template properly parameterises all interpolated values). No breaking API changes — all new fields in ExecutionLoggerService are optional.
  • No files require special attention.

Important Files Changed

FilenameOverview
apps/sim/app/workspace/[workspaceId]/settings/components/admin/admin.tsxReplaces the "Load Users" button with a live search input (email and UUID). State management is clean: searchInput tracks the field value, searchQuery is committed on Enter/button, pagination resets on each new search, and the table is hidden until a non-empty search query is active.
apps/sim/hooks/queries/admin-users.tsRefactors from enabled-boolean to searchQuery-string API. UUID detection with a standard regex routes to admin.getUser (exact lookup); all other non-empty queries use listUsers with a contains operator. mapUser helper correctly de-duplicates field mapping.
apps/sim/executor/execution/block-executor.tsMakes callOnBlockStart, callOnBlockComplete, and handleBlockError async; wraps each lifecycle callback invocation in try/catch so a failing callback cannot crash the executor. Clean, targeted change.
apps/sim/lib/logs/execution/logging-session.tsLarge refactor adding per-block persistence (lastStartedBlock / lastCompletedBlock) written with monotonic SQL guards, a pendingProgressWrites Set for back-pressure, drainPendingProgressWrites that loops until the set is empty, and completeExecutionWithFinalization that centralises all finalization paths. Logic is well-structured and thoroughly tested.
apps/sim/lib/workflows/executor/execution-core.tsIntroduces wrappedOnBlockStart mirroring the existing wrappedOnBlockComplete — persistence is awaited, while the user-supplied callback is fire-and-forget with .catch() suppression. The inner-try/outer-finally restructure in finalizeExecutionOutcome ensures clearExecutionCancellation always runs even when finalization throws.
apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.tsFixes a duplicate-record bug in trackChatUpload by attempting a targeted UPDATE first (keyed on s3Key + workspaceId, excluding soft-deleted rows) and only inserting a new row when no existing record is found.
apps/sim/next.config.tsAdds a dedicated /chat/:path* header block with permissive CSP and COEP/COOP, and fixes the fallback exclusion regex from (?!chat$) (only excluded the bare /chat path) to (?!chat) (correctly excludes all /chat/* paths from the generic rule).

Sequence Diagram

sequenceDiagram
participant Executor as BlockExecutor
participant WBS as wrappedOnBlockStart
participant LS as LoggingSession
participant DB as Database
participant UCB as UserCallback (onBlockStart)
Executor->>WBS: callOnBlockStart(blockId, blockName, blockType, order)
WBS->>LS: onBlockStart(blockId, blockName, blockType, now())
LS->>LS: trackProgressWrite(persistLastStartedBlock())
LS->>DB: UPDATE workflow_execution_logs SET execution_data -> lastStartedBlock WHERE startedAt <= now()
DB-->>LS: ok
LS-->>WBS: resolved
WBS-->>UCB: void callback(...).catch(warn) [fire-and-forget]
WBS-->>Executor: resolved (persistence guaranteed)
Note over Executor: Block executes…
Executor->>WBS: callOnBlockComplete(blockId, name, type, output)
WBS->>LS: onBlockComplete(blockId, name, type, output)
LS->>LS: trackProgressWrite(persistLastCompletedBlock())
LS->>DB: UPDATE workflow_execution_logs SET execution_data -> lastCompletedBlock WHERE endedAt <= output.endedAt
DB-->>LS: ok
LS->>LS: (if cost > 0) void trackProgressWrite(flushAccumulatedCost())
LS-->>WBS: resolved
WBS-->>UCB: void onBlockComplete(...).catch(warn) [fire-and-forget]
WBS-->>Executor: resolved
Note over Executor: Terminal finalization…
Executor->>LS: safeComplete / safeCompleteWithError / etc.
LS->>LS: drainPendingProgressWrites() [awaits all in-flight DB writes]
LS->>DB: completeWorkflowExecution (with finalizationPath, lastStartedBlock, lastCompletedBlock)
DB-->>LS: ok
LS-->>Executor: done
Loading

Last reviewed commit: "fix(admin): replace ..."

- Split searchInput (controlled input) from searchQuery (committed value)
so the hook only fires on Search click or Enter, not every keystroke
- Gate table render on searchQuery.length > 0 to prevent stale results
showing after input is cleared
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

Addressed all three comments:

Excessive API requests (P1) — Replaced live search with an explicit Search button + Enter key support. searchInput tracks the controlled input value; searchQuery only updates on submit. The hook only fires when a search is committed, eliminating per-keystroke requests entirely.

Stale results on clear (P1) — Gated the table render on searchQuery.length > 0 && usersData. Clearing the input and searching again (or just clearing) will hide the table, so stale results from the previous search never persist visually.

onBlockComplete fire-and-forget (P2) — Out of scope for this PR; that change is in execution-core.ts and unrelated to the admin UI work here.

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@greptile

@waleedlatif1
waleedlatif1 merged commit 0fbf31b into mainMar 18, 2026
15 checks passed
@waleedlatif1
waleedlatif1 deleted the waleedlatif1/hangzhou-v2 branch March 18, 2026 01:00
Sign up for freeto 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

@waleedlatif1@Sg312@PlaneInABottle