Skip to content

feat: filter conversations by user in organization exports#13

Open
kalus-msic wants to merge 8 commits into
osteele:mainfrom
kalus-msic:feat/user-filter
Open

feat: filter conversations by user in organization exports#13
kalus-msic wants to merge 8 commits into
osteele:mainfrom
kalus-msic:feat/user-filter

Conversation

@kalus-msic

@kalus-msic kalus-msic commented Jun 30, 2026

Copy link
Copy Markdown

Summary

  • Adds a user filter to both the sidebar (MasterDetailView) and the browse view (ConversationBrowser) that appears automatically when an organization export is loaded
  • Derives the user list from distinct account.uuid values in conversations.json; uses users.json for name lookup where available, falls back to User <uuid-prefix> when not
  • Filter is multi-select: no selection shows all conversations; selecting one or more users narrows the list (AND logic with existing text search)
  • Invisible for personal exports (single account UUID → filter not shown) and for old exports without users.json
  • Fixes UserDataSchema to accept null for verified_phone_number and email_address (org exports set these to JSON null for most users)
  • Extends onConversationList callback with an optional userMap?: UserMap parameter (backward compatible)

Behavior

Scenario users.json present Distinct account UUIDs Filter shown
Personal export Yes (1 user) 1 No
Org export Yes (N users) 2+ Yes
Old export No No

Test plan

  • Load a personal export ZIP → no user filter visible, all conversations shown as before
  • Load an organization export ZIP with multiple users → user filter appears with names sorted by conversation count
  • Select one user → list narrows to that user's conversations
  • Select multiple users → list shows conversations from all selected users
  • Combine user filter with text search → both filters apply simultaneously
  • Clear filter button resets selection
  • Load a second ZIP → user filter resets (no stale selection from previous load)
  • bun run check passes (typecheck + lint)
  • bun test passes

🤖 Generated with Claude Code

kalus-msic and others added 8 commits June 30, 2026 18:58
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Merge UserMap into existing `import type` statement in both filter
  components (biome useImportType rule)
- Apply biome formatter fixes (import order, line length)
- Add loadKey counter to ChatViewer; key MasterDetailView and
  ConversationBrowser on it so selectedUserUuids resets on each
  new file load

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- UserDataSchema: accept null for email_address and verified_phone_number
  (org exports set verified_phone_number: null for most users, breaking
  safeParse and causing all but one user to be silently dropped)
- usersWithCounts: derive user list from distinct account.uuid values in
  conversations instead of from userMap entries; use userMap only for
  name lookup with fallback to "User <uuid-prefix>" when name is absent
- JsonInput: keep userMap even when size < 2 (name lookup still useful);
  use regex search for users.json to handle nested ZIP structures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Artifact.tsx: sort Sheet imports alphabetically
sorting.ts: use double quotes (biome formatter)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@kalus-msic

Copy link
Copy Markdown
Author

Note: bun test reports 1 pre-existing failure unrelated to this PR — ChatDataSchema > should parse conversation with artifacts format fails because testdata/conversation-with-artifacts.json is missing from the repository (the test references a file that was never committed upstream). All 16 other tests pass. bun run check (biome + tsc) passes cleanly.

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