Skip to content

Rewire iOS app after web refactor#97

Merged
2witstudios merged 2 commits intomasterfrom
claude/sync-ios-web-refactor-zfl2B
Dec 19, 2025
Merged

Rewire iOS app after web refactor#97
2witstudios merged 2 commits intomasterfrom
claude/sync-ios-web-refactor-zfl2B

Conversation

@2witstudios
Copy link
Owner

No description provided.

- Add minimax provider to ProviderStatuses model
- Add minimax case to AISettings.isProviderConfigured()
- Remove unused ConversationListResponse wrapper struct
- Add /api/ai/page-agents/multi-drive endpoint to APIEndpoints
- Add /api/drives/[driveId]/agents endpoint for per-drive listing
- Add MultiDriveAgentsResponse, DriveAgentGroup, AgentSummary models
- Refactor AgentService.loadAllAgents() to use new efficient endpoint
- Reduces N+1 API calls (drives + pages per drive) to single request
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

Warning

Rate limit exceeded

@2witstudios has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 37 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 54554b4 and 24fb6e1.

📒 Files selected for processing (5)
  • apps/ios/PageSpace/Core/Models/Conversation.swift (0 hunks)
  • apps/ios/PageSpace/Core/Models/Page.swift (1 hunks)
  • apps/ios/PageSpace/Core/Models/User.swift (2 hunks)
  • apps/ios/PageSpace/Core/Networking/APIEndpoints.swift (1 hunks)
  • apps/ios/PageSpace/Core/Services/AgentService.swift (1 hunks)
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/sync-ios-web-refactor-zfl2B

Comment @coderabbitai help to get the list of available commands and usage tips.

@2witstudios
Copy link
Owner Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@2witstudios 2witstudios merged commit b538ebf into master Dec 19, 2025
3 checks passed
2witstudios added a commit that referenced this pull request Dec 19, 2025
* feat(db): add activityLogs table for audit trail

Add new database schema for enterprise activity monitoring:
- New enums: activity_operation, activity_resource
- New activityLogs table with:
  - User attribution with AI context (isAiGenerated, aiProvider, aiModel)
  - Full content snapshots for future rollback support
  - Hierarchical context (driveId, pageId) for filtering
  - Indexed for efficient queries by timestamp, user, drive, page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(lib): add activity logger service

Add fire-and-forget activity logging functions:
- logActivity(): Core logging function
- logPageActivity(): Page CRUD operations
- logPermissionActivity(): Permission changes
- logDriveActivity(): Drive operations
- logAgentConfigActivity(): Agent configuration changes

Designed to never block user operations while maintaining
comprehensive audit trail for enterprise compliance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): add /api/activities endpoint

Add context-aware activity fetching endpoint:
- user context: User's own activity (dashboard view)
- drive context: All drive activity (drive view)
- page context: All page edits (page view)

Includes permission checks (canUserViewPage, isUserDriveMember)
and pagination support for large activity lists.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ui): replace Settings tab with Activity tab in sidebar

- Add SidebarActivityTab component with context-aware activity display
- Update right sidebar to use Activity tab instead of Settings
- Update GlobalAssistantView to open Activity tab

Activity tab features:
- Search filtering
- User avatars with AI indicator (Bot icon)
- Operation icons (create, update, delete, etc.)
- Relative timestamps
- Loading skeletons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(store): update SidebarTab type from 'settings' to 'activity'

Update usePageAgentDashboardStore and tests to use 'activity'
tab instead of 'settings' to match new sidebar structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): inject activity logging into page CRUD routes

Add logPageActivity calls to track:
- Page creation (POST /api/pages)
- Page updates (PATCH /api/pages/[pageId])
- Page deletion/trash (DELETE /api/pages/[pageId])
- Page restoration (POST /api/pages/[pageId]/restore)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): inject activity logging into permission routes

Add logPermissionActivity calls to track:
- Permission grants (POST /api/pages/[pageId]/permissions)
- Permission updates (POST with existing permission)
- Permission revocations (DELETE /api/pages/[pageId]/permissions)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(api): handle null values in activities query params

Zod's .optional() and .default() only work with undefined, not null.
searchParams.get() returns null for missing params, causing validation
errors. Convert null → undefined with ?? operator.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): add activity logging to all AI tool operations

AI tools now log to the activity system with full attribution:
- Extended ToolExecutionContext with aiProvider, aiModel fields
- Added logging to 11 write tools across 4 tool files
- Pass AI context through experimental_context in 3 API routes
- Export monitoring module from @pagespace/lib/server

Tools now logged: replace_lines, create_page, rename_page, trash,
restore, move_page, edit_sheet_cells, update_agent_config,
update_task, create_drive, rename_drive

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address PR review comments

- Wrap switch case declarations in blocks (/api/activities/route.ts)
- Change driveId FK to 'set null' for audit trail preservation
- Fix ProviderSetupCard to use inline mode instead of broken handler
- Fix conversationId mapping to use session ID not page ID

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: fix mocks for activity logging functions

