# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands

- **Run tests**: `flutter test`
- **Run static analysis**: `flutter analyze` (Must be clean before submission)
- **Format code**: `dart format lib/ test/`
- **Build Android APK**: `flutter build apk --release`
- **Build iOS**: `flutter build ios --release`
- **Build Windows**: `flutter build windows --release`

## Development Workflow

1. **Code**: Write feature with implementation in `lib/` and tests in `test/`
2. **Analyze**: `flutter analyze` (Must be clean)
3. **Test**: `flutter test` (Must pass)
4. **Verify**: Ensure UI matches the Hybrid M3/M2 guidelines

## Architecture Overview

**TasQ** is a Flutter task management application with Supabase backend. The architecture follows a clean separation:

```
State Management → Providers (Riverpod) → Repository/Service → Supabase
                              ↓
                          Widgets (UI)
```

### Core Stack

- **Framework**: Flutter with Material 3 (`useMaterial3: true`)
- **State Management**: Riverpod with `StreamProvider`, `StateNotifier`, and `FutureProvider`
- **Routing**: Go Router with auth-based redirects and ShellRoute for layout
- **Backend**: Supabase (PostgreSQL + Auth + Realtime)

### UI/UX Design System (Hybrid M3/M2)

Strictly follow this hybrid approach:
- **Base Theme**: `useMaterial3: true`. Use M3 for ColorScheme (`ColorScheme.fromSeed`), Typography, Navigation Bars, and Buttons.
- **Cards & Surfaces (The M2 Exception)**:
  - Do **NOT** use flat M3 cards.
  - **Use Material 2 style elevation**: Cards must have visible shadows (`elevation: 2` to `4`) and distinct borders/colors to separate them from the background.
  - Purpose: To create clear separation of content in lists and boards.
- **Typography**: Strict adherence to `TextTheme` variables (e.g., `titleLarge`, `bodyMedium`); **NO** hardcoded font sizes.

### Data Fetching & Search (Critical)

**Server-Side Pagination**:
- **ALWAYS** implement server-side pagination using Supabase `.range(start, end)`.
- Do **NOT** fetch all rows and filter locally.
- Standard page size: 50 items (Desktop), Infinite Scroll chunks (Mobile).

**Full Text Search (FTS)**:
- Use Supabase `.textSearch()` or `.ilike()` on the server side.
- Search state must be managed in a Riverpod provider (e.g., `searchQueryProvider`) and passed to the repository stream.

**Real-Time Data**:
- Use `StreamProvider` for live updates, but ensure streams respect current search/filter parameters.

### Data Flow Pattern

1. **Supabase Queries**: Server-side pagination and search via `.range()` and `.textSearch()`
2. **Providers** (`lib/providers/`) expose data via `StreamProvider` for real-time updates
3. **Providers** handle role-based data filtering (admin/dispatcher/it_staff have global access; standard users are filtered by office assignments)
4. **Widgets** consume providers using `ConsumerWidget` or `ConsumerStatefulWidget`
5. **Controllers** (`*Controller` classes) handle mutations (create/update/delete)

### Debugging & Troubleshooting Protocol

- **RLS vs. Logic**:
  - If data returns empty or incomplete, **DO NOT** assume it is a Row Level Security (RLS) issue immediately.
  - **Step 1**: Check the query logic, specifically `.range()` offsets and `.eq()` filters.
  - **Step 2**: Verify the user role and search term binding.
  - **Step 3**: Only check RLS if specific error codes (`401`, `403`, `PGRST`) are returned.

### Key Patterns

**Role-Based Access Control**: User roles (`admin`, `dispatcher`, `it_staff`, `standard`) determine data visibility and available UI sections. See `lib/routing/app_router.dart` for routing guards and `lib/providers/` for data filters.

**TasQAdaptiveList**:
  - **Mobile**: Tile-based list with infinite scroll listeners.
  - **Desktop**: Data Table with paginated footer.
  - **Input**: Requires a reactive data source (`Stream<List<T>>`) that responds to pagination/search providers.

**Responsive Design**:
- **Support**: Mobile (<600px), Tablet (600-1024px), Desktop (>1024px)
- **Implementation**: `LayoutBuilder` or `ResponsiveWrapper`
- **Mobile**: Single-column, Infinite Scroll, Bottom Navigation
- **Desktop**: Multi-column (Row/Grid), Pagination Controls, Sidebar Navigation

**Hybrid M3/M2 Theme**: See `lib/theme/app_theme.dart`:
- Use Material 3 for ColorScheme, Typography, Navigation Bars
- Use Material 2 elevation (shadows) for Cards to create visual separation

### Important Providers

| Provider | Purpose |
|----------|---------|
| `authStateChangesProvider` | Auth state stream |
| `sessionProvider` | Current session |
| `supabaseClientProvider` | Supabase client instance |
| `currentProfileProvider` | Current user's profile with role |
| `ticketsProvider` | User's accessible tickets (filtered by office) |
| `tasksProvider` | User's accessible tasks |

### Time Handling

All timestamps use `Asia/Manila` timezone via the `timezone` package. Use `AppTime.parse()` for parsing and `AppTime.format()` for display. See `lib/utils/app_time.dart`.

## UI Conventions

- **Zero Overflow Policy**: Wrap all text in `Flexible`/`Expanded` within `Row`/`Flex`. Use `SingleChildScrollView` for tall layouts.
- **Responsive Breakpoints**: Mobile (<600px), Tablet (600-1024px), Desktop (>1024px)
- **Mono Text**: Technical data uses `MonoText` widget (defined in `lib/theme/app_typography.dart`)
- **Status Pills**: Use `StatusPill` widget for status display

## Project Conventions

- **Testing**: Mandatory for all widgets/providers/repositories.
- **Mocking**: Use `mockito` for Supabase client mocking.
- **Documentation**: DartDoc (`///`) for public APIs. Explain *Why*, not just *How*.
- **Environment**: `.env` file manages `SUPABASE_URL` and `SUPABASE_ANON_KEY`.
- **Audio**: Notification sounds via `audioplayers`.
- **Key Files**:
  - `lib/app.dart`: App setup/theme.
  - `lib/routing/app_router.dart`: Routing & Auth guards.
  - `lib/providers/`: State management.

## Testing Strategy

- Tests located in `test/` directory
- Use Riverpod's `ProviderScope` with `overrideWith` for mocking
- Mock Supabase client using `SupabaseClient('http://localhost', 'test-key')`
- Layout tests use ` tester.pump()` with 16ms delay for animations

## Project Structure

```
lib/
├── app.dart                  # App entrypoint (theme/router)
├── main.dart                 # Widget initialization
├── models/                   # Data models (fromMap/toJson)
├── providers/                # Riverpod providers & controllers
├── routing/
│   └── app_router.dart       # Go Router config with auth guards
├── screens/                  # Screen widgets
│   ├── admin/               # Admin-only screens
│   ├── auth/                # Login/Signup
│   ├── dashboard/           # Dashboard
│   ├── notifications/       # Notification center
│   ├── tasks/               # Task management
│   ├── tickets/             # Ticket management
│   ├── teams/               # Team management
│   ├── workforce/           # Workforce management
│   └── shared/              # Shared components
├── theme/                    # AppTheme, typography
├── utils/                    # Utilities (AppTime)
└── widgets/                  # Reusable widgets
```

