Skip to content

Conversation

@cj-vana
Copy link
Collaborator

@cj-vana cj-vana commented Oct 9, 2025

PR Type

Enhancement


Description

Major Release 2.0.0: Comprehensive real-time collaboration system for all document editors
Real-time Editing: Implemented collaborative editing with presence tracking, cursor synchronization, and live updates across all document types
Auto-save & Offline Support: Added debounced auto-save with offline queue management using IndexedDB for seamless editing experience
Version Control: Integrated document history, version tracking, and conflict resolution with rollback capabilities
Shared Edit Mode: Enabled anonymous user collaboration through shared links with RLS bypass functionality
Collaboration Infrastructure: Built comprehensive collaboration system with Supabase Broadcast/Presence channels, stores, and utilities
UI Enhancements: Added collaboration toolbar, presence indicators, save status, and document history components
Database Schema: Created supporting tables for document history, locks, pending saves, and activity tracking
Editor Integration: Updated all major editors (Run of Show, Stage Plot, Patch Sheet, Pixel Maps, etc.) with collaboration features


Diagram Walkthrough

flowchart LR
  A["Document Editors"] --> B["Collaboration Hooks"]
  B --> C["Auto-save System"]
  B --> D["Real-time Sync"]
  C --> E["Offline Queue"]
  D --> F["Supabase Channels"]
  F --> G["Presence Tracking"]
  F --> H["Broadcast Updates"]
  C --> I["Version Control"]
  I --> J["Document History"]
  I --> K["Conflict Resolution"]
Loading

File Walkthrough

Relevant files
Enhancement
22 files
useAutoSave.ts
Add comprehensive auto-save hook for collaborative editing

apps/web/src/hooks/useAutoSave.ts

• Implements comprehensive auto-save hook with debouncing, offline
support, and version conflict detection
• Provides optimistic UI
updates with rollback capabilities and remote update handling

Includes extensive logging and error handling for debugging
collaborative editing scenarios
• Supports shared edit mode with
shareCode parameter to bypass RLS authentication

+674/-0 
collaborativeDocStore.ts
Add collaborative document store with real-time features 

apps/web/src/stores/collaborativeDocStore.ts

• Creates Zustand store for managing collaborative document state and
real-time synchronization
• Handles presence tracking, broadcast
updates, and offline queue management
• Provides actions for field
updates, cursor tracking, and connection management
• Includes
auto-save configuration and reconnection logic for network disruptions

+542/-0 
autoSave.ts
Add auto-save utilities with offline support and conflict detection

apps/web/src/lib/autoSave.ts

• Implements core auto-save utilities with debouncing, retry logic,
and offline queue support
• Provides batch saving, version conflict
detection, and document history snapshots
• Maps document types to
correct timestamp fields and resource types for shared editing

Includes comprehensive error handling and logging for debugging save
operations

+482/-0 
collaboration.ts
Add real-time collaboration infrastructure with presence tracking

apps/web/src/lib/collaboration.ts

• Implements real-time collaboration using Supabase Broadcast and
Presence channels
• Provides user color assignment, presence tracking,
and broadcast message handling
• Includes channel setup, cleanup, and
reconnection logic for network disruptions
• Supports collaborative
cursor tracking and field editing notifications

+360/-0 
offlineQueue.ts
Add offline queue management for document synchronization

apps/web/src/lib/offlineQueue.ts

• Implements IndexedDB-based offline queue for document updates using
localforage
• Provides queue management with size limits, stale item
pruning, and statistics
• Supports enqueueing, dequeueing, and batch
operations for offline synchronization
• Includes error handling and
availability checks for IndexedDB storage

+255/-0 
collaboration.ts
Add TypeScript types for collaborative editing system       

apps/web/src/types/collaboration.ts

• Defines comprehensive TypeScript interfaces for collaborative
editing features
• Includes types for save status, presence users,
broadcast payloads, and document updates
• Provides conflict
resolution, version history, and auto-save configuration types

Supports offline queue management and connection status tracking

+266/-0 
usePresence.ts
Add presence tracking hook for collaborative cursors         

apps/web/src/hooks/usePresence.ts

• Implements presence tracking hook for collaborative cursor and field
editing
• Provides throttled updates for cursor position and editing
field changes
• Includes helper hook for tracking cursor position in
text inputs
• Supports cleanup and blur event handling for presence
state management

+252/-0 
useCollaboration.ts
Add main collaboration hook for real-time document editing

apps/web/src/hooks/useCollaboration.ts

• Creates main collaboration hook that orchestrates real-time features

• Manages broadcast and presence channels with connection status
tracking
• Provides broadcast functionality and cleanup methods for
collaboration
• Includes memoization for stable references and
prevents unnecessary re-renders

+221/-0 
shareUtils.ts
Update shared resource utilities for collaborative editing

apps/web/src/lib/shareUtils.ts

• Updates shared resource handling to support edit-mode Run of Show
links
• Modifies updateSharedResource to use RPC function for
bypassing RLS
• Adds support for additional resource types including
technical riders
• Improves error handling and logging for shared
resource operations

+41/-30 
supabase.ts
Update savePixelMap to return created data                             

apps/web/src/lib/supabase.ts

• Updates savePixelMap function to return the created data after
insertion
• Adds .select().single() to the insert operation for
retrieving the saved record
• Maintains existing error handling while
providing access to the saved data

+17/-11 
CorporateMicPlotEditor.tsx
Integrate collaborative editing features in Corporate Mic Plot Editor

apps/web/src/pages/CorporateMicPlotEditor.tsx

• Integrates comprehensive collaborative editing features including
auto-save and real-time sync
• Adds collaboration toolbar, presence
tracking, and version history functionality
• Implements real-time
database subscriptions for cross-user synchronization
• Supports both
authenticated and anonymous users in shared edit mode

+448/-34
SharedProductionSchedule.tsx
Add Real-time Collaboration to Shared Production Schedules

apps/web/src/pages/SharedProductionSchedule.tsx

• Added comprehensive collaboration features including real-time
editing, auto-save, and conflict resolution
• Implemented
authentication requirements for edit mode shared links
• Added version
history and document restoration capabilities
• Enhanced UI with
collaboration toolbar and improved error handling

+803/-98
StagePlotEditor.tsx
Enable Real-time Collaboration in Stage Plot Editor           

apps/web/src/pages/StagePlotEditor.tsx

• Integrated collaboration hooks for real-time editing and auto-save
functionality
• Added support for anonymous users in shared edit mode

• Implemented real-time database subscriptions for element
synchronization
• Enhanced UI with collaboration toolbar and conflict
resolution modals

+480/-62
RiderEditor.tsx
Implement Collaboration Features in Technical Rider Editor

apps/web/src/pages/RiderEditor.tsx

• Added collaboration features with auto-save and real-time
synchronization
• Implemented shared edit functionality with anonymous
user support
• Added version history and document restoration
capabilities
• Enhanced error handling and save status management

+602/-98
CommsPlannerEditor.tsx
Add Real-time Collaboration to Communications Planner       

apps/web/src/pages/CommsPlannerEditor.tsx

• Integrated collaboration hooks for real-time editing and auto-save

Added shared edit mode support with anonymous user capabilities

Implemented version history and conflict resolution features

Enhanced document synchronization and state management