Add missing mock functions for the new activity logging exports:
- agent-tools.test.ts: add logAgentConfigActivity mock
- page-write-tools.test.ts: add logPageActivity, logDriveActivity mocks
- permissions/route.test.ts: add logPermissionActivity mock (moved to
  @pagespace/lib), add @pagespace/db mock for db.query.pages.findFirst

All 2073 tests now pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prefix unused provider param with underscore

* Rewire iOS app after web refactor (#97)

* fix(stores): restore missing page header and clean up dead navigation code (#100)

* fix(stores): restore missing page header and clean up dead navigation code

The page header (Share button, breadcrumbs, etc.) was missing from all pages
because OptimizedViewHeader checked layoutStore.activePageId which was always
null - the navigation system was designed but never wired up.

Changes:
- Fix OptimizedViewHeader to use useParams() instead of dead store state
- Remove all dead navigation code from useLayoutStore (352→60 lines)
- Remove duplicate sidebar state from useUIStore (97→50 lines)
- Remove dead cleanup code from NavigationProvider.tsx
- Remove dead sidebar hooks from useUI.ts (keep only useTreeState)
- Update store tests to match new simplified state
- Update state-management.md documentation

The two stores now have clear, non-overlapping responsibilities:
- useLayoutStore: sidebar open/closed state (persisted)
- useUIStore: tree expansion and scroll state (persisted)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove references to deleted clearCache method in layout store

The layout store was simplified to only manage sidebar state, but
DebugPanel and LayoutErrorBoundary still referenced the deleted
clearCache() method and other removed properties (viewCache,
activeDriveId, activePageId, centerViewType).

These were all part of a navigation system that was designed but
never wired up (dead code). The useful functionality is preserved:
- Clear Cache button still clears localStorage/sessionStorage
- Error boundary still clears storage on error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: extract URL state and agent conversation helpers (#101)

* fix(stores): restore missing page header and clean up dead navigation code

The page header (Share button, breadcrumbs, etc.) was missing from all pages
because OptimizedViewHeader checked layoutStore.activePageId which was always
null - the navigation system was designed but never wired up.

Changes:
- Fix OptimizedViewHeader to use useParams() instead of dead store state
- Remove all dead navigation code from useLayoutStore (352→60 lines)
- Remove duplicate sidebar state from useUIStore (97→50 lines)
- Remove dead cleanup code from NavigationProvider.tsx
- Remove dead sidebar hooks from useUI.ts (keep only useTreeState)
- Update store tests to match new simplified state
- Update state-management.md documentation

The two stores now have clear, non-overlapping responsibilities:
- useLayoutStore: sidebar open/closed state (persisted)
- useUIStore: tree expansion and scroll state (persisted)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove references to deleted clearCache method in layout store

The layout store was simplified to only manage sidebar state, but
DebugPanel and LayoutErrorBoundary still referenced the deleted
clearCache() method and other removed properties (viewCache,
activeDriveId, activePageId, centerViewType).

These were all part of a navigation system that was designed but
never wired up (dead code). The useful functionality is preserved:
- Clear Cache button still clears localStorage/sessionStorage
- Error boundary still clears storage on error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: extract URL state and agent conversation helpers

- Add centralized url-state.ts for chat URL param management
- Add shared agent-conversations.ts API helpers (DRY up fetch calls)
- Add UI refresh protection (isPaused) to useBreadcrumbs, usePageTree, useConversations
- Refactor usePageAgentDashboardStore and usePageAgentSidebarState to use shared helpers
- Update state-management.md with AI assistant state boundaries documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address PR review comments from CodeRabbit

- Fix stale isPaused closure in useBreadcrumbs, usePageTree, useConversations
  (use isEditingActive helper that reads live state via getState())
- Change 'push' to 'replace' when auto-loading most recent conversation
- Add agentId/conversationId context to error messages for debugging
- Update ui-refresh-protection.md docs with correct isPaused pattern
- Add language identifier to code block in state-management.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* feat(db): add activityLogs table for audit trail

Add new database schema for enterprise activity monitoring:
- New enums: activity_operation, activity_resource
- New activityLogs table with:
  - User attribution with AI context (isAiGenerated, aiProvider, aiModel)
  - Full content snapshots for future rollback support
  - Hierarchical context (driveId, pageId) for filtering
  - Indexed for efficient queries by timestamp, user, drive, page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(lib): add activity logger service

Add fire-and-forget activity logging functions:
- logActivity(): Core logging function
- logPageActivity(): Page CRUD operations
- logPermissionActivity(): Permission changes
- logDriveActivity(): Drive operations
- logAgentConfigActivity(): Agent configuration changes

Designed to never block user operations while maintaining
comprehensive audit trail for enterprise compliance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): add /api/activities endpoint

Add context-aware activity fetching endpoint:
- user context: User's own activity (dashboard view)
- drive context: All drive activity (drive view)
- page context: All page edits (page view)

Includes permission checks (canUserViewPage, isUserDriveMember)
and pagination support for large activity lists.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ui): replace Settings tab with Activity tab in sidebar

- Add SidebarActivityTab component with context-aware activity display
- Update right sidebar to use Activity tab instead of Settings
- Update GlobalAssistantView to open Activity tab

Activity tab features:
- Search filtering
- User avatars with AI indicator (Bot icon)
- Operation icons (create, update, delete, etc.)
- Relative timestamps
- Loading skeletons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(store): update SidebarTab type from 'settings' to 'activity'

Update usePageAgentDashboardStore and tests to use 'activity'
tab instead of 'settings' to match new sidebar structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): inject activity logging into page CRUD routes

