tasq/.github/copilot-instructions.md

175 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 24)
- `cardTheme.shape.borderRadius`: 1216
- `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 24 and borderRadius 1216.
- 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<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
```