+611/-31
Header.tsx
Integrate Collaboration Toolbar into Header Component       

apps/web/src/components/Header.tsx

• Added collaborationToolbar prop to integrate collaboration features

• Enhanced header component to display collaboration status and
controls
• Improved responsive design for collaboration toolbar
placement

+10/-0   
RunOfShowEditor.tsx
Add real-time collaboration and duplicate functionality to Run of Show
Editor

apps/web/src/pages/RunOfShowEditor.tsx

• Added real-time collaboration features with auto-save, presence
tracking, and conflict resolution
• Implemented duplicate item
functionality with smart item numbering
• Integrated collaboration
toolbar and document history components
• Added support for
unauthenticated shared edit users with anonymous IDs

+359/-78
PatchSheetEditor.tsx
Enable real-time collaboration features in Patch Sheet Editor

apps/web/src/pages/PatchSheetEditor.tsx

• Integrated real-time collaboration system with auto-save and
presence tracking
• Added collaboration toolbar and document history
modals
• Implemented anonymous user support for shared edit sessions

Updated save logic to use auto-save for existing documents

+327/-101
LedPixelMapEditor.tsx
Implement real-time collaboration in LED Pixel Map Editor

apps/web/src/pages/LedPixelMapEditor.tsx

• Added comprehensive collaboration support with auto-save and
real-time updates
• Implemented shared edit functionality with
anonymous user support
• Integrated collaboration toolbar and conflict
resolution components
• Enhanced save logic to handle both owned and
shared documents

+435/-73
ProductionScheduleEditor.tsx
Enable comprehensive collaboration in Production Schedule Editor

apps/web/src/pages/ProductionScheduleEditor.tsx

• Added full collaboration features including auto-save, presence
tracking, and version history
• Implemented document history with
version restore functionality
• Added collaboration toolbar and
conflict resolution modals
• Enhanced with anonymous user support for
shared editing

+401/-50
StandardPixelMapEditor.tsx
Add real-time collaboration to Standard Pixel Map Editor 

apps/web/src/pages/StandardPixelMapEditor.tsx

• Integrated real-time collaboration system with auto-save
capabilities
• Added support for shared edit functionality with
anonymous users
• Implemented collaboration toolbar and document
history components
• Enhanced save logic to handle
collaboration-enabled documents

+426/-44
DocumentHistory.tsx
Create DocumentHistory component for version management   

apps/web/src/components/History/DocumentHistory.tsx

• Created new component for displaying document version history
timeline
• Implemented expandable version entries with changed fields
display
• Added version restore functionality and infinite scroll
support
• Includes loading states and error handling

+272/-0 
Dependencies
1 files
package.json
Update version to 2.0.0 and add localforage dependency     

package.json

• Updates version from 1.5.6.6 to 2.0.0 indicating major release

Adds localforage dependency for IndexedDB-based offline storage

+4/-1     
Formatting
2 files
ChartDetailModal.tsx
Minor code quality improvement in ChartDetailModal             

apps/web/src/components/analyzer/ChartDetailModal.tsx

• Changes variable declaration from let to const for data variable

Minor code quality improvement with no functional changes

+1/-1     
PrintStagePlotExport.tsx
Refactor variable declarations in PrintStagePlotExport component

apps/web/src/components/PrintStagePlotExport.tsx

• Changed variable declarations from let to const for immutable style
objects
• Applied consistent code style improvements across multiple
style object definitions

+5/-5     
Configuration changes
1 files
App.tsx
Update React Router configuration with future flags           

apps/web/src/App.tsx

• Added React Router future flags for v7 compatibility
• Enabled
v7_startTransition and v7_relativeSplatPath flags

+1/-1     
Additional files
33 files
CHANGELOG.md +143/-0 
package.json +2/-1     
CollaborationToolbar.tsx +520/-0 
ConflictResolution.tsx +351/-0 
VersionDiff.tsx +281/-0 
ActiveUsers.tsx +159/-0 
EditingIndicator.tsx +150/-0 
PresenceIndicator.tsx +175/-0 
SaveIndicator.tsx +128/-0 
ShareModal.tsx +6/-10   
PatchSheetInputs.tsx +4/-3     
PatchSheetOutputs.tsx +3/-3     
tooltip.tsx +28/-0   
AllRiders.tsx +16/-0   
SharedPatchSheet.tsx +38/-6   
SharedShowModePage.tsx +2/-3     
ShowModePage.tsx +2/-3     
TheaterMicPlotEditor.tsx +280/-44
VideoCategoryPage.tsx +1/-1     
pnpm-lock.yaml +1721/-2827
20251007100000_add_version_columns_to_documents.sql +97/-0   
20251007110000_create_document_history_tables.sql +236/-0 
20251007120000_create_document_activity_table.sql +177/-0 
20251007130000_create_pending_saves_table.sql +239/-0 
20251007140000_create_document_locks_table.sql +297/-0 
20251007145000_add_metadata_columns_to_documents.sql +82/-0   
20251007150000_add_automatic_history_triggers.sql +236/-0 
20251007160000_enable_realtime_replication.sql +204/-0 
20251007170000_add_rls_policies_for_collaboration.sql +448/-0 
20251008180000_add_update_shared_resource_rpc.sql +87/-0   
20251008190000_fix_update_shared_resource_jsonb_extraction.sql +119/-0 
20251008204809_fix_jsonb_extraction_in_update_shared_resource.sql +173/-0 
20251008210000_fix_update_shared_resource_returning.sql +100/-0 

cj-vana and others added 3 commits October 9, 2025 14:16
…itors

Add comprehensive real-time collaboration infrastructure with auto-save,
presence indicators, conflict resolution, and document history tracking.

## Collaboration Infrastructure

### Core Collaboration System
- Add `useCollaboration` hook for real-time broadcast/presence channels
- Add `useAutoSave` hook with optimistic UI and conflict detection
- Add `usePresence` hook for tracking active editors and user presence
- Implement collaboration.ts with Supabase Realtime integration
- Add autoSave.ts with debounced saves and version management
- Add offlineQueue.ts for handling offline edit scenarios

### UI Components
- Add CollaborationToolbar with save status and active users
- Add SaveIndicator with typing/saving/saved states
- Add ActiveUsers presence component with avatars
- Add EditingIndicator for field-level editing status
- Add PresenceIndicator for user activity visualization
- Add DocumentHistory modal with version comparison
- Add ConflictResolution modal for merge conflict handling
- Add VersionDiff component for side-by-side comparisons
- Add Tooltip UI primitive (Radix UI based)

### State Management
- Add collaborativeDocStore (Zustand) for document state
- Add collaboration types for conflicts, history, presence

## Editor Integration

### Real-time Collaboration Enabled
- PatchSheetEditor: Full collaboration with broadcast on all field changes
- StagePlotEditor: Broadcast for elements, stage size, background images
- TheaterMicPlotEditor: Broadcast for actors, name changes
- CorporateMicPlotEditor: Broadcast for presenters, name changes
- RunOfShowEditor: Collaboration toolbar integrated in header
- ProductionScheduleEditor: Auto-save and collaboration support
- All editors: Database real-time subscriptions for cross-client sync

