- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
5.4 KiB
5.4 KiB
Territory Filtering System
This document describes the territory filtering system implemented for Black Canyon Tickets, which provides role-based access control at the territory level.
Overview
The territory filtering system ensures that users can only see and manage data within their assigned territories, while providing administrators with flexible filtering capabilities.
Components
Core Components
- TerritoryFilter.tsx - UI component for territory selection and display
- useTerritoryFilter.ts - Hook for managing territory filter state with URL persistence
- useClaims.ts - Hook for accessing user role and territory assignments
- Query hooks - Territory-aware data fetching hooks
Data Layer
- queries/events.ts - Events filtering with territory restrictions
- queries/ticketTypes.ts - Ticket types filtering with territory validation
- queries/tickets.ts - Tickets filtering with territory-based access
Role-based Access Control
Territory Manager
- Access: Limited to assigned territories only
- Filter Control: Cannot modify territory selection (read-only)
- Data Visibility: Only events, tickets, and ticket types in assigned territories
- UI Behavior: Shows badge indicating territory restriction
Organization Admin / Super Admin
- Access: Can view all territories in organization
- Filter Control: Full control over territory selection
- Data Visibility: All data by default, can filter by selected territories
- UI Behavior: Shows selectable multi-territory filter with URL persistence
Staff
- Access: Full access within organization (can be restricted in future)
- Filter Control: Full control over territory selection
- Data Visibility: All organization data, respects territory filters
Implementation Details
URL Persistence
- Territory filters persist in URL parameters (
?territories=AAA,BBB) - LocalStorage fallback for admin users
- Territory managers don't affect URL (their territories are fixed)
Query Batching
The applyTerritoryFilter utility handles Firestore's 10-item limit for in queries by automatically batching larger territory lists:
// Handles >10 territories by creating multiple query batches
const chunks = [];
for (let i = 0; i < territoryIds.length; i += 10) {
chunks.push(territoryIds.slice(i, i + 10));
}
Filter States
- isActive: Territory filter is currently applied
- isFiltered: Data is being filtered (either by role or by admin selection)
- canModifySelection: User can change territory selection
Usage Examples
EventsIndexPage
import { TerritoryFilter } from '../../features/territory/TerritoryFilter';
import { useTerritoryFilter } from '../../features/territory/useTerritoryFilter';
import { useEventsQuery } from '../../queries/events';
function EventsIndexPage() {
const { selectedTerritoryIds, setSelectedTerritories, canModifySelection } = useTerritoryFilter();
const { events, isFiltered } = useEventsQuery(selectedTerritoryIds);
return (
<div>
<TerritoryFilter
selectedTerritoryIds={selectedTerritoryIds}
onSelectionChange={setSelectedTerritories}
selectable={canModifySelection}
/>
{/* Event list filtered by territories */}
</div>
);
}
EventDetailPage
function EventDetailPage() {
const { selectedTerritoryIds, isActive, clearAll } = useTerritoryFilter();
return (
<div>
{/* Active filter banner */}
{isActive && (
<div className="filter-banner">
Filtered by: {territoryNames}
<button onClick={clearAll}>Clear</button>
</div>
)}
</div>
);
}
Testing
Unit Tests
TerritoryFilter.test.tsx- Component behavior for different rolesterritory-filtering.test.ts- Query filtering logic and access control
Test Coverage
- ✅ Territory manager sees only assigned events
- ✅ Admin can filter via territory selection
- ✅ URL state persistence works correctly
- ✅ Query batching handles >10 territories
- ✅ Role-based access matrix validation
- ✅ Error handling for missing claims
Security Considerations
- Server-side Validation: All territory restrictions must be enforced on the backend
- Row Level Security: Database queries should include territory filtering at the RLS level
- Claims Validation: Territory assignments are stored in Firebase custom claims
- Data Isolation: Each territory's data is completely isolated from others
Performance Optimization
- Query Batching: Automatic handling of Firestore's 10-item
inlimit - Memoization: Territory filtering logic is memoized to prevent unnecessary re-renders
- Lazy Loading: Territory data is loaded on-demand
- URL Persistence: Reduces unnecessary API calls by preserving filter state
Future Enhancements
- Hierarchical Territories: Support for territory hierarchies and inheritance
- Territory Permissions: Fine-grained permissions within territories
- Multi-organization Support: Territory filtering across multiple organizations
- Analytics Integration: Territory-based analytics and reporting
Migration Notes
When implementing this system:
- Update all existing queries to use territory-aware hooks
- Add territory banners to relevant pages
- Test role-based access thoroughly
- Ensure URL state persistence works correctly
- Validate query performance with large territory lists