# 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 1. **TerritoryFilter.tsx** - UI component for territory selection and display 2. **useTerritoryFilter.ts** - Hook for managing territory filter state with URL persistence 3. **useClaims.ts** - Hook for accessing user role and territory assignments 4. **Query hooks** - Territory-aware data fetching hooks ### Data Layer 1. **queries/events.ts** - Events filtering with territory restrictions 2. **queries/ticketTypes.ts** - Ticket types filtering with territory validation 3. **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: ```typescript // 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 ```tsx 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 (