fix: Update staff application to connect with data connect
This commit is contained in:
91
docs/ARCHITECTURE/web.md
Normal file
91
docs/ARCHITECTURE/web.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# KROW Web Application Architecture
|
||||
|
||||
## 1. Overview
|
||||
The KROW Web Application serves as the "Command Center" for the platform, catering to administrators, HR, finance, and client executives. It is a high-performance, scalable dashboard designed for complex data management and analytics.
|
||||
|
||||
## 2. Tech Stack
|
||||
- **Framework**: [React 19](https://react.dev/)
|
||||
- **Build Tool**: [Vite](https://vitejs.dev/)
|
||||
- **Styling**: [Tailwind CSS v4](https://tailwindcss.com/)
|
||||
- **State Management**: [Redux Toolkit](https://redux-toolkit.js.org/)
|
||||
- **Data Fetching**: [TanStack Query (React Query)](https://tanstack.com/query/latest)
|
||||
- **Backend Integration**: Firebase Data Connect + PostgreSQL
|
||||
- **Language**: TypeScript
|
||||
|
||||
## 3. Monorepo & Project Structure
|
||||
|
||||
### Recommendation: Skip Nx
|
||||
After evaluating `nx` for the KROW project, the recommendation is to **skip its adoption** at this stage.
|
||||
|
||||
**Reasoning:**
|
||||
- **Existing Orchestration**: The root `Makefile` and `Melos` (for mobile) already provide a robust orchestration layer. Adding `nx` would introduce redundant complexity.
|
||||
- **Heterogeneous Stack**: `nx` excels in JS/TS-heavy monorepos. Our project is a mix of Flutter (Dart) and React (TS), which reduces the native benefits of `nx`.
|
||||
- **Maintainability**: The overhead of learning and maintaining `nx` configurations outweighs the current benefits for a project of this scale.
|
||||
|
||||
### Future Alternative: Turborepo
|
||||
If caching and task orchestration become a bottleneck for the web/JS side, **Turborepo** is recommended as a lighter alternative that integrates seamlessly with our current `pnpm` setup.
|
||||
|
||||
### Final Project Structure (Unified)
|
||||
```
|
||||
/apps
|
||||
/web # React Web Dashboard
|
||||
/mobile # Flutter Mobile Apps (Melos monorepo)
|
||||
/packages
|
||||
/design-tokens # Shared Design System (TS/JSON)
|
||||
/backend
|
||||
/dataconnect # Shared GraphQL Schemas
|
||||
/docs
|
||||
/ARCHITECTURE # Architecture Documentation
|
||||
/Makefile # Unified Command Orchestrator
|
||||
```
|
||||
|
||||
## 4. Shared Design System
|
||||
|
||||
### Package: `@krow/design-tokens`
|
||||
A dedicated package at `/packages/design-tokens` serves as the single source of truth for design constants across all platforms.
|
||||
|
||||
**Folder Structure:**
|
||||
```
|
||||
/packages/design-tokens
|
||||
/src
|
||||
/colors.ts # Color palette definitions
|
||||
/typography.ts # Typography scale and font families
|
||||
/index.ts # Main export entry
|
||||
/package.json
|
||||
/tsconfig.json
|
||||
```
|
||||
|
||||
### Color Palette (Aligned with Mobile)
|
||||
Based on `UiColors` from the mobile app:
|
||||
- **Primary**: `#0A39DF` (Brand Blue)
|
||||
- **Accent**: `#F9E547` (Accent Yellow)
|
||||
- **Background**: `#FAFBFC`
|
||||
- **Foreground**: `#121826`
|
||||
- **Secondary**: `#F1F3F5`
|
||||
- **Muted**: `#F1F3F5`
|
||||
- **Destructive**: `#F04444` (Error Red)
|
||||
- **Success**: `#10B981` (Success Green)
|
||||
- **Border**: `#D1D5DB`
|
||||
|
||||
### Typography Scale (Aligned with Mobile)
|
||||
- **Primary Font**: Instrument Sans
|
||||
- **Secondary Font**: Space Grotesk
|
||||
- **Scales**:
|
||||
- **Display L**: 36px, Height 1.1
|
||||
- **Display M**: 32px, Height 1.1
|
||||
- **Title 1**: 18px, Height 1.5
|
||||
- **Body 1**: 16px, Height 1.5
|
||||
- **Body 2**: 14px, Height 1.5
|
||||
|
||||
### Implementation Strategy
|
||||
1. **Definition**: Define tokens in TypeScript (or JSON) within `/packages/design-tokens`.
|
||||
2. **Web Consumption**: Export tokens for use in `tailwind.config.ts` or as CSS variables.
|
||||
3. **Mobile Consumption**: Use a script to generate `ui_colors.dart` and `ui_typography.dart` from the shared tokens to ensure perfect alignment.
|
||||
|
||||
## 5. Web Application Organization
|
||||
The web application follows a **feature-based** modular architecture:
|
||||
- `src/features/`: Contains feature-specific logic, components, and hooks (e.g., `billing`, `scheduling`, `admin`).
|
||||
- `src/components/shared/`: Reusable UI components built with Tailwind.
|
||||
- `src/hooks/`: Shared React hooks.
|
||||
- `src/store/`: Redux slices for global state.
|
||||
- `src/dataconnect-generated/`: SDK generated by Firebase Data Connect.
|
||||
266
docs/api-contracts.md
Normal file
266
docs/api-contracts.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# KROW Workforce API Contracts
|
||||
|
||||
This document captures all API contracts used by the Staff and Client mobile applications. It serves as a single reference document to understand what each endpoint does, its expected inputs, returned outputs, and any non-obvious details.
|
||||
|
||||
---
|
||||
|
||||
## Staff Application
|
||||
|
||||
### Authentication / Onboarding Pages (Get Started, Intro, Phone Verification, Profile Setup, Personal Info)
|
||||
#### Setup / User Validation API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getUserById` |
|
||||
| **Purpose** | Retrieves the base user profile to determine authentication status and role access (e.g., if user is STAFF). |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `id: UUID!` (Firebase UID) |
|
||||
| **Outputs** | `User { id, email, phone, role }` |
|
||||
| **Notes** | Required after OTP verification to route users. |
|
||||
|
||||
#### Create Default User API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/createUser` |
|
||||
| **Purpose** | Inserts a base user record into the system during initial signup. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `id: UUID!`, `role: UserBaseRole` |
|
||||
| **Outputs** | `id` of newly created User |
|
||||
| **Notes** | Used explicitly during the "Sign Up" flow if the user doesn't exist. |
|
||||
|
||||
#### Get Staff Profile API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getStaffByUserId` |
|
||||
| **Purpose** | Finds the specific Staff record associated with the base user ID. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `userId: UUID!` |
|
||||
| **Outputs** | `Staffs { id, userId, fullName, email, phone, photoUrl, status }` |
|
||||
| **Notes** | Needed to verify if a complete staff profile exists before fully authenticating. |
|
||||
|
||||
#### Update Staff Profile API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/updateStaff` |
|
||||
| **Purpose** | Saves onboarding data across Personal Info, Experience, and Preferred Locations pages. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `id: UUID!`, `fullName`, `email`, `phone`, `addres`, etc. |
|
||||
| **Outputs** | `id` |
|
||||
| **Notes** | Called incrementally during profile setup wizard. |
|
||||
|
||||
### Home Page (worker_home_page.dart) & Benefits Overview
|
||||
#### Load Today/Tomorrow Shifts
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getApplicationsByStaffId` |
|
||||
| **Purpose** | Retrieves applications (shifts) assigned to the current staff member within a specific date range. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `staffId: UUID!`, `dayStart: Timestamp`, `dayEnd: Timestamp` |
|
||||
| **Outputs** | `Applications { shift, shiftRole, status, createdAt }` |
|
||||
| **Notes** | The frontend filters the query response for `CONFIRMED` applications to display "Today's" and "Tomorrow's" shifts. |
|
||||
|
||||
#### List Recommended Shifts
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listShifts` |
|
||||
| **Purpose** | Fetches open shifts that are available for the staff to apply to. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | None directly mapped, but filters OPEN shifts purely on the client side at the time. |
|
||||
| **Outputs** | `Shifts { id, title, orderId, cost, location, startTime, endTime, status }` |
|
||||
| **Notes** | Limits output to 10 on the frontend. Should ideally rely on a `$status: OPEN` parameter. |
|
||||
|
||||
#### Benefits Summary API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listBenefitsDataByStaffId` |
|
||||
| **Purpose** | Retrieves accrued benefits (e.g., Sick time, Vacation) to display on the home screen. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `staffId: UUID!` |
|
||||
| **Outputs** | `BenefitsDatas { vendorBenefitPlan { title, total }, current }` |
|
||||
| **Notes** | Calculates `usedHours = total - current`. |
|
||||
|
||||
### Find Shifts / Shift Details Pages (shifts_page.dart)
|
||||
#### List Available Shifts Filtered
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/filterShifts` |
|
||||
| **Purpose** | Used to fetch Open Shifts in specific regions when the worker searches in the "Find Shifts" tab. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `$status: ShiftStatus`, `$dateFrom: Timestamp`, `$dateTo: Timestamp` |
|
||||
| **Outputs** | `Shifts { id, title, location, cost, durationDays, order { business, vendor } }` |
|
||||
| **Notes** | - |
|
||||
|
||||
#### Get Shift Details
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getShiftById` |
|
||||
| **Purpose** | Gets deeper details for a single shift including exact uniform/managers needed. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `id: UUID!` |
|
||||
| **Outputs** | `Shift { id, title, hours, cost, locationAddress, workersNeeded ... }` |
|
||||
| **Notes** | - |
|
||||
|
||||
#### Apply To Shift
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/createApplication` |
|
||||
| **Purpose** | Worker submits an intent to take an open shift. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `shiftId`, `staffId`, `status: APPLIED` |
|
||||
| **Outputs** | `Application ID` |
|
||||
| **Notes** | A shift status will switch to `CONFIRMED` via admin approval. |
|
||||
|
||||
### Availability Page (availability_page.dart)
|
||||
#### Get Default Availability
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listStaffAvailabilitiesByStaffId` |
|
||||
| **Purpose** | Fetches the standard Mon-Sun recurring availability for a staff member. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `staffId: UUID!` |
|
||||
| **Outputs** | `StaffAvailabilities { dayOfWeek, isAvailable, startTime, endTime }` |
|
||||
| **Notes** | - |
|
||||
|
||||
#### Update Availability
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/updateStaffAvailability` (or `createStaffAvailability`) |
|
||||
| **Purpose** | Upserts availability preferences. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `staffId`, `dayOfWeek`, `isAvailable`, `startTime`, `endTime` |
|
||||
| **Outputs** | `id` |
|
||||
| **Notes** | Called individually per day edited. |
|
||||
|
||||
### Payments Page (payments_page.dart)
|
||||
#### Get Recent Payments
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listRecentPaymentsByStaffId` |
|
||||
| **Purpose** | Loads the history of earnings and timesheets completed by the staff. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `staffId: UUID!` |
|
||||
| **Outputs** | `Payments { amount, processDate, shiftId, status }` |
|
||||
| **Notes** | Displays historical metrics under Earnings tab. |
|
||||
|
||||
### Compliance / Profiles (Agreements, W4, I9, Documents)
|
||||
#### Get Tax Forms
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getTaxFormsByStaffId` |
|
||||
| **Purpose** | Check the filing status of I9 and W4 forms. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `staffId: UUID!` |
|
||||
| **Outputs** | `TaxForms { formType, isCompleted, updatedDate }` |
|
||||
| **Notes** | Required for staff to be eligible for shifts. |
|
||||
|
||||
#### Update Tax Forms
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/updateTaxForm` |
|
||||
| **Purpose** | Submits state and filing for the given tax form type. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `id`, `dataPoints...` |
|
||||
| **Outputs** | `id` |
|
||||
| **Notes** | Updates compliance state. |
|
||||
|
||||
---
|
||||
|
||||
## Client Application
|
||||
|
||||
### Authentication / Intro (Sign In, Get Started)
|
||||
#### Client User Validation API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getUserById` |
|
||||
| **Purpose** | Retrieves the base user profile to determine authentication status and role access (e.g., if user is BUSINESS). |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `id: UUID!` (Firebase UID) |
|
||||
| **Outputs** | `User { id, email, phone, userRole }` |
|
||||
| **Notes** | Must check if `userRole == BUSINESS` or `BOTH`. |
|
||||
|
||||
#### Get Business Profile API
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getBusinessByUserId` |
|
||||
| **Purpose** | Maps the authenticated user to their client business context. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `userId: UUID!` |
|
||||
| **Outputs** | `Business { id, businessName, email, contactName }` |
|
||||
| **Notes** | Used to set the working scopes (Business ID) across the entire app. |
|
||||
|
||||
### Hubs Page (client_hubs_page.dart, edit_hub.dart)
|
||||
#### List Hubs
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listTeamHubsByBusinessId` |
|
||||
| **Purpose** | Fetches the primary working sites (Hubs) for a client. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `businessId: UUID!` |
|
||||
| **Outputs** | `TeamHubs { id, hubName, address, contact, active }` |
|
||||
| **Notes** | - |
|
||||
|
||||
#### Update / Delete Hub
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/updateTeamHub` / `/deleteTeamHub` |
|
||||
| **Purpose** | Edits or archives a Hub location. |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `id: UUID!`, `hubName`, `address`, etc (for Update) |
|
||||
| **Outputs** | `id` |
|
||||
| **Notes** | - |
|
||||
|
||||
### Orders Page (create_order, view_orders)
|
||||
#### Create Order
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/createOrder` |
|
||||
| **Purpose** | The client submits a new request for temporary staff (can result in multiple Shifts generated on the backend). |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `businessId`, `eventName`, `orderType`, `status` |
|
||||
| **Outputs** | `id` (Order ID) |
|
||||
| **Notes** | This creates an order. Shift instances are subsequently created through secondary mutations. |
|
||||
|
||||
#### List Orders
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getOrdersByBusinessId` |
|
||||
| **Purpose** | Retrieves all ongoing and past staff requests from the client. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `businessId: UUID!` |
|
||||
| **Outputs** | `Orders { id, eventName, shiftCount, status }` |
|
||||
| **Notes** | - |
|
||||
|
||||
### Billing Pages (billing_page.dart, pending_invoices)
|
||||
#### List Invoices
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/listInvoicesByBusinessId` |
|
||||
| **Purpose** | Fetches "Pending", "Paid", and "Disputed" invoices for the client to review. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `businessId: UUID!` |
|
||||
| **Outputs** | `Invoices { id, amountDue, issueDate, status }` |
|
||||
| **Notes** | Used across all Billing view tabs. |
|
||||
|
||||
#### Mark Invoice
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/updateInvoice` |
|
||||
| **Purpose** | Marks an invoice as disputed or pays it (changes status). |
|
||||
| **Operation** | Mutation |
|
||||
| **Inputs** | `id: UUID!`, `status: InvoiceStatus` |
|
||||
| **Outputs** | `id` |
|
||||
| **Notes** | Disputing usually involves setting a memo or flag. |
|
||||
|
||||
### Reports Page (reports_page.dart)
|
||||
#### Get Coverage Stats
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| **Endpoint name** | `/getCoverageStatsByBusiness` |
|
||||
| **Purpose** | Provides data on fulfillments rates vs actual requests. |
|
||||
| **Operation** | Query |
|
||||
| **Inputs** | `businessId: UUID!` |
|
||||
| **Outputs** | `Stats { totalRequested, totalFilled, percentage }` |
|
||||
| **Notes** | Driven mostly by aggregated backend views. |
|
||||
|
||||
---
|
||||
|
||||
*This document reflects the current state of Data Connect definitions implemented across the frontend and mapped manually by reviewing Repository and UI logic.*
|
||||
Reference in New Issue
Block a user