Files
blackcanyontickets/reactrebuild0825/TERRITORY_FILTERING.md
dzinesco aa81eb5adb feat: add advanced analytics and territory management system
- 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>
2025-08-26 09:25:10 -06:00

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

  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:

// 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 roles
  • territory-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

  1. Server-side Validation: All territory restrictions must be enforced on the backend
  2. Row Level Security: Database queries should include territory filtering at the RLS level
  3. Claims Validation: Territory assignments are stored in Firebase custom claims
  4. Data Isolation: Each territory's data is completely isolated from others

Performance Optimization

  1. Query Batching: Automatic handling of Firestore's 10-item in limit
  2. Memoization: Territory filtering logic is memoized to prevent unnecessary re-renders
  3. Lazy Loading: Territory data is loaded on-demand
  4. URL Persistence: Reduces unnecessary API calls by preserving filter state

Future Enhancements

  1. Hierarchical Territories: Support for territory hierarchies and inheritance
  2. Territory Permissions: Fine-grained permissions within territories
  3. Multi-organization Support: Territory filtering across multiple organizations
  4. Analytics Integration: Territory-based analytics and reporting

Migration Notes

When implementing this system:

  1. Update all existing queries to use territory-aware hooks
  2. Add territory banners to relevant pages
  3. Test role-based access thoroughly
  4. Ensure URL state persistence works correctly
  5. Validate query performance with large territory lists