### Shared Edit Link Fixes
- Fix TheaterMicPlotEditor shareCode parameter for anonymous saves
- Fix CorporateMicPlotEditor shareCode parameter for anonymous saves
- Enable anonymous users to save via update_shared_resource RPC
- Prevent 406 errors for shared edit link users

### Infinite Loop Fixes
- Fix PatchSheetOutputs circular dependency (remove ref tracking)
- Match PatchSheetInputs pattern for stable remote updates
- Ensure broadcasts don't trigger save loops with proper change detection

## Database Migrations

### Version Control System
- Add version columns to all document tables
- Add last_edited timestamps for conflict detection
- Add metadata JSONB columns for collaboration data

### History & Activity Tracking
- Create document_history tables for all document types
- Add document_activity table for audit logging
- Add automatic history triggers on document updates
- Enable point-in-time recovery and version comparison

### Collaboration Support Tables
- Add pending_saves table for offline queue
- Add document_locks table for optimistic locking
- Add RLS policies for collaboration features
- Enable realtime replication for all document tables

### Shared Resource Updates
- Add update_shared_resource RPC function with SECURITY DEFINER
- Fix JSONB extraction in RPC for proper field updates
- Enable anonymous users to save via share codes
- Add proper RETURNING clause for version tracking

## Bug Fixes

### Header Component
- Move collaboration toolbar integration to header
- Add collaborationToolbar prop for editor integration
- Match RunOfShowEditor pattern across all editors

### Share Modal
- Update share link generation for collaboration context
- Maintain compatibility with existing share workflows

### Supabase Client
- Configure realtime options for collaboration channels
- Add proper channel cleanup on unmount

## Dependencies
- Add @radix-ui/react-tooltip for collaboration UI
- Update package.json and pnpm-lock.yaml

## Breaking Changes
None - all changes are additive and backward compatible.

## Performance Improvements
- Debounced auto-save (1500ms default) reduces database writes
- Optimistic UI updates for instant feedback
- Broadcast-first architecture for sub-second propagation
- Reference-based change detection prevents unnecessary saves

## Security
- RLS policies prevent unauthorized access to collaboration data
- Share code validation in update_shared_resource RPC
- Version mismatch detection prevents data loss
- Proper authentication checks for all collaboration features

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

Co-Authored-By: Claude <noreply@anthropic.com>
Major version bump reflecting the addition of comprehensive real-time
collaboration features across all document types.

Changes:
- Updated root package.json from 1.5.6.6 to 2.0.0
- Updated apps/web/package.json from 1.5.6.8 to 2.0.0
- Added comprehensive CHANGELOG entry documenting:
  - Real-time collaboration infrastructure with WebSocket support
  - Shared edit links with anonymous editing capabilities
  - Document versioning and history tracking
  - Collaboration UI components and toolbars
  - Offline support infrastructure
  - Database schema additions (13 migrations)
  - Editor integrations (PatchSheet, StagePlot, TheaterMicPlot, CorporateMicPlot)
  - Bug fixes (infinite loops, 406 errors, JSONB handling)

Note: Capture agent version remains at 0.2.0 (unchanged)

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

Co-Authored-By: Claude <noreply@anthropic.com>
… Show

Added duplicate functionality and fixed UI issues across Run of Show editor and view modes:

Run of Show Editor (RunOfShowEditor.tsx):
- Added duplicate item feature with Copy icon for all items and headers
- Intelligent item numbering: pure numbers increment (5→6), text appends "(copy)"
- Preserves all fields including custom columns and highlight colors
- Fixed critical bug: item numbers now preserved during reordering (no longer auto-renumbered)
- Fixed sticky section header gap: adjusted from top-[49px] to top-[40px]

Show Mode Pages:
- Fixed sticky header gap in ShowModePage.tsx: adjusted to top-[40px]
- Fixed sticky header gap in SharedShowModePage.tsx: adjusted to top-[40px]

These changes ensure:
✓ Users can duplicate items with all properties intact
✓ Custom item names persist when reordering ("Opening Prayer" stays as-is)
✓ Seamless sticky header behavior across all Run of Show views
✓ Duplicate feature available in both regular and shared edit modes

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

Co-Authored-By: Claude <noreply@anthropic.com>
@cj-vana cj-vana changed the title 6.0.0 2.0.0 Oct 9, 2025
@netlify
Copy link

netlify bot commented Oct 9, 2025

Deploy Preview for sounddocsbeta ready!

Name Link
🔨 Latest commit 0aae9d4
🔍 Latest deploy log https://app.netlify.com/projects/sounddocsbeta/deploys/68e8065df7afa70008aafa45
😎 Deploy Preview https://deploy-preview-109--sounddocsbeta.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@qodo-code-review
Copy link
Contributor

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: typescript-checks

Failed stage: ESLint on changed files [❌]

Failure summary:

The action failed because ESLint reported 188 errors (and 25 warnings) when linting the specified
changed files, and the command was run with --max-warnings 0, causing a non-zero exit code.
Key
issues included:
- @typescript-eslint/no-explicit-any violations across many files (e.g.,
PrintStagePlotExport.tsx:9:15, ChartDetailModal.tsx:191:22, multiple editor pages).
-
@typescript-eslint/no-unused-vars where variables are defined or assigned but never used (e.g.,
ConflictResolution.tsx:183:3 'documentId', CommsPlannerEditor.tsx:204:5 'broadcast').
- Additional
rule warnings like react-hooks/exhaustive-deps and react-refresh/only-export-components.
Example
errors with file and line numbers:
- /apps/web/src/components/ConflictResolution.tsx:183:3
'documentId' is defined but never used.
- /apps/web/src/components/Header.tsx:38:36Unexpected
any. Specify a different type.
- /apps/web/src/components/analyzer/ChartDetailModal.tsx:191:22
Unexpected any. Specify a different type.
Total reported: 213 problems (188 errors, 25 warnings).
ESLint exit code 1 caused the workflow to fail.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

