# 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 — cards are the one M2 visual exception in our hybrid system. Use M3 for tokens, M2 for card elevation. - Card token rules (strict): - `cardTheme.elevation`: 3 (allowed range 2–4) - `cardTheme.shape.borderRadius`: 12–16 - `card border`: 1px `outlineVariant` to readably separate content - `shadowColor`: subtle black (light theme ~0.12, dark theme ~0.24) - Implementation rules: - Do **not** set `elevation: 0` on `Card` or other surfaced containers — rely on `CardTheme`. - Keep `useMaterial3: true` for ColorScheme, Typography, Navigation and Buttons; only the card elevation/shadows follow M2. - Prefer `Card` without local elevation overrides so the theme controls appearance across the app. - Acceptance criteria: - `lib/theme/app_theme.dart` sets `cardTheme.elevation` within 2–4 and borderRadius 12–16. - No source file should set `elevation: 0` on `Card` (exceptions must be documented with a code comment). - Add a widget test (`test/theme_overhaul_test.dart`) asserting card elevation and visual material elevation. - Purpose: Provide clear, elevated surfaces for lists/boards while keeping M3 tokens for color/typography. - **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>`) 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 ```