191 lines
8.9 KiB
Markdown
191 lines
8.9 KiB
Markdown
# COPILOT_README.md
|
|
|
|
This file provides guidance to Github Copilot 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 without overflow or rendering exceptions)
|
|
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 (M3 Expressive)
|
|
|
|
Strictly follow the Material 3 Expressive approach:
|
|
- **Base Theme**: `useMaterial3: true`. Seed color `#4A6FA5` drives the entire tonal palette via `ColorScheme.fromSeed`.
|
|
- **Cards & Surfaces**:
|
|
- Use **tonal elevation** (surface tint color overlays) instead of drop-shadows.
|
|
- Three M3 card variants: **Elevated** (tonal tint, minimal shadow), **Filled** (surfaceContainerHighest, no shadow), **Outlined** (outline border, transparent fill).
|
|
- Card token rules:
|
|
- Default `cardTheme.elevation`: 1 with transparent shadow (uses `surfaceTintColor` for tonal depth).
|
|
- `cardTheme.shape.borderRadius`: 16 dp.
|
|
- No hard borders unless using the Outlined variant (which uses `outlineVariant`).
|
|
- Status/summary cards use **Filled** variant with semantic container colors (`errorContainer`, `tertiaryContainer`, etc.).
|
|
- Use `M3Card.elevated()`, `M3Card.filled()`, or `M3Card.outlined()` from `lib/widgets/m3_card.dart` for new cards.
|
|
- **Corner Radii (M3 Expressive)**:
|
|
- Large containers / dialogs / bottom sheets: **28 dp**.
|
|
- Standard cards: **16 dp**.
|
|
- Compact list items: **12 dp**.
|
|
- Chips / badges: **12 dp**.
|
|
- **Buttons (M3 hierarchy)**:
|
|
- `FilledButton` — primary actions.
|
|
- `FilledButton.tonal` — secondary emphasis.
|
|
- `OutlinedButton` — tertiary / neutral actions.
|
|
- `TextButton` — low-emphasis / destructive cancel.
|
|
- Do **NOT** use `ElevatedButton` — use `FilledButton` instead.
|
|
- **Motion (M3 Expressive)**:
|
|
- Standard duration: 400 ms with `Curves.easeInOutCubicEmphasized`.
|
|
- Use `M3Motion` constants from `lib/theme/m3_motion.dart`.
|
|
- Container transitions: `AnimatedContainer` with M3 curves.
|
|
- Page transitions: shared-axis (vertical) using `M3SharedAxisRoute`.
|
|
- List item reveal: `M3FadeSlideIn` with staggered delays.
|
|
- **Typography**: Strict adherence to `TextTheme` variables (e.g., `titleLarge`, `bodyMedium`); **NO** hardcoded font sizes.
|
|
- **Navigation**:
|
|
- Mobile: `NavigationBar` (bottom) with pill-shaped indicators.
|
|
- Tablet: `NavigationRail` (collapsed) with tonal surface container.
|
|
- Desktop: `NavigationRail` (extended) with branding in the leading area.
|
|
|
|
### 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
|
|
|
|
**M3 Expressive Theme**: See `lib/theme/app_theme.dart`:
|
|
- Pure Material 3 Expressive — no M2 fallbacks
|
|
- Tonal elevation (surface tint) instead of drop-shadows
|
|
- 28 dp radius for large containers, 16 dp for cards
|
|
- See `lib/theme/m3_motion.dart` for animation constants
|
|
- See `lib/widgets/m3_card.dart` for M3 card variants
|
|
|
|
### 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**: Layout Smoke Test only, and do not create and run tests unless I say so.
|
|
- **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
|
|
```
|
|
|