Add logPageActivity calls to track:
- Page creation (POST /api/pages)
- Page updates (PATCH /api/pages/[pageId])
- Page deletion/trash (DELETE /api/pages/[pageId])
- Page restoration (POST /api/pages/[pageId]/restore)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(api): inject activity logging into permission routes

Add logPermissionActivity calls to track:
- Permission grants (POST /api/pages/[pageId]/permissions)
- Permission updates (POST with existing permission)
- Permission revocations (DELETE /api/pages/[pageId]/permissions)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(api): handle null values in activities query params

Zod's .optional() and .default() only work with undefined, not null.
searchParams.get() returns null for missing params, causing validation
errors. Convert null → undefined with ?? operator.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat(ai): add activity logging to all AI tool operations

AI tools now log to the activity system with full attribution:
- Extended ToolExecutionContext with aiProvider, aiModel fields
- Added logging to 11 write tools across 4 tool files
- Pass AI context through experimental_context in 3 API routes
- Export monitoring module from @pagespace/lib/server

Tools now logged: replace_lines, create_page, rename_page, trash,
restore, move_page, edit_sheet_cells, update_agent_config,
update_task, create_drive, rename_drive

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address PR review comments

- Wrap switch case declarations in blocks (/api/activities/route.ts)
- Change driveId FK to 'set null' for audit trail preservation
- Fix ProviderSetupCard to use inline mode instead of broken handler
- Fix conversationId mapping to use session ID not page ID

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: fix mocks for activity logging functions

Add missing mock functions for the new activity logging exports:
- agent-tools.test.ts: add logAgentConfigActivity mock
- page-write-tools.test.ts: add logPageActivity, logDriveActivity mocks
- permissions/route.test.ts: add logPermissionActivity mock (moved to
  @pagespace/lib), add @pagespace/db mock for db.query.pages.findFirst

All 2073 tests now pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prefix unused provider param with underscore

* refactor: replace ORM chain mocks with repository seams

Create proper architectural boundaries for database operations:

- Add pageRepository with 11 methods (findById, create, update, trash, etc.)
- Add driveRepository with 5 methods (findById, findByIdBasic, etc.)
- Add agentRepository with 2 methods (findById, updateConfig)

Refactor AI tools to use repository seams:
- agent-tools.ts now uses agentRepository
- page-write-tools.ts now uses pageRepository + driveRepository

Rewrite tests to mock repository boundaries:
- agent-tools.test.ts: removed @scaffold label, 9 tests passing
- page-write-tools.test.ts: removed @scaffold label, 23 tests passing

Test scores improved from 6/10 to 9/10 per testing rubric.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(test): add missing isEditingActive export to usePageTree test mock

The test mock for @/stores/useEditingStore was missing the
isEditingActive named export that usePageTree.ts imports.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: remove unused db imports from page-write-tools

Removed leftover imports (db, pages, drives, eq, and) that were
replaced by repository seams in the refactor.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(test): add missing getActorInfo and logPageActivity mocks

Added missing mocks for activity logging functions that were added
to the API routes:
- getActorInfo in @pagespace/lib/server mock
- logPageActivity in @pagespace/lib mock

Fixes 8 failing tests in pages route tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: implement fire-and-forget activity logging pattern

Replace blocking `await getActorInfo()` calls with non-blocking helpers
to avoid blocking user operations during activity logging:

- Add logPageActivityAsync() for fire-and-forget page activity logging
- Add logDriveActivityAsync() for fire-and-forget drive activity logging
- Update all 9 logging call sites in page-write-tools.ts
- Handle errors gracefully (still log activity even if actor lookup fails)
- Use nullish coalescing for optional context fields
- Fix TypeScript errors in test file with proper type assertions

Addresses CodeRabbit review comment about blocking activity logging
defeating the fire-and-forget design goal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use null instead of undefined for parentId when moving to root

Also add activity logging test assertions to verify logging is called
after successful page operations (replace_lines, create_page, rename_page).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: prefix unused mockLogDriveActivity with underscore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
@2witstudios 2witstudios deleted the claude/sync-ios-web-refactor-zfl2B branch January 29, 2026 02:24
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.

2 participants