174:  + prettier 3.5.3
175:  + typescript 5.9.2
176:  + typescript-eslint 8.39.1
177:  . prepare$ husky
178:  . prepare: Done
179:  Done in 4.3s using pnpm v9.15.9
180:  ##[group]Run # Convert comma-separated list to space-separated for ESLint
181:  �[36;1m# Convert comma-separated list to space-separated for ESLint�[0m
182:  �[36;1mFILES="apps/web/src/hooks/useAutoSave.ts,apps/web/src/hooks/useCollaboration.ts,apps/web/src/hooks/usePresence.ts,apps/web/src/lib/autoSave.ts,apps/web/src/lib/collaboration.ts,apps/web/src/lib/offlineQueue.ts,apps/web/src/stores/collaborativeDocStore.ts,apps/web/src/types/collaboration.ts,apps/web/src/components/CollaborationToolbar.tsx,apps/web/src/components/ConflictResolution.tsx,apps/web/src/components/History/DocumentHistory.tsx,apps/web/src/components/History/VersionDiff.tsx,apps/web/src/components/Presence/ActiveUsers.tsx,apps/web/src/components/Presence/EditingIndicator.tsx,apps/web/src/components/Presence/PresenceIndicator.tsx,apps/web/src/components/SaveIndicator.tsx,apps/web/src/components/ui/tooltip.tsx,apps/web/src/lib/shareUtils.ts,apps/web/src/lib/supabase.ts,apps/web/src/App.tsx,apps/web/src/components/Header.tsx,apps/web/src/components/PrintStagePlotExport.tsx,apps/web/src/components/ShareModal.tsx,apps/web/src/components/analyzer/ChartDetailModal.tsx,apps/web/src/components/patch-sheet/PatchSheetInputs.tsx,apps/web/src/components/patch-sheet/PatchSheetOutputs.tsx,apps/web/src/pages/AllRiders.tsx,apps/web/src/pages/CommsPlannerEditor.tsx,apps/web/src/pages/CorporateMicPlotEditor.tsx,apps/web/src/pages/LedPixelMapEditor.tsx,apps/web/src/pages/PatchSheetEditor.tsx,apps/web/src/pages/ProductionScheduleEditor.tsx,apps/web/src/pages/RiderEditor.tsx,apps/web/src/pages/RunOfShowEditor.tsx,apps/web/src/pages/SharedPatchSheet.tsx,apps/web/src/pages/SharedProductionSchedule.tsx,apps/web/src/pages/SharedShowModePage.tsx,apps/web/src/pages/ShowModePage.tsx,apps/web/src/pages/StagePlotEditor.tsx,apps/web/src/pages/StandardPixelMapEditor.tsx,apps/web/src/pages/TheaterMicPlotEditor.tsx,apps/web/src/pages/VideoCategoryPage.tsx"�[0m
183:  �[36;1mFILES_ARRAY=$(echo "$FILES" | tr ',' ' ')�[0m
184:  �[36;1m�[0m
185:  �[36;1mecho "Running ESLint on changed files:"�[0m
186:  �[36;1mecho "$FILES_ARRAY" | tr ' ' '\n'�[0m
187:  �[36;1m�[0m
188:  �[36;1m# Run ESLint only on changed files�[0m
189:  �[36;1m# Note: ESLint might need context from imported files, but will only report errors in specified files�[0m
190:  �[36;1mnpx eslint $FILES_ARRAY --max-warnings 0 || EXIT_CODE=$?�[0m
191:  �[36;1m�[0m
192:  �[36;1m# If ESLint found issues, fail the check�[0m
193:  �[36;1mif [ "${EXIT_CODE:-0}" -ne 0 ]; then�[0m
...

232:  apps/web/src/pages/CorporateMicPlotEditor.tsx
233:  apps/web/src/pages/LedPixelMapEditor.tsx
234:  apps/web/src/pages/PatchSheetEditor.tsx
235:  apps/web/src/pages/ProductionScheduleEditor.tsx
236:  apps/web/src/pages/RiderEditor.tsx
237:  apps/web/src/pages/RunOfShowEditor.tsx
238:  apps/web/src/pages/SharedPatchSheet.tsx
239:  apps/web/src/pages/SharedProductionSchedule.tsx
240:  apps/web/src/pages/SharedShowModePage.tsx
241:  apps/web/src/pages/ShowModePage.tsx
242:  apps/web/src/pages/StagePlotEditor.tsx
243:  apps/web/src/pages/StandardPixelMapEditor.tsx
244:  apps/web/src/pages/TheaterMicPlotEditor.tsx
245:  apps/web/src/pages/VideoCategoryPage.tsx
246:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/ConflictResolution.tsx
247:  ##[error]  183:3  error  'documentId' is defined but never used  @typescript-eslint/no-unused-vars
248:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/Header.tsx
249:  ##[error]  38:36  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
250:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/History/DocumentHistory.tsx
251:  ##[error]  2:61  error  'Filter' is defined but never used  @typescript-eslint/no-unused-vars
252:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/Presence/EditingIndicator.tsx
253:  ##[warning]  118:14  warning  Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components  react-refresh/only-export-components
254:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/PrintStagePlotExport.tsx
255:  ##[error]    9:15  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
256:  ##[error]  105:37  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
257:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/ShareModal.tsx
258:  ##[error]   65:19  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
259:  ##[error]   97:19  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
260:  ##[error]  125:19  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
261:  ##[error]  139:19  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
262:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/analyzer/ChartDetailModal.tsx
263:  ##[error]  102:12  error    'first' is assigned a value but never used                                                                                                  @typescript-eslint/no-unused-vars
264:  ##[error]  102:19  error    'second' is assigned a value but never used                                                                                                 @typescript-eslint/no-unused-vars
265:  ##[error]  191:22  error    Unexpected any. Specify a different type                                                                                                    @typescript-eslint/no-explicit-any
266:  ##[error]  198:34  error    Unexpected any. Specify a different type                                                                                                    @typescript-eslint/no-explicit-any
267:  ##[error]  350:14  error    Unexpected any. Specify a different type                                                                                                    @typescript-eslint/no-explicit-any
268:  ##[error]  361:12  error    Unexpected any. Specify a different type                                                                                                    @typescript-eslint/no-explicit-any
269:  ##[warning]  380:6   warning  React Hook useMemo has missing dependencies: 'coherenceAlpha' and 'coherenceThreshold'. Either include them or remove the dependency array  react-hooks/exhaustive-deps
270:  ##[error]  395:24  error    Unexpected any. Specify a different type                                                                                                    @typescript-eslint/no-explicit-any
271:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/patch-sheet/PatchSheetInputs.tsx
272:  ##[warning]  191:6   warning  React Hook useEffect has a missing dependency: 'inputs'. Either include it or remove the dependency array                                                                                                                            react-hooks/exhaustive-deps
273:  ##[warning]  250:6   warning  React Hook useEffect has missing dependencies: 'analogSnakeTypes', 'baseDeviceOptions', 'consoleTypeOptions', 'digitalSnakeTypes', 'inputTypeOptions', and 'networkTypeOptions'. Either include them or remove the dependency array  react-hooks/exhaustive-deps
274:  ##[warning]  266:6   warning  React Hook useEffect has a missing dependency: 'editModeInputs'. Either include it or remove the dependency array                                                                                                                    react-hooks/exhaustive-deps
275:  ##[warning]  278:6   warning  React Hook useEffect has a missing dependency: 'updateParentInputs'. Either include it or remove the dependency array                                                                                                                react-hooks/exhaustive-deps
276:  ##[error]  361:83  error    Unexpected any. Specify a different type                                                                                                                                                                                             @typescript-eslint/no-explicit-any
277:  ##[error]  363:22  error    Unexpected any. Specify a different type                                                                                                                                                                                             @typescript-eslint/no-explicit-any
278:  /home/runner/work/sounddocs/sounddocs/apps/web/src/components/patch-sheet/PatchSheetOutputs.tsx
279:  ##[warning]  153:6   warning  React Hook useEffect has a missing dependency: 'outputs'. Either include it or remove the dependency array                                                                                                            react-hooks/exhaustive-deps
280:  ##[warning]  209:6   warning  React Hook useEffect has missing dependencies: 'analogSnakeTypes', 'consoleTypeOptions', 'destinationTypeOptions', 'digitalSnakeTypes', and 'networkTypeOptions'. Either include them or remove the dependency array  react-hooks/exhaustive-deps
281:  ##[warning]  223:6   warning  React Hook useEffect has a missing dependency: 'editModeOutputs'. Either include it or remove the dependency array                                                                                                    react-hooks/exhaustive-deps
282:  ##[warning]  235:6   warning  React Hook useEffect has a missing dependency: 'updateParentOutputs'. Either include it or remove the dependency array                                                                                                react-hooks/exhaustive-deps
283:  ##[error]  315:85  error    Unexpected any. Specify a different type                                                                                                                                                                              @typescript-eslint/no-explicit-any
284:  ##[error]  317:23  error    Unexpected any. Specify a different type                                                                                                                                                                              @typescript-eslint/no-explicit-any
285:  /home/runner/work/sounddocs/sounddocs/apps/web/src/hooks/useAutoSave.ts
286:  ##[error]   17:34  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
287:  ##[error]   65:54  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
288:  ##[error]  165:36  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
289:  ##[error]  312:51  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
290:  ##[error]  312:71  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
291:  ##[warning]  407:5   warning  React Hook useCallback has unnecessary dependencies: 'documentId', 'documentType', and 'userId'. Either exclude them or remove the dependency array  react-hooks/exhaustive-deps
292:  ##[error]  438:53  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
293:  ##[error]  438:73  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
294:  ##[error]  561:28  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
295:  ##[error]  600:57  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
296:  ##[error]  600:77  error    Unexpected any. Specify a different type                                                                                                             @typescript-eslint/no-explicit-any
297:  /home/runner/work/sounddocs/sounddocs/apps/web/src/hooks/useCollaboration.ts
298:  172:5  warning  Unused eslint-disable directive (no problems were reported from 'react-hooks/exhaustive-deps')
299:  ##[warning]  174:6  warning  React Hook useEffect has missing dependencies: 'channels' and 'onRemoteUpdate'. Either include them or remove the dependency array. If 'onRemoteUpdate' changes too often, find the parent component that defines it and wrap that definition in useCallback  react-hooks/exhaustive-deps
300:  /home/runner/work/sounddocs/sounddocs/apps/web/src/lib/autoSave.ts
301:  ##[error]   92:46  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
302:  ##[error]   92:56  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
303:  ##[error]  171:38  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
304:  ##[error]  248:40  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
305:  ##[error]  401:28  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
306:  /home/runner/work/sounddocs/sounddocs/apps/web/src/lib/collaboration.ts
307:  ##[error]  157:51  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
308:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/CommsPlannerEditor.tsx
309:  ##[error]   204:5   error    'broadcast' is assigned a value but never used                                                                          @typescript-eslint/no-unused-vars
310:  ##[error]   223:11  error    'setEditingField' is assigned a value but never used                                                                    @typescript-eslint/no-unused-vars
311:  ##[error]   252:21  error    'version' is assigned a value but never used                                                                            @typescript-eslint/no-unused-vars
312:  ##[error]   252:30  error    'last_edited' is assigned a value but never used                                                                        @typescript-eslint/no-unused-vars
313:  ##[error]   252:43  error    'metadata' is assigned a value but never used                                                                           @typescript-eslint/no-unused-vars
314:  ##[error]   252:94  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
315:  ##[error]   266:75  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
316:  ##[warning]   318:6   warning  React Hook useEffect has a missing dependency: 'handleSave'. Either include it or remove the dependency array           react-hooks/exhaustive-deps
317:  ##[error]   744:69  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
318:  ##[error]   752:68  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
319:  ##[error]   764:25  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
320:  ##[error]   976:42  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
321:  ##[error]  1007:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
322:  ##[error]  1033:54  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
323:  ##[error]  1054:66  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
324:  ##[error]  1075:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
325:  ##[warning]  1086:6   warning  React Hook useEffect has a missing dependency: 'fetchVersionHistory'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
326:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/CorporateMicPlotEditor.tsx
327:  ##[error]    4:10  error    'useAuth' is defined but never used                                                                                     @typescript-eslint/no-unused-vars
328:  ##[error]   42:36  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
329:  ##[error]  124:23  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
330:  ##[error]  193:27  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
331:  ##[error]  202:11  error    'setEditingField' is assigned a value but never used                                                                    @typescript-eslint/no-unused-vars
332:  ##[error]  246:21  error    'version' is assigned a value but never used                                                                            @typescript-eslint/no-unused-vars
333:  ##[error]  246:30  error    'last_edited' is assigned a value but never used                                                                        @typescript-eslint/no-unused-vars
334:  ##[error]  246:43  error    'metadata' is assigned a value but never used                                                                           @typescript-eslint/no-unused-vars
335:  ##[error]  246:94  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
336:  ##[error]  247:31  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
337:  ##[error]  318:82  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
338:  ##[error]  431:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
339:  ##[error]  473:42  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
340:  ##[error]  504:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
341:  ##[error]  530:54  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
342:  ##[error]  557:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
343:  ##[warning]  568:6   warning  React Hook useEffect has a missing dependency: 'fetchVersionHistory'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
344:  ##[error]  593:9   error    'isOwner' is assigned a value but never used                                                                            @typescript-eslint/no-unused-vars
345:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/PatchSheetEditor.tsx
346:  ##[error]   73:48  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
347:  ##[error]   79:10  error  'shareLink' is assigned a value but never used        @typescript-eslint/no-unused-vars
348:  ##[error]   79:46  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
349:  ##[error]  195:30  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
350:  ##[error]  222:11  error  'setEditingField' is assigned a value but never used  @typescript-eslint/no-unused-vars
351:  ##[error]  324:26  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
352:  ##[error]  333:25  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
353:  ##[error]  400:26  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
354:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/ProductionScheduleEditor.tsx
355:  ##[error]    1:38  error    'useMemo' is defined but never used                                                                                             @typescript-eslint/no-unused-vars
356:  ##[warning]   66:14  warning  Fast refresh only works when a file only exports components. Use a new file to share constants or functions between components  react-refresh/only-export-components
357:  ##[error]  210:5   error    'broadcast' is assigned a value but never used                                                                                  @typescript-eslint/no-unused-vars
358:  ##[error]  221:28  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
359:  ##[error]  230:11  error    'setEditingField' is assigned a value but never used                                                                            @typescript-eslint/no-unused-vars
360:  ##[error]  262:21  error    'version' is assigned a value but never used                                                                                    @typescript-eslint/no-unused-vars
361:  ##[error]  262:30  error    'last_edited' is assigned a value but never used                                                                                @typescript-eslint/no-unused-vars
362:  ##[error]  262:43  error    'metadata' is assigned a value but never used                                                                                   @typescript-eslint/no-unused-vars
363:  ##[error]  262:94  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
364:  ##[error]  263:32  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
365:  ##[error]  368:90  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
366:  ##[error]  385:25  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
367:  ##[error]  441:88  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
368:  ##[warning]  465:6   warning  React Hook useEffect has a missing dependency: 'user'. Either include it or remove the dependency array                         react-hooks/exhaustive-deps
369:  ##[error]  621:33  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
370:  ##[error]  659:89  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
371:  ##[error]  674:21  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
372:  ##[error]  716:42  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
373:  ##[error]  747:21  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
374:  ##[error]  773:54  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
375:  ##[error]  800:21  error    Unexpected any. Specify a different type                                                                                        @typescript-eslint/no-explicit-any
376:  ##[warning]  811:6   warning  React Hook useEffect has a missing dependency: 'fetchVersionHistory'. Either include it or remove the dependency array          react-hooks/exhaustive-deps
377:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/RiderEditor.tsx
378:  ##[error]  139:5   error    'broadcast' is assigned a value but never used                                                                          @typescript-eslint/no-unused-vars
379:  ##[error]  150:25  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
380:  ##[error]  159:11  error    'setEditingField' is assigned a value but never used                                                                    @typescript-eslint/no-unused-vars
381:  ##[error]  188:21  error    'version' is assigned a value but never used                                                                            @typescript-eslint/no-unused-vars
382:  ##[error]  188:30  error    'last_edited' is assigned a value but never used                                                                        @typescript-eslint/no-unused-vars
383:  ##[error]  188:43  error    'metadata' is assigned a value but never used                                                                           @typescript-eslint/no-unused-vars
384:  ##[error]  188:94  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
385:  ##[error]  189:29  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
386:  ##[error]  299:25  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
387:  ##[warning]  375:6   warning  React Hook useEffect has a missing dependency: 'user'. Either include it or remove the dependency array                 react-hooks/exhaustive-deps
388:  ##[error]  432:33  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
389:  ##[error]  472:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
390:  ##[error]  514:42  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
391:  ##[error]  545:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
392:  ##[error]  571:54  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
393:  ##[error]  598:21  error    Unexpected any. Specify a different type                                                                                @typescript-eslint/no-explicit-any
394:  ##[warning]  609:6   warning  React Hook useEffect has a missing dependency: 'fetchVersionHistory'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
395:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/RunOfShowEditor.tsx
396:  ##[error]  31:10  error  'CollaborationToolbar' is defined but never used  @typescript-eslint/no-unused-vars
397:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/SharedPatchSheet.tsx
398:  ##[error]    5:3   error  'ArrowLeft' is defined but never used                   @typescript-eslint/no-unused-vars
399:  ##[error]    6:3   error  'Download' is defined but never used                    @typescript-eslint/no-unused-vars
400:  ##[error]   17:29  error  'updateSharedResource' is defined but never used        @typescript-eslint/no-unused-vars
401:  ##[error]   18:10  error  'supabase' is defined but never used                    @typescript-eslint/no-unused-vars
402:  ##[error]   46:9   error  'navigate' is assigned a value but never used           @typescript-eslint/no-unused-vars
403:  ##[error]   50:48  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
404:  ##[error]   51:46  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
405:  ##[error]   53:10  error  'downloadingSheet' is assigned a value but never used   @typescript-eslint/no-unused-vars
406:  ##[error]   72:30  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
407:  ##[error]  101:23  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
408:  ##[error]  112:9   error  'handleExportClick' is assigned a value but never used  @typescript-eslint/no-unused-vars
409:  ##[error]  218:59  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
410:  ##[error]  340:39  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
411:  ##[error]  342:27  error  'linkedChannel' is assigned a value but never used      @typescript-eslint/no-unused-vars
412:  ##[error]  466:41  error  Unexpected any. Specify a different type                @typescript-eslint/no-explicit-any
413:  ##[error]  468:27  error  'linkedChannel' is assigned a value but never used      @typescript-eslint/no-unused-vars
414:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/SharedShowModePage.tsx
415:  ##[error]  79:21  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
416:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/ShowModePage.tsx
417:  ##[error]   29:20  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
418:  ##[error]   71:40  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
419:  ##[error]  137:80  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
420:  ##[error]  159:21  error    Unexpected any. Specify a different type                                                                        @typescript-eslint/no-explicit-any
421:  ##[warning]  209:6   warning  React Hook useEffect has a missing dependency: 'itemTimerId'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
422:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/StagePlotEditor.tsx
423:  ##[error]  117:82  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
424:  ##[error]  132:46  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
425:  ##[error]  242:31  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
426:  ##[error]  254:31  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
427:  ##[error]  264:11  error    'setEditingField' is assigned a value but never used                                                           @typescript-eslint/no-unused-vars
428:  ##[error]  296:21  error    'version' is assigned a value but never used                                                                   @typescript-eslint/no-unused-vars
429:  ##[error]  296:30  error    'last_edited' is assigned a value but never used                                                               @typescript-eslint/no-unused-vars
430:  ##[error]  296:43  error    'metadata' is assigned a value but never used                                                                  @typescript-eslint/no-unused-vars
431:  ##[error]  296:94  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
432:  ##[error]  299:33  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
433:  ##[warning]  347:6   warning  React Hook useEffect has a missing dependency: 'handleSave'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
434:  ##[error]  354:56  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
435:  ##[error]  356:43  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
436:  ##[error]  405:18  error    'error' is defined but never used                                                                              @typescript-eslint/no-unused-vars
437:  ##[error]  405:25  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
438:  ##[error]  464:18  error    'error' is defined but never used                                                                              @typescript-eslint/no-unused-vars
439:  ##[error]  707:77  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
440:  ##[error]  738:47  error    'icon' is defined but never used                                                                               @typescript-eslint/no-unused-vars
441:  ##[error]  789:21  error    Unexpected any. Specify a different type                                                                       @typescript-eslint/no-explicit-any
442:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/StandardPixelMapEditor.tsx
443:  ##[error]   41:14  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
444:  ##[error]  130:5   error    'broadcast' is assigned a value but never used                                                           @typescript-eslint/no-unused-vars
445:  ##[error]  141:27  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
446:  ##[error]  146:11  error    'setEditingField' is assigned a value but never used                                                     @typescript-eslint/no-unused-vars
447:  ##[error]  178:21  error    'version' is assigned a value but never used                                                             @typescript-eslint/no-unused-vars
448:  ##[error]  178:30  error    'last_edited' is assigned a value but never used                                                         @typescript-eslint/no-unused-vars
449:  ##[error]  178:43  error    'metadata' is assigned a value but never used                                                            @typescript-eslint/no-unused-vars
450:  ##[error]  178:94  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
451:  ##[error]  179:31  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
452:  ##[error]  191:32  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
453:  ##[error]  310:25  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
454:  ##[warning]  391:6   warning  React Hook useEffect has a missing dependency: 'user'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
455:  ##[error]  420:22  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
456:  ##[error]  473:21  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
457:  ##[error]  518:18  error    'e' is defined but never used                                                                            @typescript-eslint/no-unused-vars
458:  ##[error]  534:19  error    Unexpected any. Specify a different type                                                                 @typescript-eslint/no-explicit-any
459:  ##[error]  696:25  error    'resolution' is defined but never used                                                                   @typescript-eslint/no-unused-vars
460:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/TheaterMicPlotEditor.tsx
461:  ##[error]    1:38  error  'useMemo' is defined but never used                   @typescript-eslint/no-unused-vars
462:  ##[error]   21:3   error  'verifyShareLink' is defined but never used           @typescript-eslint/no-unused-vars
463:  ##[error]  124:27  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
464:  ##[error]  129:11  error  'setEditingField' is assigned a value but never used  @typescript-eslint/no-unused-vars
465:  ##[error]  158:21  error  'version' is assigned a value but never used          @typescript-eslint/no-unused-vars
466:  ##[error]  158:30  error  'last_edited' is assigned a value but never used      @typescript-eslint/no-unused-vars
467:  ##[error]  158:43  error  'metadata' is assigned a value but never used         @typescript-eslint/no-unused-vars
468:  ##[error]  158:94  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
469:  ##[error]  159:31  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
470:  ##[error]  206:25  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
471:  ##[error]  316:74  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
472:  ##[error]  414:21  error  Unexpected any. Specify a different type              @typescript-eslint/no-explicit-any
473:  ##[error]  611:25  error  'resolution' is defined but never used                @typescript-eslint/no-unused-vars
474:  /home/runner/work/sounddocs/sounddocs/apps/web/src/pages/VideoCategoryPage.tsx
475:  ##[error]   17:3  error    'Clapperboard' is defined but never used                                                              @typescript-eslint/no-unused-vars
476:  ##[error]   19:3  error    'Minimize' is defined but never used                                                                  @typescript-eslint/no-unused-vars
477:  ##[warning]  131:6  warning  React Hook useMemo has a missing dependency: 'gcd'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
478:  /home/runner/work/sounddocs/sounddocs/apps/web/src/stores/collaborativeDocStore.ts
479:  ##[error]  37:32  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
480:  ##[error]  61:21  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
481:  /home/runner/work/sounddocs/sounddocs/apps/web/src/types/collaboration.ts
482:  ##[error]   43:39  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
483:  ##[error]   66:37  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
484:  ##[error]  120:39  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
485:  ##[error]  150:28  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
486:  ##[error]  261:24  error  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
487:  ✖ 213 problems (188 errors, 25 warnings)
488:  0 errors and 1 warning potentially fixable with the `--fix` option.
489:  ❌ ESLint found issues in changed files
490:  ##[error]Process completed with exit code 1.
491:  Post job cleanup.

@qodo-code-review
Copy link
Contributor

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: pr-checks-summary

Failed stage: Summary [❌]

Failure summary:

The action failed because the TypeScript checks step reported a failure, causing the overall status
to fail and the job to exit with code 1.
- TypeScript checks status: failure -> printed "❌
TypeScript checks: FAILED" (lines 31–38, 84)
- Python checks: No files changed (lines 44–54, 85)
-
SQL checks: PASSED (lines 57–65, 86)
- Overall gate detected a failure status and exited with code 1
(lines 71–77, 87–89)

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

22:  Secret source: Actions
23:  Prepare workflow directory
24:  Prepare all required actions
25:  Complete job name: pr-checks-summary
26:  ##[group]Run echo "## PR Checks Summary"
27:  �[36;1mecho "## PR Checks Summary"�[0m
28:  �[36;1mecho ""�[0m
29:  �[36;1m�[0m
30:  �[36;1m# Check TypeScript�[0m
31:  �[36;1mif [ "true" == "true" ]; then�[0m
32:  �[36;1m  if [ "failure" == "success" ]; then�[0m
33:  �[36;1m    echo "✅ TypeScript checks: PASSED"�[0m
34:  �[36;1m  elif [ "failure" == "skipped" ]; then�[0m
35:  �[36;1m    echo "⏭️  TypeScript checks: SKIPPED (no changes)"�[0m
36:  �[36;1m  else�[0m
37:  �[36;1m    echo "❌ TypeScript checks: FAILED"�[0m
38:  �[36;1m  fi�[0m
39:  �[36;1melse�[0m
40:  �[36;1m  echo "⏭️  TypeScript checks: No files changed"�[0m
41:  �[36;1mfi�[0m
42:  �[36;1m�[0m
43:  �[36;1m# Check Python�[0m
44:  �[36;1mif [ "false" == "true" ]; then�[0m
45:  �[36;1m  if [ "skipped" == "success" ]; then�[0m
46:  �[36;1m    echo "✅ Python checks: PASSED"�[0m
47:  �[36;1m  elif [ "skipped" == "skipped" ]; then�[0m
48:  �[36;1m    echo "⏭️  Python checks: SKIPPED (no changes)"�[0m
49:  �[36;1m  else�[0m
50:  �[36;1m    echo "❌ Python checks: FAILED"�[0m
51:  �[36;1m  fi�[0m
52:  �[36;1melse�[0m
53:  �[36;1m  echo "⏭️  Python checks: No files changed"�[0m
54:  �[36;1mfi�[0m
55:  �[36;1m�[0m
56:  �[36;1m# Check SQL�[0m
57:  �[36;1mif [ "true" == "true" ]; then�[0m
58:  �[36;1m  if [ "success" == "success" ]; then�[0m
59:  �[36;1m    echo "✅ SQL checks: PASSED"�[0m
60:  �[36;1m  elif [ "success" == "skipped" ]; then�[0m
61:  �[36;1m    echo "⏭️  SQL checks: SKIPPED (no changes)"�[0m
62:  �[36;1m  else�[0m
63:  �[36;1m    echo "❌ SQL checks: FAILED"�[0m
64:  �[36;1m  fi�[0m
65:  �[36;1melse�[0m
66:  �[36;1m  echo "⏭️  SQL checks: No files changed"�[0m
67:  �[36;1mfi�[0m
68:  �[36;1m�[0m
69:  �[36;1m# Overall status�[0m
70:  �[36;1mecho ""�[0m
71:  �[36;1mif [ "failure" == "failure" ] || \�[0m
72:  �[36;1m   [ "skipped" == "failure" ] || \�[0m
73:  �[36;1m   [ "success" == "failure" ]; then�[0m
74:  �[36;1m  echo "❌ **Overall Status: FAILED**"�[0m
75:  �[36;1m  echo "Please fix the issues above before merging."�[0m
76:  �[36;1m  exit 1�[0m
77:  �[36;1melse�[0m
78:  �[36;1m  echo "✅ **Overall Status: PASSED**"�[0m
79:  �[36;1m  echo "All checks on changed files have passed!"�[0m
80:  �[36;1mfi�[0m
81:  shell: /usr/bin/bash -e {0}
82:  ##[endgroup]
83:  ## PR Checks Summary
84:  ❌ TypeScript checks: FAILED
85:  ⏭️  Python checks: No files changed
86:  ✅ SQL checks: PASSED
87:  ❌ **Overall Status: FAILED**
88:  Please fix the issues above before merging.
89:  ##[error]Process completed with exit code 1.
90:  Cleaning up orphan processes

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 9, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
RLS bypass update

Description: The generic shared-resource update path allows updating arbitrary fields via an RPC
bypassing RLS using a share code, so improper server-side validation of allowed fields or
resource type could enable unauthorized or overbroad modifications if the RPC is
misconfigured.
shareUtils.ts [376-436]

Referred Code
try {
  if (!shareCode) throw new Error("Share code is required");

  // Map resource type to table name
  let tableName: string;
  switch (resourceType) {
    case "patch_sheet":
      tableName = "patch_sheets";
      break;
    case "stage_plot":
      tableName = "stage_plots";
      break;
    case "production_schedule":
      tableName = "production_schedules";
      break;
    case "run_of_show":
      tableName = "run_of_shows";
      break;
    case "corporate_mic_plot":
      tableName = "corporate_mic_plots";
      break;


 ... (clipped 40 lines)
Local data exposure

Description: Document updates including potentially sensitive data are stored in IndexedDB via
localforage without encryption or redaction, risking local data exposure on shared or
compromised devices.
offlineQueue.ts [29-56]

Referred Code
export const enqueueUpdate = async (update: DocumentUpdate): Promise<string> => {
  try {
    const queuedItem: QueuedSave = {
      id: crypto.randomUUID(),
      update,
      queuedAt: new Date().toISOString(),
      attempts: 0,
    };

    // Check queue size before adding
    const currentQueue = await getAllQueuedUpdates();
    if (currentQueue.length >= MAX_QUEUE_SIZE) {
      // Remove oldest items to make room
      const sorted = currentQueue.sort(
        (a, b) => new Date(a.queuedAt).getTime() - new Date(b.queuedAt).getTime(),
      );
      const toRemove = sorted.slice(0, currentQueue.length - MAX_QUEUE_SIZE + 1);
      await Promise.all(toRemove.map((item) => queueStore.removeItem(item.id)));
    }

    await queueStore.setItem(queuedItem.id, queuedItem);


 ... (clipped 7 lines)
Realtime data leakage

Description: Broadcast messages on Supabase Realtime are sent without payload size/shape validation or
redaction, which could leak sensitive field values to unauthorized subscribers if channel
naming or access is misconfigured.
collaboration.ts [55-86]

Referred Code
export const setupBroadcastChannel = async (
  channelName: string,
  onMessage: (payload: BroadcastPayload) => void,
): Promise<RealtimeChannel> => {
  const channel = supabase.channel(channelName, {
    config: {
      broadcast: {
        self: false, // Don't receive our own broadcasts
        ack: false, // Don't wait for acknowledgment
      },
    },
  });

  // Listen for broadcast events
  channel.on("broadcast", { event: "update" }, ({ payload }) => {
    console.log("[Collaboration] Received broadcast:", payload);
    onMessage(payload as BroadcastPayload);
  });

  // Subscribe to the channel
  await channel.subscribe((subscriptionStatus) => {


 ... (clipped 11 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Oct 9, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Unify state management for collaboration

Unify the two conflicting state management systems for collaboration—a Zustand
store and a set of decentralized hooks—into a single architecture. The
centralized Zustand store should be the single source of truth.

Examples:

apps/web/src/pages/SharedProductionSchedule.tsx [148-193]
  // Auto-save hook (only for edit mode)
  const {
    saveStatus,
    lastSavedAt,
    forceSave,
    error: autoSaveError,
  } = useAutoSave({
    documentId: schedule?.id || "",
    documentType: "production_schedules",
    userId: user?.id || "",

 ... (clipped 36 lines)
apps/web/src/stores/collaborativeDocStore.ts [75-526]
export const useCollaborativeDocStore = create<CollaborativeDocState>((set, get) => {
  // Debounced save function - created once and reused
  let debouncedSave: ReturnType<typeof debounce> | null = null;

  return {
    // Initial state
    channels: null,
    connectionStatus: "disconnected",
    connectionError: null,
    documentId: null,

 ... (clipped 442 lines)

Solution Walkthrough:

Before:

// In a component like `SharedProductionSchedule.tsx`

// Component manages its own state
const [schedule, setSchedule] = useState(null);
const { user } = useAuth();

// Decentralized hooks are fed component state
const { saveStatus, forceSave } = useAutoSave({
  documentId: schedule?.id,
  data: schedule,
  userId: user?.id,
  ...
});

const { activeUsers } = useCollaboration({
  documentId: schedule?.id,
  onRemoteUpdate: (payload) => {
    // Manually update component state from remote changes
    setSchedule(prev => ({ ...prev, [payload.field]: payload.value }));
  },
  ...
});

// The centralized `useCollaborativeDocStore` is not used here.

After:

// In a component like `SharedProductionSchedule.tsx`

// Get state and actions from the centralized Zustand store
const documentData = useCollaborativeDocStore((state) => state.documentData);
const setupCollaboration = useCollaborativeDocStore((state) => state.setupCollaboration);
const updateField = useCollaborativeDocStore((state) => state.updateField);
const { user } = useAuth();

useEffect(() => {
  // Initialize the store with the document
  setupCollaboration(documentId, documentType, user.id, ...);
}, [documentId]);

const handleFieldChange = (field, value) => {
  // All updates go through the store's action
  updateField(field, value, user.id);
};

// The component now reads from the store, and all logic is centralized.
// `useAutoSave` and `useCollaboration` hooks are removed from components.
Suggestion importance[1-10]: 10

__

Why: The suggestion correctly identifies a critical architectural flaw where two conflicting state management systems (Zustand store and a decentralized hook-based approach) are implemented, leading to redundancy and potential data synchronization issues.

High
Possible issue
Fix N+1 query performance issue

Refactor the user email fetching logic to avoid an N+1 query problem by batching
user profile lookups into a single database call.

apps/web/src/pages/SharedProductionSchedule.tsx [484-513]

-const versionsWithUsers = await Promise.all(
-  (data || []).map(async (version) => {
-    let userEmail = "Unknown User";
+const userIds = [...new Set((data || []).map((v) => v.created_by).filter(Boolean) as string[])];
+let userEmailMap: Record<string, string> = {};
 
-    if (version.created_by) {
-      try {
-        const { data: userData } = await supabase
-          .from("profiles")
-          .select("email")
-          .eq("id", version.created_by)
-          .single();
+if (userIds.length > 0) {
+  try {
+    const { data: usersData, error: usersError } = await supabase
+      .from("profiles")
+      .select("id, email")
+      .in("id", userIds);
 
-        if (userData?.email) {
-          userEmail = userData.email;
-        }
-      } catch (err) {
-        console.warn("Could not fetch user email:", err);
+    if (usersError) throw usersError;
+
+    userEmailMap = (usersData || []).reduce((acc, profile) => {
+      if (profile.id && profile.email) {
+        acc[profile.id] = profile.email;
       }
-    }
+      return acc;
+    }, {} as Record<string, string>);
+  } catch (err) {
+    console.warn("Could not fetch user emails:", err);
+  }
+}
 
-    return {
-      id: version.id,
-      version: version.version,
-      userEmail,
-      createdAt: version.created_at,
-      changedFields: version.changed_fields || [],
-      description: `${version.save_type} save`,
-    } as VersionHistory;
-  }),
-);
+const versionsWithUsers = (data || []).map((version) => {
+  const userEmail = version.created_by ? userEmailMap[version.created_by] || "Unknown User" : "Unknown User";
+  return {
+    id: version.id,
+    version: version.version,
+    userEmail,
+    createdAt: version.created_at,
+    changedFields: version.changed_fields || [],
+    description: `${version.save_type} save`,
+  } as VersionHistory;
+});
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies and provides a robust solution for an N+1 query problem, which is a significant performance optimization that improves scalability.

Medium
  • Update

Fixed critical issue where updating an item's start time or duration
would only recalculate the immediately following item's timing, not
all subsequent items. This left the schedule out of sync.

Root cause: `break` statement in calculateNextCueTime function was
stopping the cascade after updating first item.

Solution: Removed break statement and added cumulative time tracking
to properly cascade timing updates through all following items
(headers and cue items).

Changes:
- Modified calculateNextCueTime function (lines 590-634)
- Removed break statement after updating first following item
- Added cumulativeEndTimeSeconds tracking for proper cascade
- All subsequent items now update when any item timing changes

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

Co-Authored-By: Claude <noreply@anthropic.com>
@cj-vana cj-vana merged commit 297a8dc into beta Oct 9, 2025
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant