tasq/GEMINI.md

163 lines
7.3 KiB
Markdown

# 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
```