Resolved README conflict

This commit is contained in:
2026-04-07 12:34:25 +05:30
2686 changed files with 311363 additions and 18 deletions

16
docs/00-vision.md Normal file
View File

@@ -0,0 +1,16 @@
# KROW Platform Vision
Our vision is to build a fully autonomous, modern, and scalable workforce management platform by leveraging a unified and productive tech stack.
## Core Objective
To achieve complete technical independence by consolidating the KROW platform (Web, Mobile Client, Mobile Staff) onto a single, robust, and maintainable ecosystem: **Firebase & Google Cloud**.
## Guiding Principles
1. **Velocity & Focus:** We will use tools that maximize the productivity of our small, focused development team. **Firebase Data Connect** and its generated SDKs are central to this principle.
2. **Unified Backend:** A single backend (Data Connect) will power all applications (Web, iOS, Android). This ensures data consistency, reduces code duplication, and simplifies maintenance.
3. **Scalability & Low Overhead:** We will rely on managed services (Cloud SQL, Firebase Auth, Firebase Hosting) to minimize operational burden and ensure high performance and reliability.
4. **Data Ownership & Future-Proofing:** We will have full control over our relational database (PostgreSQL). This is a strategic asset that will enable complex reporting and advanced features in the future.
5. **Base44 as a Design Accelerator:** We will treat the Base44 platform not as a system to migrate, but as an advanced visual prototyping tool. It defines the "what" (the UI/UX), and our team builds the "how" (the robust backend).
6. **Automation as a Force Multiplier:** We will automate all repetitive tasks (environment setup, deployment, testing) via a `Makefile` and CI/CD pipelines. This is crucial for our small team's efficiency and for reducing errors.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,101 @@
# Codemagic Environment Variables
This document outlines the environment variables required for the Codemagic CI/CD pipelines defined in `codemagic.yaml`. These variables should be configured in your Codemagic project under **Environment variables**.
## Client App (`client-app`)
---
### Group: `client_app_dev_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `dev` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:DEV_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Dev). |
| `FIREBASE_APP_ID_IOS` | `1:DEV_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Dev). |
| `FIREBASE_TESTER_GROUPS` | `developers` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Dev). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Dev). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `client_app_staging_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `staging` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:STAGING_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Staging). |
| `FIREBASE_APP_ID_IOS` | `1:STAGING_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Staging). |
| `FIREBASE_TESTER_GROUPS` | `qa-team, stakeholders` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Staging). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Staging). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `client_app_prod_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `prod` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:PROD_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Prod). |
| `FIREBASE_APP_ID_IOS` | `1:PROD_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Prod). |
| `FIREBASE_TESTER_GROUPS` | `(empty or specific group)` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Prod). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Prod). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
## Staff App (`staff-app`)
---
### Group: `staff_app_dev_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `dev` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:DEV_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Dev). |
| `FIREBASE_APP_ID_IOS` | `1:DEV_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Dev). |
| `FIREBASE_TESTER_GROUPS` | `developers` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Dev). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Dev). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `staff_app_staging_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `staging` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:STAGING_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Staging). |
| `FIREBASE_APP_ID_IOS` | `1:STAGING_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Staging). |
| `FIREBASE_TESTER_GROUPS` | `qa-team, stakeholders` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Staging). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Staging). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `staff_app_prod_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `prod` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:PROD_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Prod). |
| `FIREBASE_APP_ID_IOS` | `1:PROD_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Prod). |
| `FIREBASE_TESTER_GROUPS` | `(empty or specific group)` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Prod). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Prod). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |

92
docs/03-contributing.md Normal file
View File

@@ -0,0 +1,92 @@
# Contributing to KROW Workforce Platform
Welcome to the KROW Workforce development team! This guide will help you get set up and understand our development practices.
---
## 🚀 Getting Started & Setup Checklist
Follow these steps to set up your development environment and gain access to all necessary resources.
1. **Access Google Chat Space:**
* Ensure you have been invited to and joined our main Google Chat space for daily communication and quick questions.
2. **GitHub Access & SSH Key:**
* Confirm you have read/write access to this GitHub repository.
* Configure your SSH key for GitHub. Ensure your commits are verified (GPG signing is recommended).
3. **Install & Configure Gemini CLI:**
* Install the Gemini CLI on your local machine.
* Familiarize yourself with its usage for code assistance and documentation.
4. **Install & Configure Enpass:**
* Install Enpass (our team's shared password manager).
* Ensure you have access to the shared KROW vault for all project credentials (API keys, service accounts, etc.).
5. **Install Required Development Tools:**
Before running the project, ensure you have the following installed:
* **Node.js (v20+):** We recommend using **[nvm](https://github.com/nvm-sh/nvm)** (Node Version Manager) to install and manage Node versions.
* **pnpm:** Our preferred package manager for JavaScript projects. (`npm install -g pnpm`)
* **Flutter Version Management (FVM):** We use **[FVM](https://fvm.app/)** to manage Flutter SDK versions per project. Install it via Homebrew (`brew install fvm`) or Dart (`dart pub global activate fvm`).
* **Firebase CLI:** Required for emulation and deployment. (`npm install -g firebase-tools`)
* **Google Cloud CLI (gcloud):** Required for backend authentication and resource management.
**Recommended IDE:**
* **[Google Project IDX (Antigravity)](https://idx.google.com/)** or **VS Code**.
* **Essential Extensions:**
* Flutter & Dart
* Firebase
* Tailwind CSS IntelliSense
* ESLint & Prettier
**Diagramming:**
* Use **MermaidChart.com** for creating and editing diagrams (Mermaid syntax).
6. **Local Development Environment Setup:**
* Clone the monorepo: `git clone git@github.com:Oloodi/krow-workforce.git`
* Navigate to the project root: `cd krow-workforce`
* Install web frontend dependencies: `make install`
- **Install Git Hooks:**
- Run `make install-git-hooks` to set up local safeguards that prevent direct pushes to protected branches (`main` and `dev`). **This is a mandatory step.**
7. **Firebase Project Access Validation:**
* Confirm you have access to the `dev` Firebase/GCP project.
* Verify you can run `firebase login` and `gcloud auth login` successfully.
8. **Understand the Monorepo Structure:**
* Familiarize yourself with the project layout (`apps/`, `backend/`, `internal/`) as described in the main `README.md`.
---
## 💡 Development Guidelines
1. **Branching Strategy:**
* We adopt a **feature branch workflow**. All code modifications must be done on a new branch.
* The `main` and `dev` branches are protected.
2. **Commit Messages:**
* Use clear and descriptive commit messages (standardized via Open Commit if available).
3. **Code Standards:**
* Adhere to existing code style, formatting, and architectural patterns found in the codebase.
* Run linters and formatters before committing.
4. **Documentation:**
* Keep documentation up to date in the `docs/` directory.
5. **Diagrams:**
* All diagrams should be created using **Mermaid syntax** and stored in Markdown files.
---
## 🔗 Useful Links
- **KROW Internal Launchpad:** [https://launchpad.krowwithus.com](https://launchpad.krowwithus.com)
- **Project Onboarding (Start Here):** [docs/05-project-onboarding-master.md](./05-project-onboarding-master.md) - Comprehensive guide covering architecture, domain logic, feature gap analysis, and development strategy
- **Project Vision:** [docs/00-vision.md](./00-vision.md)
- **Backend Specification (Legacy Reference):** [docs/01-backend-api-specification.md](./01-backend-api-specification.md) - Historical API spec from Digital Ocean stack
- **Codemagic Env Vars:** [docs/02-codemagic-env-vars.md](./02-codemagic-env-vars.md)

View File

@@ -0,0 +1,58 @@
# Synchronization of Prototypes
This document explains how to synchronize visual prototypes and POCs (Proof of Concept) into this monorepo.
## Overview
Prototypes are developed in separate repositories (e.g., `client-krow-poc`). To keep this main repository clean and focused on production code, we do not commit the build artifacts of these prototypes. Instead, we use a synchronization script to bring them in locally.
**Key benefits:**
1. **AI Context:** Once synced, AI tools (like Gemini) can read the prototype code to understand the intended UI/UX and logic.
2. **Local Preview:** You can view the prototypes directly through the **DevOps Launchpad**.
3. **Local Deployment:** Allows you to deploy the latest prototypes to Firebase Hosting from your machine.
## Prerequisites
The synchronization script assumes that the prototype repository is cloned **adjacent** to this project directory.
```bash
# Navigate to your workspace root
cd ..
# Clone the POC repository
git clone git@github.com:Oloodi/client-krow-poc.git
```
Your folder structure should look like this:
```
/workspace
├── krow-workforce-web (This repo)
└── client-krow-poc (POC repo)
```
## How to Synchronize
Run the following command from the root of this repository:
```bash
make sync-prototypes
```
**What this command does:**
1. Navigates to the adjacent `client-krow-poc` repository.
2. Installs dependencies (via `pnpm`).
3. Builds the web application (`pnpm run build`).
4. Copies the resulting `dist/` folder into `internal/launchpad/prototypes/web/`.
## Git & AI Behavior
* **Git:** The contents of the `prototypes/` directories are defined in `.gitignore`. They will **not** be committed to this repository.
* **Gemini/AI:** These files are **not** ignored in `.geminiignore`. Once you run the sync script, the AI will be able to "see" the code and use it as a reference for your tasks.
## Deployment to Hosting
If you want to make these prototypes available on the live DevOps Launchpad (`launchpad.krowwithus.com`), you must:
1. Run `make sync-prototypes` on your local machine.
2. Run `make deploy-launchpad-hosting`.
---
*Note: As we add mobile prototypes (Flutter), this guide and the script will be updated to include the `flutter build web` steps.*

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,681 @@
# KROW Feature Roadmap & Tickets
> **Organization:** By priority (P0 → P1 → P2), then by domain
> **Source:** Analysis of prototypes in `internal/launchpad/prototypes-src/`
---
## Overview
```mermaid
flowchart LR
subgraph P0["P0: MVP Core (Sprint 3-4)"]
A[Auth] --> B[Staff Onboarding]
B --> C[Events/Orders]
C --> D[Shifts/Assignment]
D --> E[Clock In/Out]
E --> F[Timesheets]
F --> G[Invoices]
G --> H[Earnings View]
end
subgraph P1["P1: Enhanced (Sprint 5-6)"]
I[Smart Assignment]
J[Early Pay]
K[RAPID Orders]
L[Reports]
end
subgraph P2["P2: Full Vision (Sprint 7+)"]
M[KROW University]
N[Gamification]
O[Advanced Analytics]
end
P0 --> P1 --> P2
```
---
## Progression by App
### At the end of P0 (MVP), each app allows:
```mermaid
flowchart TB
subgraph WEB["WEB (Admin/Client)"]
W1[Email/Password Login]
W2[Role-based Dashboard]
W3[Manage Staff]
W4[Create Events/Orders]
W5[Assign Staff to Shifts]
W6[Approve Timesheets]
W7[Generate Invoices]
W8[View Basic Reports]
end
subgraph MC["MOBILE CLIENT"]
MC1[Email + Social Login]
MC2[Coverage Dashboard]
MC3[Create Orders]
MC4[View Active Shifts]
MC5[Manage Hubs]
MC6[View Billing]
MC7[Basic Reports]
end
subgraph MS["MOBILE STAFF"]
MS1[Phone + SMS OTP Login]
MS2[Complete Onboarding]
MS3[View Available Shifts]
MS4[Accept/Decline Shifts]
MS5[Swipe Clock In/Out]
MS6[View Earnings]
MS7[I-9/W-4 Forms]
MS8[Bank Account Setup]
end
```
---
# P0 - MUST HAVE (Sprint 3-4)
> **Goal:** End-to-end functional MVP
> **Total:** 52 tickets
---
## P0.1 - Authentication
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-AUTH-01 | Email/Password Login | Login form with email + password |
| P0-AUTH-02 | Password Reset | Send reset email, link, new password |
| P0-AUTH-03 | Role-Based Redirect | Admin → `/dashboard/admin`, Client → `/dashboard/client`, Vendor → `/dashboard/vendor` |
| P0-AUTH-04 | Session Persistence | Token persist, auto-refresh, logout |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-AUTH-05 | Get Started Screen | Welcome screen with Sign In / Sign Up options |
| P0-AUTH-06 | Email/Password Login | Form with email + password |
| P0-AUTH-07 | Social Login (Apple/Google) | Apple and Google sign-in buttons |
| P0-AUTH-08 | Client Registration | Business signup form |
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-AUTH-09 | Get Started Screen | Welcome screen "Work, Grow, Elevate" |
| P0-AUTH-10 | Phone Verification | US phone number input (+1) |
| P0-AUTH-11 | SMS OTP Code | Send and validate 6-digit code |
| P0-AUTH-12 | Login vs Signup Mode | Same flow, different destination |
---
## P0.2 - Staff Management
### MOBILE STAFF - Onboarding
| ID | Ticket | Description |
|----|--------|-------------|
| P0-STAFF-01 | Profile Setup Wizard | Screen after phone verification |
| P0-STAFF-02 | Personal Info Screen | Name, date of birth, address |
| P0-STAFF-03 | Emergency Contact | Emergency contact (name, relationship, phone) |
| P0-STAFF-04 | Experience Screen | Skills/experience selection |
| P0-STAFF-05 | Attire Screen | Uniform/outfit photo |
| P0-STAFF-06 | Bank Account Setup | Banking info for payment |
### WEB - Admin Staff Management
| ID | Ticket | Description |
|----|--------|-------------|
| P0-STAFF-07 | Staff List | List with search, filters (status, skills) |
| P0-STAFF-08 | Staff Detail View | Full profile, documents, history |
| P0-STAFF-09 | Add Staff (Admin) | Staff creation form |
| P0-STAFF-10 | Edit Staff | Modify staff info |
| P0-STAFF-11 | Staff Approval Queue | Approve/Reject new staff |
---
## P0.3 - Business & Hub Management
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-BIZ-01 | Client List | Business list with search/filter |
| P0-BIZ-02 | Add Client | Business creation form |
| P0-BIZ-03 | Edit Client | Modify business info |
| P0-BIZ-04 | Service Rates Config | Configure rates per position |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-BIZ-05 | Client Hubs Screen | Location list and management |
| P0-BIZ-06 | Client Settings | Business account settings |
---
## P0.4 - Event & Order Management
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-EVENT-01 | Order List (Admin) | All orders with filters |
| P0-EVENT-02 | Order List (Client) | Client's orders only |
| P0-EVENT-03 | Order List (Vendor) | Orders assigned to vendor |
| P0-EVENT-04 | Order Detail | Detailed view with shifts |
| P0-EVENT-05 | Edit Order | Modify event/shifts |
| P0-EVENT-06 | Schedule View | Event calendar |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-EVENT-07 | Create Order Screen | Order type selection |
| P0-EVENT-08 | One-Time Order Flow | Wizard for one-time event creation |
| P0-EVENT-09 | Client Shifts Screen | Client's shifts list |
| P0-EVENT-10 | Client Coverage Screen | Staffing coverage view |
---
## P0.5 - Shift & Assignment
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-SHIFT-01 | Staff Availability View | View staff availability |
| P0-SHIFT-02 | Manual Assignment | Assign staff to shift |
| P0-SHIFT-03 | Task Board | Task/assignment kanban |
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-SHIFT-04 | Shifts Screen (Tabs) | Available / My Shifts / History |
| P0-SHIFT-05 | Shift Details Screen | Details with location, hours, pay |
| P0-SHIFT-06 | Accept/Decline Shift | Actions on proposed shift |
| P0-SHIFT-07 | Jobs Screen | Explore all available jobs |
| P0-SHIFT-08 | Availability Screen | Configure availability |
---
## P0.6 - Time & Attendance
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-TIME-01 | Clock In Screen | Main clock-in screen |
| P0-TIME-02 | Swipe to Clock In | Swipe gesture to confirm |
| P0-TIME-03 | Swipe to Clock Out | Swipe gesture to end |
| P0-TIME-04 | GPS Location Capture | Record position at clock |
| P0-TIME-05 | Time Card Screen | Clock history |
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-TIME-06 | Timesheet Approval | Timesheet approval queue |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-TIME-07 | Client Timesheets | View timesheets for approval |
---
## P0.7 - Financial
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-FIN-01 | Invoice List | Invoice list with status |
| P0-FIN-02 | Invoice Detail | Detailed invoice view |
| P0-FIN-03 | Invoice Editor | Create/modify invoice |
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-FIN-04 | Payments Screen | Earnings dashboard |
| P0-FIN-05 | Earnings Screen | Earnings detail |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-FIN-06 | Client Billing Screen | Client billing view |
---
## P0.8 - Compliance & Documents
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-COMP-01 | Tax Forms Screen | Tax forms list |
| P0-COMP-02 | Form I-9 | I-9 employment eligibility form |
| P0-COMP-03 | Form W-4 | W-4 tax withholding form |
| P0-COMP-04 | Documents Screen | Upload/view documents |
| P0-COMP-05 | Certificates Screen | Manage certifications |
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-COMP-06 | Compliance Dashboard | Compliance view for all staff |
| P0-COMP-07 | Document Vault | Document storage |
---
## P0.9 - Dashboards & Navigation
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P0-DASH-01 | Admin Dashboard | Widgets: stats, alerts, actions |
| P0-DASH-02 | Client Dashboard | Widgets: coverage, orders, spend |
| P0-DASH-03 | Vendor Dashboard | Widgets: orders, staff, revenue |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P0-DASH-04 | Client Home Screen | Mobile main dashboard |
| P0-DASH-05 | Bottom Navigation | Coverage, Billing, Home, Shifts, Reports |
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P0-DASH-06 | Worker Home Screen | Staff main dashboard |
| P0-DASH-07 | Bottom Navigation | Shifts, Payments, Home, Clock-In, Profile |
| P0-DASH-08 | Worker Profile Screen | Settings and features menu |
---
## Complete P0 Workflow
```mermaid
sequenceDiagram
participant Staff as Mobile Staff
participant Client as Mobile Client
participant Admin as Web Admin
Note over Staff,Admin: 1. SETUP
Staff->>Staff: Phone + OTP Login
Staff->>Staff: Complete Onboarding
Staff->>Staff: Submit I-9, W-4
Admin->>Admin: Approve Staff
Note over Staff,Admin: 2. ORDER
Client->>Client: Email Login
Client->>Client: Create Order (One-Time)
Admin->>Admin: View Order
Note over Staff,Admin: 3. ASSIGNMENT
Admin->>Admin: Assign Staff to Shift
Staff->>Staff: View Shift Offer
Staff->>Staff: Accept Shift
Note over Staff,Admin: 4. WORK
Staff->>Staff: Swipe Clock In (GPS)
Staff->>Staff: Swipe Clock Out
Note over Staff,Admin: 5. PAYMENT
Client->>Client: Approve Timesheet
Admin->>Admin: Generate Invoice
Client->>Client: View Invoice
Staff->>Staff: View Earnings
```
---
# P1 - SHOULD HAVE (Sprint 5-6)
> **Goal:** Differentiating features
> **Total:** 38 tickets
---
## P1.1 - Smart Features
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P1-SMART-01 | Smart Assignment Engine | Auto-match staff based on skills, availability, proximity |
| P1-SMART-02 | Conflict Detection | Detect double-booking |
| P1-SMART-03 | Overtime Calculator | OT/DT calculation with California rules |
| P1-SMART-04 | Savings Engine | Potential savings analysis |
---
## P1.2 - Advanced Orders
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P1-ORDER-01 | RAPID Order Flow | Quick simplified order creation |
| P1-ORDER-02 | Recurring Order Flow | Recurring orders (weekly, monthly) |
| P1-ORDER-03 | Permanent Order Flow | Permanent placements |
| P1-ORDER-04 | Verify Worker Attire | Staff attire verification |
---
## P1.3 - Early Pay
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P1-PAY-01 | Early Pay Screen | Access earnings before payday |
| P1-PAY-02 | Early Pay Request | Request early payment (5% fee) |
| P1-PAY-03 | Instant Transfer | Transfer to bank account |
| P1-PAY-04 | Benefits Screen | Available benefits view |
---
## P1.4 - Reports
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P1-REPORT-01 | Client Reports Screen | Reports hub |
| P1-REPORT-02 | Daily Ops Report | Daily operations report |
| P1-REPORT-03 | Spend Report | Spending analysis |
| P1-REPORT-04 | Forecast Report | Needs forecast |
| P1-REPORT-05 | Performance Report | Staff performance |
| P1-REPORT-06 | No-Show Report | Absence report |
| P1-REPORT-07 | Coverage Report | Coverage report |
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P1-REPORT-08 | Reports Dashboard | Admin reports center |
| P1-REPORT-09 | Activity Log | System activity log |
| P1-REPORT-10 | Vendor Performance | Vendor performance |
---
## P1.5 - Communication
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P1-COMM-01 | Message Center | Internal messaging |
| P1-COMM-02 | Tutorial List | Training videos/guides |
| P1-COMM-03 | Support Center | Help center |
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P1-COMM-04 | Messages Screen | Staff messaging |
| P1-COMM-05 | FAQs Screen | Frequently asked questions |
| P1-COMM-06 | Privacy Screen | Privacy settings |
---
## P1.6 - Teams & Workers
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P1-TEAM-01 | Team List | Team list |
| P1-TEAM-02 | Create Team | Create team |
| P1-TEAM-03 | Team Detail | Team details |
| P1-TEAM-04 | Staff Onboarding Flow | Web onboarding wizard |
### MOBILE CLIENT
| ID | Ticket | Description |
|----|--------|-------------|
| P1-TEAM-05 | Client Workers Screen | View assigned staff |
---
## P1.7 - Marketplace
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P1-MKT-01 | Vendor Marketplace | Discover vendors |
| P1-MKT-02 | Compare Rates | Compare rates |
---
## P1 Added Workflow
```mermaid
flowchart TB
subgraph SMART["Smart Features"]
A[Client creates Order] --> B{Smart Engine}
B --> C[Auto-suggest Staff]
C --> D[Check Conflicts]
D --> E[Calculate OT Impact]
E --> F[Assign Optimal Staff]
end
subgraph EARLYPAY["Early Pay"]
G[Staff completes Shift]
G --> H[Earnings Available]
H --> I[Request Early Pay]
I --> J[5% Fee Applied]
J --> K[Instant Bank Transfer]
end
subgraph RAPID["RAPID Orders"]
L[Client opens RAPID]
L --> M[Quick Selection]
M --> N[Minimal Fields]
N --> O[Instant Submit]
end
```
---
# P2 - NICE TO HAVE (Sprint 7+)
> **Goal:** Complete prototype vision
> **Total:** 28 tickets
---
## P2.1 - KROW University
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P2-UNI-01 | KROW University Screen | Training hub |
| P2-UNI-02 | Trainings Screen | Available courses list |
| P2-UNI-03 | Course Enrollment | Enroll in a course |
| P2-UNI-04 | Video Lessons | Video playback |
| P2-UNI-05 | Quizzes | Knowledge tests |
| P2-UNI-06 | Certificates Earned | Earned badges/certs |
---
## P2.2 - Gamification
### MOBILE STAFF
| ID | Ticket | Description |
|----|--------|-------------|
| P2-GAME-01 | Leaderboard Screen | Staff ranking |
| P2-GAME-02 | XP System | Experience points |
| P2-GAME-03 | Badges | Achievement badges |
| P2-GAME-04 | Level Progression | Level progression |
| P2-GAME-05 | Referral Program | Referral program |
---
## P2.3 - Advanced Scheduling
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P2-SCHED-01 | Drag-Drop Scheduler | Drag-and-drop planning |
| P2-SCHED-02 | Automation Engine | Automation rules |
| P2-SCHED-03 | Double-Booking Override | Exception handling |
| P2-SCHED-04 | Cancellation Fee Modal | Cancellation fee management |
---
## P2.4 - Advanced Finance
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P2-FIN-01 | Auto Invoice Generator | Auto invoice generation |
| P2-FIN-02 | Invoice Export Panel | Multi-format export |
| P2-FIN-03 | Invoice Quick Actions | Quick actions |
---
## P2.5 - Advanced Analytics
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P2-ANAL-01 | Staffing Cost Report | Staffing cost analysis |
| P2-ANAL-02 | Staff Performance Report | Individual performance |
| P2-ANAL-03 | Operational Efficiency | Operational efficiency |
| P2-ANAL-04 | Report Template Library | Template library |
| P2-ANAL-05 | Scheduled Reports | Scheduled reports |
| P2-ANAL-06 | Report PDF Preview | PDF preview |
| P2-ANAL-07 | Report Insights Banner | Automatic insights |
---
## P2.6 - Advanced Client Features
### WEB
| ID | Ticket | Description |
|----|--------|-------------|
| P2-CLI-01 | Client Loyalty Card | Loyalty program |
| P2-CLI-02 | Client Vendor Preferences | Vendor preferences |
| P2-CLI-03 | Dashboard Customizer | Dashboard customization |
---
## Complete P2 Workflow
```mermaid
flowchart TB
subgraph UNI["KROW University"]
U1[Staff opens University] --> U2[Browse Courses]
U2 --> U3[Enroll in Course]
U3 --> U4[Watch Videos]
U4 --> U5[Pass Quiz]
U5 --> U6[Earn Certificate]
U6 --> U7[+XP Points]
end
subgraph GAME["Gamification"]
G1[Complete Shifts] --> G2[Earn XP]
G2 --> G3[Level Up]
G3 --> G4[Unlock Badges]
G4 --> G5[Climb Leaderboard]
G5 --> G6[Better Shift Priority]
end
subgraph AUTO["Advanced Automation"]
A1[New Order Created]
A1 --> A2[Automation Rules Check]
A2 --> A3[Auto-Assign Preferred Staff]
A3 --> A4[Auto-Generate Invoice]
A4 --> A5[Auto-Send Reports]
end
```
---
# Completion Checklist
## When P0 is done:
- [ ] **Auth works** for all 3 apps (phone OTP for staff, email for client/web)
- [ ] **Staff can fully onboard** via mobile
- [ ] **Client can create** one-time orders
- [ ] **Admin can assign** staff to shifts
- [ ] **Staff can clock in/out** with swipe + GPS
- [ ] **Timesheets are approved** by client
- [ ] **Invoices are generated** and visible
- [ ] **Staff can view earnings**
- [ ] **I-9/W-4 forms** work
**= MVP ACHIEVED**
---
## When P1 is done:
- [ ] **Smart Assignment** automatically suggests best staff
- [ ] **Conflict detection** prevents double-bookings
- [ ] **Early Pay** allows staff to access earnings
- [ ] **RAPID orders** speeds up creation
- [ ] **Recurring orders** handles repetitive needs
- [ ] **Full reports** give clients visibility
- [ ] **Messaging** enables direct communication
**= ENHANCED MVP**
---
## When P2 is done:
- [ ] **KROW University** trains staff
- [ ] **Gamification** motivates via XP and leaderboard
- [ ] **Advanced scheduling** optimizes planning
- [ ] **Auto-invoicing** reduces manual work
- [ ] **Advanced analytics** provide business insights
**= FULL PROTOTYPE VISION ACHIEVED**
---
# Summary
| Priority | Sprints | Tickets |
|----------|---------|---------|
| **P0** | 3-4 | **52** |
| **P1** | 5-6 | **38** |
| **P2** | 7+ | **28** |
| **TOTAL** | - | **118** |
### By App
| App | P0 | P1 | P2 | Total |
|-----|----|----|-----|-------|
| Web | 22 | 16 | 14 | 52 |
| Mobile Client | 12 | 12 | 3 | 27 |
| Mobile Staff | 18 | 10 | 11 | 39 |
---
**Document Created:** January 2026
**Source:** Analysis of `internal/launchpad/prototypes-src/`

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
# KROW Platform: System Architecture Overview
## 1. Executive Summary: The Business Purpose
The **KROW Platform** is an end-to-end workforce management ecosystem designed to bridge the gap between businesses that need staff ("Clients") and the temporary workers who fill those roles ("Staff").
Traditionally, this process involves phone calls, paper timesheets, and manual payroll. KROW digitizes the entire lifecycle:
1. **Finding Work:** Clients post shifts instantly; workers claim them via mobile.
2. **Doing Work:** GPS-verified clock-ins and digital timesheets ensure accuracy.
3. **Managing Business:** A web dashboard provides analytics, billing, and compliance oversight.
The system's goal is to reduce administrative friction, ensure legal compliance, and optimize labor costs through automation and real-time data.
## 2. The Application Ecosystem
The platform consists of three distinct applications, each tailored to a specific user group:
### A. Client Mobile App (The "Requester")
* **User:** Business Owners, Venue Managers.
* **Role:** The demand generator. It allows clients to request staff on the fly, track who is arriving, and approve hours worked.
* **Key Value:** Speed and visibility. A manager can fill a sudden "no-show" gap in seconds from their phone.
### B. Staff Mobile App (The "Worker")
* **User:** Temporary Staff (Servers, Cooks, Bartenders).
* **Role:** The supply pool. It acts as their personal agency, handling job discovery, schedule management, and instant payouts.
* **Key Value:** Flexibility and financial security. Workers choose when they work and get paid faster.
### C. KROW Web Application (The "HQ")
* **User:** Administrators, HR, Finance, and Client Executives.
* **Role:** The command center. It handles the heavy lifting—complex invoicing, vendor management, compliance audits, and strategic data analysis.
* **Key Value:** Control and insight. It turns operational data into cost-saving strategies.
## 3. How the Applications Interact
The three applications do not "talk" directly to each other (e.g., the staff app doesn't send a message directly to the client app). Instead, they all communicate with a central **Shared Backend System** (The "Brain").
* **Scenario: Filling a Shift**
1. **Client App:** Manager posts a shift for "Friday, 6 PM".
2. **Backend:** Receives the request, validates it, and notifies eligible workers.
3. **Staff App:** Worker sees the notification and taps "Accept".
4. **Backend:** Confirms the match, updates the schedule, and alerts the client.
5. **Web App:** Admin sees the shift status change from "Open" to "Filled" on the live dashboard.
## 4. Shared Services & Infrastructure
To function as a cohesive unit, the ecosystem relies on several shared foundational services:
* **Central Database:** The "Single Source of Truth." Whether a worker updates their profile photo on mobile or an admin updates it on the web, the change is saved in one place (Firebase/Firestore) and reflects everywhere instantly.
* **Authentication Service:** A unified login system. While users have different roles (Client vs. Staff), the security mechanism verifying their identity is shared.
* **Notification Engine:** A centralized service that knows how to reach users—sending push notifications to phones (Mobile Apps) and emails to desktops (Web App).
* **Payment Gateway:** A shared financial pipe. It collects money from clients (Credit Card/ACH) and disburses it to workers (Direct Deposit/Instant Pay).
## 5. Data Ownership & Boundaries
To maintain privacy and organization, data is strictly compartmentalized:
* **Worker Data:** Owned by the worker but accessible to the platform. Clients can only see limited details (Name, Rating, Skills) of workers assigned to *their* specific shifts. They cannot see a worker's full financial history or assignments with other clients.
* **Client Data:** Owned by the business. Workers see only what is necessary to do the job (Location, Dress Code, Supervisor Name). They cannot see the client's internal billing or strategic reports.
* **Platform Data:** owned by KROW (Admins). This includes the aggregate data used for "Smart Strategies" and market analysis—e.g., "Average hourly rate for a Bartender in downtown."
## 6. Security & Access Control
The system operates on a **Role-Based Access Control (RBAC)** model:
* **Authentication (Who are you?):** Strict verification using email/password or phone/OTP (One-Time Password).
* **Authorization (What can you do?):**
* **Staff:** Can *read* job details but *write* only to their own timesheets and profile.
* **Clients:** Can *write* new orders and *read* reports for their own venues only.
* **Admins:** Have "Super User" privileges to view and modify data across the entire system to resolve disputes or manage configurations.
## 7. Inter-Application Dependencies
While the apps are installed separately, they are operationally dependent:
* **Dependency A:** The **Client App** cannot function without the **Staff App** users. An order posted by a client is useless if no workers exist to claim it.
* **Dependency B:** The **Staff App** relies on the **Web App** for financial processing. A worker can "clock out," but they don't get paid until the backend logic (managed via Web App rules) processes the invoice.
* **Dependency C:** All apps depend on the **Backend API**. If the central server goes down, no app can fetch data, effectively pausing the entire operation.
---
# System Overview Diagram
```mermaid
flowchart LR
subgraph Users [Users]
ClientUser((Client Manager))
StaffUser((Temporary Worker))
AdminUser((Admin / Ops))
end
subgraph FrontEnd [Application Ecosystem]
direction TB
ClientApp[Client Mobile App]
StaffApp[Staff Mobile App]
WebApp[Web Management Console]
end
subgraph Backend [Shared Backend Services]
direction TB
APIGateway[API Gateway]
subgraph CoreServices [Core Business Logic]
AuthService[Authentication Service]
OrderService[Order & Shift Service]
WorkerService[Worker Profile Service]
FinanceService[Billing & Payroll Service]
NotificationEngine[Notification Engine]
AnalyticsEngine[Analytics & AI Engine]
end
Database[("Central Database (Firebase/Firestore)")]
end
subgraph External [External Integrations]
PaymentProvider["Payment Gateway (Stripe/Bank)"]
MapService[Maps & Geolocation]
SMSGateway[SMS / OTP Service]
end
%% User Interactions
ClientUser -- Uses --> ClientApp
StaffUser -- Uses --> StaffApp
AdminUser -- Uses --> WebApp
%% App to Backend Communication
ClientApp -- "Auth, Orders, Timesheets" --> APIGateway
StaffApp -- "Auth, Job Claims, Clock-In" --> APIGateway
WebApp -- "Auth, Admin, Reports" --> APIGateway
%% Internal Backend Flow
APIGateway --> CoreServices
CoreServices --> Database
%% Specific Service Interactions
AuthService -- "Verifies Identity" --> Database
OrderService -- "Matches Shifts" --> Database
WorkerService -- "Stores Profiles" --> Database
FinanceService -- "Processes Invoices" --> Database
AnalyticsEngine -- "Reads Data" --> Database
%% External Connections
AuthService -- "Sends OTP" --> SMSGateway
StaffApp -- "Verifies Location" --> MapService
FinanceService -- "Processes Payouts" --> PaymentProvider
NotificationEngine -- "Push Alerts" --> ClientApp
NotificationEngine -- "Push Alerts" --> StaffApp
%% Styling
classDef user fill:#e1f5fe,stroke:#01579b,stroke-width:2px;
classDef app fill:#fff9c4,stroke:#fbc02d,stroke-width:2px;
classDef backend fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
classDef external fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px;
classDef db fill:#e0e0e0,stroke:#616161,stroke-width:2px;
class ClientUser,StaffUser,AdminUser user;
class ClientApp,StaffApp,WebApp app;
class APIGateway,AuthService,OrderService,WorkerService,FinanceService,NotificationEngine,AnalyticsEngine backend;
class PaymentProvider,MapService,SMSGateway external;
class Database db;
```

View File

@@ -0,0 +1,209 @@
# Client Application: Use Case Overview
This document details the primary business actions and user flows within the **Client Mobile Application**. It is organized according to the application's logical structure and navigation flow.
---
## 1. Application Access & Authentication
### 1.1 Initial Startup & Auth Check
* **Actor:** Business Manager
* **Description:** The system determines if the user is already logged in or needs to authenticate.
* **Main Flow:**
1. User opens the application.
2. System checks for a valid session.
3. If authenticated, user is directed to the **Home Dashboard**.
4. If unauthenticated, user is directed to the **Get Started** screen.
### 1.2 Register Business Account (Sign Up)
* **Actor:** New Business Manager
* **Description:** Creating a new identity for the business on the KROW platform.
* **Main Flow:**
1. User taps "Sign Up".
2. User enters company details (Name, Industry).
3. User enters contact information and password.
4. User confirms registration and is directed to the Main App.
### 1.3 Business Sign In
* **Actor:** Existing Business Manager
* **Description:** Accessing an existing account.
* **Main Flow:**
1. User enters registered email and password.
2. System validates credentials.
3. User is granted access to the dashboard.
---
## 2. Order Management (Requesting Staff)
### 2.1 Rapid Order (Urgent Needs)
* **Actor:** Business Manager
* **Description:** Posting a shift for immediate, same-day fulfillment.
* **Main Flow:** Taps "RAPID" -> Selects Role -> Sets Quantity -> Confirms ASAP status -> Posts Order.
### 2.2 Scheduled Orders (Planned Needs)
* **Actor:** Business Manager
* **Description:** Planning for future staffing requirements.
* **Main Flow:**
1. User selects "Create Order".
2. User chooses the frequency:
* **One-Time:** A single specific shift.
* **Recurring:** Shifts that repeat on a schedule (e.g., every Monday).
* **Permanent:** Long-term staffing placement.
3. User enters date, time, role, and location.
4. User reviews cost and posts the order.
---
## 3. Operations & Workforce Management
### 3.1 Monitor Today's Coverage (Coverage Tab)
* **Actor:** Business Manager
* **Description:** A bird's-eye view of all shifts happening today.
* **Main Flow:** User navigates to "Coverage" tab -> Views percentage filled -> Identifies open gaps -> Re-posts unfilled shifts if necessary.
### 3.2 Live Activity Tracking
* **Actor:** Business Manager
* **Description:** Real-time feed of worker clock-ins and status updates.
* **Location:** Home Tab / Coverage Detail.
* **Main Flow:** User monitors the live feed for worker arrivals and on-site status.
### 3.3 Verify Worker Attire
* **Actor:** Business Manager / Site Supervisor
* **Description:** Ensuring staff arriving on-site meet the required dress code.
* **Main Flow:** User selects an active shift -> Selects worker -> Checks attire compliance (shoes, uniform, ID) -> Submits verification.
### 3.4 Review & Approve Timesheets
* **Actor:** Business Manager
* **Description:** Finalizing hours worked for payroll processing.
* **Main Flow:** User navigates to "Timesheets" -> Reviews actual vs. scheduled hours -> Taps "Approve" or "Dispute".
---
## 4. Reports & Analytics
### 4.1 Business Intelligence Reporting
* **Actor:** Business Manager / Executive
* **Description:** Accessing data visualizations to optimize business operations.
* **Available Reports:**
* **Daily Ops:** Day-to-day fulfillment and performance.
* **Spend Report:** Financial breakdown of labor costs.
* **Forecast:** Projected staffing needs and costs.
* **Performance:** Worker and vendor reliability scores.
* **No-Show:** Tracking attendance issues.
* **Coverage:** Detailed fill-rate analysis.
---
## 5. Billing & Administration
### 5.1 Financial Management (Billing Tab)
* **Actor:** Business Manager / Finance Admin
* **Description:** Reviewing invoices and managing payment methods.
* **Main Flow:** User navigates to "Billing" -> Views current balance -> Downloads past invoices -> Updates credit card/ACH info.
### 5.2 Manage Business Locations (Hubs)
* **Actor:** Business Manager
* **Description:** Defining different venues or branches where staff will be sent.
* **Main Flow:** User goes to Settings -> Client Hubs -> Adds/Edits location details and addresses.
### 5.3 Profile & Settings Management
* **Actor:** Business Manager
* **Description:** Updating personal contact info and notification preferences.
* **Main Flow:** User goes to Settings -> Edits Profile -> Toggles notification settings for shift updates and billing alerts.
---
# Use Case Diagram
```mermaid
flowchart TD
subgraph AppInitialization [App Initialization]
Start[Start App] --> CheckAuth{Check Auth Status}
CheckAuth -- Authenticated --> GoHome[Go to Main App]
CheckAuth -- Unauthenticated --> GetStarted[Go to Get Started]
end
subgraph Authentication [Authentication]
GetStarted --> AuthChoice{Select Option}
AuthChoice -- Sign In --> SignIn[Sign In Screen]
AuthChoice -- Sign Up --> SignUp[Sign Up Screen]
SignIn --> EnterCreds[Enter Credentials]
EnterCreds --> VerifySignIn{Verify}
VerifySignIn -- Success --> GoHome
VerifySignIn -- Failure --> SignInError[Show Error]
SignUp --> EnterBusinessDetails[Enter Business Details]
EnterBusinessDetails --> CreateAccount[Create Account]
CreateAccount -- Success --> GoHome
end
subgraph MainApp [Main Application Shell]
GoHome --> Shell[Scaffold with Nav Bar]
Shell --> TabNav{Tab Navigation}
TabNav -- Index 0 --> Coverage[Coverage Tab]
TabNav -- Index 1 --> Billing[Billing Tab]
TabNav -- Index 2 --> Home[Home Tab]
TabNav -- Index 3 --> Orders[Orders/Shifts Tab]
TabNav -- Index 4 --> Reports[Reports Tab]
end
subgraph HomeActions [Home Tab Actions]
Home --> CreateOrderAction{Create Order}
CreateOrderAction -- Rapid --> RapidOrder[Rapid Order Flow]
CreateOrderAction -- One-Time --> OneTimeOrder[One-Time Order Flow]
CreateOrderAction -- Recurring --> RecurringOrder[Recurring Order Flow]
CreateOrderAction -- Permanent --> PermanentOrder[Permanent Order Flow]
Home --> QuickActions[Quick Actions Widget]
Home --> Settings[Go to Settings]
Home --> Hubs[Go to Client Hubs]
end
subgraph OrderManagement [Order Management Flows]
RapidOrder --> SubmitRapid[Submit Rapid Order]
OneTimeOrder --> SubmitOneTime[Submit One-Time Order]
RecurringOrder --> SubmitRecurring[Submit Recurring Order]
PermanentOrder --> SubmitPermanent[Submit Permanent Order]
SubmitRapid --> OrderSuccess[Order Success]
SubmitOneTime --> OrderSuccess
SubmitRecurring --> OrderSuccess
SubmitPermanent --> OrderSuccess
OrderSuccess --> Home
end
subgraph ReportsAnalysis [Reports & Analytics]
Reports --> SelectReport{Select Report}
SelectReport -- Daily Ops --> DailyOps[Daily Ops Report]
SelectReport -- Spend --> SpendReport[Spend Report]
SelectReport -- Forecast --> ForecastReport[Forecast Report]
SelectReport -- Performance --> PerfReport[Performance Report]
SelectReport -- No-Show --> NoShowReport[No-Show Report]
SelectReport -- Coverage --> CovReport[Coverage Report]
end
subgraph WorkforceMgmt [Workforce Management]
Orders --> ViewShifts[View Shifts List]
ViewShifts --> ShiftDetail[View Shift Detail]
ShiftDetail --> VerifyAttire[Verify Attire]
Home --> ViewWorkers[View Workers List]
Home --> ViewTimesheets[View Timesheets]
ViewTimesheets --> ApproveTime[Approve Hours]
ViewTimesheets --> DisputeTime[Dispute Hours]
end
subgraph SettingsFlow [Settings & Configuration]
Settings --> EditProfile[Edit Profile]
Settings --> ManageHubsLink[Manage Hubs]
Hubs --> AddHub[Add New Hub]
Hubs --> EditHub[Edit Existing Hub]
end
%% Relationships across subgraphs
OrderSuccess -.-> Coverage
VerifySignIn -.-> Shell
CreateAccount -.-> Shell
```

View File

@@ -0,0 +1,208 @@
# Staff Application: Use Case Overview
This document details the primary business actions available within the **Staff Mobile Application**. It is organized according to the application's logical structure and navigation flow.
---
## 1. Application Access & Authentication
### 1.1 App Initialization
* **Actor:** Temporary Worker
* **Description:** The system checks if the user is logged in upon startup.
* **Main Flow:**
1. Worker opens the app.
2. System checks for a valid auth token.
3. If valid, worker goes to **Home**.
4. If invalid, worker goes to **Get Started**.
### 1.2 Onboarding & Registration
* **Actor:** New Worker
* **Description:** Creating a new profile to join the KROW network.
* **Main Flow:**
1. Worker enters phone number.
2. System sends SMS OTP.
3. Worker verifies OTP.
4. System checks if profile exists.
5. If new, worker completes **Profile Setup Wizard** (Personal Info -> Role/Experience -> Attire Sizes).
6. Worker enters the Main App.
---
## 2. Job Discovery (Home Tab)
### 2.1 Browse & Filter Jobs
* **Actor:** Temporary Worker
* **Description:** Finding suitable work opportunities.
* **Main Flow:**
1. Worker taps "View Available Jobs".
2. Worker filters by Role (e.g., Server) or Distance.
3. Worker selects a job card to view details (Pay, Location, Requirements).
### 2.2 Claim Open Shift
* **Actor:** Temporary Worker
* **Description:** Committing to work a specific shift.
* **Main Flow:**
1. From Job Details, worker taps "Claim Shift".
2. System validates eligibility (Certificates, Conflicts).
3. If eligible, shift is added to "My Schedule".
4. If missing requirements, system prompts to **Upload Compliance Docs**.
### 2.3 Set Availability
* **Actor:** Temporary Worker
* **Description:** Defining working hours to get better job matches.
* **Main Flow:** Worker taps "Set Availability" -> Selects dates/times -> Saves preferences.
---
## 3. Shift Execution (Shifts & Clock In Tabs)
### 3.1 View Schedule
* **Actor:** Temporary Worker
* **Description:** Reviewing upcoming commitments.
* **Main Flow:** Navigate to "My Shifts" tab -> View list of claimed shifts.
### 3.2 GPS-Verified Clock In
* **Actor:** Temporary Worker
* **Description:** Starting a shift once on-site.
* **Main Flow:**
1. Navigate to "Clock In" tab.
2. System checks GPS location against job site coordinates.
3. If **On Site**, "Swipe to Clock In" becomes active.
4. Worker swipes to start the timer.
5. If **Off Site**, system displays an error message.
### 3.3 Submit Timesheet
* **Actor:** Temporary Worker
* **Description:** Completing a shift and submitting hours for payment.
* **Main Flow:**
1. Worker swipes to "Clock Out".
2. Worker confirms total hours and break times.
3. Worker submits timesheet for client approval.
---
## 4. Financial Management (Payments Tab)
### 4.1 Track Earnings
* **Actor:** Temporary Worker
* **Description:** Monitoring financial progress.
* **Main Flow:** Navigate to "Payments" -> View "Pending Pay" (unpaid) and "Total Earned" (paid).
### 4.2 Request Early Pay
* **Actor:** Temporary Worker
* **Description:** Accessing wages before the standard payday.
* **Main Flow:**
1. Tap "Request Early Pay".
2. Select amount to withdraw from available balance.
3. Confirm transfer fee.
4. Funds are transferred to the linked bank account.
---
## 5. Profile & Compliance (Profile Tab)
### 5.1 Manage Compliance Documents
* **Actor:** Temporary Worker
* **Description:** Keeping certifications up to date.
* **Main Flow:** Navigate to "Compliance Menu" -> "Upload Certificates" -> Take photo of ID/License -> Submit.
### 5.2 Manage Tax Forms
* **Actor:** Temporary Worker
* **Description:** Submitting legal employment forms.
* **Main Flow:** Navigate to "Tax Forms" -> Complete W-4 or I-9 digitally -> Sign and Submit.
### 5.3 KROW University Training
* **Actor:** Temporary Worker
* **Description:** Improving skills to unlock better jobs.
* **Main Flow:** Navigate to "KROW University" -> Select Module -> Watch Video/Take Quiz -> Earn Badge.
### 5.4 Account Settings
* **Actor:** Temporary Worker
* **Description:** Managing personal data.
* **Main Flow:** Update Bank Details, View Benefits, or Access Support/FAQs.
---
# Use Cases Diagram
```mermaid
flowchart TD
subgraph AppInitialization [App Initialization]
Start[Start App] --> CheckAuth{Check Auth Status}
CheckAuth -- Authenticated --> GoHome[Go to Main App]
CheckAuth -- Unauthenticated --> GetStarted[Go to Get Started]
end
subgraph Authentication [Onboarding & Authentication]
GetStarted --> InputPhone[Enter Phone Number]
InputPhone --> VerifyOTP[Verify SMS Code]
VerifyOTP --> CheckProfile{Profile Complete?}
CheckProfile -- Yes --> GoHome
CheckProfile -- No --> SetupProfile[Profile Setup Wizard]
SetupProfile --> Step1[Personal Info]
Step1 --> Step2[Role & Experience]
Step2 --> Step3[Attire Sizes]
Step3 --> GoHome
end
subgraph MainApp [Main Application Shell]
GoHome --> Shell[Scaffold with Nav Bar]
Shell --> TabNav{Tab Navigation}
TabNav -- Index 0 --> Shifts[My Shifts Tab]
TabNav -- Index 1 --> Payments[Payments Tab]
TabNav -- Index 2 --> Home[Home Tab]
TabNav -- Index 3 --> ClockIn[Clock In Tab]
TabNav -- Index 4 --> Profile[Profile Tab]
end
subgraph HomeAndDiscovery [Job Discovery]
Home --> ViewOpenJobs[View Available Jobs]
ViewOpenJobs --> FilterJobs[Filter by Role/Distance]
ViewOpenJobs --> JobDetail[View Job Details]
JobDetail --> ClaimShift{Claim Shift}
ClaimShift -- Success --> ShiftSuccess[Shift Added to Schedule]
ClaimShift -- "Missing Req" --> PromptUpload[Prompt Compliance Upload]
Home --> SetAvailability[Set Availability]
Home --> ViewUpcoming[View Upcoming Shifts]
end
subgraph ShiftExecution [Shift Execution]
Shifts --> ViewSchedule[View My Schedule]
ClockIn --> CheckLocation{Verify GPS Location}
CheckLocation -- "On Site" --> SwipeIn[Swipe to Clock In]
CheckLocation -- "Off Site" --> LocationError[Show Location Error]
SwipeIn --> ActiveShift[Shift In Progress]
ActiveShift --> SwipeOut[Swipe to Clock Out]
SwipeOut --> ConfirmHours[Confirm Hours & Breaks]
ConfirmHours --> SubmitTimesheet[Submit Timesheet]
end
subgraph Financials [Earnings & Payments]
Payments --> ViewEarnings[View Pending Earnings]
Payments --> ViewHistory[View Payment History]
ViewEarnings --> EarlyPay{Request Early Pay?}
EarlyPay -- Yes --> SelectAmount[Select Amount]
SelectAmount --> ConfirmTransfer[Confirm Transfer]
end
subgraph ProfileAndCompliance [Profile & Compliance]
Profile --> ComplianceMenu[Compliance Menu]
ComplianceMenu --> UploadDocs[Upload Certificates]
ComplianceMenu --> TaxForms["Manage Tax Forms (W-4/I-9)"]
Profile --> KrowUniversity[KROW University]
KrowUniversity --> StartTraining[Start Training Module]
Profile --> BankAccount[Manage Bank Details]
Profile --> Benefits[View Benefits]
Profile --> Support["Access Support/FAQs"]
end
%% Relationships across subgraphs
SubmitTimesheet -.-> ViewEarnings
PromptUpload -.-> ComplianceMenu
ShiftSuccess -.-> ViewSchedule
```

View File

@@ -0,0 +1,251 @@
# The KROW Platform System Bible
**Status:** Official / Living Document
**Version:** 1.0.0
---
## 1. Executive Summary
### What the System Is
The **KROW Platform** is a multi-sided workforce management ecosystem that digitizes the entire lifecycle of temporary staffing. It replaces fragmented, manual processes (phone calls, spreadsheets, paper timesheets) with a unified digital infrastructure connecting businesses ("Clients") directly with temporary workers ("Staff").
### Why It Exists
The temporary staffing industry suffers from friction, lack of transparency, and delayed payments. Businesses struggle to find reliable staff quickly, while workers face uncertain schedules and slow wage access. KROW exists to remove this friction, ensuring shifts are filled instantly, work is verified accurately, and payments are processed swiftly.
### Who It Serves
1. **Clients (Businesses):** Venue managers and owners who need on-demand or scheduled staff.
2. **Staff (Workers):** Individuals seeking flexible, temporary employment opportunities.
3. **Admins (Operations):** Internal teams managing the marketplace, compliance, and financial flows.
### High-Level Value Proposition
KROW transforms labor from a manual logistical headache into a streamlined digital asset. For clients, it provides "staff on tap" with verified compliance. For workers, it offers "freedom and instant pay." For the platform operators, it delivers data-driven oversight of a complex marketplace.
---
## 2. System Vision & Product Principles
### Core Goals
1. **Immediacy:** Reduce the time-to-fill for urgent shifts from hours to minutes.
2. **Accuracy:** Eliminate payroll disputes through GPS-verified digital timesheets.
3. **Compliance:** Automate the enforcement of legal and safety requirements (attire, certifications).
### Problems It Intentionally Solves
* **The "No-Show" Epidemic:** By creating a transparent marketplace with reliability ratings.
* **Payroll Latency:** By enabling "Early Pay" features rooted in verified digital time cards.
* **Administrative Bloat:** By automating invoice generation and worker onboarding.
### Problems It Intentionally Does NOT Solve
* **Full-Time Recruitment:** This system is optimized for shift-based, temporary labor, not permanent headhunting.
* **Gig Economy "Tasking":** It focuses on professional hospitality and event roles, not general unskilled errands.
### Guiding Product Principles
* **Mobile-First for Operations:** If a task happens on a job site (clocking in, checking coverage), it *must* be possible on a phone.
* **Data as the Truth:** We do not rely on verbal confirmations. If it isn't in the system (GPS stamp, digital signature), it didn't happen.
* **Separation of Concerns:** Clients manage demand; Staff manage supply; Admin manages the rules. These roles never blur.
---
## 3. Ecosystem Overview
The ecosystem comprises three distinct applications, each serving a specific user persona but operating on a shared reality.
### 1. Client Mobile Application (The "Requester")
* **Platform:** Flutter (Mobile)
* **Responsibility:** Demand generation. Allows businesses to post orders, track arriving staff in real-time, and approve work hours.
* **Concept:** The "Remote Control" for the venue's staffing operations.
### 2. Staff Mobile Application (The "Worker")
* **Platform:** Flutter (Mobile)
* **Responsibility:** Supply fulfillment. Empowering workers to find jobs, manage their schedule, verify their presence (Clock In), and access earnings.
* **Concept:** The worker's "Digital Agency" in their pocket.
### 3. KROW Web Application (The "HQ")
* **Platform:** React (Web)
* **Responsibility:** Ecosystem governance. The command center for high-level analytics, complex financial operations (invoicing/payouts), vendor management, and system administration.
* **Concept:** The "Mission Control" for the business backend.
---
## 4. System Architecture Overview
The KROW Platform follows a **Service-Oriented Architecture (SOA)** where multiple front-end clients interface with a shared, monolithic logical backend (exposed via API Gateway).
### Architectural Style
* **Centralized State:** A single backend database serves as the source of truth for all apps.
* **Role-Based Access:** The API exposes different endpoints and data views depending on the authenticated user's role (Client vs. Staff).
* **Event-Driven Flows:** Key actions (e.g., "Shift Posted") trigger downstream effects (e.g., "Push Notification Sent") across the ecosystem.
### System Boundaries
The "System" encompasses the three front-end apps and the shared backend services. External boundaries are drawn at:
* **Payment Gateways:** We initiate transfers, but the actual money movement is external.
* **Maps/Geolocation:** We consume location data but do not maintain mapping infrastructure.
* **SMS/Identity:** We offload OTP delivery to specialized providers.
### Trust Boundaries
* **Mobile Apps are Untrusted:** We assume any data coming from a client device (GPS coordinates, timestamps) could be manipulated and must be validated server-side.
* **Web App is Semi-Trusted:** Admin actions are logged for audit but are assumed to be authorized operations.
```mermaid
flowchart TD
subgraph Clients [Client Layer]
CMA[Client Mobile App]
SMA[Staff Mobile App]
WEB[Web Admin Portal]
end
subgraph API [Interface Layer]
Gateway[API Gateway]
end
subgraph Services [Core Service Layer]
Auth[Identity Service]
Ops[Operations Service]
Finance[Financial Service]
end
subgraph Data [Data Layer]
DB[(Central Database)]
end
CMA --> Gateway
SMA --> Gateway
WEB --> Gateway
Gateway --> Services
Services --> DB
```
---
## 5. Application Responsibility Matrix
| Feature Domain | Client App (Mobile) | Staff App (Mobile) | Web App (Admin/Ops) |
| :--- | :--- | :--- | :--- |
| **User Onboarding** | Register Business | Register Worker | Onboard Vendors |
| **Shift Management** | **Create** & Monitor | **Claim** & Execute | **Oversee** & Resolve |
| **Time Tracking** | Approve / Dispute | Clock In / Out | Audit Logs |
| **Finance** | Pay Invoices | Request Payout | Generate Bills |
| **Compliance** | Verify Attire | Upload Docs | Verify Docs |
| **Analytics** | View My Venue Stats | View My Earnings | Global Market Analysis |
### Critical Rules
* **Client App MUST NOT** access worker financial data (bank details, total platform earnings).
* **Staff App MUST NOT** see client billing rates or internal venue notes.
* **Web App MUST** be the only place where global system configurations (e.g., platform fees) are changed.
---
## 6. Use Cases
The following are the **official system use cases**. Any feature request not mapping to one of these must be scrutinized.
### A. Staffing Operations
1. **Post Urgent Shift (Client):**
* *Pre:* Valid client account.
* *Flow:* Select Role -> Set Qty -> Post.
* *Post:* Notification sent to eligible workers.
2. **Claim Shift (Staff):**
* *Pre:* Worker meets compliance reqs.
* *Flow:* View Job -> Accept.
* *Post:* Shift is locked; Client notified.
3. **Execute Shift (Staff):**
* *Pre:* On-site GPS verification.
* *Flow:* Clock In -> Work -> Clock Out.
* *Validation:* Location check passes.
4. **Approve Timesheet (Client):**
* *Pre:* Shift completed.
* *Flow:* Review Hours -> Approve.
* *Post:* Payment scheduled.
### B. Financial Operations
5. **Process Billing (Web/Admin):**
* *Flow:* Aggregate approved hours -> Generate Invoice -> Charge Client.
6. **Request Early Pay (Staff):**
* *Pre:* Accrued unpaid earnings.
* *Flow:* Select Amount -> Confirm -> Transfer.
### C. Governance
7. **Verify Compliance (Web/Admin):**
* *Flow:* Review uploaded ID -> Mark as Verified.
* *Post:* Worker eligible for shifts.
8. **Strategic Analysis (Web/Client):**
* *Flow:* View Savings Engine -> Adopt Recommendation.
---
## 7. Cross-Application Interaction Rules
### Communication Patterns
* **Indirect Communication:** Apps NEVER speak peer-to-peer.
* *Correct:* Client App posts order -> Backend -> Staff App receives notification.
* *Forbidden:* Client App sends data directly to Staff App via Bluetooth/LAN.
* **Push Notifications:** Used as the primary signal to "wake up" an app and fetch fresh data from the server.
### Dependency Direction
* **Downstream Dependency:** The Mobile Apps depend on the Web App's configuration (e.g., if Admin adds a new "Role Type" on Web, it appears on Mobile).
* **Upstream Data Flow:** Operational data flows *up* from Mobile (Clock-ins) to Web (Reporting).
### Anti-Patterns to Avoid
* **"Split Brain" Logic:** Business logic (e.g., "How is overtime calculated?") must live in the Backend, NOT duplicated in the mobile apps.
* **Local-Only State:** Critical data (shift status) must never exist only on a user's device. It must be synced immediately.
---
## 8. Data Ownership & Source of Truth
| Data Domain | Source of Truth | Write Access | Read Access |
| :--- | :--- | :--- | :--- |
| **User Identity** | Auth Service | User (Self), Admin | System-wide |
| **Shift Status** | Order Service | Client (Create), Staff (Update status) | All (Context dependent) |
| **Time Cards** | Database | Staff (Create), Client (Approve) | Admin, Payroll |
| **Compliance Docs** | Worker Profile | Staff (Upload), Admin (Verify) | Client (Status only) |
| **Platform Rates** | System Config | Admin | Read-only |
### Consistency Principle
**"The Server is Right."** If a mobile device displays a shift as "Open" but the server says "Filled," the device is wrong and must refresh. We prioritize data integrity over offline availability for critical transaction states.
---
## 9. Security & Access Model
### User Roles
1. **Super Admin:** Full system access.
2. **Client Manager:** Access to own venue data only.
3. **Worker:** Access to own schedule and public job board only.
### Authentication Philosophy
* **Zero Trust:** Every API request must carry a valid, unexpired token.
* **Session Management:** Mobile sessions are persistent (long-lived tokens) for usability; Web sessions (Admin) are shorter for security.
### Authorization Boundaries
* **Horizontal Separation:** Client A cannot see Client B's orders. Worker A cannot see Worker B's pay.
* **Vertical Separation:** Staff cannot access Admin APIs.
---
## 10. Non-Negotiables & Guardrails
1. **No GPS, No Pay:** A clock-in event *must* have valid geolocation data attached. No exceptions.
2. **Compliance First:** A worker cannot claim a shift if their required documents (e.g., Food Handler Card) are expired. The system must block this at the API level.
3. **Immutable Audit Trail:** Once a timesheet is approved and paid, it cannot be deleted or modified, only reversed via a new corrective transaction.
4. **One Account Per Person:** Strict identity checks to prevent duplicate worker profiles.
---
## 11. Known Constraints & Assumptions
* **Connectivity:** The system assumes a reliable internet connection for critical actions (Claiming, Clocking In). Offline mode is limited to read-only views of cached schedules.
* **Device Capability:** We assume worker devices have functional GPS and Camera hardware.
* **Payment Timing:** "Instant" pay is subject to external banking network delays (ACH/RTP) and is not truly real-time in all cases.
---
## 12. Glossary
* **Shift:** A single unit of work with a start time, end time, and role.
* **Order:** A request from a client containing one or more shifts.
* **Clock-In:** The digital timestamp marking the start of work, verified by GPS.
* **Rapid Order:** A specific order type designed for immediate (<24h) fulfillment.
* **Early Pay:** A financial feature allowing workers to withdraw accrued wages before the standard pay period ends.
* **Hub:** A specific physical location or venue belonging to a Client.
* **Compliance:** The state of having all necessary legal and safety documents verified.

View File

@@ -0,0 +1,639 @@
# Web Application: Use Case Overview
This document details the primary business actions and user flows within the **KROW Web Application**. It is organized according to the logical workflows for each primary user role as defined in the system's architecture.
---
## 1. Access & Authentication (Common)
### 1.1 Web Portal Login
* **Actor:** All Users (Admin, Client, Vendor)
* **Description:** Secure entry into the management console.
* **Main Flow:**
1. User enters email and password on the login screen.
2. System verifies credentials against authentication service.
3. System determines user role (Admin, Client, or Vendor).
4. User is directed to their specific role-based dashboard with customizable widgets.
5. System loads user-specific dashboard layout preferences.
---
## 2. Admin Workflows (Operations Manager)
### 2.1 Global Operational Oversight
* **Actor:** Admin
* **Description:** Monitoring the pulse of the entire platform through a customizable dashboard.
* **Main Flow:**
1. User accesses Admin Dashboard with global metrics.
2. Views fill rate, total spend, performance score, and active events.
3. Monitors today's orders with status indicators (RAPID, Fully Staffed, Partial Staffed).
4. Reviews action items prioritized by urgency (critical, high, medium).
5. Accesses ecosystem visualization showing connections between Buyers, Enterprises, Sectors, Partners, and Vendors.
6. Customizes dashboard widget layout via drag-and-drop.
### 2.2 Vendor & Partner Management
* **Actor:** Admin
* **Description:** Managing the vendor network and partnerships.
* **Main Flow:**
1. User navigates to Vendor Marketplace.
2. Reviews vendor approval status and performance metrics.
3. Sets vendor tier levels (Approved Vendor, Gold Vendor).
4. Monitors vendor CSAT scores and compliance rates.
5. Views vendor rate books and service rates.
### 2.3 Order & Schedule Management
* **Actor:** Admin
* **Description:** Overseeing all orders across the platform.
* **Main Flow:**
1. User views all orders with filtering by status (All, Upcoming, Active, Past, Conflicts).
2. Reviews order details including business, hub, date/time, assigned staff.
3. Monitors assignment status (Requested vs Assigned counts).
4. Detects and resolves scheduling conflicts.
5. Accesses schedule view for visual timeline.
### 2.4 Workforce Management
* **Actor:** Admin
* **Description:** Managing platform-wide workforce.
* **Main Flow:**
1. User navigates to Staff Directory.
2. Views staff with filters (position, department, hub, profile type).
3. Monitors compliance status (background checks, certifications).
4. Reviews staff performance metrics (rating, reliability score, shift coverage).
5. Manages onboarding workflows for new staff.
### 2.5 Analytics & Reporting
* **Actor:** Admin
* **Description:** Generating insights through reports and activity logs.
* **Main Flow:**
1. User accesses Reports Dashboard.
2. Selects report type (Staffing Cost, Staff Performance, Operational Efficiency, Client Trends).
3. Configures report parameters and filters.
4. Views report insights with AI-generated recommendations.
5. Exports reports in multiple formats (PDF, Excel, CSV).
6. Reviews Activity Log for audit trail.
---
## 3. Client Executive Workflows
### 3.1 Dashboard Overview
* **Actor:** Client Executive
* **Description:** Personalized dashboard for order and labor management.
* **Main Flow:**
1. User opens Client Dashboard with customizable widgets.
2. Views action items (overdue invoices, unfilled orders, rapid requests).
3. Monitors key metrics (Today's Count, In Progress, Needs Attention).
4. Reviews labor summary with cost breakdown by position.
5. Analyzes sales analytics via pie charts.
### 3.2 Order Management
* **Actor:** Client Executive / Operations Manager
* **Description:** Creating and managing staffing requests.
* **Main Flow:**
1. User clicks "Order Now" or "RAPID Order" for urgent requests.
2. Selects business, hub, and event details.
3. Defines shifts with roles, counts, start/end times, and rates.
4. Chooses order type (one-time, rapid, recurring, permanent).
5. Enables conflict detection to prevent scheduling issues.
6. Reviews detected conflicts before submission.
7. Submits order to preferred vendor or marketplace.
### 3.3 Vendor Discovery & Selection
* **Actor:** Client Executive
* **Description:** Finding and managing vendor relationships.
* **Main Flow:**
1. User navigates to Vendor Marketplace.
2. Searches and filters vendors by region, category, rating, price.
3. Views vendor profiles with metrics (staff count, rating, fill rate, response time).
4. Expands vendor cards to view rate books by category.
5. Sets preferred vendor for automatic order routing.
6. Configures vendor preferences (locked vendors for optimization).
7. Contacts vendors via integrated messaging.
### 3.4 Savings Engine (Strategic Insights)
* **Actor:** Client Executive
* **Description:** Using AI to optimize labor spend and vendor mix.
* **Main Flow:**
1. User opens Savings Engine.
2. Reviews overview cards showing total spend, potential savings, fill rate.
3. Selects analysis timeframe (7 days, 30 days, Quarter, Year).
4. Navigates tabs for different insights:
- **Overview**: Dynamic dashboard with savings opportunities
- **Budget**: Budget utilization tracker
- **Strategies**: Smart operation strategies with AI recommendations
- **Predictions**: Cost forecasts and trend analysis
- **Vendors**: Vendor performance comparison
5. Views actionable strategies (vendor consolidation, rate optimization).
6. Exports analysis report.
### 3.5 Finance & Invoicing
* **Actor:** Client Executive / Finance Admin
* **Description:** Managing invoices and payments.
* **Main Flow:**
1. User views invoice list filtered by status (Open, Overdue, Paid, Disputed).
2. Opens invoice detail to review line items by role and staff.
3. Views from/to company information and payment terms.
4. Downloads invoice in PDF or Excel format.
5. Processes payment or disputes invoice with reason.
6. Tracks payment history.
### 3.6 Communication & Support
* **Actor:** Client Executive
* **Description:** Engaging with vendors and getting help.
* **Main Flow:**
1. User accesses Message Center for conversations.
2. Initiates conversation with vendors or admins.
3. Views conversation threads grouped by type (client-vendor, client-admin).
4. Accesses Tutorials for platform guidance.
5. Submits support tickets via Support Center.
---
## 4. Vendor Workflows (Staffing Agency)
### 4.1 Vendor Dashboard
* **Actor:** Vendor Manager
* **Description:** Comprehensive view of operations and performance.
* **Main Flow:**
1. User accesses Vendor Dashboard with customizable widgets.
2. Views KPI cards (Orders Today, In Progress, RAPID, Staff Assigned).
3. Monitors action items (urgent unfilled orders, expiring certifications, invoices to submit).
4. Reviews recent orders table with assignment status.
5. Accesses revenue carousel showing monthly revenue, total revenue, active orders.
6. Views top clients by revenue and order count.
7. Reviews client loyalty status (Champion, Loyal, At Risk).
8. Monitors top performer staff by rating.
### 4.2 Order Fulfillment
* **Actor:** Vendor Manager
* **Description:** Fulfilling client staffing requests.
* **Main Flow:**
1. User views incoming orders via "Orders" section.
2. Filters orders by tab (All, Conflicts, Upcoming, Active, Past).
3. Reviews order details (business, hub, event, date/time, roles).
4. Identifies RAPID orders (< 24 hours) needing immediate attention.
5. Clicks "Assign Staff" to open Smart Assign Modal.
6. Selects optimal staff based on skills, availability, and proximity.
7. Confirms assignments and updates order status.
8. Reviews conflict alerts for staff/venue overlaps.
### 4.3 Workforce Roster Management
* **Actor:** Vendor Manager
* **Description:** Managing agency's worker pool.
* **Main Flow:**
1. User navigates to Staff Directory.
2. Views staff with filtering options (profile type, position, department, hub).
3. Toggles between grid and list view.
4. Adds new staff via "Add Staff" button.
5. Fills staff profile form (personal info, position, department, hub, contact).
6. Edits existing staff profiles.
7. Monitors staff metrics (rating, reliability score, shift coverage, cancellations).
8. Reviews compliance status (background checks, certifications).
### 4.4 Staff Onboarding
* **Actor:** Vendor Manager
* **Description:** Streamlined multi-step onboarding for new workers.
* **Main Flow:**
1. User navigates to "Onboard Staff" section.
2. Completes profile setup step (name, email, position, department).
3. Uploads required documents (ID, certifications, licenses).
4. Assigns training modules.
5. Reviews completion status.
6. Activates staff member upon completion.
### 4.5 Compliance Management
* **Actor:** Vendor Manager
* **Description:** Maintaining workforce compliance standards.
* **Main Flow:**
1. User accesses Compliance Dashboard.
2. Views compliance metrics (background check status, certification expiry).
3. Filters staff needing attention.
4. Updates compliance documents in Document Vault.
5. Tracks certification renewal deadlines.
### 4.6 Schedule & Availability
* **Actor:** Vendor Manager
* **Description:** Managing staff availability and schedules.
* **Main Flow:**
1. User navigates to Staff Availability.
2. Views calendar-based availability grid.
3. Updates staff availability preferences.
4. Accesses Schedule view for visual timeline of assignments.
5. Identifies gaps and conflicts.
### 4.7 Client Relationship Management
* **Actor:** Vendor Manager
* **Description:** Managing client accounts and preferences.
* **Main Flow:**
1. User navigates to Clients section.
2. Views client list with business details.
3. Adds new client accounts.
4. Edits client information (contact, address, hubs, departments).
5. Configures client preferences (favorite staff, blocked staff).
6. Sets ERP integration details (vendor ID, cost center, EDI format).
### 4.8 Rate Management
* **Actor:** Vendor Manager
* **Description:** Managing service rates and pricing.
* **Main Flow:**
1. User accesses Service Rates section.
2. Views rate cards by client and role.
3. Creates new rate entries (role, client rate, employee wage).
4. Configures markup percentage and vendor fee.
5. Sets approved cap rates.
6. Activates/deactivates rates.
### 4.9 Vendor Finance & Invoicing
* **Actor:** Vendor Manager
* **Description:** Managing revenue and submitting invoices.
* **Main Flow:**
1. User views invoice list for completed orders.
2. Auto-generates invoices from completed events.
3. Reviews invoice details with staff entries and line items.
4. Edits invoice before submission if needed.
5. Submits invoice to client.
6. Tracks invoice status (Draft, Open, Confirmed, Paid).
7. Downloads invoice for records.
### 4.10 Performance Analytics
* **Actor:** Vendor Manager
* **Description:** Monitoring vendor performance metrics.
* **Main Flow:**
1. User accesses Performance section.
2. Reviews fill rate, on-time performance, client satisfaction.
3. Views staff performance leaderboard.
4. Analyzes revenue trends by client and timeframe.
### 4.11 Savings Engine (Growth Opportunities)
* **Actor:** Vendor Manager
* **Description:** Identifying growth and optimization opportunities.
* **Main Flow:**
1. User opens Savings Engine with vendor-specific tabs.
2. Reviews performance metrics and benchmarks.
3. Identifies opportunities to improve ratings and win more business.
4. Views workforce utilization statistics.
5. Analyzes growth forecasts.
---
## 5. Shared Functional Modules
### 5.1 Order Details & History
* **Actor:** All Roles
* **Description:** Accessing granular data for any specific staffing request.
* **Main Flow:**
1. User clicks any order ID from lists or dashboards.
2. System displays comprehensive order information:
- Event details (name, business, hub, date, time)
- Shift configuration with roles, counts, and rates
- Assigned staff with profiles
- Status history and audit trail
- Detected conflicts (if any)
- Invoice linkage (if completed)
3. User can edit order (if permissions allow).
4. User can assign/reassign staff.
5. User can view related invoices.
### 5.2 Invoice Detail View
* **Actor:** Admin, Client, Vendor
* **Description:** Reviewing the breakdown of costs for a billing period.
* **Main Flow:**
1. User opens an invoice from the invoice list.
2. System displays invoice header (invoice number, dates, status, parties).
3. Views detailed breakdown:
- Roles section with staff entries per role
- Hours worked (regular, overtime, double-time)
- Bill rates and totals per role
- Additional charges
- Subtotal and grand total
4. Reviews payment terms and PO reference.
5. Downloads invoice in PDF or Excel.
6. Copies invoice data to clipboard.
7. Sends invoice via email (vendor role).
8. Approves or disputes invoice (client role).
### 5.3 Task Board
* **Actor:** All Roles
* **Description:** Collaborative task management across teams.
* **Main Flow:**
1. User accesses Task Board.
2. Views tasks in columns by status (Pending, In Progress, On Hold, Completed).
3. Drags tasks between columns to update status.
4. Creates new tasks with details (name, description, priority, due date).
5. Assigns tasks to team members.
6. Adds comments and attachments to tasks.
7. Filters tasks by department, priority, or assignee.
### 5.4 Message Center
* **Actor:** All Roles
* **Description:** Cross-platform communication hub.
* **Main Flow:**
1. User accesses Message Center.
2. Views conversation list with unread counts.
3. Filters by conversation type (client-vendor, client-admin, internal).
4. Opens conversation thread.
5. Sends messages with attachments.
6. Views system-generated messages for automated events.
7. Archives completed conversations.
### 5.5 Reports & Analytics
* **Actor:** All Roles (with role-specific access)
* **Description:** Data-driven insights and custom reporting.
* **Main Flow:**
1. User accesses Reports Dashboard.
2. Selects from report types:
- Staffing Cost Report
- Staff Performance Report
- Operational Efficiency Report
- Client Trends Report
- Custom Report Builder
3. Configures report parameters (date range, filters, grouping).
4. Views AI-generated insights banner with key findings.
5. Exports report in preferred format.
6. Schedules recurring reports for automated delivery.
7. Saves report templates for reuse.
### 5.6 Teams Management
* **Actor:** Admin, Client, Vendor
* **Description:** Creating and managing staff teams.
* **Main Flow:**
1. User navigates to Teams section.
2. Views team list with member counts.
3. Creates new team with name and description.
4. Adds team members from staff directory.
5. Views team detail page with member profiles.
6. Assigns teams to orders as groups.
### 5.7 Staff Conflict Detection
* **Actor:** Admin, Vendor
* **Description:** Automated detection of scheduling conflicts.
* **Main Flow:**
1. System automatically detects conflicts when creating/editing orders:
- **Staff Overlap**: Same staff assigned to overlapping shifts
- **Venue Overlap**: Same venue booked for overlapping times
- **Time Buffer**: Insufficient travel time between assignments
2. System assigns severity level (Critical, High, Medium, Low).
3. Displays conflict alerts with details (conflicting event, staff, location).
4. User resolves conflicts before finalizing order.
5. System tracks conflict resolution in audit log.
### 5.8 Dashboard Customization
* **Actor:** All Roles
* **Description:** Personalizing dashboard layouts.
* **Main Flow:**
1. User clicks "Customize Dashboard" button.
2. Enters customization mode with drag-and-drop interface.
3. Reorders widgets by dragging.
4. Hides/shows widgets using visibility controls.
5. Previews changes in real-time.
6. Saves layout preferences to user profile.
7. Resets to default layout if desired.
---
## 6. Advanced Features
### 6.1 Smart Assignment Engine (Vendor)
* **Actor:** Vendor Manager
* **Description:** AI-powered staff assignment optimization.
* **Main Flow:**
1. User clicks "Smart Assign" on an order.
2. System analyzes requirements (skills, location, time, availability).
3. Engine scores available staff based on:
- Skill match
- Proximity to venue
- Past performance
- Availability
- Client preferences
4. Presents ranked staff recommendations.
5. User reviews suggestions and confirms assignments.
### 6.2 Auto-Invoice Generation
* **Actor:** Vendor Manager
* **Description:** Automated invoice creation from completed orders.
* **Main Flow:**
1. When order status changes to "Completed", system triggers auto-invoice.
2. System aggregates staff entries, hours, and rates.
3. Generates invoice line items by role.
4. Calculates totals (regular, overtime, double-time).
5. Applies additional charges if configured.
6. Creates draft invoice for vendor review.
7. Vendor reviews and submits to client.
### 6.3 Vendor Preferences & Optimization (Client)
* **Actor:** Client Executive
* **Description:** Configuring vendor routing and procurement strategies.
* **Main Flow:**
1. User accesses Client Vendor Preferences panel.
2. Sets preferred vendor for automatic order routing.
3. Configures locked vendors (never used for optimization).
4. Enables/disables procurement optimization.
5. System respects preferences when suggesting vendors in Savings Engine.
### 6.4 Contract Conversion & Tier Optimization
* **Actor:** Admin, Client (via Savings Engine)
* **Description:** Analyzing opportunities to move spend to preferred vendors.
* **Main Flow:**
1. User accesses "Conversion Map" tab in Savings Engine.
2. Views non-contracted spend by vendor.
3. System identifies conversion opportunities to approved/gold vendors.
4. Reviews potential savings from rate arbitrage.
5. Approves conversion strategy.
6. System routes future orders accordingly.
### 6.5 Predictive Savings Model
* **Actor:** Admin, Client
* **Description:** Forecasting cost savings through AI analysis.
* **Main Flow:**
1. User accesses "Predictions" tab in Savings Engine.
2. System analyzes historical spend, rates, and vendor performance.
3. Generates forecasts for 7 days, 30 days, quarter, year.
4. Identifies rate optimization opportunities.
5. Recommends vendor consolidation strategies.
6. Shows projected ROI for each strategy.
---
# Use Case Diagram
```mermaid
flowchart TD
subgraph AccessControl [Access & Authentication]
Start[Start Web Portal] --> CheckSession{Check Session}
CheckSession -- Valid --> CheckRole{Check User Role}
CheckSession -- Invalid --> Login[Login Screen]
Login --> EnterCreds[Enter Credentials]
EnterCreds --> Verify{Verify}
Verify -- Success --> CheckRole
Verify -- Failure --> Error[Show Error]
CheckRole -- Admin --> AdminDash[Admin Dashboard]
CheckRole -- Client --> ClientDash[Client Dashboard]
CheckRole -- Vendor --> VendorDash[Vendor Dashboard]
end
subgraph AdminWorkflows [Admin Workflows]
AdminDash --> GlobalOversight[Global Oversight]
GlobalOversight --> EcosystemWheel[Ecosystem Wheel]
GlobalOversight --> ViewAllOrders[View All Orders]
GlobalOversight --> ActionItems[Action Items]
AdminDash --> VendorMgmt[Vendor Management]
VendorMgmt --> ApproveVendors[Approve Vendors]
VendorMgmt --> SetTiers[Set Vendor Tiers]
AdminDash --> WorkforceMgmt[Workforce Management]
WorkforceMgmt --> StaffDirectory[Staff Directory]
WorkforceMgmt --> Compliance[Compliance Dashboard]
AdminDash --> AnalyticsReports[Analytics & Reports]
AnalyticsReports --> ReportsDashboard[Reports Dashboard]
AnalyticsReports --> ActivityLog[Activity Log]
end
subgraph ClientWorkflows [Client Executive Workflows]
ClientDash --> ClientActionItems[Action Items]
ClientActionItems --> ReviewAlerts[Review Alerts]
ClientDash --> OrderMgmt[Order Management]
OrderMgmt --> CreateOrder[Create Order]
CreateOrder --> DefineShifts[Define Shifts & Roles]
DefineShifts --> ConflictDetection[Conflict Detection]
ConflictDetection --> SubmitOrder[Submit Order]
OrderMgmt --> ViewMyOrders[View My Orders]
ViewMyOrders --> OrderDetail[Order Detail]
ClientDash --> VendorDiscovery[Vendor Discovery]
VendorDiscovery --> BrowseMarketplace[Browse Marketplace]
BrowseMarketplace --> SetPreferred[Set Preferred Vendor]
BrowseMarketplace --> ContactVendor[Contact Vendor]
ClientDash --> SavingsEngine[Savings Engine]
SavingsEngine --> AnalyzeSpend[Analyze Spend]
AnalyzeSpend --> ViewStrategies[View Strategies]
ViewStrategies --> ApproveStrategy[Approve Strategy]
SavingsEngine --> PredictiveSavings[Predictive Savings]
SavingsEngine --> ConversionMap[Conversion Map]
ClientDash --> ClientFinance[Finance & Invoicing]
ClientFinance --> ViewInvoices[View Invoices]
ViewInvoices --> InvoiceDetail[Invoice Detail]
InvoiceDetail --> PayInvoice[Pay Invoice]
InvoiceDetail --> DisputeInvoice[Dispute Invoice]
ClientDash --> Communication[Communication]
Communication --> MessageCenter[Message Center]
Communication --> SupportCenter[Support Center]
end
subgraph VendorWorkflows [Vendor Workflows]
VendorDash --> VendorKPIs[KPI Dashboard]
VendorKPIs --> RevenueStats[Revenue Stats]
VendorKPIs --> TopClients[Top Clients]
VendorKPIs --> TopPerformers[Top Performers]
VendorDash --> OrderFulfillment[Order Fulfillment]
OrderFulfillment --> ViewOrders[View Orders]
ViewOrders --> FilterOrders[Filter Orders]
FilterOrders --> AssignStaff[Smart Assign Staff]
AssignStaff --> ResolveConflicts[Resolve Conflicts]
VendorDash --> RosterMgmt[Roster Management]
RosterMgmt --> StaffDir[Staff Directory]
StaffDir --> AddStaff[Add Staff]
StaffDir --> EditStaff[Edit Staff]
StaffDir --> ViewMetrics[View Staff Metrics]
RosterMgmt --> OnboardStaff[Onboard Staff]
OnboardStaff --> ProfileSetup[Profile Setup]
ProfileSetup --> UploadDocs[Upload Documents]
UploadDocs --> AssignTraining[Assign Training]
AssignTraining --> ActivateStaff[Activate Staff]
VendorDash --> ComplianceMgmt[Compliance Management]
ComplianceMgmt --> ComplianceDash[Compliance Dashboard]
ComplianceDash --> DocumentVault[Document Vault]
ComplianceDash --> CertTracking[Certification Tracking]
VendorDash --> ScheduleAvail[Schedule & Availability]
ScheduleAvail --> StaffAvailability[Staff Availability]
ScheduleAvail --> ScheduleView[Schedule View]
VendorDash --> ClientMgmt[Client Management]
ClientMgmt --> ManageClients[Manage Clients]
ManageClients --> ClientPrefs[Client Preferences]
VendorDash --> RateMgmt[Rate Management]
RateMgmt --> ServiceRates[Service Rates]
ServiceRates --> RateCards[Rate Cards]
VendorDash --> VendorFinance[Finance]
VendorFinance --> AutoInvoice[Auto-Generate Invoice]
VendorFinance --> SubmitInvoice[Submit Invoice]
VendorFinance --> TrackPayments[Track Payments]
VendorDash --> VendorPerformance[Performance Analytics]
VendorPerformance --> FillRate[Fill Rate]
VendorPerformance --> CSAT[Client Satisfaction]
VendorPerformance --> RevenueAnalysis[Revenue Analysis]
end
subgraph SharedModules [Shared Functional Modules]
TaskBoard[Task Board] -.-> Tasks[Manage Tasks]
Tasks -.-> DragDrop[Drag & Drop Status]
MessageCenter -.-> Conversations[Conversations]
Conversations -.-> SendMessage[Send Message]
ReportsDashboard -.-> ReportTypes[Report Types]
ReportTypes -.-> CustomBuilder[Custom Report Builder]
ReportTypes -.-> ScheduledReports[Scheduled Reports]
ReportTypes -.-> ExportReport[Export Report]
TeamsModule[Teams] -.-> CreateTeam[Create Team]
CreateTeam -.-> AddMembers[Add Members]
DashboardCustom[Dashboard Customization] -.-> DragWidgets[Drag Widgets]
DragWidgets -.-> HideShow[Hide/Show Widgets]
HideShow -.-> SaveLayout[Save Layout]
end
```
---
## Summary of Key Enhancements
**Compared to the original document, this updated version includes:**
1. **Detailed Dashboard Workflows**: Comprehensive descriptions of customizable dashboards for each role with specific widgets and metrics.
2. **Advanced Order Management**: Multi-step order creation with shift configuration, conflict detection, and order type options (one-time, rapid, recurring, permanent).
3. **Smart Assignment**: AI-powered staff assignment engine for vendors to optimize worker selection.
4. **Savings Engine**: Detailed AI-driven cost optimization workflows with predictive modeling, vendor conversion strategies, and budget tracking.
5. **Vendor Marketplace**: Complete vendor discovery and selection process with filtering, rate comparison, and preference settings.
6. **Enhanced Finance**: Auto-invoice generation, detailed invoice views, export capabilities, and dispute resolution.
7. **Onboarding Workflow**: Multi-step staff onboarding process for vendors.
8. **Compliance Management**: Dedicated compliance dashboard and document vault.
9. **Conflict Detection**: Automated scheduling conflict detection with severity levels.
10. **Communication Hub**: Integrated message center for cross-platform communication.
11. **Teams Management**: Team creation and assignment workflows.
12. **Advanced Analytics**: Multiple report types, custom report builder, scheduled reports, and AI-generated insights.
13. **Dashboard Customization**: Drag-and-drop widget management with layout persistence.
14. **Schedule & Availability**: Calendar-based staff availability management with visual schedule view.
15. **Client & Rate Management**: Vendor-side client relationship and service rate management.
This document now accurately reflects the robust feature set implemented in the krow_web_application.

91
docs/ARCHITECTURE/web.md Normal file
View 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.

View File

@@ -0,0 +1,14 @@
# Backend API Guides
## Use this for current frontend work
- [V2 Backend API Guide](./V2/README.md)
- [V2 Core API](./V2/core-api.md)
- [V2 Command API](./V2/command-api.md)
- [V2 Query API](./V2/query-api.md)
## Legacy reference
- [Initial API contracts](./00-initial-api-contracts.md)
The legacy contract doc reflects the older Data Connect-oriented application shape. Do not use it as the source of truth for new v2 frontend work.

View File

@@ -0,0 +1,191 @@
# V2 Backend API Guide
This is the frontend-facing source of truth for the v2 backend.
## 1) Use one base URL
Frontend should call one public gateway:
```env
API_V2_BASE_URL=https://krow-api-v2-e3g6witsvq-uc.a.run.app
```
Frontend should not call the internal `core`, `command`, or `query` Cloud Run services directly.
## 2) Current status
The unified v2 gateway is ready for frontend integration in `dev`.
What was validated live against the deployed stack:
- client sign-in
- staff auth bootstrap
- client dashboard, billing, coverage, hubs, vendors, managers, team members, orders, and reports
- client coverage incident feed for geofence and override review
- client blocked-staff review and invited shift-manager creation
- client hub, order, coverage review, device token, and late-worker cancellation flows
- client swap-request review, dispatch-team management, and dispatch-candidate ranking
- client invoice approve and dispute
- staff dashboard, availability, payments, shifts, profile sections, documents, certificates, attire, bank accounts, benefits, and time card
- staff benefit history read model
- staff availability, profile, tax form, bank account, shift apply, shift accept, push token registration, clock-in, clock-out, location stream upload, swap request, and completed-shift submission
- direct file upload helpers and verification job creation through the unified host
- client and staff sign-out
The live validation command is:
```bash
export FIREBASE_WEB_API_KEY="$(gcloud secrets versions access latest --secret=firebase-web-api-key --project=krow-workforce-dev)"
source ~/.nvm/nvm.sh
nvm use 23.5.0
node backend/unified-api/scripts/live-smoke-v2-unified.mjs
```
The demo tenant can be reset with:
```bash
source ~/.nvm/nvm.sh
nvm use 23.5.0
cd backend/command-api
npm run seed:v2-demo
```
## 3) Auth and headers
Protected routes require:
```http
Authorization: Bearer <firebase-id-token>
```
Write routes also require:
```http
Idempotency-Key: <unique-per-user-action>
```
For now:
- backend wraps sign-in and sign-out
- frontend can keep using Firebase token refresh on the client
- backend is the only thing frontend should call for session-oriented API flows
All routes return the same error envelope:
```json
{
"code": "STRING_CODE",
"message": "Human readable message",
"details": {},
"requestId": "uuid"
}
```
## 3.1) Time handling
V2 stores operational timestamps in UTC using PostgreSQL `TIMESTAMPTZ`.
Rules:
- frontend sends UTC timestamps to backend
- backend returns ISO 8601 UTC timestamps for source-of-truth fields
- frontend converts those timestamps to local time for display
Source-of-truth timestamp fields include:
- `startsAt`
- `endsAt`
- `clockInAt`
- `clockOutAt`
- `createdAt`
- `updatedAt`
Helper fields like `date`, `startTime`, and `endTime` are display helpers and should not replace the raw timestamp fields.
## 4) Attendance policy and monitoring
V2 now supports an explicit attendance proof policy:
- `NFC_REQUIRED`
- `GEO_REQUIRED`
- `EITHER`
The effective policy is resolved as:
1. shift override if present
2. hub default if present
3. fallback to `EITHER`
For geofence-heavy staff flows, frontend should read the policy from:
- `GET /staff/clock-in/shifts/today`
- `GET /staff/shifts/:shiftId`
- `GET /staff/orders/:orderId`
- `GET /client/hubs`
Important operational rules:
- outside-geofence clock-ins can be accepted only when override is enabled and a written reason is provided
- NFC mismatches are rejected and are not overrideable
- attendance proof logs are durable in SQL and raw object storage
- device push tokens are durable in SQL and can be registered separately for client and staff apps
- background location streams are stored as raw batch payloads in the private v2 bucket and summarized in SQL for query speed
- incident review lives on `GET /client/coverage/incidents`
- confirmed late-worker recovery is exposed on `POST /client/coverage/late-workers/:assignmentId/cancel`
- client swap review is exposed on:
- `GET /client/coverage/swap-requests`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
- dispatch-team management is exposed on:
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
- dispatch ranking order is:
1. `CORE`
2. `CERTIFIED_LOCATION`
3. `MARKETPLACE`
- expired swap requests are auto-cancelled by the notification worker and emit manager plus staff alerts
- queued alerts are written to `notification_outbox`, dispatched by the private Cloud Run worker service `krow-notification-worker-v2`, and recorded in `notification_deliveries`
## 5) Route model
Frontend sees one base URL and one route shape:
- `/auth/*`
- `/client/*`
- `/staff/*`
- direct upload aliases like `/upload-file` and `/staff/profile/*`
Internally, the gateway still forwards to:
| Frontend use case | Internal service |
| --- | --- |
| auth/session wrapper | `krow-api-v2` |
| uploads, signed URLs, model calls, verification workflows | `core-api-v2` |
| writes and workflow actions | `command-api-v2` |
| reads and mobile read models | `query-api-v2` |
## 6) Frontend integration rule
Use the unified routes first.
Do not build new frontend work on:
- `/query/tenants/*`
- `/commands/*`
- `/core/*`
Those routes still exist for backend/internal compatibility, but mobile/frontend migration should target the unified surface documented in [Unified API](./unified-api.md).
## 7) Docs
- [Authentication](./authentication.md)
- [Unified API](./unified-api.md)
- [Mobile Coding Agent Spec](./mobile-coding-agent-spec.md)
- [Mobile Frontend Implementation Spec](./mobile-frontend-implementation-spec.md)
- [Staff Shifts](./staff-shifts.md)
- [Core API](./core-api.md)
- [Command API](./command-api.md)
- [Query API](./query-api.md)
- [Mobile API Reconciliation](./mobile-api-gap-analysis.md)

View File

@@ -0,0 +1,350 @@
# V2 Authentication Guide
This document is the source of truth for V2 authentication.
Base URL:
```env
API_V2_BASE_URL=https://krow-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) What is implemented
### Client app
Client authentication is implemented through backend endpoints:
- `POST /auth/client/sign-in`
- `POST /auth/client/sign-up`
- `POST /auth/client/sign-out`
- `GET /auth/session`
The backend signs the user in with Firebase Identity Toolkit, validates the user against the V2 database, and returns the full auth envelope.
### Staff app
Staff authentication is implemented, but it is a hybrid flow.
Routes:
- `POST /auth/staff/phone/start`
- `POST /auth/staff/phone/verify`
- `POST /auth/staff/sign-out`
- `GET /auth/session`
Important:
- the default mobile path is **not** a fully backend-managed OTP flow
- the usual mobile path uses the Firebase Auth SDK on-device for phone verification
- after the device gets a Firebase `idToken`, frontend sends that token to `POST /auth/staff/phone/verify`
So if someone expects `POST /auth/staff/phone/start` to always send the SMS and always return `sessionInfo`, that expectation is wrong for the current implementation
## 2) Auth refresh
There is currently **no** backend `/auth/refresh` endpoint.
That is intentional for now.
Current refresh model:
- frontend keeps Firebase Auth local session state
- frontend lets the Firebase SDK refresh the ID token
- frontend sends the latest Firebase ID token in:
```http
Authorization: Bearer <firebase-id-token>
```
Use:
- `authStateChanges()` / `idTokenChanges()` listeners
- `currentUser.getIdToken()`
- `currentUser.getIdToken(true)` only when a forced refresh is actually needed
`GET /auth/session` is **not** a refresh endpoint.
It is a context endpoint used to:
- hydrate role/tenant/business/staff context
- validate that the signed-in Firebase user is allowed in this app
## 3) Client auth flow
### Client sign-in
Request:
```http
POST /auth/client/sign-in
Content-Type: application/json
```
```json
{
"email": "legendary.owner+v2@krowd.com",
"password": "Demo2026!"
}
```
Response:
```json
{
"sessionToken": "firebase-id-token",
"refreshToken": "firebase-refresh-token",
"expiresInSeconds": 3600,
"user": {
"id": "user-uuid",
"email": "legendary.owner+v2@krowd.com",
"displayName": "Legendary Owner",
"phone": null
},
"tenant": {
"tenantId": "tenant-uuid",
"tenantName": "Legendary Event Staffing and Entertainment"
},
"business": {
"businessId": "business-uuid",
"businessName": "Google Mountain View Cafes"
},
"requestId": "uuid"
}
```
Frontend behavior:
1. Call `POST /auth/client/sign-in`
2. If success, sign in locally with Firebase Auth SDK using the same email/password
3. Use Firebase SDK token refresh for later API calls
4. Use `GET /auth/session` when role/session hydration is needed on app boot
### Client sign-up
Request:
```http
POST /auth/client/sign-up
Content-Type: application/json
```
```json
{
"companyName": "Legendary Event Staffing and Entertainment",
"email": "legendary.owner+v2@krowd.com",
"password": "Demo2026!"
}
```
What it does:
- creates Firebase Auth account
- creates V2 user
- creates tenant
- creates business
- creates tenant membership
- creates business membership
Frontend behavior after success:
1. call `POST /auth/client/sign-up`
2. sign in locally with Firebase Auth SDK using the same email/password
3. use Firebase SDK for later token refresh
## 4) Staff auth flow
## Step 1: start phone auth
Request:
```http
POST /auth/staff/phone/start
Content-Type: application/json
```
```json
{
"phoneNumber": "+15551234567"
}
```
Possible response A:
```json
{
"mode": "CLIENT_FIREBASE_SDK",
"provider": "firebase-phone-auth",
"phoneNumber": "+15551234567",
"nextStep": "Complete phone verification in the mobile client, then call /auth/staff/phone/verify with the Firebase idToken.",
"requestId": "uuid"
}
```
This is the normal mobile path when frontend does **not** send recaptcha or integrity tokens.
Current dev demo worker:
- phone number: `+15557654321`
- email: `ana.barista+v2@krowd.com`
Those two now resolve to the same Firebase user and the same seeded staff profile in v2.
Possible response B:
```json
{
"mode": "IDENTITY_TOOLKIT_SMS",
"phoneNumber": "+15551234567",
"sessionInfo": "firebase-session-info",
"requestId": "uuid"
}
```
This is the server-managed SMS path.
## Step 2A: normal mobile path (`CLIENT_FIREBASE_SDK`)
Frontend must do this on-device:
1. call `FirebaseAuth.verifyPhoneNumber(...)`
2. collect the `verificationId`
3. collect the OTP code from the user
4. create a Firebase phone credential
5. call `signInWithCredential(...)`
6. get Firebase `idToken`
7. call `POST /auth/staff/phone/verify` with that `idToken`
Request:
```http
POST /auth/staff/phone/verify
Content-Type: application/json
```
```json
{
"mode": "sign-in",
"idToken": "firebase-id-token-from-device"
}
```
Response:
```json
{
"sessionToken": "firebase-id-token-from-device",
"refreshToken": null,
"expiresInSeconds": 3600,
"user": {
"id": "user-uuid",
"phone": "+15551234567"
},
"staff": {
"staffId": "staff-uuid"
},
"requiresProfileSetup": false,
"requestId": "uuid"
}
```
Important:
- `refreshToken` is expected to be `null` in this path
- refresh remains owned by Firebase Auth SDK on the device
## Step 2B: server SMS path (`IDENTITY_TOOLKIT_SMS`)
If `start` returned `sessionInfo`, frontend can call:
```json
{
"mode": "sign-in",
"sessionInfo": "firebase-session-info",
"code": "123456"
}
```
The backend exchanges `sessionInfo + code` with Identity Toolkit and returns the hydrated auth envelope.
## 5) Sign-out
Routes:
- `POST /auth/sign-out`
- `POST /auth/client/sign-out`
- `POST /auth/staff/sign-out`
All sign-out routes require:
```http
Authorization: Bearer <firebase-id-token>
```
What sign-out does:
- revokes backend-side Firebase sessions for that user
- frontend should still clear local Firebase Auth state with `FirebaseAuth.instance.signOut()`
## 6) Session endpoint
Route:
- `GET /auth/session`
Headers:
```http
Authorization: Bearer <firebase-id-token>
```
Use it for:
- app startup hydration
- role validation
- deciding whether this app should allow the current signed-in user
Do not use it as:
- a refresh endpoint
- a login endpoint
## 7) Error contract
All auth routes use the standard V2 error envelope:
```json
{
"code": "STRING_CODE",
"message": "Human readable message",
"details": {},
"requestId": "uuid"
}
```
Common auth failures:
- `UNAUTHENTICATED`
- `FORBIDDEN`
- `VALIDATION_ERROR`
- `AUTH_PROVIDER_ERROR`
## 8) Troubleshooting
### Staff sign-in does not work, but endpoints are reachable
The most likely causes are:
1. frontend expected `POST /auth/staff/phone/start` to always return `sessionInfo`
2. frontend did not complete Firebase phone verification on-device
3. frontend called `POST /auth/staff/phone/verify` without a valid Firebase `idToken`
4. frontend phone-auth setup in Firebase mobile config is incomplete
### `POST /auth/staff/phone/start` returns `CLIENT_FIREBASE_SDK`
That is expected for the normal mobile flow when no recaptcha or integrity tokens are sent.
### There is no `/auth/refresh`
That is also expected right now.
Refresh is handled by Firebase Auth SDK on the client.

View File

@@ -0,0 +1,229 @@
# V2 Command API
Use `command-api-v2` for write actions that change business state.
Base URL:
```text
https://krow-command-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Required headers
```http
Authorization: Bearer <firebase-id-token>
Idempotency-Key: <unique-per-user-action>
Content-Type: application/json
```
## 2) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `POST` | `/commands/orders/create` | Create order with shifts and roles |
| `POST` | `/commands/orders/:orderId/update` | Update mutable order fields |
| `POST` | `/commands/orders/:orderId/cancel` | Cancel order and related eligible records |
| `POST` | `/commands/shifts/:shiftId/assign-staff` | Assign workforce to shift role |
| `POST` | `/commands/shifts/:shiftId/accept` | Accept an assigned shift |
| `POST` | `/commands/shifts/:shiftId/change-status` | Move shift to a new valid status |
| `POST` | `/commands/attendance/clock-in` | Record clock-in event |
| `POST` | `/commands/attendance/clock-out` | Record clock-out event |
| `POST` | `/commands/businesses/:businessId/favorite-staff` | Add favorite staff |
| `DELETE` | `/commands/businesses/:businessId/favorite-staff/:staffId` | Remove favorite staff |
| `POST` | `/commands/assignments/:assignmentId/reviews` | Create or update staff review |
| `GET` | `/readyz` | Ready check |
## 3) Order create
```text
POST /commands/orders/create
```
Request body:
```json
{
"tenantId": "uuid",
"businessId": "uuid",
"vendorId": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"serviceType": "EVENT",
"shifts": [
{
"shiftCode": "SHIFT-1",
"title": "Morning Shift",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"requiredWorkers": 2,
"roles": [
{
"roleCode": "BARISTA",
"roleName": "Barista",
"workersNeeded": 2
}
]
}
]
}
```
## 4) Order update
```text
POST /commands/orders/:orderId/update
```
Required body fields:
- `tenantId`
- at least one mutable field such as `title`, `description`, `vendorId`, `serviceType`, `startsAt`, `endsAt`, `locationName`, `locationAddress`, `latitude`, `longitude`, `notes`, `metadata`
You can also send `null` to clear nullable fields.
## 5) Order cancel
```text
POST /commands/orders/:orderId/cancel
```
Example request:
```json
{
"tenantId": "uuid",
"reason": "Client cancelled"
}
```
## 6) Shift assign staff
```text
POST /commands/shifts/:shiftId/assign-staff
```
Example request:
```json
{
"tenantId": "uuid",
"shiftRoleId": "uuid",
"workforceId": "uuid",
"applicationId": "uuid"
}
```
## 7) Shift accept
```text
POST /commands/shifts/:shiftId/accept
```
Example request:
```json
{
"shiftRoleId": "uuid",
"workforceId": "uuid"
}
```
## 8) Shift status change
```text
POST /commands/shifts/:shiftId/change-status
```
Example request:
```json
{
"tenantId": "uuid",
"status": "PENDING_CONFIRMATION",
"reason": "Waiting for worker confirmation"
}
```
Allowed status values:
- `DRAFT`
- `OPEN`
- `PENDING_CONFIRMATION`
- `ASSIGNED`
- `ACTIVE`
- `COMPLETED`
- `CANCELLED`
## 9) Attendance
### Clock in
```text
POST /commands/attendance/clock-in
```
### Clock out
```text
POST /commands/attendance/clock-out
```
Example request body for both:
```json
{
"assignmentId": "uuid",
"sourceType": "NFC",
"sourceReference": "iphone-15-pro-max",
"nfcTagUid": "NFC-DEMO-ANA-001",
"deviceId": "device-123",
"latitude": 37.422,
"longitude": -122.084,
"accuracyMeters": 8,
"capturedAt": "2026-03-11T17:15:00.000Z"
}
```
## 10) Favorite staff
### Add favorite
```text
POST /commands/businesses/:businessId/favorite-staff
```
### Remove favorite
```text
DELETE /commands/businesses/:businessId/favorite-staff/:staffId
```
Request body when adding:
```json
{
"tenantId": "uuid",
"staffId": "uuid"
}
```
## 11) Staff review
```text
POST /commands/assignments/:assignmentId/reviews
```
Example request:
```json
{
"tenantId": "uuid",
"businessId": "uuid",
"staffId": "uuid",
"rating": 5,
"reviewText": "Strong shift performance",
"tags": ["punctual", "professional"]
}
```
## 12) Live status
These routes were live-tested on `2026-03-11` against the deployed dev service and `krow-sql-v2`.

View File

@@ -0,0 +1,203 @@
# V2 Core API
Use `core-api-v2` for backend capabilities that should not live in the client.
Base URL:
```text
https://krow-core-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `POST` | `/core/upload-file` | Upload file to Google Cloud Storage |
| `POST` | `/core/create-signed-url` | Generate a read URL for an uploaded file |
| `POST` | `/core/invoke-llm` | Run a model call |
| `POST` | `/core/rapid-orders/transcribe` | Turn uploaded audio into text |
| `POST` | `/core/rapid-orders/parse` | Turn order text into structured order data |
| `POST` | `/core/verifications` | Create a verification job |
| `GET` | `/core/verifications/:verificationId` | Fetch verification status |
| `POST` | `/core/verifications/:verificationId/review` | Apply manual review decision |
| `POST` | `/core/verifications/:verificationId/retry` | Retry a verification job |
| `GET` | `/health` | Health check |
## 2) Upload file
Route:
```text
POST /core/upload-file
```
Send multipart form data:
- `file`: required
- `category`: optional string
- `visibility`: `public` or `private`
Example response:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/file.pdf",
"contentType": "application/pdf",
"size": 12345,
"bucket": "krow-workforce-dev-private",
"path": "uploads/<uid>/file.pdf",
"requestId": "uuid"
}
```
## 3) Create signed URL
Route:
```text
POST /core/create-signed-url
```
Example request:
```json
{
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/file.pdf",
"expiresInSeconds": 300
}
```
Example response:
```json
{
"signedUrl": "https://...",
"expiresAt": "2026-03-11T18:30:00.000Z",
"requestId": "uuid"
}
```
## 4) Invoke model
Route:
```text
POST /core/invoke-llm
```
Example request:
```json
{
"prompt": "Summarize this staffing request",
"fileUrls": ["gs://krow-workforce-dev-private/uploads/<uid>/notes.pdf"],
"responseJsonSchema": {
"type": "object",
"properties": {
"summary": { "type": "string" }
},
"required": ["summary"]
}
}
```
Example response:
```json
{
"result": {
"summary": "..."
},
"model": "vertex model name",
"latencyMs": 1200,
"requestId": "uuid"
}
```
## 5) Rapid order helpers
### Transcribe
```text
POST /core/rapid-orders/transcribe
```
Example request:
```json
{
"audioFileUri": "gs://krow-workforce-dev-private/uploads/<uid>/note.m4a",
"locale": "en-US",
"promptHints": ["staffing order", "shift details"]
}
```
### Parse
```text
POST /core/rapid-orders/parse
```
Example request:
```json
{
"text": "Need two baristas tomorrow from 8am to 4pm at Google Mountain View Cafe",
"locale": "en-US",
"timezone": "America/Los_Angeles"
}
```
## 6) Verification routes
### Create verification
```text
POST /core/verifications
```
Example request:
```json
{
"type": "attire",
"subjectType": "staff",
"subjectId": "staff-uuid",
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/attire.jpg",
"rules": {
"label": "black shoes"
}
}
```
### Get verification
```text
GET /core/verifications/:verificationId
```
### Manual review
```text
POST /core/verifications/:verificationId/review
```
Example request:
```json
{
"decision": "APPROVED",
"note": "Manual review passed"
}
```
### Retry
```text
POST /core/verifications/:verificationId/retry
```
## 7) Caveat
Verification state is not yet stored in `krow-sql-v2`.
Use these routes now for frontend integration, but do not depend on verification history being durable until the persistence work lands.

View File

@@ -0,0 +1,47 @@
# Mobile API Reconciliation
Source compared against implementation:
- `mobile-backend-api-specification.md`
## Result
The current mobile v2 surface is implemented behind the unified gateway and validated live in `dev`.
That includes:
- auth session routes
- client dashboard, billing, coverage, hubs, vendor lookup, managers, team members, orders, and reports
- client order, hub, coverage review, and invoice write flows
- staff dashboard, availability, payments, shifts, profile sections, documents, attire, certificates, bank accounts, benefits, privacy, and frequently asked questions
- staff availability, tax forms, emergency contacts, bank account, shift decision, clock-in/out, and swap write flows
- upload and verification flows for profile photo, government document, attire, and certificates
- attendance policy enforcement, geofence incident review, background location-stream ingest, and queued manager alerts
## What was validated live
The live smoke executed successfully against:
- `https://krow-api-v2-e3g6witsvq-uc.a.run.app`
- Firebase demo users
- `krow-sql-v2`
- `krow-core-api-v2`
- `krow-command-api-v2`
- `krow-query-api-v2`
The validation script is:
```bash
node backend/unified-api/scripts/live-smoke-v2-unified.mjs
```
## Remaining work
The remaining items are not blockers for current mobile frontend migration.
They are follow-up items:
- extend the same unified pattern to new screens added after the current mobile specification
- add stronger contract automation around the unified route surface
- add a device-token registry and dispatch worker on top of `notification_outbox`
- keep refining reporting and financial read models as product scope expands

View File

@@ -0,0 +1,407 @@
# Mobile Coding Agent Spec
This document is the frontend handoff spec for an AI coding agent working on the mobile applications against the v2 backend.
Use this as the primary implementation brief.
Base URL:
- `https://krow-api-v2-e3g6witsvq-uc.a.run.app`
Supporting docs:
- `/Users/wiel/Development/krow-workforce/docs/BACKEND/API_GUIDES/V2/authentication.md`
- `/Users/wiel/Development/krow-workforce/docs/BACKEND/API_GUIDES/V2/unified-api.md`
- `/Users/wiel/Development/krow-workforce/docs/BACKEND/API_GUIDES/V2/mobile-frontend-implementation-spec.md`
- `/Users/wiel/Development/krow-workforce/docs/BACKEND/API_GUIDES/V2/staff-shifts.md`
## 1) Non-negotiable rules
- Use the unified base URL only.
- Do not call `/query/*`, `/commands/*`, or `/core/*` directly from frontend.
- Send `Authorization: Bearer <firebase-id-token>` on protected routes.
- Send `Idempotency-Key` on every write route.
- Treat `order`, `shift`, `shiftRole`, and `assignment` as different objects.
- For staff shift applications, `roleId` must come from the response of `GET /staff/shifts/open`.
- For staff order booking, `roleId` must come from the response of `GET /staff/orders/:orderId`.
- Treat API timestamp fields as UTC and convert them to local time in the app.
## 2) What is implemented now
Safe to build against now:
- client auth/session
- client dashboard, billing, coverage, hubs, vendors, managers, team members, orders, reports
- client coverage reviews, worker rating, block/unblock, late-worker cancellation
- client swap review and dispatch-team management
- staff auth/session
- staff dashboard, availability, payments, shifts, profile, tax forms, bank accounts, benefits, documents, attire, certificates
- staff clock-in, clock-out, location streaming, swap request, completed-shift submission
- upload, signed URL, verification, and rapid-order processing
Not part of this implementation spec:
- backend `/auth/refresh`
- SMS or email notification fallback
- AI-driven report insights
- AI-driven personalized shift matching
- full NFC attestation enforcement
- chat backend
## 3) Auth implementation
### Client app
Use:
- `POST /auth/client/sign-in`
- `POST /auth/client/sign-up`
- `GET /auth/session`
- `POST /auth/client/sign-out`
Do not build a separate refresh route.
Token refresh remains on the Firebase client SDK side.
### Staff app
Use:
- `POST /auth/staff/phone/start`
- `POST /auth/staff/phone/verify`
- `GET /auth/session`
- `POST /auth/staff/sign-out`
Important:
- `POST /auth/staff/phone/start` can return `mode = CLIENT_FIREBASE_SDK`
- when that happens, the app must complete Firebase phone verification on-device
- after that, the app must call `POST /auth/staff/phone/verify` with the Firebase `idToken`
Do not assume staff auth is a fully backend-managed OTP flow.
## 4) Core data model assumptions
- `order`: client-facing staffing request
- `shift`: a scheduled work instance under an order
- `shiftRole`: a role slot inside a shift
- `application`: worker applies to a `shiftRole`
- `assignment`: worker is actually attached to a shift
Rules:
- `GET /staff/shifts/open` returns opportunities, not assignments
- `GET /staff/orders/available` returns grouped order opportunities for booking
- `GET /staff/shifts/assigned` returns active assigned shifts
- `GET /client/shifts/scheduled` is the canonical timeline/read model for client
- `GET /client/orders/view` is now a deprecated compatibility alias
- `POST /client/orders/:orderId/edit` and `POST /client/orders/:orderId/cancel` apply to future shifts only
## 5) Client app screen mapping
### Home
- `GET /client/session`
- `GET /client/dashboard`
- `GET /client/reorders`
### Billing
- `GET /client/billing/accounts`
- `GET /client/billing/invoices/pending`
- `GET /client/billing/invoices/history`
- `GET /client/billing/current-bill`
- `GET /client/billing/savings`
- `GET /client/billing/spend-breakdown`
- `POST /client/billing/invoices/:invoiceId/approve`
- `POST /client/billing/invoices/:invoiceId/dispute`
### Coverage
- `GET /client/coverage?date=YYYY-MM-DD`
- `GET /client/coverage/stats?date=YYYY-MM-DD`
- `GET /client/coverage/core-team?date=YYYY-MM-DD`
- `GET /client/coverage/incidents?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD`
- `GET /client/coverage/blocked-staff`
- `GET /client/coverage/swap-requests?status=OPEN`
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates?shiftId=uuid&roleId=uuid`
- `POST /client/coverage/reviews`
- `POST /client/coverage/late-workers/:assignmentId/cancel`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Coverage review payload:
```json
{
"assignmentId": "uuid",
"rating": 4,
"comment": "Strong performance on the shift",
"markAsBlocked": false
}
```
Rules:
- worker rating happens through `POST /client/coverage/reviews`
- the same endpoint also supports `markAsFavorite` to add or remove a worker from business favorites
- blocking a worker is done through the same endpoint using `markAsBlocked`
- coverage shift items now include `locationName` and `locationAddress`
- assigned worker items now include `hasReview`
- dispatch ranking order is:
1. `CORE`
2. `CERTIFIED_LOCATION`
3. `MARKETPLACE`
Swap management flow:
1. worker requests swap
2. backend moves original assignment to `SWAP_REQUESTED`
3. replacement workers see the shift in `GET /staff/shifts/open`
4. client/ops reads `GET /client/coverage/swap-requests`
5. client/ops reads `GET /client/coverage/dispatch-candidates`
6. client/ops resolves or cancels the swap request
7. if unresolved and expired, backend auto-cancels it
### Orders
- `GET /client/shifts/scheduled`
- `GET /client/orders/view` deprecated alias
- `GET /client/orders/:orderId/reorder-preview`
- `POST /client/orders/one-time`
- `POST /client/orders/recurring`
- `POST /client/orders/permanent`
- `POST /client/orders/:orderId/edit`
- `POST /client/orders/:orderId/cancel`
- `POST /rapid-orders/process`
Rules:
- use `POST /rapid-orders/process` for the single-call rapid-order flow
- recent orders should expect total price and hourly rate fields
- order edit and cancel only affect future shifts
### Hubs and managers
- `GET /client/hubs`
- `GET /client/cost-centers`
- `GET /client/hubs/:hubId/managers`
- `GET /client/team-members`
- `POST /client/shift-managers`
- `POST /client/hubs`
- `PUT /client/hubs/:hubId`
- `DELETE /client/hubs/:hubId`
- `POST /client/hubs/:hubId/assign-nfc`
- `POST /client/hubs/:hubId/managers`
Rules:
- `POST /client/shift-managers` creates an invited manager identity
- if `hubId` is present, backend links the manager to that hub too
### Reports
- `GET /client/reports/summary?date=YYYY-MM-DD`
- `GET /client/reports/daily-ops?date=YYYY-MM-DD`
- `GET /client/reports/spend?date=YYYY-MM-DD`
- `GET /client/reports/coverage?date=YYYY-MM-DD`
- `GET /client/reports/forecast?date=YYYY-MM-DD`
- `GET /client/reports/performance?date=YYYY-MM-DD`
- `GET /client/reports/no-show?date=YYYY-MM-DD`
Important:
- these are operational reports
- this is not the same as the separate AI insights research issue
## 6) Staff app screen mapping
### Home
- `GET /staff/session`
- `GET /staff/dashboard`
- `GET /staff/profile/stats`
- `GET /staff/profile-completion`
### Availability
- `GET /staff/availability`
- `PUT /staff/availability`
- `POST /staff/availability/quick-set`
### Find shifts
- `GET /staff/orders/available`
- `GET /staff/orders/:orderId`
- `POST /staff/orders/:orderId/book`
- `GET /staff/shifts/open`
- `POST /staff/shifts/:shiftId/apply`
Rule:
- use `GET /staff/orders/:orderId` as the source of truth for the order details page
- use `roleId` from the order-detail response when booking an order
- that `roleId` is the role catalog id for the grouped order booking flow
- if order booking returns `422`, render `details.blockers` and keep the worker on the order details page
- use `roleId` from the open-shifts response only for shift-level apply
- that `roleId` is the concrete `shift_roles.id`
### My shifts
- `GET /staff/shifts/pending`
- `GET /staff/shifts/assigned`
- `GET /staff/shifts/cancelled`
- `GET /staff/shifts/completed`
- `GET /staff/shifts/:shiftId`
- `POST /staff/shifts/:shiftId/accept`
- `POST /staff/shifts/:shiftId/decline`
- `POST /staff/shifts/:shiftId/request-swap`
- `POST /staff/shifts/:shiftId/submit-for-approval`
Staff shift detail and list rules:
- `GET /staff/orders/:orderId` returns the worker booking detail contract with `schedule`, `location`, `pay`, `staffing`, `managers`, and `eligibility`
- assigned shifts include `clientName`, `hourlyRate`, `totalRate`, `startTime`, `endTime`
- shift detail includes `clientName`, `latitude`, `longitude`, `hourlyRate`, `totalRate`
- completed shifts include `date`, `clientName`, `startTime`, `endTime`, `hourlyRate`, `totalRate`
- `GET /staff/profile/stats` returns `totalShifts`, `averageRating`, `ratingCount`, `onTimeRate`, `noShowCount`, `cancellationCount`, `reliabilityScore`
### Clock in / clock out
- `GET /staff/clock-in/shifts/today`
- `GET /staff/clock-in/status`
- `POST /staff/clock-in`
- `POST /staff/clock-out`
- `POST /staff/location-streams`
Clock-in payload rules:
- if using NFC, send `nfcTagId`
- if using geo, send `latitude`, `longitude`, `accuracyMeters`
- send `overrideReason` only when geo override is allowed
- send `proofNonce` and `proofTimestamp` on attendance writes
- send `attestationProvider` and `attestationToken` only if the device has them
- if backend returns `ALREADY_CLOCKED_IN`, treat it as a valid retry-state signal and refresh attendance/session state
Clock-in read rules:
`GET /staff/clock-in/shifts/today` returns fields including:
- `clientName`
- `hourlyRate`
- `totalRate`
- `latitude`
- `longitude`
- `clockInMode`
- `allowClockInOverride`
- `geofenceRadiusMeters`
- `nfcTagId`
Policy values:
- `NFC_REQUIRED`
- `GEO_REQUIRED`
- `EITHER`
### Payments
- `GET /staff/payments/summary`
- `GET /staff/payments/history`
- `GET /staff/payments/chart`
### Profile
- `GET /staff/profile/sections`
- `GET /staff/profile/personal-info`
- `GET /staff/profile/industries`
- `GET /staff/profile/skills`
- `GET /staff/profile/documents`
- `GET /staff/profile/attire`
- `GET /staff/profile/tax-forms`
- `GET /staff/profile/emergency-contacts`
- `GET /staff/profile/certificates`
- `GET /staff/profile/bank-accounts`
- `GET /staff/profile/benefits`
- `GET /staff/profile/benefits/history`
- `GET /staff/profile/time-card`
- `GET /staff/profile/privacy`
- `PUT /staff/profile/personal-info`
- `PUT /staff/profile/experience`
- `PUT /staff/profile/locations`
- `POST /staff/profile/emergency-contacts`
- `PUT /staff/profile/emergency-contacts/:contactId`
- `PUT /staff/profile/tax-forms/:formType`
- `POST /staff/profile/tax-forms/:formType/submit`
- `POST /staff/profile/bank-accounts`
- `PUT /staff/profile/privacy`
Profile data rules:
- `GET /staff/profile/documents` returns documents only
- `GET /staff/profile/attire` returns attire only
- `GET /staff/profile/tax-forms` returns tax forms only
- `GET /staff/profile/certificates` returns certificates only
- benefit summary and benefit history are separate endpoints
### FAQ
- `GET /staff/faqs`
- `GET /staff/faqs/search?q=...`
## 7) Upload flows
### General upload pattern
For documents, attire, and certificates:
1. `POST /upload-file`
2. `POST /create-signed-url`
3. upload bytes to storage
4. `POST /verifications`
5. finalize using the appropriate staff route
Staff upload routes:
- `POST /staff/profile/photo`
- `POST /staff/profile/documents/:documentId/upload`
- `PUT /staff/profile/documents/:documentId/upload`
- `POST /staff/profile/attire/:documentId/upload`
- `PUT /staff/profile/attire/:documentId/upload`
- `POST /staff/profile/certificates`
- `DELETE /staff/profile/certificates/:certificateId`
Rules:
- backend treats verification-linked file state as the source of truth
- frontend may still send `fileUri` or `photoUrl`, but verification linkage wins
## 8) What the coding agent should not assume
- do not invent a backend refresh route
- do not assume swap is staff-only; there is now a client/ops review side
- do not assume documents and attire share the same read endpoint
- do not assume backend direct CRUD on internal services
- do not assume AI reports, SMS fallback, or full NFC attestation are available
## 9) Suggested implementation order for the coding agent
1. auth/session flows
2. client home + orders + coverage
3. staff home + shifts + clock-in
4. profile sections and upload flows
5. reports and billing polish
6. swap review and dispatch-team management
## 10) Definition of done for frontend integration
Frontend implementation is aligned when:
- every screen calls the unified v2 routes only
- every write sends an `Idempotency-Key`
- staff shift apply uses `roleId` from open shifts
- clock-in respects `clockInMode`
- swap request uses the staff endpoint and swap review uses the client coverage endpoints
- documents, attire, certificates, and tax forms use their correct route families

View File

@@ -0,0 +1,317 @@
# Mobile Frontend Implementation Spec
This is the shortest path for frontend to implement the v2 mobile clients against the unified backend.
Base URL:
- `https://krow-api-v2-e3g6witsvq-uc.a.run.app`
Use this doc together with:
- [Authentication](./authentication.md)
- [Unified API](./unified-api.md)
- [Staff Shifts](./staff-shifts.md)
## 1) Global rules
- Use unified routes only.
- Send `Authorization: Bearer <firebase-id-token>` on protected routes.
- Send `Idempotency-Key` on all write routes.
- Do not call `/query/*`, `/commands/*`, or `/core/*` directly from frontend.
## 2) Core model frontend should assume
- `order` is the client-facing request for staffing.
- `shift` is the concrete scheduled unit of work under an order.
- `shiftRole` is the role slot inside a shift that staff apply to.
- `assignment` is the worker-to-shift record once a worker is attached.
Important consequences:
- `GET /staff/shifts/open` returns open shift-role opportunities.
- `POST /staff/shifts/:shiftId/apply` must send the `roleId` from that response.
- `GET /staff/orders/available` returns grouped order opportunities for atomic booking.
- `POST /staff/orders/:orderId/book` must send the `roleId` from that response.
- if order booking returns `422`, use `details.blockers` to explain why the worker is not eligible
- `GET /client/shifts/scheduled` is the canonical timeline/read model for the client app.
- `GET /client/orders/view` is a deprecated compatibility alias.
- `POST /client/orders/:orderId/edit` and `POST /client/orders/:orderId/cancel` only affect future shifts.
## 3) Auth implementation
### Client app
- sign in with `POST /auth/client/sign-in`
- sign up with `POST /auth/client/sign-up`
- hydrate session with `GET /auth/session`
- sign out with `POST /auth/client/sign-out`
### Staff app
- start phone auth with `POST /auth/staff/phone/start`
- complete phone auth with `POST /auth/staff/phone/verify`
- hydrate session with `GET /auth/session`
- sign out with `POST /auth/staff/sign-out`
Token refresh:
- keep using Firebase client SDK refresh behavior
- there is no backend `/auth/refresh` route
## 4) Client app screen mapping
### Home / dashboard
- `GET /client/session`
- `GET /client/dashboard`
- `GET /client/reorders`
### Billing / payments
- `GET /client/billing/accounts`
- `GET /client/billing/invoices/pending`
- `GET /client/billing/invoices/history`
- `GET /client/billing/current-bill`
- `GET /client/billing/savings`
- `GET /client/billing/spend-breakdown`
- `POST /client/billing/invoices/:invoiceId/approve`
- `POST /client/billing/invoices/:invoiceId/dispute`
### Coverage
- `GET /client/coverage?date=YYYY-MM-DD`
- `GET /client/coverage/stats?date=YYYY-MM-DD`
- `GET /client/coverage/core-team?date=YYYY-MM-DD`
- `GET /client/coverage/incidents?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD`
- `GET /client/coverage/blocked-staff`
- `GET /client/coverage/swap-requests?status=OPEN`
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates?shiftId=uuid&roleId=uuid`
- `POST /client/coverage/reviews`
- `POST /client/coverage/late-workers/:assignmentId/cancel`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Use `POST /client/coverage/reviews` when the business is rating a worker after coverage review.
Payload may include:
```json
{
"staffId": "uuid",
"assignmentId": "uuid",
"rating": 4,
"feedback": "Strong performance on the shift",
"markAsFavorite": true,
"markAsBlocked": false
}
```
If `markAsFavorite` is `true`, backend adds that worker to the business favorites list. If `markAsFavorite` is `false`, backend removes them from that list. If `markAsBlocked` is `true`, backend blocks that worker for that business and rejects future apply or assign attempts until a later review sets `markAsBlocked: false`.
Swap-management rule:
- use `GET /client/coverage/swap-requests` as the client review feed
- use `GET /client/coverage/dispatch-candidates` for the ranked replacement list
- use `POST /client/coverage/swap-requests/:swapRequestId/resolve` when ops selects a replacement
- use `POST /client/coverage/swap-requests/:swapRequestId/cancel` when ops wants to close the swap request without replacement
Dispatch-priority rule:
1. `CORE`
2. `CERTIFIED_LOCATION`
3. `MARKETPLACE`
### Orders
- `GET /client/shifts/scheduled`
- `GET /client/orders/view` deprecated alias
- `GET /client/orders/:orderId/reorder-preview`
- `POST /client/orders/one-time`
- `POST /client/orders/recurring`
- `POST /client/orders/permanent`
- `POST /client/orders/:orderId/edit`
- `POST /client/orders/:orderId/cancel`
Rapid-order flow:
- use `POST /rapid-orders/process` for the single-call transcribe-and-parse flow
### Hubs and managers
- `GET /client/hubs`
- `GET /client/cost-centers`
- `GET /client/hubs/:hubId/managers`
- `GET /client/team-members`
- `POST /client/shift-managers`
- `POST /client/hubs`
- `PUT /client/hubs/:hubId`
- `DELETE /client/hubs/:hubId`
- `POST /client/hubs/:hubId/assign-nfc`
- `POST /client/hubs/:hubId/managers`
`POST /client/shift-managers` is the fastest path to create an invited manager identity for a business. If `hubId` is provided, backend also links that manager to the hub.
### Reports
- `GET /client/reports/summary?date=YYYY-MM-DD`
- `GET /client/reports/daily-ops?date=YYYY-MM-DD`
- `GET /client/reports/spend?date=YYYY-MM-DD`
- `GET /client/reports/coverage?date=YYYY-MM-DD`
- `GET /client/reports/forecast?date=YYYY-MM-DD`
- `GET /client/reports/performance?date=YYYY-MM-DD`
- `GET /client/reports/no-show?date=YYYY-MM-DD`
## 5) Staff app screen mapping
### Home / dashboard
- `GET /staff/session`
- `GET /staff/dashboard`
- `GET /staff/profile-completion`
### Availability
- `GET /staff/availability`
- `PUT /staff/availability`
- `POST /staff/availability/quick-set`
### Find shifts
- `GET /staff/orders/available`
- `GET /staff/orders/:orderId`
- `POST /staff/orders/:orderId/book`
- `GET /staff/shifts/open`
- `POST /staff/shifts/:shiftId/apply`
Rule:
- use `GET /staff/orders/:orderId` as the source of truth for the order details page
- send the `roleId` from the order-detail response when booking an order
- this `roleId` is the role catalog id for grouped order booking
- if booking fails with `422`, render `details.blockers` and keep the worker on the review screen
- send the `roleId` from the open-shifts response only when applying to one shift
- that route still uses the concrete `shift_roles.id`
### My shifts
- `GET /staff/shifts/pending`
- `GET /staff/shifts/assigned`
- `GET /staff/shifts/cancelled`
- `GET /staff/shifts/completed`
- `GET /staff/shifts/:shiftId`
- `POST /staff/shifts/:shiftId/accept`
- `POST /staff/shifts/:shiftId/decline`
- `POST /staff/shifts/:shiftId/request-swap`
- `POST /staff/shifts/:shiftId/submit-for-approval`
Current swap behavior:
- backend records the swap request
- assignment moves to `SWAP_REQUESTED`
- shift becomes visible in the replacement pool
- client/ops can review and resolve swap requests through the coverage endpoints
- if the swap request expires without coverage, backend auto-cancels it and alerts both the manager path and the original worker
### Clock in / clock out
- `GET /staff/clock-in/shifts/today`
- `GET /staff/clock-in/status`
- `POST /staff/clock-in`
- `POST /staff/clock-out`
- `POST /staff/location-streams`
Frontend should respect:
- `clockInMode`
- `allowClockInOverride`
- `latitude`
- `longitude`
- `geofenceRadiusMeters`
- `nfcTagId`
Clock-in proof rules:
- use `nfcTagId` for NFC clocking
- use `latitude`, `longitude`, and `accuracyMeters` for geolocation clocking
- send `overrideReason` only when a geofence override is allowed
- send `proofNonce` and `proofTimestamp` on attendance writes
### Payments
- `GET /staff/payments/summary`
- `GET /staff/payments/history`
- `GET /staff/payments/chart`
### Profile
- `GET /staff/profile/sections`
- `GET /staff/profile/personal-info`
- `GET /staff/profile/industries`
- `GET /staff/profile/skills`
- `GET /staff/profile/documents`
- `GET /staff/profile/attire`
- `GET /staff/profile/tax-forms`
- `GET /staff/profile/emergency-contacts`
- `GET /staff/profile/certificates`
- `GET /staff/profile/bank-accounts`
- `GET /staff/profile/benefits`
- `GET /staff/profile/benefits/history`
- `GET /staff/profile/time-card`
- `GET /staff/profile/privacy`
- `PUT /staff/profile/personal-info`
- `PUT /staff/profile/experience`
- `PUT /staff/profile/locations`
- `POST /staff/profile/emergency-contacts`
- `PUT /staff/profile/emergency-contacts/:contactId`
- `PUT /staff/profile/tax-forms/:formType`
- `POST /staff/profile/tax-forms/:formType/submit`
- `POST /staff/profile/bank-accounts`
- `PUT /staff/profile/privacy`
Document model rule:
- `GET /staff/profile/documents` returns only documents
- `GET /staff/profile/attire` returns attire items
- `GET /staff/profile/tax-forms` returns tax-form rows
- `GET /staff/profile/certificates` returns certificates
### FAQ
- `GET /staff/faqs`
- `GET /staff/faqs/search?q=...`
## 6) Upload implementation
For documents, attire, and certificates:
1. `POST /upload-file`
2. `POST /create-signed-url`
3. upload file bytes to storage with the signed URL
4. `POST /verifications`
5. finalize with:
- `PUT /staff/profile/documents/:documentId/upload`
- `PUT /staff/profile/attire/:documentId/upload`
- `POST /staff/profile/certificates`
Use the verification-linked file as the source of truth.
## 7) What frontend should not assume
- do not assume order edit mutates past shifts
- do not assume swap resolution is complete beyond the request step
- do not assume raw `/query/*` or `/commands/*` routes are stable for app integration
- do not assume blocked workers can still apply to future shifts for that business
## 8) Demo reset
To reset dev demo data:
```bash
source ~/.nvm/nvm.sh
nvm use 23.5.0
cd backend/command-api
npm run seed:v2-demo
```

View File

@@ -0,0 +1,151 @@
# V2 Query API
Use `query-api-v2` for implemented read screens in the v2 clients.
Base URL:
```text
https://krow-query-api-v2-e3g6witsvq-uc.a.run.app
```
## 1) Required header
```http
Authorization: Bearer <firebase-id-token>
```
## 2) Route summary
| Method | Route | Purpose |
| --- | --- | --- |
| `GET` | `/query/tenants/:tenantId/orders` | Order list |
| `GET` | `/query/tenants/:tenantId/orders/:orderId` | Order detail with shifts and roles |
| `GET` | `/query/tenants/:tenantId/businesses/:businessId/favorite-staff` | Favorite staff list |
| `GET` | `/query/tenants/:tenantId/staff/:staffId/review-summary` | Staff rating summary and recent reviews |
| `GET` | `/query/tenants/:tenantId/assignments/:assignmentId/attendance` | Attendance session and event detail |
| `GET` | `/readyz` | Ready check |
## 3) Order list
```text
GET /query/tenants/:tenantId/orders
```
Optional query params:
- `businessId`
- `status`
- `limit`
- `offset`
Response shape:
```json
{
"items": [
{
"id": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"status": "OPEN",
"serviceType": "EVENT",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"businessId": "uuid",
"businessName": "Google Mountain View Cafes",
"vendorId": "uuid",
"vendorName": "Legendary Staffing Pool A",
"shiftCount": 1,
"requiredWorkers": 2,
"assignedWorkers": 1
}
],
"requestId": "uuid"
}
```
## 4) Order detail
```text
GET /query/tenants/:tenantId/orders/:orderId
```
Response shape:
```json
{
"id": "uuid",
"orderNumber": "ORD-1001",
"title": "Cafe Event Staffing",
"status": "OPEN",
"businessId": "uuid",
"businessName": "Google Mountain View Cafes",
"vendorId": "uuid",
"vendorName": "Legendary Staffing Pool A",
"shifts": [
{
"id": "uuid",
"shiftCode": "SHIFT-1",
"title": "Morning Shift",
"status": "OPEN",
"startsAt": "2026-03-12T08:00:00.000Z",
"endsAt": "2026-03-12T16:00:00.000Z",
"requiredWorkers": 2,
"assignedWorkers": 1,
"roles": [
{
"id": "uuid",
"roleCode": "BARISTA",
"roleName": "Barista",
"workersNeeded": 2,
"assignedCount": 1
}
]
}
],
"requestId": "uuid"
}
```
## 5) Favorite staff list
```text
GET /query/tenants/:tenantId/businesses/:businessId/favorite-staff
```
Optional query params:
- `limit`
- `offset`
## 6) Staff review summary
```text
GET /query/tenants/:tenantId/staff/:staffId/review-summary
```
Optional query params:
- `limit`
Response includes:
- staff identity
- average rating
- rating count
- recent reviews
## 7) Assignment attendance detail
```text
GET /query/tenants/:tenantId/assignments/:assignmentId/attendance
```
Response includes:
- assignment status
- shift info
- attendance session
- ordered attendance events
- NFC and geofence validation fields
## 8) Current boundary
Frontend should use only these documented reads on `query-api-v2`.
Do not point dashboard, reports, finance, or other undocumented list/detail views here yet.

View File

@@ -0,0 +1,285 @@
# Staff Shifts V2
This document is the frontend handoff for the `staff/shifts/*` routes on the unified v2 API.
Base URL:
- `https://krow-api-v2-e3g6witsvq-uc.a.run.app`
## Read routes
- `GET /staff/orders/available`
- `GET /staff/orders/:orderId`
- `GET /staff/shifts/assigned`
- `GET /staff/shifts/open`
- `GET /staff/shifts/pending`
- `GET /staff/shifts/cancelled`
- `GET /staff/shifts/completed`
- `GET /staff/shifts/:shiftId`
## Write routes
- `POST /staff/orders/:orderId/book`
- `POST /staff/shifts/:shiftId/apply`
- `POST /staff/shifts/:shiftId/accept`
- `POST /staff/shifts/:shiftId/decline`
- `POST /staff/shifts/:shiftId/request-swap`
- `POST /staff/shifts/:shiftId/submit-for-approval`
All write routes require:
- `Authorization: Bearer <firebase-id-token>`
- `Idempotency-Key: <unique-per-action>`
## Shift lifecycle
### Find work by order
`GET /staff/orders/available`
- use this for grouped recurring or permanent work cards
- each item represents one order plus one role
- this feed is already filtered to the current worker context
- `schedule` gives the preview for the whole booking window
Example response:
```json
{
"orderId": "uuid",
"orderType": "RECURRING",
"roleId": "uuid",
"roleCode": "BARISTA",
"roleName": "Barista",
"clientName": "Google Mountain View Cafes",
"location": "Google MV Cafe Clock Point",
"locationAddress": "1600 Amphitheatre Pkwy, Mountain View, CA",
"hourlyRateCents": 2300,
"hourlyRate": 23,
"requiredWorkerCount": 1,
"filledCount": 0,
"instantBook": false,
"dispatchTeam": "CORE",
"dispatchPriority": 1,
"schedule": {
"totalShifts": 3,
"startDate": "2026-03-24",
"endDate": "2026-03-28",
"daysOfWeek": ["WED", "FRI"],
"startTime": "09:00",
"endTime": "15:00",
"timezone": "America/Los_Angeles",
"firstShiftStartsAt": "2026-03-25T16:00:00.000Z",
"lastShiftEndsAt": "2026-03-27T22:00:00.000Z"
}
}
```
`POST /staff/orders/:orderId/book`
- use this when the worker books the full order instead of one shift
- booking is atomic across the future shifts in that order for the selected role
- backend returns `PENDING` when the booking is reserved but not instant-booked
- backend returns `CONFIRMED` when every future shift in that booking path is instant-booked
- backend returns `422 UNPROCESSABLE_ENTITY` when the worker is not eligible to book that order
Example request:
```json
{
"roleId": "uuid"
}
```
Important:
- `GET /staff/orders/:orderId` is now the source of truth for the order detail screen before booking
- `roleId` for the order-booking flow is the role catalog id returned by `GET /staff/orders/:orderId`
- it is not the same thing as the per-shift `shift_roles.id`
- when booking is rejected, use `details.blockers` from the error response to explain why
### Order detail
`GET /staff/orders/:orderId`
Use this as the source of truth for the worker order-review page before calling `POST /staff/orders/:orderId/book`.
Response shape includes:
- `orderId`
- `orderType`
- `roleId`
- `roleCode`
- `roleName`
- `clientName`
- `businessId`
- `instantBook`
- `dispatchTeam`
- `dispatchPriority`
- `jobDescription`
- `instructions`
- `status`
- `schedule`
- `location`
- `pay`
- `staffing`
- `managers`
- `eligibility`
Frontend rules:
- call this endpoint after a worker taps an order card from `GET /staff/orders/available`
- use the returned `roleId` when calling `POST /staff/orders/:orderId/book`
- if `eligibility.isEligible` is `false`, show the blocker messages and disable booking
### Find shifts
`GET /staff/shifts/open`
- use this for the worker marketplace feed
- the worker applies to a concrete shift role
- send the `roleId` returned by the open-shifts response
- `roleId` here means `shift_roles.id`, not the role catalog id
Apply request example:
```json
{
"roleId": "uuid",
"instantBook": false
}
```
### Pending shifts
`GET /staff/shifts/pending`
- use `POST /staff/shifts/:shiftId/accept` to accept
- use `POST /staff/shifts/:shiftId/decline` to decline
### Assigned shifts
`GET /staff/shifts/assigned`
Each item now includes:
- `clientName`
- `hourlyRate`
- `totalRate`
- `startTime`
- `endTime`
### Shift detail
`GET /staff/shifts/:shiftId`
Each detail response now includes:
- `clientName`
- `latitude`
- `longitude`
- `hourlyRate`
- `totalRate`
Use this as the source of truth for the shift detail screen.
### Request swap
`POST /staff/shifts/:shiftId/request-swap`
Example:
```json
{
"reason": "Need coverage for a family emergency"
}
```
Current backend behavior:
- marks the assignment as `SWAP_REQUESTED`
- stores the reason
- emits `SHIFT_SWAP_REQUESTED`
- exposes the shift in the replacement pool
- starts the swap-expiry window used by backend auto-cancellation
Manager/ops review happens through:
- `GET /client/coverage/swap-requests`
- `GET /client/coverage/dispatch-candidates`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
If the swap request expires without coverage, backend auto-cancels it and alerts the manager path plus the original worker.
### Submit completed shift for approval
`POST /staff/shifts/:shiftId/submit-for-approval`
Use this after the worker has clocked out.
Example:
```json
{
"note": "Worked full shift and all tasks were completed"
}
```
Current backend behavior:
- only allows shifts in `CHECKED_OUT` or `COMPLETED`
- creates or updates the assignment timesheet
- sets the timesheet to `SUBMITTED` unless it is already `APPROVED` or `PAID`
- emits `TIMESHEET_SUBMITTED_FOR_APPROVAL`
Example response:
```json
{
"assignmentId": "uuid",
"shiftId": "uuid",
"timesheetId": "uuid",
"status": "SUBMITTED",
"submitted": true
}
```
## Completed shifts
`GET /staff/shifts/completed`
Each item now includes:
- `date`
- `clientName`
- `startTime`
- `endTime`
- `hourlyRate`
- `totalRate`
- `timesheetStatus`
- `paymentStatus`
## Clock-in support fields
`GET /staff/clock-in/shifts/today`
Each item now includes:
- `clientName`
- `hourlyRate`
- `totalRate`
- `latitude`
- `longitude`
- `clockInMode`
- `allowClockInOverride`
## Frontend rule
Use the unified routes only.
Do not build new mobile work on:
- `/query/*`
- `/commands/*`
- `/core/*`

View File

@@ -0,0 +1,459 @@
# Unified API V2
Frontend should use this service as the single base URL:
- `https://krow-api-v2-e3g6witsvq-uc.a.run.app`
The gateway keeps backend services separate internally, but frontend should treat it as one API.
## 1) Auth routes
Full auth behavior, including staff phone flow and refresh rules, is documented in [Authentication](./authentication.md).
### Client auth
- `POST /auth/client/sign-in`
- `POST /auth/client/sign-up`
- `POST /auth/client/sign-out`
### Staff auth
- `POST /auth/staff/phone/start`
- `POST /auth/staff/phone/verify`
- `POST /auth/staff/sign-out`
### Shared auth
- `GET /auth/session`
- `POST /auth/sign-out`
## 2) Client routes
### Client reads
- `GET /client/session`
- `GET /client/dashboard`
- `GET /client/reorders`
- `GET /client/billing/accounts`
- `GET /client/billing/invoices/pending`
- `GET /client/billing/invoices/history`
- `GET /client/billing/current-bill`
- `GET /client/billing/savings`
- `GET /client/billing/spend-breakdown`
- `GET /client/coverage`
- `GET /client/coverage/stats`
- `GET /client/coverage/core-team`
- `GET /client/coverage/incidents`
- `GET /client/coverage/blocked-staff`
- `GET /client/coverage/swap-requests`
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates`
- `GET /client/hubs`
- `GET /client/cost-centers`
- `GET /client/vendors`
- `GET /client/vendors/:vendorId/roles`
- `GET /client/hubs/:hubId/managers`
- `GET /client/team-members`
- `GET /client/shifts/scheduled`
- `GET /client/orders/view` deprecated compatibility alias
- `GET /client/orders/:orderId/reorder-preview`
- `GET /client/reports/summary`
- `GET /client/reports/daily-ops`
- `GET /client/reports/spend`
- `GET /client/reports/coverage`
- `GET /client/reports/forecast`
- `GET /client/reports/performance`
- `GET /client/reports/no-show`
### Client writes
- `POST /client/devices/push-tokens`
- `DELETE /client/devices/push-tokens`
- `POST /client/orders/one-time`
- `POST /client/orders/recurring`
- `POST /client/orders/permanent`
- `POST /client/orders/:orderId/edit`
- `POST /client/orders/:orderId/cancel`
- `POST /client/shift-managers`
- `POST /client/hubs`
- `PUT /client/hubs/:hubId`
- `DELETE /client/hubs/:hubId`
- `POST /client/hubs/:hubId/assign-nfc`
- `POST /client/hubs/:hubId/managers`
- `POST /client/billing/invoices/:invoiceId/approve`
- `POST /client/billing/invoices/:invoiceId/dispute`
- `POST /client/coverage/reviews`
- `POST /client/coverage/late-workers/:assignmentId/cancel`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Timeline route naming:
- `GET /client/shifts/scheduled` is the canonical client timeline route
- it returns shift-level scheduled items, not order headers
- `GET /client/orders/view` still returns the same payload for compatibility, but now emits a deprecation header
Coverage-review request payload may also send:
```json
{
"staffId": "uuid",
"assignmentId": "uuid",
"rating": 2,
"feedback": "Worker left the shift early without approval",
"markAsFavorite": false,
"issueFlags": ["LEFT_EARLY"],
"markAsBlocked": true
}
```
If `markAsFavorite` is `true`, backend adds that worker to the business favorites list. If `markAsFavorite` is `false`, backend removes them from that list. If `markAsBlocked` is `true`, backend adds that staff member to the business-level blocked list and future apply or assign attempts are rejected until a later review sends `markAsBlocked: false`.
`GET /client/coverage` response notes:
- each shift item includes `locationName` and `locationAddress`
- each assigned worker item includes `hasReview`
Swap-review routes:
- `GET /client/coverage/swap-requests?status=OPEN`
- `POST /client/coverage/swap-requests/:swapRequestId/resolve`
- `POST /client/coverage/swap-requests/:swapRequestId/cancel`
Resolve example:
```json
{
"applicationId": "uuid",
"note": "Dispatch selected the strongest replacement candidate"
}
```
Dispatch-team routes:
- `GET /client/coverage/dispatch-teams`
- `GET /client/coverage/dispatch-candidates?shiftId=uuid&roleId=uuid`
- `POST /client/coverage/dispatch-teams/memberships`
- `DELETE /client/coverage/dispatch-teams/memberships/:membershipId`
Dispatch-team membership example:
```json
{
"staffId": "uuid",
"hubId": "uuid",
"teamType": "CORE",
"notes": "Preferred lead barista for this location"
}
```
Dispatch priority order is:
1. `CORE`
2. `CERTIFIED_LOCATION`
3. `MARKETPLACE`
Shift-manager creation example:
```json
{
"firstName": "Nora",
"lastName": "Lead",
"email": "nora.lead@example.com",
"phone": "+15550001234",
"hubId": "uuid"
}
```
The manager is created as an invited business membership. If `hubId` is present, backend also links the manager to that hub.
## 3) Staff routes
### Staff reads
- `GET /staff/session`
- `GET /staff/dashboard`
- `GET /staff/profile/stats`
- `GET /staff/profile-completion`
- `GET /staff/availability`
- `GET /staff/clock-in/shifts/today`
- `GET /staff/clock-in/status`
- `GET /staff/payments/summary`
- `GET /staff/payments/history`
- `GET /staff/payments/chart`
- `GET /staff/orders/available`
- `GET /staff/orders/:orderId`
- `GET /staff/shifts/assigned`
- `GET /staff/shifts/open`
- `GET /staff/shifts/pending`
- `GET /staff/shifts/cancelled`
- `GET /staff/shifts/completed`
- `GET /staff/shifts/:shiftId`
- `GET /staff/profile/sections`
- `GET /staff/profile/personal-info`
- `GET /staff/profile/industries`
- `GET /staff/profile/skills`
- `GET /staff/profile/documents`
- `GET /staff/profile/attire`
- `GET /staff/profile/tax-forms`
- `GET /staff/profile/emergency-contacts`
- `GET /staff/profile/certificates`
- `GET /staff/profile/bank-accounts`
- `GET /staff/profile/benefits`
- `GET /staff/profile/benefits/history`
- `GET /staff/profile/time-card`
- `GET /staff/profile/privacy`
- `GET /staff/faqs`
- `GET /staff/faqs/search`
Example `GET /staff/clock-in/shifts/today` item:
```json
{
"assignmentId": "uuid",
"shiftId": "uuid",
"title": "Assigned espresso shift",
"clientName": "Google Mountain View Cafes",
"hourlyRate": 23,
"roleName": "Barista",
"location": "Google MV Cafe Clock Point",
"locationAddress": "1600 Amphitheatre Pkwy, Mountain View, CA",
"latitude": 37.4221,
"longitude": -122.0841,
"startTime": "2026-03-17T13:48:23.482Z",
"endTime": "2026-03-17T21:48:23.482Z",
"clockInMode": "GEO_REQUIRED",
"allowClockInOverride": true,
"geofenceRadiusMeters": 120,
"nfcTagId": "NFC-DEMO-ANA-001",
"attendanceStatus": "NOT_CLOCKED_IN",
"clockInAt": null
}
```
Example `GET /staff/profile/stats` response:
```json
{
"staffId": "uuid",
"totalShifts": 12,
"averageRating": 4.8,
"ratingCount": 7,
"onTimeRate": 91.7,
"noShowCount": 1,
"cancellationCount": 0,
"reliabilityScore": 92.3
}
```
Order booking route notes:
- `GET /staff/orders/available` is the canonical order-level marketplace feed for recurring and grouped work
- `GET /staff/orders/:orderId` is the canonical staff order-detail route before booking
- `GET /staff/shifts/open` remains available for shift-level opportunities and swap coverage
- `POST /staff/orders/:orderId/book` books the future shifts of an order atomically for one role
- if booking is rejected for eligibility reasons, backend returns `422 UNPROCESSABLE_ENTITY` with `details.blockers`
- use the `roleId` returned by `GET /staff/orders/:orderId` when booking
- that `roleId` is the role catalog id for the order booking flow
- the `roleId` returned by `GET /staff/shifts/open` is still the concrete `shift_roles.id` for shift-level apply
### Staff writes
- `POST /staff/profile/setup`
- `POST /staff/devices/push-tokens`
- `DELETE /staff/devices/push-tokens`
- `POST /staff/clock-in`
- `POST /staff/clock-out`
- `POST /staff/location-streams`
- `PUT /staff/availability`
- `POST /staff/availability/quick-set`
- `POST /staff/orders/:orderId/book`
- `POST /staff/shifts/:shiftId/apply`
- `POST /staff/shifts/:shiftId/accept`
- `POST /staff/shifts/:shiftId/decline`
- `POST /staff/shifts/:shiftId/request-swap`
- `POST /staff/shifts/:shiftId/submit-for-approval`
- `PUT /staff/profile/personal-info`
- `PUT /staff/profile/experience`
- `PUT /staff/profile/locations`
- `POST /staff/profile/emergency-contacts`
- `PUT /staff/profile/emergency-contacts/:contactId`
- `PUT /staff/profile/tax-forms/:formType`
- `POST /staff/profile/tax-forms/:formType/submit`
- `POST /staff/profile/bank-accounts`
- `PUT /staff/profile/privacy`
## 4) Upload and verification routes
These are exposed as direct unified aliases even though they are backed by `core-api-v2`.
### Generic core aliases
- `POST /upload-file`
- `POST /create-signed-url`
- `POST /invoke-llm`
- `POST /rapid-orders/transcribe`
- `POST /rapid-orders/parse`
- `POST /rapid-orders/process`
- `POST /verifications`
- `GET /verifications/:verificationId`
- `POST /verifications/:verificationId/review`
- `POST /verifications/:verificationId/retry`
### Staff upload aliases
- `POST /staff/profile/photo`
- `POST /staff/profile/documents/:documentId/upload`
- `PUT /staff/profile/documents/:documentId/upload`
- `POST /staff/profile/attire/:documentId/upload`
- `PUT /staff/profile/attire/:documentId/upload`
- `POST /staff/profile/certificates`
- `DELETE /staff/profile/certificates/:certificateId`
## 5) Notes that matter for frontend
- `roleId` on `POST /staff/shifts/:shiftId/apply` is the concrete `shift_roles.id` for that shift, not the catalog role definition id.
- `accountType` on `POST /staff/profile/bank-accounts` accepts either lowercase or uppercase and is normalized by the backend.
- Document routes now return only document rows. They do not mix in attire items anymore.
- Tax-form data should come from `GET /staff/profile/tax-forms`, not `GET /staff/profile/documents`.
- Staff benefit activity should come from `GET /staff/profile/benefits/history`; the summary card should keep using `GET /staff/profile/benefits`.
- File upload routes return a storage path plus a signed URL. Frontend uploads the file directly to storage using that URL.
- The frontend upload contract for documents, attire, and certificates is:
1. `POST /upload-file`
2. `POST /create-signed-url`
3. `POST /verifications`
4. finalize with:
- `PUT /staff/profile/documents/:documentId/upload`
- `PUT /staff/profile/attire/:documentId/upload`
- `POST /staff/profile/certificates`
- Finalization requires `verificationId`. Frontend may still send `fileUri` or `photoUrl`, but the backend treats the verification-linked file as the source of truth.
- `POST /rapid-orders/process` is the single-call route for "transcribe + parse".
- `POST /client/orders/:orderId/edit` builds a replacement order from future shifts only.
- `POST /client/orders/:orderId/cancel` cancels future shifts only on the mobile surface and leaves historical shifts intact.
- Verification upload and review routes are live and were validated through document, attire, and certificate flows. Do not rely on long-lived verification history durability until the dedicated persistence slice is landed in `core-api-v2`.
- Attendance policy is explicit. Reads now expose `clockInMode` and `allowClockInOverride`.
- `clockInMode` values are:
- `NFC_REQUIRED`
- `GEO_REQUIRED`
- `EITHER`
- all source-of-truth timestamps are UTC ISO 8601 values. Frontend should convert them to local time for display.
- For `POST /staff/clock-in` and `POST /staff/clock-out`:
- send `nfcTagId` when clocking with NFC
- send `latitude`, `longitude`, and `accuracyMeters` when clocking with geolocation
- send `proofNonce` and `proofTimestamp` for attendance-proof logging; these are most important on NFC paths
- send `attestationProvider` and `attestationToken` only when the device has a real attestation result to forward
- send `overrideReason` only when the worker is bypassing a geofence failure and the shift/hub allows overrides
- if the worker is already clocked in, backend returns `409` with code `ALREADY_CLOCKED_IN`
- `POST /staff/location-streams` is for the background tracking loop after a worker is already clocked in.
- `GET /client/coverage/incidents` is the review feed for geofence breaches, missing-location batches, and clock-in overrides.
- `GET /client/coverage/blocked-staff` is the review feed for workers currently blocked by that business.
- `POST /client/coverage/late-workers/:assignmentId/cancel` is the client-side recovery action when lateness is confirmed by incident evidence or elapsed grace time.
- `GET /client/coverage/swap-requests` is the manager/ops review feed for swap requests, candidate applications, and status.
- `GET /client/coverage/dispatch-candidates` returns ranked candidates with the dispatch-team priority already applied.
- swap auto-cancellation is backend-driven. If a swap request expires without a replacement, backend cancels the original assignment, marks the swap request `AUTO_CANCELLED`, and alerts both the manager path and the original worker.
- Raw location stream payloads are stored in the private v2 bucket; SQL only stores the summary and incident index.
- Push delivery is backed by:
- SQL token registry in `device_push_tokens`
- durable queue in `notification_outbox`
- per-attempt delivery records in `notification_deliveries`
- private Cloud Run worker service `krow-notification-worker-v2`
- Cloud Scheduler job `krow-notification-dispatch-v2`
### Push token request example
```json
{
"provider": "FCM",
"platform": "IOS",
"pushToken": "expo-or-fcm-device-token",
"deviceId": "iphone-15-pro-max",
"appVersion": "2.0.0",
"appBuild": "2000",
"locale": "en-US",
"timezone": "America/Los_Angeles"
}
```
Push-token delete requests may send `tokenId` or `pushToken` either:
- as JSON in the request body
- or as query params on the `DELETE` URL
Using query params is safer when the client stack or proxy is inconsistent about forwarding `DELETE` bodies.
### Clock-in request example
```json
{
"shiftId": "uuid",
"sourceType": "GEO",
"deviceId": "iphone-15-pro",
"latitude": 37.4221,
"longitude": -122.0841,
"accuracyMeters": 12,
"proofNonce": "nonce-generated-on-device",
"proofTimestamp": "2026-03-16T09:00:00.000Z",
"overrideReason": "Parking garage entrance is outside the marked hub geofence",
"capturedAt": "2026-03-16T09:00:00.000Z"
}
```
### Location-stream batch example
```json
{
"shiftId": "uuid",
"sourceType": "GEO",
"deviceId": "iphone-15-pro",
"points": [
{
"capturedAt": "2026-03-16T09:15:00.000Z",
"latitude": 37.4221,
"longitude": -122.0841,
"accuracyMeters": 12
},
{
"capturedAt": "2026-03-16T09:30:00.000Z",
"latitude": 37.4301,
"longitude": -122.0761,
"accuracyMeters": 20
}
],
"metadata": {
"source": "background-workmanager"
}
}
```
### Coverage incidents response shape
```json
{
"items": [
{
"incidentId": "uuid",
"assignmentId": "uuid",
"shiftId": "uuid",
"staffName": "Ana Barista",
"incidentType": "OUTSIDE_GEOFENCE",
"severity": "CRITICAL",
"status": "OPEN",
"clockInMode": "GEO_REQUIRED",
"overrideReason": null,
"message": "Worker drifted outside hub geofence during active monitoring",
"distanceToClockPointMeters": 910,
"withinGeofence": false,
"occurredAt": "2026-03-16T09:30:00.000Z"
}
],
"requestId": "uuid"
}
```
## 6) Why this shape
- frontend gets one host
- backend keeps reads, writes, and service helpers separated
- routing can change internally later without forcing frontend rewrites

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
flowchart LR
subgraph C1["Login"]
S_client_sign_in["client_sign_in_screen.dart"]
S_client_sign_in --> S_client_sign_in_Q["Queries<br/>* user - getUserById<br/>* business - getBusinessesByUserId"]
S_client_sign_in --> S_client_sign_in_F["Firebase<br/>* user - auth"]
end
subgraph C2["Create account"]
S_client_sign_up["client_sign_up_screen.dart"]
S_client_sign_up --> S_client_sign_up_Q["Queries<br/>* business - getBusinessesByUserId"]
S_client_sign_up --> S_client_sign_up_M["Mutations<br/>* user - createUser<br/>* business - createBusiness"]
end
subgraph C3["Edit account"]
S_edit_account_na["manual_or_unknown_screen.dart"]
S_edit_account_na --> S_edit_account_na_M["Mutations<br/>* business - updateBusiness"]
end
subgraph C4["Profile"]
S_client_settings["client_settings_screen.dart"]
S_client_settings --> S_client_settings_Q["Queries<br/>* user - getUserById<br/>* business - getBusinessesByUserId"]
end
subgraph C5["Hubs"]
S_client_hubs["client_hubs_screen.dart"]
S_client_hubs --> S_client_hubs_Q["Queries<br/>* TeamHub - listTeamHubsByOwnerId"]
S_client_hubs --> S_client_hubs_M["Mutations<br/>* TeamHub - createTeamHub<br/>* TeamHub - updateTeamHub<br/>* TeamHub - deleteTeamHub"]
end
subgraph C6["Orders"]
S_client_shifts["client_shifts_screen.dart"]
S_client_shifts --> S_client_shifts_Q["Queries<br/>* order - getOrdersByBusinessId"]
end
subgraph C7["RAPID Order"]
S_rapid_order["rapid_order_flow_page.dart"]
S_rapid_order --> S_rapid_order_M["Mutations<br/>* order - createOrder"]
end
subgraph C8["One-time Order"]
S_one_time["one_time_order_flow_page.dart"]
S_one_time --> S_one_time_Q["Queries<br/>* role - listRolesByOwnerId"]
S_one_time --> S_one_time_M["Mutations<br/>* ShiftRole - createShiftRole<br/>* order - createOrder"]
end
subgraph C9["Permanent Placement"]
S_permanent["permanent_order_flow_page.dart"]
S_permanent --> S_permanent_Q["Queries<br/>* role - listRolesByOwnerId"]
S_permanent --> S_permanent_M["Mutations<br/>* ShiftRole - createShiftRole<br/>* order - createOrder"]
end
subgraph C10["Recurring Order"]
S_recurring["recurring_order_flow_page.dart"]
S_recurring --> S_recurring_Q["Queries<br/>* role - listRolesByOwnerId"]
S_recurring --> S_recurring_M["Mutations<br/>* ShiftRole - createShiftRole<br/>* order - createOrder"]
end
subgraph C11["Billing"]
S_billing["client_billing_screen.dart"]
S_billing --> S_billing_Q["Queries<br/>* account - getAccountsByOwnerId<br/>* invoice - listInvoicesByBusinessId<br/>* recentPayment - listRecentPaymentsByBusinessId"]
S_billing --> S_billing_M["Mutations<br/>* account - createAccount<br/>* account - updateAccount<br/>* account - deleteAccount"]
end
subgraph C12["Coverage"]
S_coverage["coverage_dashboard.dart"]
S_coverage --> S_coverage_Q["Queries<br/>* order - getOrdersByBusinessId<br/>* shift - getShiftsByBusinessId<br/>* application - getApplicationsByShiftId"]
end
subgraph C13["Home"]
S_client_home["client_home_screen.dart"]
S_client_home --> S_client_home_Q["Queries<br/>* order - getOrdersByBusinessId<br/>* shift - getShiftsByBusinessId<br/>* application - getApplicationsByShiftId<br/>* recentPayment - listRecentPaymentsByBusinessId"]
S_client_home --> S_client_home_M["Mutations<br/>* order - createOrder"]
end

View File

@@ -0,0 +1,121 @@
flowchart LR
subgraph L1["login/create user"]
S_auth_phone["phone_verification_screen.dart"]
S_auth_phone --> S_auth_phone_Q["Queries<br/>* user - getUserById<br/>* staff - getStaffByUserId"]
S_auth_phone --> S_auth_phone_M["Mutations<br/>* user - createUser"]
S_auth_phone --> S_auth_phone_F["Firebase<br/>* user - auth"]
end
subgraph L2["Profile"]
S_worker_profile["worker_profile_screen.dart"]
S_worker_profile --> S_worker_profile_Q["Queries<br/>* user - getUserById<br/>* staff - getStaffByUserId"]
end
subgraph L3["Personal info"]
S_personal_info["personal_info_screen.dart"]
S_personal_info --> S_personal_info_Q["Queries<br/>* staff - getStaffByUserId"]
S_personal_info --> S_personal_info_M["Mutations<br/>* staff - UpdateStaff"]
end
subgraph L4["Emergency Contact"]
S_emergency["emergency_contact_screen.dart"]
S_emergency --> S_emergency_Q["Queries<br/>* emergencyContact - getEmergencyContactsByStaffId"]
S_emergency --> S_emergency_M["Mutations<br/>* conemergencyContacttact - updateEmergencyContact<br/>* emergencyContact - createEmergencyContact<br/>* contemergencyContactact - deleteEmergencyContact"]
end
subgraph L5["Experience & skills"]
S_experience["experience_screen.dart"]
S_experience --> S_experience_Q["Queries<br/>* staff - getStaffByUserId"]
S_experience --> S_experience_M["Mutations<br/>* staff - UpdateStaff"]
end
subgraph L6["Attire"]
S_attire["attire_screen.dart"]
S_attire --> S_attire_Q["Queries<br/>* attireOption - filterAttireOptions<br/>* staff - getStaffByUserId"]
S_attire --> S_attire_M["Mutations<br/>* staff - UpdateStaff"]
end
subgraph L7["Documents"]
S_documents["documents_screen.dart"]
S_documents --> S_documents_Q["Queries<br/>* document - listDocuments<br/>* staffDocument - listStaffDocumentsByStaffId"]
S_documents --> S_documents_M["Mutations<br/>* staffDocument - updateStaffDocument<br/>* staffDocument - createStaffDocument"]
end
subgraph L8["Certificates"]
S_certificates["certificates_screen.dart"]
S_certificates --> S_certificates_Q["Queries<br/>* certificate - listCertificatesByStaffId"]
S_certificates --> S_certificates_M["Mutations<br/>* certificate - UpdateCertificate<br/>* certificate - CreateCertificate<br/>* certificate - DeleteCertificate"]
end
subgraph L9["Tax Documents"]
S_tax_forms["tax_forms_screen.dart"]
S_tax_forms --> S_tax_forms_Q["Queries<br/>* taxForm - getTaxFormsBystaffId"]
S_tax_forms --> S_tax_forms_M["Mutations<br/>* taxForm - createTaxForm<br/>* taxForm - updateTaxForm"]
end
subgraph L10["KROW University"]
S_uni["krow_university_screen.dart"]
S_uni --> S_uni_Q["Queries<br/>* course - listCourses<br/>* staffCourse - listStaffCoursesByStaffId<br/>* staff - getStaffByUserId<br/>* level - listLevels<br/>* certificate - listCertificatesByStaffId"]
end
subgraph L11["Trainings"]
S_trainings["trainings_screen.dart"]
S_trainings --> S_trainings_Q["Queries<br/>* course - listCourses<br/>* staffCourse - listStaffCoursesByStaffId"]
end
subgraph L12["Leaderboard"]
S_leaderboard["leaderboard_screen.dart"]
S_leaderboard --> S_leaderboard_Q["Queries<br/>* staffCourse - missing"]
end
subgraph L13["Bank Account"]
S_bank["bank_account_screen.dart"]
S_bank --> S_bank_Q["Queries<br/>* account - getAccountsByOwnerId"]
S_bank --> S_bank_M["Mutations<br/>* account - createAccount<br/>* account - updateAccount<br/>* account - deleteAccount"]
end
subgraph L14["Earnings/Payments"]
S_payments["payments_screen.dart"]
S_payments --> S_payments_Q["Queries<br/>* recentPayment - listRecentPaymentsByStaffId"]
end
subgraph L15["Timecard"]
S_timecard["time_card_screen.dart"]
S_timecard --> S_timecard_Q["Queries<br/>* application - getApplicationsByStaffId"]
end
subgraph L16["Clock in"]
S_clockin["clock_in_screen.dart"]
S_clockin --> S_clockin_Q["Queries<br/>* application - getApplicationsByStaffId"]
S_clockin --> S_clockin_M["Mutations<br/>* application - createApplication<br/>* application - updateApplicationStatus"]
end
subgraph L17["Shifts"]
S_shifts["shifts_screen.dart"]
S_shifts --> S_shifts_Q["Queries<br/>* application - getApplicationsByStaffId<br/>* shiftRole - listShiftRolesByVendorId/listShiftRolesByRoleId<br/>* application - getApplicationsByStaffId"]
S_shifts --> S_shifts_M["Mutations<br/>* application - updateApplicationStatus<br/>* application - createApplication"]
end
subgraph L18["My availability"]
S_availability["availability_screen.dart"]
S_availability --> S_availability_Q["Queries<br/>* staffAvailability - listStaffAvailabilitiesByStaffId/getStaffAvailabilityByKey"]
S_availability --> S_availability_M["Mutations<br/>* staffAvailability - updateStaffAvailability<br/>* staffAvailability - createStaffAvailability<br/>* staffAvailability - deleteStaffAvailability"]
end
subgraph L19["Your Benefits Overview"]
S_benefits["benefits_screen.dart"]
S_benefits --> S_benefits_Q["Queries<br/>* benefitsData - listBenefitsDataByStaffId"]
S_benefits --> S_benefits_M["Mutations<br/>* benefitsData - updateBenefitsData<br/>* benefitsData - createBenefitsData"]
end
subgraph L20["Home"]
S_home["worker_home_screen.dart"]
S_home --> S_home_Q["Queries<br/>* application - getApplicationsByStaffId<br/>* shiftRole - listShiftRolesByVendorId/listShiftRolesByRoleId<br/>* benefitsData - getBenefitsDataByStaffId"]
end
subgraph L21["Shift detail"]
S_shift_detail["shift_details_screen.dart"]
S_shift_detail --> S_shift_detail_Q["Queries<br/>* application - getApplicationsByStaffId"]
S_shift_detail --> S_shift_detail_M["Mutations<br/>* application - updateApplicationStatus"]
end

View File

@@ -0,0 +1,130 @@
---
config:
theme: mc
layout: dagre
---
classDiagram
direction TB
class User {
id: String
email: String
}
class Business {
id: UUID
userId: String
businessName: String
status: BusinessStatus
}
class Vendor {
id: UUID
userId: String
companyName: String
}
class Order {
id: UUID
businessId: UUID
vendorId: UUID
status: OrderStatus
}
class Shift {
id: UUID
orderId: UUID
status: ShiftStatus
}
class ShiftRole {
shiftId: UUID
roleId: UUID
}
class Role {
id: UUID
name: String
vendorId: UUID
}
class Application {
id: UUID
shiftId: UUID
staffId: UUID
roleId: UUID
}
class Invoice {
id: UUID
businessId: UUID
vendorId: UUID
orderId: UUID
status: InvoiceStatus
}
class InvoiceTemplate {
id: UUID
name: String
ownerId: UUID
businessId: UUID
vendorId: UUID
}
class RecentPayment {
id: UUID
invoiceId: UUID
applicationId: UUID
staffId: UUID
}
class ClientFeedback {
id: UUID
businessId: UUID
vendorId: UUID
rating: Int
}
class Team {
id: UUID
teamName: String
ownerId: String
}
class TeamMember {
id: UUID
teamId: UUID
userId: String
role: TeamMemberRole
}
class TeamHub {
id: UUID
teamId: UUID
hubName: String
}
class Staff {
id: UUID
userId: String
}
note for Staff "business can create a staff too"
Business "1" -- "*" Order : places
Business "1" -- "*" Invoice : receives
Business "1" -- "*" ClientFeedback : gives
Business "1" --o "1" Team : (ownerId)
Business "1" --o "*" InvoiceTemplate : (ownerId)
User "1" -- "1" Business : owns
Vendor "1" -- "*" Order : fulfills
Vendor "1" -- "*" Invoice : issues
Order "1" -- "*" Shift : contains
Order "1" -- "1" Invoice : billed via
Shift "1" -- "*" ShiftRole : requires
ShiftRole "1" -- "1" Role
ShiftRole "1" -- "*" Application : target for
Application "1" -- "1" Staff
Application "1" -- "1" RecentPayment
Invoice "1" -- "*" RecentPayment : paid through
Team "1" -- "*" TeamHub : contains
Team "1" -- "*" TeamMember : has

View File

@@ -0,0 +1,181 @@
classDiagram
direction TB
class User {
id: String
email: String
fullName: String
role: UserBaseRole
}
class Staff {
id: UUID
userId: String
fullName: String
ownerId: UUID
hubId: UUID
rollId: UUID
status: BackgroundCheckStatus
}
class Account{
id: UUID
ownerId:UUID
type:AccountType
}
class Workforce {
id: UUID
vendorId: UUID
staffId: UUID
status: WorkforceStatus
}
class Application {
id: UUID
shiftId: UUID
staffId: UUID
roleId: UUID
status: ApplicationStatus
}
class Assignment {
id: UUID
workforceId: UUID
shiftId: UUID
roleId: UUID
status: AssignmentStatus
}
class ShiftRole {
id: UUID
shiftId: UUID
roleId: UUID
}
class Shift {
id: UUID
orderId: UUID
status: ShiftStatus
}
class Order {
id: UUID
vendorId: UUID
businessId: UUID
status: OrderStatus
}
class Vendor {
id: UUID
userId: String
companyName: String
}
class Business {
id: UUID
userId: String
businessName: String
}
class Role {
id: UUID
name: String
vendorId: UUID
roleCategoryId: UUID
}
class StaffDocument {
staffId: UUID
documentId: UUID
status: DocumentStatus
}
class Document {
id: UUID
name: String
documentType: DocumentType
}
class StaffCourse {
staffId: UUID
courseId: UUID
}
class Course {
id: UUID
title: String
categoryId: UUID
}
class Category {
id: UUID
label: String
}
class StaffAvailability {
staffId: UUID
day: DayOfWeek
slot: AvailabilitySlot
}
class Certificate {
staffId: UUID
certificationType: ComplianceType
status: CertificateStatus
}
class BenefitData {
staffId: UUID
vendorBenefitPlanId: UUID
current: int
}
class Contact {
staffId: UUID
relationship: RelationshipType
name: string
}
class Invoice {
orderId: UUID
}
class RecentPayment {
staffId: UUID
applicationId: UUID
status: RecentPaymentStatus
}
class TaxForm {
staffId: UUID
formType: TaxFormType
status: TaxFormStatus
}
User "1" -- "1" Staff : has
Staff "1" -- "*" Application : applies to
Staff "1" -- "*" Workforce : part of
Staff "1" -- "*" StaffDocument : has
Staff "1" -- "*" Certificate : has
Staff "1" -- "*" BenefitData : has
Staff "1" -- "*" Contact : has
Staff "1" -- "*" TaxForm : has
Staff "1" -- "*" Account : has
Staff "1" -- "*" StaffCourse : takes
Staff "1" -- "*" StaffAvailability : sets
Workforce "1" -- "*" Assignment : receives
Assignment -- ShiftRole
Vendor "1" -- "*" Order : receives
Business "1" -- "*" Order : places
Order "1" -- "1" Invoice : has
Invoice "1" -- "*" RecentPayment : has
RecentPayment "1" -- "1" Application : has
Staff "1" --o "1" Vendor : (ownerId)
Staff "1" --o "1" Business : (ownerId)
Application -- ShiftRole
ShiftRole "*" -- "1" Shift : belongs to
ShiftRole "*" -- "1" Role : defines
Shift "*" -- "1" Order : belongs to
StaffDocument "1" -- "1" Document : references
StaffCourse "1" -- "1" Course : references
Course "1" -- "1" Category : belongs to

View File

@@ -0,0 +1,79 @@
---
config:
layout: elk
theme: mc
---
classDiagram
class User {
id: String
email: String
fullName: String
}
class TeamMember {
id: UUID
teamId: UUID
userId: String
teamHubId: UUID
role: TeamMemberRole
inviteStatus: TeamMemberInviteStatus
inviteCode: UUID
}
class Team {
id: UUID
teamName: String
ownerId: String
}
class TeamHub {
id: UUID
teamId: UUID
hubName: String
}
class TeamHudDepartment {
id: UUID
name: String
teamHubId: UUID
}
class MemberTask {
teamMemberId: UUID
taskId: UUID
}
class Task {
id: UUID
taskName: String
status: TaskStatus
priority: TaskPriority
ownerId: UUID
}
class Vendor {
id: UUID
companyName: String
}
class Business {
id: UUID
businessName: String
}
User "1" -- "1" TeamMember : has
Team "1" -- "*" TeamHub : contains
Team "1" --o "1" Vendor : (ownerId)
Team "1" --o "1" Business : (ownerId)
TeamHub "1" -- "*" TeamHudDepartment : has
TeamHub "1" -- "*" TeamMember : is assigned to
TeamMember "*" -- "1" Team
TeamMember "1" -- "*" MemberTask : has assigned
Task "1" -- "*" MemberTask : is assigned to
Task --o Vendor : (ownerId)
Task --o Business : (ownerId)

View File

@@ -0,0 +1,71 @@
classDiagram
direction TB
class User {
id: String
email: String
fullName: String
role: UserBaseRole
}
class Staff {
id: UUID
userId: String
fullName: String
ownerId: UUID
hubId: UUID
rollId: UUID
status: BackgroundCheckStatus
}
class Vendor {
id: UUID
userId: String
companyName: String
}
class Business {
id: UUID
userId: String
businessName: String
}
class TeamMember {
id: UUID
teamId: UUID
userId: String
role: TeamMemberRole
}
class ActivityLog {
id: UUID
userId: String
activityType: ActivityType
}
class UserConversation {
conversationId: UUID
userId: String
}
class Conversation {
id: UUID
conversationType: ConversationType
}
class Message{
id: UUID
conversationId: UUID
content: String
}
User <|-- Staff
User <|-- Business
User <|-- Vendor
User <|-- TeamMember
User "1" -- "*" ActivityLog : logs
User "1" -- "*" UserConversation : participates in
UserConversation "*" -- "1" Conversation : is part of
Conversation "1" -- "*" Message : has

View File

@@ -0,0 +1,164 @@
---
config:
layout: dagre
---
classDiagram
direction TB
class User {
id: String
email: String
}
class Vendor {
id: UUID
userId: String
companyName: String
tier: VendorTier
}
class Staff {
id: UUID
userId: String
fullName: String
}
class VendorBenefitPlan {
id: UUID
vendorId: UUID
title: String
}
class InvoiceTemplate {
id: UUID
name: String
ownerId: UUID
}
class VendorRate {
id: UUID
vendorId: UUID
roleName: String
}
class AttireOption{
id: UUID
vendorId: UUID
}
class Team {
id: UUID
teamName: String
ownerId: String
}
class TeamMember {
id: UUID
teamId: UUID
userId: String
role: TeamMemberRole
}
class TeamHub {
id: UUID
teamId: UUID
hubName: String
}
class Business {
id: UUID
userId: String
businessName: String
}
class ClientFeedback {
id: UUID
businessId: UUID
vendorId: UUID
rating: Int
}
class Order {
id: UUID
vendorId: UUID
businessId: UUID
status: OrderStatus
}
class Shift {
id: UUID
orderId: UUID
status: ShiftStatus
}
class Role {
id: UUID
name: String
vendorId: UUID
}
class ShiftRole {
shiftId: UUID
roleId: UUID
}
class Workforce {
id: UUID
vendorId: UUID
staffId: UUID
status: WorkforceStatus
}
class Application {
id: UUID
shiftId: UUID
staffId: UUID
roleId: UUID
status: ApplicationStatus
}
class Assignment {
id: UUID
workforceId: UUID
shiftId: UUID
roleId: UUID
status: AssignmentStatus
}
class Invoice {
id: UUID
vendorId: UUID
businessId: UUID
orderId: UUID
status: InvoiceStatus
}
class RecentPayment {
id: UUID
staffId: UUID
applicationId: UUID
invoiceId: UUID
status: RecentPaymentStatus
}
note for Vendor "All tables has relationship with vendor"
User "1" -- "1" Vendor : has
Vendor "1" o-- "1" Staff : (ownerId)
Vendor "1" -- "*" VendorBenefitPlan : offers
Vendor "1" -- "*" AttireOption
Vendor o-- InvoiceTemplate : (ownerId)
Vendor "1" -- "*" VendorRate : has
Vendor "1" -- "*" ClientFeedback : receives
Vendor "1" -- "*" Order : receives
Business "1" -- "*" Order : places
Order "1" -- "*" Shift : contains
Shift "1" -- "*" ShiftRole : requires
Role "1" -- "*" ShiftRole : fills
ShiftRole "1" -- "*" Application : receives
Assignment "1" -- "1" ShiftRole
Assignment "1" -- "1" Workforce
Invoice "1" -- "1" Order
Invoice "1" -- "*" RecentPayment : details
Vendor "1" o-- "1" Team
Team "1" -- "*" TeamHub : contains
Team "1" -- "*" TeamMember : has

View File

@@ -0,0 +1,308 @@
# KROW Workforce Backend Manual
Firebase Data Connect + Cloud SQL (PostgreSQL)
---
## 1. Backend Overview
This project uses Firebase Data Connect with Cloud SQL (PostgreSQL) as the main backend system.
The architecture is based on:
- GraphQL Schemas → Define database tables
- Connectors (Queries & Mutations) → Data access layer
- Cloud SQL → Real database
- Auto-generated SDK → Used by Web & Mobile apps
- Makefile → Automates backend workflows
The goal is to keep the backend scalable, structured, and aligned with Web and Mobile applications.
---
## 2. Project Structure
```
dataconnect/
├── dataconnect.yaml
├── schema/
│ ├── Staff.gql
│ ├── Vendor.gql
│ ├── Business.gql
│ └── ...
├── connector/
│ ├── staff/
│ │ ├── queries.gql
│ │ └── mutations.gql
│ ├── invoice/
│ └── ...
├── connector/connector.yaml
docs/backend-diagrams/
│ ├── business_uml_diagram.mmd
│ ├── staff_uml_diagram.mmd
│ ├── team_uml_diagram.mmd
│ ├── user_uml_diagram.mmd
│ └── vendor_uml_diagram_simplify.mmd
```
---
## 3. dataconnect.yaml (Main Configuration)
```yaml
specVersion: "v1"
serviceId: "krow-workforce-db"
location: "us-central1"
schema:
source: "./schema"
datasource:
postgresql:
database: "krow_db"
cloudSql:
instanceId: "krow-sql"
connectorDirs: ["./connector"]
```
### Purpose
| Field | Description |
|------|------------|
| serviceId | Data Connect service name |
| schema.source | Where GraphQL schemas live |
| datasource | Cloud SQL connection |
| connectorDirs | Where queries/mutations are |
---
## 4. Database Schemas
All database schemas are located in:
```
dataconnect/schema/
```
Each `.gql` file represents a table:
- Staff.gql
- Invoice.gql
- ShiftRole.gql
- Application.gql
- etc.
Schemas define:
- Fields
- Enums
- Relationships (`@ref`)
- Composite keys (`key: []`)
---
## 5. Queries & Mutations (Connectors)
Located in:
```
dataconnect/connector/<entity>/
```
Example:
```
dataconnect/connector/staff/queries.gql
dataconnect/connector/staff/mutations.gql
```
Each folder represents one entity.
This layer defines:
- listStaff
- getStaffById
- createStaff
- updateStaff
- deleteStaff
- etc.
---
## 6. connector.yaml (SDK Generator)
```yaml
connectorId: example
generate:
dartSdk:
- outputDir: ../../mobile/staff/staff_app_mvp/lib/dataconnect_generated
package: dataconnect_generated/generated.dart
- outputDir: ../../mobile/client/client_app_mvp/lib/dataconnect_generated
package: dataconnect_generated/generated.dart
```
This file generates the SDK for:
- Staff Mobile App
- Client Mobile App
---
## 7. What is the SDK?
The SDK is generated using:
```bash
firebase dataconnect:sdk:generate
```
It allows the apps to:
- Call queries/mutations
- Use strong typing
- Avoid manual GraphQL
- Reduce runtime errors
Example in Flutter:
```dart
client.listStaff();
client.createInvoice();
```
---
## 8. Makefile Automation Commands
### Main Commands
| Command | Purpose |
|--------|---------|
| dataconnect-enable-apis | Enable required APIs |
| dataconnect-init | Initialize Data Connect |
| dataconnect-deploy | Deploy schemas |
| dataconnect-sql-migrate | Apply DB migrations |
| dataconnect-generate-sdk | Generate SDK |
| dataconnect-sync | Fast connector + SDK sync |
| dataconnect-sync-full | Full backend update |
| dataconnect-test | Test without breaking |
| dataconnect-seed | Insert seed data |
| dataconnect-bootstrap-db | Create Cloud SQL |
---
## 9. Correct Backend Workflow
### Query/Connector Flow
```bash
make dataconnect-sync
```
Steps:
1. Deploy connector
2. Generate SDK
---
### Full Schema Flow
```bash
make dataconnect-sync-full
```
Steps:
1. Deploy schema
2. Run SQL migrations
3. Generate SDK
---
### Safe Test Flow
```bash
make dataconnect-test
```
This runs:
- Deploy dry-run
- SQL diff
- Shows errors without changing DB
---
## 10. Seed Data
Current command:
```make
dataconnect-seed:
@firebase dataconnect:execute seeds/seed_min.graphql --project=$(FIREBASE_ALIAS)
```
Purpose:
- Validate schema
- Detect missing tables
- Prevent bad inserts
---
## 11. UML Diagrams
Located in:
```
docs/backend-diagrams/
```
Divided by role:
| File | Scope |
|------|-------|
| user_uml_diagram.mmd | User |
| staff_uml_diagram.mmd | Staff |
| vendor_uml_diagram_simplify.mmd | Vendor |
| business_uml_diagram.mmd | Business |
| team_uml_diagram.mmd | Teams |
Used with Mermaid to visualize relationships.
---
## 12. Core Business Workflow
```text
Order
→ Shift
→ ShiftRole
→ Application
→ Workforce
→ Assignment
→ Invoice
→ RecentPayment
```
This represents the full work & payment lifecycle.
---
## 13. Final Notes
This backend is designed to:
- Scale efficiently
- Maintain data consistency
- Align Web & Mobile models
- Support reporting and billing
- Avoid duplicated data
---
END OF MANUAL

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
# Backend Cloud Run / Functions Guide
## 1) Validate Shift Acceptance (Worker)
**Best fit:** Cloud Run
**Why backend logic is required**
- Shift acceptance must be enforced serverside to prevent bypassing the client.
- It must be racecondition safe (two accepts at the same time).
- It needs to be extensible for future eligibility rules.
**Proposed backend solution**
Add a single command endpoint:
- `POST /shifts/:shiftId/accept`
**Backend flow**
- Verify Firebase Auth token + permissions (worker identity).
- Run an extensible validation pipeline (pluggable rules):
- `NoOverlapRule` (M4)
- Future rules can be added without changing core logic.
- Apply acceptance in a DB transaction (atomic).
- Return a clear error payload on rejection:
- `409 CONFLICT` (overlap) with `{ code, message, conflictingShiftIds }`
---
## 2) Validate Shift Creation by a Client (Minimum Hours — soft check)
**Best fit:** Cloud Run
**Why backend logic is required**
- Creation rules must be enforced serverside so clients cant bypass validations by skipping the UI or calling APIs directly.
- We want a scalable rule system so new creation checks can be added without rewriting core logic.
**Proposed backend solution**
Add/route creation through a backend validation layer (Cloud Run endpoint or a dedicated “create order” command).
**On create**
- Compute shift duration and compare against vendor minimum (current: **5 hours**).
- Return a consistent validation response when below minimum, e.g.:
- `200 OK` with `{ valid: false, severity: "SOFT", code: "MIN_HOURS", message, minHours: 5 }`
- (or `400` only if we decide it should block creation; for now its a soft check)
**FE note**
- Show the same message before submission (UX feedback), but backend remains the source of truth.
---
## 3) Enforce Cancellation Policy (no cancellations within 24 hours)
**Best fit:** Cloud Run
**Why backend logic is required**
- Cancellation restrictions must be enforced serverside to prevent policy bypass.
- Ensures consistent behavior across web/mobile and future clients.
**Proposed backend solution**
Add a backend command endpoint for cancel:
- `POST /shifts/:shiftId/cancel` (or `/orders/:id/cancel` depending on ownership model)
**Backend checks**
- If `now >= shiftStart - 24h`, reject cancellation.
**Error response**
- `403 FORBIDDEN` (or `409 CONFLICT`) with `{ code: "CANCEL_WINDOW_LOCKED", message, windowHours: 24, penalty: <TBD> }`
- Once penalty is finalized, include it in the response and logs/audit trail.
---
## 4) Implement Worker Documentation Upload Process
**Best fit:** Cloud Functions v2 + Cloud Storage
**Why backend logic is required**
- Uploads must be stored securely and reliably linked to the correct worker profile.
- Requires serverside auth and auditing.
**Proposed backend solution**
- HTTP/Callable Function: `uploadInit(workerId, docType)` → returns signed upload URL + `documentId`.
- Client uploads directly to Cloud Storage.
- Storage trigger (`onFinalize`) or `uploadComplete(documentId)`:
- Validate uploader identity/ownership.
- Store metadata in DB (type, path, status, timestamps).
- Link document to worker profile.
- Enforce access control (worker/self, admins, authorized client reviewers).
---
## 5) Parse Uploaded Documentation for Verification
**Best fit:** Cloud Functions (eventdriven) or Cloud Run worker (async)
**Why backend logic is required**
- Parsing should run asynchronously.
- Store structured results for review while keeping manual verification as the final authority.
**Proposed backend solution**
- Trigger on Storage upload finalize:
- OCR/AI extract key fields → store structured output (`parsedFields`, `confidence`, `aiStatus`).
- Keep manual review:
- Client can approve/override AI results.
- Persist reviewer decision + audit trail.
---
## 6) Support Attire Upload for Workers
**Best fit:** Cloud Functions v2 + Cloud Storage
**Why backend logic is required**
- Attire images must be securely stored and linked to the correct worker profile.
- Requires serverside authorization.
**Proposed backend solution**
- HTTP/Callable Function: `attireUploadInit(workerId)` → signed upload URL + `attireAssetId`.
- Client uploads to Cloud Storage.
- Storage trigger (`onFinalize`) or `attireUploadComplete(attireAssetId)`:
- Validate identity/ownership.
- Store metadata and link to worker profile.
---
## 7) Verify Attire Images Against Shift Dress Code
**Best fit:** Cloud Functions (trigger) or Cloud Run worker (async)
**Why backend logic is required**
- Verification must be enforced serverside.
- Must remain reviewable/overrideable by the client even if AI passes.
**Proposed backend solution**
- Async verification triggered after upload or when tied to a shift:
- Evaluate dress code rules (and optional AI).
- Store results `{ status, reasons, evidence, confidence }`.
- Client can manually approve/override; audit every decision.
---
## 8) Support Shifts Requiring “Awaiting Confirmation” Status
**Best fit:** Cloud Run (domain state transitions)
**Why backend logic is required**
- State transitions must be enforced serverside.
- Prevent invalid bookings and support future workflow rules.
**Proposed backend solution**
- Add status flow: `AWAITING_CONFIRMATION → BOOKED/ACTIVE` (per lifecycle).
- Command endpoint: `POST /shifts/:id/confirm`.
**Backend validates**
- Caller is the assigned worker.
- Shift is still eligible (not started/canceled/overlapped, etc.).
- Persist transition + audit event.
---
## 9) Enable NFCBased ClockIn and ClockOut
**Best fit:** Cloud Run (secure API) + optional Cloud Functions for downstream events
**Why backend logic is required**
- Clockin/out is securitysensitive and must be validated serverside.
- Requires strong auditing and antifraud checks.
**Proposed backend solution**
API endpoints:
- `POST /attendance/clock-in`
- `POST /attendance/clock-out`
**Validate**
- Firebase identity.
- NFC tag legitimacy (mapped to hub/location).
- Time window rules + prevent duplicates/inconsistent sequences.
**Persist**
- Store immutable events + derived attendance record.
- Emit audit logs/alerts if needed.
---
## 10) Update Recurring & Permanent Orders (Backend)
**Best fit:** Cloud Run
**Why backend logic is required**
Updating a recurring or permanent order is not a single update. It may affect **N shifts** and **M shift roles**, and requires extra validations, such as:
- Prevent editing shifts that already started.
- Prevent removing or reducing roles with assigned staff.
- Control whether changes apply to future only, from a given date, or all.
- Ensure data consistency (allornothing updates).
These operations can take time and must be enforced serverside, even if the client is bypassed.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,257 @@
# KROW Workforce Platform — Feature Testing Plan for Milestone 3
**Version:** Milestone 3 (0.0.1-IlianaStaffM3 and 0.0.1-IlianaClientM3)
**Estimated Duration:** 25-30 minutes
---
## Required Applications
- Client Mobile Application (v0.0.1-IlianaClientM3)
- Staff Mobile Application (v0.0.1-IlianaStaffM3)
---
## 1. Testing Environment Setup
### Required Test Accounts
**Client Account (Business User):**
- Email: `legendary@krowd.com`
- Password: `Demo2026!`
- Client Name: "KROW"
**Staff Account (Worker):**
- Phone: `+15557654321`
- OTP Code: `123456` (testing mode)
- Name: "Mariana Torres"
### Prerequisites
1. ✅ Both apps installed on the device
2. ✅ Network connection stable
---
## 2. Testing Steps
### 2.1: Register Business (Client App)
**Purpose:** Show the client onboarding experience
**Steps:**
1. Open Client App → Tap "Create Account"
2. Enter business email, and password (not the provided test account credentials, use a new email for this step)
3. Navigate to the home page
**Observable Points:** :
- Empty dashboard, no orders, no workers, clean slate
---
### 2.2: Register Staff (Staff App)
**Purpose:** Show the worker onboarding experience
**Steps:**
1. Open Staff App → Tap "Sign Up"
2. Enter phone number and verify with OTP code (not the provided test account credentials, use a new phone number for this step)
3. Follow the onboarding process
4. Navigate to the home page
**Observable Points:** :
- Empty shifts list, no available work yet
---
### 2.3: Client Sign In with an Existing Account (Client App)
**Note:** Use the client demo account credentials provided above.
**Purpose:** Show the sign-in experience for returning users
**Steps:**
1. Close Client App and reopen it.
2. Tap "Sign In" button
3. Enter credentials:
- Email: `legendary@krowd.com`
- Password: `Demo2026!`
4. Tap "Sign In"
---
### 2.4: Client Views the Populated Dashboard (Client App)
**Purpose:** Show how the client app displays active operations
**Steps:**
1. After signing in, observe the home screen
2. Navigate through populated sections:
- Home: Coverage stats, upcoming shifts
- Orders: Posted shifts with workers assigned
- Coverage: Real-time worker status
**Observable Points:**
- Coverage percentage for today's shifts
- Workers checked in vs. needed
- Late workers alerts
- Today's estimated labor cost
---
### 2.5: Client Creates a New Hub (Client App)
**Purpose:** Show the hub creation process
**Steps:**
1. Navigate to Hubs page via the settings button in the top right corner of the home screen
2. Tap the "Hubs" button in the settings menu.
3. Tap the "+" icon at the bottom right of the hubs list, to open the hub creation form.
4. Fill in hub details:
- Hub name: "Downtown Convention Center"
- Address: Start typing and select an address.
5. Tap "Create Hub"
6. See the new hub appear in the hubs list
---
### 2.6: Client Creates New Order (Client App)
**Purpose:** Walk through the order creation process
**Steps:**:
1. Go back to the home screen.
2. Navigate to the "Orders" tab in the bottom navigation.
3. Tap the "+ Post" button on top right to open the order type selection screen.
4. Select "One-Time" from the order type options.
5. Fill in order details:
- Order name: "Summer Gala 2026"
- Date: [Select upcoming date]
- Hub: [Select existing hub]
- Add position: Server, Count: 3, Hours: 5PM-9PM
6. Tap "Create Order"
---
### 2.7: Client Views Order Details (Client App)
**Purpose:** View detailed shift information and worker assignments
**Steps:**
1. View the created order in the orders list on the order screen.
**Observable Points:**
- Event name and location
- Roles needed
- Clock in/out times
- Estimated cost
- Coverage percentage bar
---
### 2.8: Client Monitors Coverage Dashboard (Client App)
**Purpose:** Show real-time worker tracking capabilities
**Steps:**
1. Navigate to the "Coverage" tab in the bottom navigation.
2. Observe the worker status for active shifts.
**Observable Points:**
- Worker status (Checked In, En Route, Late, Not Arrived)
- Color-coded status badges (green, yellow, red)
- Worker information
---
### 2.9: Staff Logs In with Existing Account (Staff App)
**Note:** Use the staff demo account credentials provided above.
**Purpose:** Show the staff app sign-in experience for returning users
**Steps:**
1. Close the staff app and reopen it.
2. Tap "Log In" button
3. Enter phone number: `5557654321`
4. Tap "Send Code"
5. Enter OTP: `123456`
---
### 2.10: Staff Views Home Dashboard (Staff App)
**Purpose:** View worker's personalized dashboard
**Observable Points:**
- Welcome message with worker's name
- Today's Shifts section (confirmed shifts for today)
- Tomorrow's Shifts section
- Recommended shifts section
---
### 2.11: Staff Finds Available Shifts (Staff App)
**Purpose:** Show the shift search and discovery experience for workers
**Steps:**
1. Navigate to the "Shifts" tab in the bottom navigation.
2. Tap the "Find Shifts" button on top to view available shifts.
**Observable Points:**
- List of shifts
- Hourly rate prominently displayed
- Role requirements (e.g., "Bartender - Spring Gala")
- Date, time, and duration
**Note:**
>Due to the current order flow, newly created orders do not appear in the Find Shifts section, as it requires an approval from the vendor. This was discussed during the demo.
>We are actively updating this flow so orders will appear correctly in a future iteration.
---
### 2.12: Staff Applies for Shift (Staff App)
**Purpose:** Show the application process from worker side
**Steps:**
1. Tap on an available shift to view details
2. Review business name, location, pay, requirements
3. Tap "Book Shift" button
4. Tap "Book" on the confirmation dialog
4. See confirmation
---
### 2.13: Staff Views Confirmed Shifts (Staff App)
**Purpose:** Show worker's shift confirmation
**Observable Points:**
- Week-by-week calendar navigation
- Color-coded status (Confirmed, Pending, Completed)
- Quick access to shift details and directions
---
### 2.14: Staff Clock-In to Shift (Day of Event) (Staff App)
**Purpose:** Demonstrate the clock-in process
**Steps:**
1. Navigate to the clock-in page.
2. Use the "Clock In" slider to clock in.
**Observable Points:**
- Timestamp automatically recorded
- Status changes to "Checked In" with green indicator
---
### 2.15: Staff Clocks-Out of Shift (Day of Event) (Staff App)
**Purpose:** Demonstrate the clock-out process and shift completion
**Steps:**
1. Navigate to the clock-out page.
2. Use the "Clock Out" slider to clock out.
3. Navigate to the "My Shifts" section in the Shifts tab to see the updated status via the bottom navigation.
**Observable Points:**
- Clock-out timestamp automatically recorded
- Status changes to "Completed"
---
### 2.16: Staff Profile Management (Staff App)
**Purpose:** Demonstrate worker profile features and compliance management
**Steps:**
1. Navigate to Profile tab in bottom navigation
2. Review profile sections:
- **Profile Info:**
- **Emergency Contact:** Name, relationship, phone number
- **Bank Account:** Linked payment account for direct deposit
- **Tax Forms:** W-4, I-9 compliance documents
- **Time Card:** Historical shift records with hours and earnings

View File

@@ -0,0 +1,63 @@
# KROW M3 Demo — Test Feedback
**Date:** February 3, 2026
---
## Demo 1: Register Business & Show Empty States (Client App)
- **Flickering company name:** Every time I navigate to the home screen, I see "your company" for a moment before it changes to the real name.
- Creating a One-Time Order shows "No Vendors Available" — this is expected, OK.
**Suggestions: Achintha:**
- We need to have a shimmer loading state while fetching data, to avoid flickering and empty states.
---
## Demo 2: Register Staff & Show Empty States (Staff App)
**Onboarding — Add preferred work locations:**
- Suggestion: Use Google Maps to suggest only city names. Currently users can type anything, which will cause misspellings and inconsistent data. Important for the max distance feature.
**Home page:**
- Same flickering issue — shows "KROWER" briefly before displaying the real name.
**Profile page:**
- Phone number should be read-only, or require re-verification if changed.
- Emergency contact: "Save & Continue" works, but shouldn't we navigate to the profile page after? Other flows do this.
- Tax Documents: Would be great to add a file uploader where our AI could identify documents and prefill fields.
- Bank Account: Need to plan real bank verification (KYC)? Ensure the account is real and belongs to the user. Also, I can list banks but I don't see how to change/switch bank.
**Home (empty state):**
- Clicking "Find shifts →" does nothing. But "Find Shifts" with the search icon works.
**My Availability:**
- Working. Some latency, but OK for now.
---
## Demo 5: Client Creates a New Hub
- Hub editing feature seems missing — we'll need this for NFC configuration later.
- No confirmation before deleting a hub.
---
## Demo 6: Client Creates New Order
- "Up Next (x)" counter is confusing. I created 2 orders but it shows "Up Next (1)". Sometimes shows 0 when navigating, then back to 1.
---
## Demo 8: Staff Logs In with Existing Account
- If you accidentally click "Sign Up" with an existing phone number, you get stuck:
1. OTP screen shows error: "This user already has a staff profile. Please log in"
2. Clicking back → login → same OTP error loop
3. Only fix: kill and restart the app
---
## Demo 10: Staff Browses Available Shifts
- **Blocker:** I don't see the shift I created as the Client.

View File

@@ -0,0 +1,348 @@
# KROW Workforce Platform — Feature Demo Plan for Milestone 3
**Version:** Milestone 3 (v3.0)
**Date:** February 3, 2026
**Audience:** Business Stakeholders, Customer Engineers, Sales Teams
**Duration:** 25-30 minutes
---
## 1⃣ Demo Overview
### Purpose
This demo showcases the progress of the milestone 3.
- **For Businesses (Client App):** One-time shift creation, worker management, real-time coverage tracking
- **For Workers (Staff App):** Easy access to available shifts, clock-in and profile management
- **Complete Workflow:** From shift posting and worker check-in and completion
### Estimated Demo Duration
**25-30 minutes**
---
## 2⃣ Demo Environment Setup
### Required Test Accounts
**Client Account (Business User):**
- Email: `legendary@krowd.com`
- Password: `Demo2026!`
- Client Name: "KROW"
**Staff Account (Worker):**
- Phone: `+15557654321`
- OTP Code: `123456` (demo mode)
- Name: "Mariana Torres"
### Prerequisites
1. ✅ Both apps installed on demo devices (or simulators)
2. ✅ Network connection stable
3. ✅ Seed data is ready to be populated (the database should be empty at start)
### Make Commands Reference
| Command | Purpose |
|---------|---------|
| `make dataconnect-clean` | Clean the database before seeding |
| `make dataconnect-seed` | Populate the database with seed data for demo |
### Recent Fixes Applied
- ✅ Fixed 2 bugs on TaxForm: marital status and Citizenship Status now properly saved
- ✅ Fixed update screen after create or update TaxForm
- ✅ Created seed data script
- ✅ Created make commands to create and delete information in DataConnect
---
## 3⃣ Demo Flows
### Demo 0: Show Empty Database
**Purpose:** Demonstrate the starting point before any data exists
**Steps:**
1. Run `make dataconnect-clean` to ensure database is empty
2. Show the empty database in Firebase console
---
### Demo 1: Register Business & Show Empty States (Client App)
**Purpose:** Show the client onboarding experience and empty states
**Steps:**
1. Open Client App → Tap "Create Account"
2. Enter business email, and password
3. Navigate to home page
4. **Point out:** Empty dashboard, no orders, no workers, clean slate
---
### Demo 2: Register Staff & Show Empty States (Staff App)
**Purpose:** Show the worker onboarding experience and empty states
**Steps:**
1. Open Staff App → Tap "Sign Up"
2. Enter phone number and verify with OTP code
3. Follow the onboarding process
4. Navigate to home page
5. **Point out:** Empty shifts list, no available work yet
---
### 🔄 PAUSE: Populate Database
Run the seeding command:
```bash
make dataconnect-seed
```
---
### Demo 3: Client Logs In with Existing Account
**Purpose:** Show the sign-in experience for returning users
**Screen:** Get Started → Sign In
**Steps:**
1. Restart Client App
2. Tap "Sign In" button
3. Enter credentials:
- Email: `legendary@krowd.com`
- Password: `Demo2026!`
4. Tap "Sign In"
---
### Demo 4: Client Views Populated Dashboard
**Purpose:** Show how the client app displays active operations
**Steps:**
1. After signing in, observe the home screen
2. Navigate through populated sections:
- Home: Coverage stats, upcoming shifts
- Orders: Posted shifts with workers assigned
- Coverage: Real-time worker status
**What to Notice:**
- Coverage percentage for today's shifts
- Workers checked in vs. needed
- Late workers alerts
- Today's estimated labor cost
---
### Demo 5: Client Creates a New Hub
**Screen:** Hubs Tab → "Add Hub" button
**Steps:**
1. Navigate to Hubs tab in bottom navigation
2. Tap the "+" or "Add Hub" button
3. Fill in hub details:
- Hub name: "Downtown Convention Center"
- Address: Start typing and select from Google Places autocomplete
4. Tap "Create Hub"
5. See the new hub appear in the hubs list
---
### 📋 Main Demo Flow Explanation
```
Client Posts Shift [O1]
*Vendor Accepts the Shift (Missing for now) / Vendor is selected by client* [O2]
Worker Searches for a Shift [O3]
Worker Applies [O4]
Confirmation (Missing for now, auto-confirmed)* [O5]
Worker Checks In [O6]
Shift Completed [O7]
```
---
### Demo 6: Client Creates New Order - [O1]
**Purpose:** Walk through the shift creation process
**Screen:** Orders Tab → "Post" button
**What to Fill:**
- Order name: "Spring Gala 2026"
- Date: [Select upcoming date]
- Location: [Select existing hub]
- Add position: Server, Count: 3, Hours: 5PM-9PM
---
### Demo 7: Client Views Order Details
**Purpose:** Show detailed shift information and worker assignments (second part is missing for now)
**Screen:** Orders Tab → Tap on any order card
**What to Notice:**
- Event name and location
- Roles needed (e.g., "2 Servers")
- Clock in/out times
- Estimated cost
- Coverage percentage bar
---
### Demo 8: Staff Logs In with Existing Account
**Purpose:** Show the worker sign-in experience
**Screen:** Get Started → Sign In with Phone
**Steps:**
1. Restart the staff app
2. Enter phone number: `5557654321`
3. Tap "Send Code"
4. Enter OTP: `123456`
---
### Demo 9: Staff Views Home Dashboard
**Purpose:** Show worker's personalized dashboard
**What to Notice:**
- Today's Shifts section (confirmed shifts for today)
- Tomorrow's Shifts section
---
### Demo 10: Staff Browses Available Shifts - [O3]
**Purpose:** Show how workers discover and view available work
**Screen:** Shifts → "Find Work"
**What to Notice:**
- List of shifts matching worker skills
- Hourly rate prominently displayed
- Role requirements (e.g., "Bartender - Spring Gala")
- Date, time, and duration
---
### Demo 11: Staff Applies for Shift - [O4]
**Purpose:** Show the application process from worker side
**Screen:** Shift Details → "Book" Shift button
**Steps:**
1. Tap on an available shift to view details
2. Review business name, location, pay, requirements
3. Tap "Book" Shift button
4. See confirmation
---
### Demo 12: Staff Views Confirmed Shifts - [O5]
**Purpose:** Show worker's shift management interface
**Screen:** Shifts Tab → "My Shifts"
**What to Notice:**
- Week-by-week calendar navigation
- Color-coded status (Confirmed, Pending, Completed)
- Quick access to shift details and directions
---
### Demo 13: Client Monitors Coverage Dashboard - [O5]
**Purpose:** Show real-time worker tracking capabilities
**Screen:** Client App → Coverage Tab
**What to Notice:**
- Live worker status (Checked In, En Route, Late, Not Arrived)
- Color-coded status badges (green, yellow, red)
- Worker information
---
### Demo 14: Staff Clock-In to Shift (Day of Event) - [O6]
**Purpose:** Demonstrate the clock-in process
**Screen:** Clockin page → "Clock In" slider
**What to Notice:**
- Timestamp automatically recorded
- Status changes to "Checked In" with green indicator
---
### Demo 15: Client Sees Clock-In Update - [O6]
**Purpose:** Show cross-app interaction and real-time updates
**Screen:** Client App → Coverage Tab
**Action:** Press the update button on the top right to refresh worker statuses
**What to Notice:**
- Status update
- User status changes to "Checked In"
- Check-in time displayed
---
### Demo 16: Staff Clocks-Out of Shift - [O7]
**Purpose:** Demonstrate the clocks-out process and shift completion
**Screen:** Clockin page -> Clock-out slider
**What to Notice:**
- Clock-out timestamp automatically recorded
- Status changes to "Completed"
- Total hours worked calculated automatically
---
### Demo 17: Client Views Completed Shift in Coverage - [O7]
**Purpose:** Show how completed shifts appear in the client app
**Screen:** Client App → Coverage Tab
**Action:** Press the refresh button to update worker statuses
**What to Notice:**
- Worker status changes to "Completed"
- Check-out time displayed alongside check-in time
- Total hours worked visible
- Shift marked as complete in orders list
- Cost finalized based on actual hours
---
### Demo 18: Staff Profile Management
**Purpose:** Demonstrate worker profile features and compliance management
**Screen:** Staff App → Profile Tab
**Steps:**
1. Navigate to Profile tab in bottom navigation
2. Review profile sections:
- **Profile Info:**
- **Emergency Contact:** Name, relationship, phone number
- **Bank Account:** Linked payment account for direct deposit
- **Tax Forms:** W-9, I-9 compliance documents *(bugs fixed: marital status and Citizenship Status now work properly)*
- **Time Card:** Historical shift records with hours and earnings
---
## 4⃣ Customer Handover Checklist
### Deliverables
- [ ] Android apps (Client and Staff)
- [ ] Demo account credentials (see below)
### Demo Accounts
| Account | Credentials |
|---------|-------------|
| **Client** | Email: `legendary@krowd.com` / Password: `Demo2026!` |
| **Staff** | Phone: `+15557654321` / OTP: `123456` (demo mode) |

View File

@@ -0,0 +1,82 @@
# KROW Workforce Platform — M4 Guide
**Version:** Milestone 4 (0.0.1-IlianaStaffM4 and 0.0.1-IlianaClientM4)
**Estimated Duration:** 25-30 minutes
---
## 📦 Deliverables
- **Client Mobile Application** (v0.0.1-IlianaClientM4)
- **Staff Mobile Application** (v0.0.1-IlianaStaffM4)
- **Full Demo Video** - Comprehensive walkthrough of all (M1 - M4) completed features of the mobile applications.
---
## 1. Overview
### Core Improvements
M4 delivers three key areas of improvement:
1. **Overall Application Improvements**
- Auth session persistence: Users stay signed in after reopening the app
- Stability fixes from M3 client feedback and dev team discoveries
- UI/UX improvements across key screens for clarity and speed
2. **Client App Updates**
- Complete order creation flow (Rapid, Permanent, Recurring orders)
- Shift manager assignment support
- Paid/unpaid break handling in orders
- Complete Reports section (Daily Ops, Spend, Coverage, No-show, Performance)
- Cost centres in hubs for location/business unit tracking
- Billing approval workflow for pending bills
3. **Staff App Updates**
- Profile completion requirements gating payments and clockings
- Worker benefits integration
- Enhanced shift discovery with filtering by location
- Spanish localization support
- AI-verified document uploads (Attire, Documents, Certificates)
- FAQ and Privacy Policy
- Worker profile visibility controls
---
## 2. Required Test Accounts
**Client Account (Business User):**
- Email: `legendary@krowd.com`
- Password: `Demo2026!`
- Client Name: "KROW"
**Staff Account (Worker):**
- Phone: `+15557654321`
- OTP Code: `123456` (testing mode)
- Name: "Mariana Torres"
***Note on Profile Completion***
When a staff user hasn't completed their profile, they see an empty/incomplete state on their home screen. Currently tracked sections to mark as complete:
- Profile Information (full name, email, phone, preferred locations)
- Emergency Contact
Future sections can be added as mandatory, such as Tax Forms, Bank Account, Documents, Certificates, and Attires.
***Profile Blocking Rules***
When the profile is incomplete, the following features are blocked to encourage completion:
- Clock-in page is hidden
- Payments are blocked
- "My Shifts" and History sections are hidden
- Users can view available shifts but cannot book them
This ensures we have all necessary information for compliance and payroll before workers are allowed to work.
---
## 3. M4 Key Deliverables
✅ Stronger reliability and stability
✅ Completed client ordering and reporting workflows
✅ Better profile and shift tooling for staff
✅ AI-assisted document verification
✅ Localization support (Spanish)
✅ Improved billing and cost tracking controls

View File

@@ -0,0 +1,10 @@
# Moved
The canonical v2 backend API docs now live here:
- `docs/BACKEND/API_GUIDES/V2/README.md`
- `docs/BACKEND/API_GUIDES/V2/core-api.md`
- `docs/BACKEND/API_GUIDES/V2/command-api.md`
- `docs/BACKEND/API_GUIDES/V2/query-api.md`
This file is kept only as a compatibility pointer.

View File

@@ -0,0 +1,269 @@
# M4 Backend Foundation Implementation Plan (Dev First)
Date: 2026-02-24
Owner: Wilfred (Technical Lead)
Primary environment: `krow-workforce-dev`
## 1) Objective
Build a secure, modular, and scalable backend foundation in `dev` without breaking the current frontend while we migrate high-risk writes from direct Data Connect mutations to backend command endpoints.
## 2) First-principles architecture rules
1. Client apps are untrusted for business-critical writes.
2. Backend is the enforcement layer for validation, permissions, and write orchestration.
3. Multi-entity writes must be atomic, idempotent, and observable.
4. Configuration and deployment must be reproducible by automation.
5. Migration must be backward-compatible until each frontend flow is cut over.
## 3) Pre-coding gates (must be true before implementation starts)
## Gate A: Security boundary
1. Frontend sends Firebase token only. No database credentials in client code.
2. Every new backend endpoint validates Firebase token.
3. Data Connect write access strategy is defined:
- keep simple reads available to client
- route high-risk writes through backend command endpoints
4. Upload and signed URL paths are server-controlled.
## Gate B: Contract standards
1. Standard error envelope is frozen:
```json
{
"code": "STRING_CODE",
"message": "Human readable message",
"details": {},
"requestId": "optional-request-id"
}
```
2. Request validation layer is chosen and centralized.
3. Route naming strategy is frozen:
- canonical routes under `/core` and `/commands`
- compatibility aliases preserved during migration (`/uploadFile`, `/createSignedUrl`, `/invokeLLM`)
4. Validation standard is locked:
- library: `zod`
- schema location: `backend/<service>/src/contracts/` with `core/` and `commands/` subfolders
## Gate C: Atomicity and reliability
1. Command endpoints support idempotency keys for retry-safe writes.
2. Multi-step write flows are wrapped in single backend transaction boundaries.
3. Domain conflict codes are defined for expected business failures.
4. Idempotency storage is locked:
- store in Cloud SQL table
- key scope: `userId + route + idempotencyKey`
- retain records for 24 hours
- repeated key returns original response
## Gate D: Automation and operability
1. Makefile is source of truth for backend setup and deploy in dev.
2. Core deploy and smoke test commands exist before feature migration.
3. Logging format and request tracing fields are standardized.
## 4) Security baseline for foundation phase
## 4.1 Authentication and authorization
1. Foundation phase is authentication-first.
2. Role-based access control is intentionally deferred.
3. All handlers include a policy hook for future role checks (`can(action, resource, actor)`).
## 4.2 Data access control model
1. Client retains Data Connect reads required for existing screens.
2. High-risk writes move behind `/commands/*` endpoints.
3. Backend mediates write interactions with Data Connect and Cloud SQL.
## 4.3 File and URL security
1. Validate file type and size server-side.
2. Separate public and private storage behavior.
3. Signed URL creation checks ownership/prefix scope and expiry limits.
4. Bucket policy split is locked:
- `krow-workforce-dev-public`
- `krow-workforce-dev-private`
- private bucket access only through signed URL
## 4.4 Model invocation safety
1. Enforce schema-constrained output.
2. Apply per-user rate limits and request timeout.
3. Log model failures with safe redaction (no sensitive prompt leakage in logs).
4. Model provider and timeout defaults are locked:
- provider: Vertex AI Gemini
- max route timeout: 20 seconds
- timeout error code: `MODEL_TIMEOUT`
## 4.5 Secrets and credentials
1. Runtime secrets come from Secret Manager only.
2. Service accounts use least-privilege roles.
3. No secrets committed in repository files.
## 5) Modularity baseline
## 5.1 Backend module boundaries
1. `core` module: upload, signed URL, model invocation, health.
2. `commands` module: business writes and state transitions.
3. `policy` module: validation and future role checks.
4. `data` module: Data Connect adapters and transaction wrappers.
5. `infra` module: logging, tracing, auth middleware, error mapping.
## 5.2 Contract separation
1. Keep API request/response schemas in one location.
2. Keep domain errors in one registry file.
3. Keep route declarations thin; business logic in services.
## 5.3 Cloud runtime roles
1. Cloud Run is the primary command and core API execution layer.
2. Cloud Functions v2 is worker-only in this phase:
- upload-related async handlers
- notification jobs
- model-related async helpers when needed
## 6) Automation baseline
## 6.1 Makefile requirements
Add `makefiles/backend.mk` and wire it into root `Makefile` with at least:
1. `make backend-enable-apis`
2. `make backend-bootstrap-dev`
3. `make backend-deploy-core`
4. `make backend-deploy-commands`
5. `make backend-deploy-workers`
6. `make backend-smoke-core`
7. `make backend-smoke-commands`
8. `make backend-logs-core`
## 6.2 CI requirements
1. Backend lint
2. Backend tests
3. Build/package
4. Smoke test against deployed dev route(s)
5. Block merge on failed checks
## 6.3 Session hygiene
1. Update `TASKS.md` and `CHANGELOG.md` each working session.
2. If a new service/API is added, Makefile target must be added in same change.
## 7) Migration safety contract (no frontend breakage)
1. Backend routes ship first.
2. Frontend migration is per-feature wave, not big bang.
3. Keep compatibility aliases until clients migrate.
4. Keep existing Data Connect reads during foundation.
5. For each migrated write flow:
- before/after behavior checklist
- rollback path
- smoke verification
## 8) Scope for foundation build
1. Backend runtime/deploy foundation in dev.
2. Core endpoints:
- `POST /core/upload-file`
- `POST /core/create-signed-url`
- `POST /core/invoke-llm`
- `GET /healthz`
3. Compatibility aliases:
- `POST /uploadFile`
- `POST /createSignedUrl`
- `POST /invokeLLM`
4. Command layer scaffold for first migration routes.
5. Initial migration of highest-risk write paths.
## 9) Implementation phases
## Phase 0: Baseline and contracts
Deliverables:
1. Freeze endpoint naming and compatibility aliases.
2. Freeze error envelope and error code registry.
3. Freeze auth middleware interface and policy hook interface.
4. Publish route inventory from web/mobile direct writes.
Exit criteria:
1. No unresolved contract ambiguity.
2. Team agrees on auth-first now and role-map-later approach.
## Phase 1: Backend infra and automation
Deliverables:
1. `makefiles/backend.mk` with bootstrap, deploy, smoke, logs targets.
2. Environment templates for backend runtime config.
3. Secret Manager and service account setup automation.
Exit criteria:
1. A fresh machine can deploy core backend to dev via Make commands.
## Phase 2: Core endpoint implementation
Deliverables:
1. `/core/upload-file`
2. `/core/create-signed-url`
3. `/core/invoke-llm`
4. `/healthz`
5. Compatibility aliases (`/uploadFile`, `/createSignedUrl`, `/invokeLLM`)
Exit criteria:
1. API harness passes for core routes.
2. Error, logging, and auth standards are enforced.
## Phase 3: Command layer scaffold
Deliverables:
1. `/commands/orders/create`
2. `/commands/orders/{orderId}/cancel`
3. `/commands/orders/{orderId}/update`
4. `/commands/shifts/{shiftId}/change-status`
5. `/commands/shifts/{shiftId}/assign-staff`
6. `/commands/shifts/{shiftId}/accept`
Exit criteria:
1. High-risk writes have backend command alternatives ready.
## Phase 4: Wave 1 frontend migration
Deliverables:
1. Replace direct writes in selected web/mobile flows.
2. Keep reads stable.
3. Verify no regressions in non-migrated screens.
Exit criteria:
1. Migrated flows run through backend commands only.
2. Rollback instructions validated.
## Phase 5: Hardening and handoff
Deliverables:
1. Runbook for deploy, rollback, and smoke.
2. Backend CI pipeline active.
3. Wave 2 and wave 3 migration task list defined.
Exit criteria:
1. Foundation is reusable for staging/prod with environment changes only.
## 10) Wave 1 migration inventory (real call sites)
Web:
1. `apps/web/src/features/operations/tasks/TaskBoard.tsx:100`
2. `apps/web/src/features/operations/orders/OrderDetail.tsx:145`
3. `apps/web/src/features/operations/orders/EditOrder.tsx:84`
4. `apps/web/src/features/operations/orders/components/CreateOrderDialog.tsx:31`
5. `apps/web/src/features/operations/orders/components/AssignStaffModal.tsx:60`
6. `apps/web/src/features/workforce/documents/DocumentVault.tsx:99`
Mobile:
1. `apps/mobile/packages/features/client/home/lib/src/presentation/widgets/shift_order_form_sheet.dart:232`
2. `apps/mobile/packages/features/client/view_orders/lib/src/presentation/widgets/view_order_card.dart:1195`
3. `apps/mobile/packages/features/client/create_order/lib/src/data/repositories_impl/client_create_order_repository_impl.dart:68`
4. `apps/mobile/packages/features/staff/shifts/lib/src/data/repositories_impl/shifts_repository_impl.dart:446`
5. `apps/mobile/packages/features/client/authentication/lib/src/data/repositories_impl/auth_repository_impl.dart:257`
6. `apps/mobile/packages/features/staff/profile_sections/onboarding/profile_info/lib/src/data/repositories/personal_info_repository_impl.dart:51`
## 11) Definition of done for foundation
1. Core endpoints deployed in dev and validated.
2. Command scaffolding in place for wave 1 writes.
3. Auth-first protection active on all new routes.
4. Idempotency + transaction model defined for command writes.
5. Makefile and CI automation cover bootstrap/deploy/smoke paths.
6. Frontend remains stable during migration.
7. Role-map integration points are documented for next phase.
## 12) Locked defaults (approved)
1. Idempotency key storage strategy:
- Cloud SQL table, 24-hour retention, keyed by `userId + route + idempotencyKey`.
2. Validation library and schema location:
- `zod` in `backend/<service>/src/contracts/` (`core/`, `commands/`).
3. Storage bucket naming and split:
- `krow-workforce-dev-public` and `krow-workforce-dev-private`.
4. Model provider and timeout:
- Vertex AI Gemini, 20-second max timeout.
5. Target response-time objectives (p95):
- `/healthz` under 200ms
- `/core/create-signed-url` under 500ms
- `/commands/*` under 1500ms
- `/core/invoke-llm` under 15000ms

View File

@@ -0,0 +1,9 @@
# Moved
The canonical Core API frontend doc now lives here:
- `docs/BACKEND/API_GUIDES/V2/core-api.md`
Start from:
- `docs/BACKEND/API_GUIDES/V2/README.md`

View File

@@ -0,0 +1,166 @@
# M4 Core Data Actors and Example Scenarios
Status: Working draft
Date: 2026-02-25
Owner: Technical Lead
## 1) Core data actors
1. `Tenant`: staffing company boundary and data isolation root.
2. `User`: human identity that signs in.
3. `TenantMembership`: user role/context inside one tenant.
4. `Business`: client account served by the tenant.
5. `BusinessMembership`: maps users to a business with role/status (`owner`, `manager`, `approver`, `viewer`).
6. `Vendor`: supplier account that can fulfill staffing demand.
7. `VendorMembership`: maps users to a vendor with role/status (`owner`, `manager`, `scheduler`, `viewer`).
8. `Workforce/Staff`: worker profile used for assignment and attendance.
9. `StakeholderType`: typed category (`buyer`, `operator`, `vendor_partner`, `workforce`, `partner`, `procurement_partner`).
10. `StakeholderProfile`: typed actor record inside a tenant.
11. `StakeholderLink`: relationship between stakeholder profiles.
## 1.1 Current schema coverage (today)
Current Data Connect handles this only partially:
1. `Business.userId` supports one primary business user.
2. `Vendor.userId` supports one primary vendor user.
3. `TeamMember` can represent multiple users by team as a workaround.
This is why we need first-class membership tables:
1. `business_memberships`
2. `vendor_memberships`
Without those, client/vendor user partitioning is indirect and harder to enforce safely at scale.
## 2) Minimal actor map
```mermaid
flowchart LR
T["Tenant"] --> TM["TenantMembership (global tenant access)"]
U["User"] --> TM
T --> B["Business"]
T --> V["Vendor"]
U --> BM["BusinessMembership"]
BM --> B
U --> VM["VendorMembership"]
VM --> V
U --> S["Workforce/Staff"]
T --> SP["StakeholderProfile"]
ST["StakeholderType"] --> SP
SP --> SL["StakeholderLink"]
B --> O["Orders/Shifts"]
V --> O
S --> O
```
## 3) Scenario A: Legendary Event Staffing
Context:
1. Tenant is `Legendary Event Staffing and Entertainment`.
2. Business is `Google Mountain View Cafes`.
3. Legendary uses its own workforce, and can still route overflow to approved vendors.
Actor mapping (text):
1. Tenant: `Legendary Event Staffing and Entertainment` (the company using KROW).
2. User: `Wil` (ops lead), `Maria` (Google client manager), `Omar` (Google procurement approver), `Jose` (vendor scheduler), `Ana` (worker).
3. TenantMembership:
4. `Wil` is `admin` in Legendary tenant.
5. `Maria` is `member` in Legendary tenant.
6. `Omar` is `member` in Legendary tenant.
7. `Jose` is `member` in Legendary tenant.
8. `Ana` is `member` in Legendary tenant.
9. BusinessMembership:
10. `Maria` is `manager` in `Google Mountain View Cafes`.
11. `Omar` is `approver` in `Google Mountain View Cafes`.
12. VendorMembership:
13. `Jose` is `scheduler` in `Legendary Staffing Pool A`.
14. `Wil` is `owner` in `Legendary Staffing Pool A`.
15. Business: `Google Mountain View Cafes` (client account under the tenant).
16. Vendor: `Legendary Staffing Pool A` (or an external approved vendor).
17. Workforce/Staff: `Ana` is a staff profile in workforce, linked to certifications and assignments.
18. StakeholderType: `buyer`, `operator`, `vendor_partner`, `workforce`, `procurement_partner`.
19. StakeholderProfile:
20. `Google Procurement` = `buyer`.
21. `Legendary Ops` = `operator`.
22. `FoodBuy` = `procurement_partner`.
23. StakeholderLink:
24. `Google Procurement` `contracts_with` `Legendary Ops`.
25. `Legendary Ops` `sources_from` `Legendary Staffing Pool A`.
26. `Google Procurement` `reports_through` `FoodBuy`.
```mermaid
sequenceDiagram
participant Tenant as "Tenant (Legendary)"
participant BizUser as "Business user (Maria/Omar)"
participant Ops as "Ops user (Wil)"
participant VendorUser as "Vendor user (Jose)"
participant Staff as "Workforce/Staff (Barista Ana)"
participant StakeRel as "StakeholderLink"
BizUser->>Ops: "Create staffing request"
Ops->>Tenant: "Create order under tenant scope"
Ops->>StakeRel: "Resolve business-to-vendor/workforce relationships"
Ops->>VendorUser: "Dispatch role demand"
VendorUser->>Staff: "Confirm worker assignment"
Staff-->>Ops: "Clock in/out and complete shift"
Ops-->>BizUser: "Invoice/report generated with audit trail"
```
## 4) Scenario B: Another tenant (external vendor-heavy)
Context:
1. Tenant is `Peakline Events`.
2. Business is `NVIDIA Campus Dining`.
3. Peakline primarily fulfills demand through external approved vendors.
Actor mapping (text):
1. Tenant: `Peakline Events` (another staffing company using KROW).
2. User: `Chris` (operations coordinator), `Nina` (client manager), `Sam` (vendor manager), `Leo` (worker).
3. TenantMembership:
4. `Chris` is `admin` in Peakline tenant.
5. `Nina` is `member` in Peakline tenant.
6. `Sam` is `member` in Peakline tenant.
7. `Leo` is `member` in Peakline tenant.
8. BusinessMembership:
9. `Nina` is `manager` in `NVIDIA Campus Dining`.
10. VendorMembership:
11. `Sam` is `manager` in `Metro Staffing LLC`.
12. Business: `NVIDIA Campus Dining` (client account under the tenant).
13. Vendor: `Metro Staffing LLC` (approved external vendor for this tenant).
14. Workforce/Staff: `Leo` is a workforce profile fulfilled through Metro Staffing for assignment and attendance.
15. StakeholderType: `buyer`, `operator`, `vendor_partner`, `workforce`, `procurement_partner`.
16. StakeholderProfile:
17. `NVIDIA Procurement` = `buyer`.
18. `Peakline Ops` = `operator`.
19. `FoodBuy Regional` = `procurement_partner`.
20. StakeholderLink:
21. `NVIDIA Procurement` `contracts_with` `Peakline Ops`.
22. `Peakline Ops` `sources_from` `Metro Staffing LLC`.
23. `NVIDIA Procurement` `reports_through` `FoodBuy Regional`.
```mermaid
sequenceDiagram
participant Tenant as "Tenant (Peakline Events)"
participant BizUser as "Business user (Nina)"
participant Ops as "Ops user (Chris)"
participant VendorUser as "Vendor user (Sam)"
participant Staff as "Workforce/Staff (Vendor worker)"
BizUser->>Ops: "Request recurring event staffing"
Ops->>Tenant: "Create recurring order"
Ops->>VendorUser: "Dispatch required roles"
VendorUser->>Staff: "Provide available workers"
Staff-->>Ops: "Attendance and completion events"
Ops-->>BizUser: "Settlement + performance reports"
```
## 5) Why this model scales
1. New stakeholders can be added through `StakeholderType` and `StakeholderProfile` without changing core order/shift tables.
2. Business and vendor user partitioning is explicit through membership tables, not hidden in one owner field.
3. Multi-tenant isolation stays strict because all critical records resolve through `Tenant`.
4. Legendary and non-Legendary operating models both fit the same structure.
## 6) Industry alignment (primary references)
1. Google Cloud Identity Platform multi-tenancy:
- https://docs.cloud.google.com/identity-platform/docs/multi-tenancy
2. AWS SaaS tenant isolation fundamentals:
- https://docs.aws.amazon.com/whitepapers/latest/saas-architecture-fundamentals/tenant-isolation.html
3. B2B organization-aware login flows (Auth0 Organizations):
- https://auth0.com/docs/manage-users/organizations/login-flows-for-organizations
4. Supplier-side multi-user management patterns (Coupa Supplier Portal):
- https://compass.coupa.com/en-us/products/product-documentation/supplier-resources/for-suppliers/coupa-supplier-portal/set-up-the-csp/users/manage-users

View File

@@ -0,0 +1,132 @@
## M4 Demo Checklist Staff & Client Apps
---
# ✅ Staff App Demo
## 🔐 Authentication
* [ ] Open Staff app launch screen
* [ ] Show **Sign Up** flow (new user registration)
* [ ] Return to login
* [ ] Sign in with existing account
* [ ] Close and reopen app (demonstrate session persistence)
---
## 🏠 Home & Availability
* [ ] Open Home page
* [ ] Open Availability section
* [ ] Update a time slot
---
## 🔎 Find & Book Shifts
* [ ] Go to Find Shifts
* [ ] Open a shift (revamped single shift interface)
* [ ] Tap Book Shift
---
## 📅 Shift Management
* [ ] Open My Shifts
* [ ] Open Completed Shifts
* [ ] Open Payment Summary
* [ ] Open a booked shift
* [ ] Tap Clock-In
---
## 👤 Profile & Settings
* [ ] Open Profile
### Profile Sections
* [ ] Edit Profile
* [ ] Emergency Contact
* [ ] Experiences
* [ ] Attire
* [ ] Documents
* [ ] Certificates
* [ ] Tax Forms
* [ ] Bank Account
* [ ] Time Card
* [ ] FAQ
* [ ] Privacy Settings
* [ ] Toggle “Hide account from business” option
* [ ] Confirm Staff app walkthrough complete
---
# ✅ Client App Demo
## 🔐 Authentication
* [ ] Open Client app launch screen
* [ ] Briefly show Sign Up
* [ ] Sign in with existing account
* [ ] Close and reopen app (demonstrate session persistence)
---
## 🏠 Home
* [ ] Open Home page
* [ ] Tap Reorder
* [ ] Tap Insights
---
## 📦 Orders
* [ ] Go to Order section
* [ ] Open View Shifts
* [ ] Open Create Orders
### Order Types
* [ ] One Time
* [ ] Rapid
* [ ] Permanent
* [ ] Multi
* [ ] Open View Orders
---
## 📊 Reporting & Billing
* [ ] Open Reports (mention six report types)
* [ ] Open Billing (review and accept bills)
* [ ] Open Coverage
---
# ✅ Demo Wrap-Up
* [ ] Summarize Staff app workflow
* [ ] Summarize Client app workflow
* [ ] Thank audience and conclude demo
---
If you'd like, I can also format this as a downloadable `.md` file for you.

View File

@@ -0,0 +1,648 @@
# M4 Milestone Planning
---
## Backend (BE)
### Make Order creation flow a transaction using cloud functions
**Goal:** Make Order creation flow a transaction using cloud functions
**Based on:** https://github.com/Oloodi/krow-workforce/issues/420
---
### Validate Shift Acceptance by a Worker
**Goal:** Prevent workers from accepting shifts they are not eligible to accept.
**Where:** Backend validation (server-side).
#### Key Rules (M4)
- Prevent accepting overlapping shifts. If a shift is already accepted in that time window, reject the accept action.
#### Design Requirement
Make the algorithm scalable so future shift-acceptance rules can be added without rewriting core logic.
#### Acceptance Criteria
- Backend rejects overlapping acceptance with a clear error reason.
- Validation is enforced even if the client app is bypassed.
---
### Validate Shift Creation by a Client
**Goal:** Ensure shifts/orders created by clients meet required criteria.
**Where:** Backend validation (server-side).
#### Key Rules (M4)
- Add a soft check for minimum shift hours when creating an order.
- When a client creates an order, check if shift hours are below the vendor minimum.
- Current minimum hours: **5 hours**.
#### FE Dependency
Also add a FE validation (user feedback) in addition to BE enforcement.
#### Design Requirement
Make the algorithm scalable so future creation rules can be added.
#### Acceptance Criteria
- Backend returns a consistent validation response when the minimum-hours check fails.
- FE shows a clear validation message before submission (soft check).
---
### Enforce Cancellation Policy (No Cancellations Within 24 Hours)
**Goal:** Prevent cancellations within 24 hours of shift start time.
**Where:** Backend enforcement.
#### Open Decision
Finalize the penalty for cancellations within this window.
#### Acceptance Criteria
- Backend blocks cancellation attempts inside the 24-hour window.
- API response communicates the policy reason and references the penalty (once finalized).
---
### Implement Worker Documentation Upload Process
**Goal:** Allow workers to upload required documents (e.g., certifications, tax forms) securely.
**Where:** Backend (storage + linking).
#### Scope
- Upload flow.
- Store documents.
- Link documents to the worker profile.
#### Acceptance Criteria
- Uploaded documents are stored securely and retrievable by authorized parties.
- Each upload is reliably associated with the correct worker profile.
---
### Parse Uploaded Documentation for Verification
**Goal:** Extract relevant info from uploaded documents to assist verification.
**Where:** Backend.
#### Policy Requirement
Manual verification by the client must still exist even if AI verification passes.
#### Acceptance Criteria
- Parsed fields are stored in a structured format for review.
- Client can manually verify/override AI results.
---
### Support Attire Upload for Workers
**Goal:** Allow workers to upload attire images for verification.
**Where:** Backend.
#### Acceptance Criteria
- Attire images can be uploaded and linked to the worker profile.
---
### Verify Attire Images Against Shift Dress Code
**Goal:** Verify uploaded attire meets dress code requirements.
**Where:** Backend.
#### Policy Requirement
Manual verification by the client must still exist even if AI verification passes.
#### Acceptance Criteria
- Verification results are stored and visible to the client for manual review.
---
### Support Shifts Requiring "Awaiting Confirmation" Status
**Goal:** Support shifts where the worker must manually confirm before the shift becomes active.
**Where:** Backend.
#### Acceptance Criteria
- Shift can enter an "awaiting confirmation" state.
- Worker confirmation transitions the shift to the next expected active state.
---
### Enable NFC-Based Clock-In and Clock-Out
**Goal:** Allow attendance via NFC.
**Where:** Backend tasks (APIs/events/storage to support NFC clock-in/out).
#### Acceptance Criteria
- Backend can record NFC clock-in/out events with appropriate validation and auditing.
---
### Implement Worker Profile Visibility Settings ✅
**Goal:** Allow workers to hide their profile from clients if they choose.
**Where:** Backend tasks (visibility settings + enforcement).
#### Acceptance Criteria
- Worker can change visibility setting.
- Backend enforces visibility in client-facing queries.
---
### Support Rapid Order Parsing (Voice and Text) Using AI
**Goal:** Let clients create orders by describing needs in voice/text.
**Where:** Backend tasks (parsing + mapping).
#### Notes
Always map the output similar to one-time order creation.
#### Acceptance Criteria
- Backend returns a structured draft order that matches the one-time order model.
---
### Personalize Shifts Shown to Workers (Auto Match)
**Goal:** Show worker-personalized shifts.
**Where:** Backend matching/filtering logic.
#### Inputs (M4)
- Preferred locations.
- Experience.
#### Acceptance Criteria
- Worker shift feed is personalized based on these inputs.
---
### Recurring Order and Reorder — Backend Support
**Goal:** Enable recurring orders and reorder.
**Where:** Backend.
#### Acceptance Criteria
- Backend can create and manage recurring orders and support reorder actions.
---
### Permanent Order and Reorder — Backend Support
**Goal:** Enable permanent orders and reorder.
**Where:** Backend.
#### Acceptance Criteria
- Backend can create and manage permanent orders and support reorder actions.
---
### Backend Support for Reports Page (Client Mobile)
**Goal:** Provide APIs/data needed to render the main reports entry and summary experience.
**Where:** Backend.
#### Acceptance Criteria
- Reports API contracts are defined and documented.
- Client can load the reports page without placeholder data.
---
### Backend Support for "Daily Ops" Report (Client Mobile)
**Goal:** Provide the data required for the Daily Ops report.
**Where:** Backend.
#### Acceptance Criteria
- Daily Ops report API returns all fields required by the UI.
- Response is documented (including filters/date ranges, if applicable).
---
### Backend Support for "Spend Report" (Client Mobile)
**Goal:** Provide the data required for the Spend report.
**Where:** Backend.
#### Acceptance Criteria
- Spend report API returns all fields required by the UI.
- Response is documented (including filters/date ranges, if applicable).
---
### Backend Support for "Coverage Report" (Client Mobile)
**Goal:** Provide the data required for the Coverage report.
**Where:** Backend.
#### Acceptance Criteria
- Coverage report API returns all fields required by the UI.
- Response is documented (including filters/date ranges, if applicable).
---
### Backend Support for "No-Show" Report (Client Mobile)
**Goal:** Provide the data required for the No-show report.
**Where:** Backend.
#### Acceptance Criteria
- No-show report API returns all fields required by the UI.
- Response is documented (including filters/date ranges, if applicable).
---
### Backend Support for "Performance Report" (Client Mobile)
**Goal:** Provide the data required for the Performance report.
**Where:** Backend.
#### Acceptance Criteria
- Performance report API returns all fields required by the UI.
- Response is documented (including filters/date ranges, if applicable).
---
### Calculate the 3 AI Insights for Client Mobile Reports Page
**Goal:** Produce the three AI insights shown on the reports page.
**Where:** Backend.
#### Acceptance Criteria
- Insights are generated consistently and returned in the reports API response.
---
## Frontend (FE)
### Maintain Auth Session (Client and Staff Mobile)
**Goal:** Maintain the authentication session of the client and staff mobile application.
#### Details
Currently when the user restarts the application they are prompted to login. This UX barrier should be removed — if a valid authentication session is available, use it instead of prompting the user to re-login.
#### Acceptance Criteria
- The authentication session of the client and staff mobile applications is maintained across restarts.
---
### Enable iOS Deployment
**Goal:** Enable iOS deployment of both applications.
---
## Staff Mobile Application
### Show Google Maps Location in Worker Shift Details ✅
**Goal:** Display shift location on a map.
#### Acceptance Criteria
- Shift details page shows the correct location using Google Maps.
---
### Show Shift Requirements in Worker Shift Details
**Goal:** Make requirements visible before acceptance.
#### Details
The main goal is to list the required attires in the requirements section, but any other requirements can also be listed there.
#### Acceptance Criteria
- Shift details page includes a requirements section for that shift.
---
### Implement Attire Screen in Worker App
**Goal:** Let workers understand attire requirements and submit attire for review.
#### Scope (M4)
- Show the list of MUST HAVE attire items.
- Show the list of NICE TO HAVE attire items.
- Allow workers to upload images of their attire for verification.
- Show uploaded attire images in the worker profile.
#### Acceptance Criteria
- Attire screen renders required lists and supports image upload flow.
- Uploaded images appear in the worker profile UI.
---
### Implement FAQ Screen in Worker App
**Goal:** Provide common answers in-app.
#### Acceptance Criteria
- Worker app includes an FAQ screen accessible from appropriate navigation.
---
### Implement Privacy and Security Screen in Worker App
**Goal:** Provide key privacy/security controls and documents.
#### Scope (M4)
- Profile visibility setting.
- Terms of service (use a generated placeholder for now; replace with final for launch).
- Privacy policy (use a generated placeholder for now; replace with final for launch).
#### Acceptance Criteria
- Screen is accessible and displays all items above.
---
### Restrict Navigation When Worker Profile Is Incomplete
**Goal:** Reduce access until onboarding/profile completion.
#### Acceptance Criteria
- If the user has not completed their profile, only show **Profile** and **Home**.
---
### Preferred Location Edit
**Goal:** Create a separate page to edit the preferred locations of the staff.
---
## Client Mobile Application
### Hide Edit Icon for Past or Completed Orders
**Goal:** In the client application view order screen, hide the edit icon for orders that are in the past or completed.
---
### Implement Rapid Order Creation (Voice + Text)
**Goal:** Allow clients to quickly create same-day orders by describing needs via voice/text.
#### Scope (M4)
- Capture voice/text input.
- Send input for parsing.
- Populate a screen equivalent to the one-time order creation screen so the client can adjust before finalizing.
- Always map similar to one-time order creation (handles same-day orders).
#### Acceptance Criteria
- Parsed output populates the one-time order creation UI correctly.
- Client can edit and successfully submit the order.
---
### Implement Recurring Order
**Goal:** Allow clients to create recurring orders.
#### Scope (M4)
- Create a recurring order UI flow.
#### Acceptance Criteria
- Client can create and submit a recurring order successfully.
---
### Implement Permanent Order
**Goal:** Allow clients to create permanent orders.
#### Scope (M4)
- Create a permanent order UI flow.
#### Acceptance Criteria
- Client can create and submit a permanent order successfully.
---
### Update Reorder Modal to Support Order Types
**Goal:** Ensure reorder works across supported order types.
#### Acceptance Criteria
- Reorder modal reflects the correct order type and fields.
---
### Complete Reports Interface with AI Insights
**Goal:** Implement the main reports UI and display AI insights.
#### Dependencies
Requires backend reports APIs and AI insights availability.
#### Acceptance Criteria
- Reports interface is complete and shows AI insights (no placeholder UI).
---
### Complete "Daily Ops" Report UI
**Goal:** Implement the Daily Ops report screen.
#### Dependencies
Requires backend Daily Ops report support.
#### Acceptance Criteria
- Daily Ops report UI is complete and renders real data.
---
### Complete "Spend Report" UI
**Goal:** Implement the Spend report screen.
#### Dependencies
Requires backend Spend report support.
#### Acceptance Criteria
- Spend report UI is complete and renders real data.
---
### Complete "Coverage Report" UI
**Goal:** Implement the Coverage report screen.
#### Dependencies
Requires backend Coverage report support.
#### Acceptance Criteria
- Coverage report UI is complete and renders real data.
---
### Complete "No-Show" Report UI
**Goal:** Implement the No-show report screen.
#### Dependencies
Requires backend No-show report support.
#### Acceptance Criteria
- No-show report UI is complete and renders real data.
---
### Complete "Performance Report" UI
**Goal:** Implement the Performance report screen.
#### Dependencies
Requires backend Performance report support.
#### Acceptance Criteria
- Performance report UI is complete and renders real data.
---
### Build Dedicated Interface to Display Hub Details
**Goal:** Show hub details in a dedicated UI.
#### Acceptance Criteria
- Hub details page exists and displays hub information.
---
### Enable Hub Editing (Separate Page)
**Goal:** Allow hub editing via a dedicated screen.
#### Acceptance Criteria
- Separate edit hub page exists and updates the hub data.
---
## Research Tasks
### Validate Worker SSN Number in the US
**Goal:** Identify a viable SSN validation approach.
#### Scope (Research)
- Research third-party services/APIs that provide SSN validation.
- Evaluate cost, reliability, and integration effort.
- Outline an integration plan and highlight risks.
---
### Validate Worker Bank Account Details in the US
**Goal:** Identify a viable bank account validation approach.
#### Scope (Research)
- Research third-party services/APIs for bank account validation.
- Evaluate cost, reliability, and integration effort.
- Outline an integration plan and highlight risks.
> **Note:** Legacy app only uses soft FE checks; M4 aims for a proper validation process.
---
### Payment Platform Research for Worker Payouts
**Goal:** Select a payout/payment platform.
#### Scope (Research)
- Research platforms (e.g., Stripe, PayPal, Square) that support payouts.
- Evaluate cost, reliability, and integration effort.
- Outline an integration plan and highlight risks.
---
### Implement Test Cases for 2 Web Dashboard Features Using Agent Browser
**Goal:** Add automated test coverage runnable via [agent-browser.dev](https://agent-browser.dev/).
#### Scope (Research + Spike)
- Research how to implement test cases for web apps using the agent browser.
---
## Business Tasks
### Create Template Model for PDF Reports (Client and Web Apps)
**Goal:** Align report format across platforms.
#### Acceptance Criteria
- A shared template model is defined and ready to implement.
---
### Handle Operational Risk Scenarios That Disadvantage Clients
**Goal:** Define policies for common operational issues.
#### Scenarios (M4)
- Worker is a no-show.
- Shifts are not getting enough applicants.
#### Acceptance Criteria
- Written policy decisions exist and are ready to translate into product rules.
---
### Finalize Terms of Service and Privacy Policy for Mobile Apps
**Goal:** Provide legal documents for launch readiness.
#### Acceptance Criteria
- Terms of service and privacy policy drafts exist and are approved for implementation.
---
### Handle Worker Data Requests
**Goal:** Define a process for worker data requests.
#### Acceptance Criteria
- A documented workflow exists (intake, verification, fulfillment, timelines).
---
### Rephrase Key Terminology in the App
**Goal:** Use consistent product language.
#### Topics (M4)
- **Worker registration:** Is it "signup" or "onboarding"?
- Context: Workers are expected to be attached to a vendor; the flow is closer to onboarding (phone number + OTP) than self-service signup.
- **Worker profile visibility:** Is it "profile visibility" or "availability status"?
- Context: Workers are not fully invisible; they are marking themselves unavailable.
- **"Auto match":** What do we mean by this?
- Should this exist by default anyway?
- Is this only a marketing item?
> These are just examples; the discussion may surface additional terminology decisions.
#### Acceptance Criteria
- A terminology decision list exists with approved wording.

View File

@@ -0,0 +1,168 @@
# M4 Roadmap CSV Schema Reconciliation
Status: Draft for implementation alignment
Date: 2026-02-25
Owner: Technical Lead
## 1) Why this exists
We reviewed the original product-roadmap exports to confirm that the target schema can support all stakeholder lanes as the platform grows.
This avoids two failure modes:
1. Building command APIs on top of a schema that cannot represent required workflows.
2. Hard-coding today's customer setup in a way that blocks future staffing companies.
## 2) Inputs reviewed
All 13 roadmap exports from `/Users/wiel/Downloads`:
1. `KROW App Roadmap - Business App_ Google, Nvidia.csv`
2. `KROW App Roadmap - Client_ Google, Nvidia.csv`
3. `KROW App Roadmap - Compass- The Operator.csv`
4. `KROW App Roadmap - Employee App.csv`
5. `KROW App Roadmap - Features.csv`
6. `KROW App Roadmap - FoodBuy- Procurement.csv`
7. `KROW App Roadmap - KROW Dashboard.csv`
8. `KROW App Roadmap - Offenses.csv`
9. `KROW App Roadmap - Partner.csv`
10. `KROW App Roadmap - Roadmap.csv`
11. `KROW App Roadmap - Sectors_ BA, Flik ( The executors).csv`
12. `KROW App Roadmap - The Workforce_ Employees.csv`
13. `KROW App Roadmap - Vendor_ Legendary (Staffing).csv`
Parsed signal:
1. 983 non-empty task lines.
2. 1,263 planning rows with task/status/priority/reference signals.
## 3) What the roadmap is clearly asking for
Cross-file recurring capabilities:
1. Multi-party org model: client, operator, vendor, procurement, workforce, partner, sector execution.
2. Orders and shift operations: recurring events, assignment, coverage, schedule management.
3. Attendance and policy enforcement: clock-in/out, no-show, tardiness, cancellation, offense ladders.
4. Compliance and document verification: certifications, insurance, legal docs, renewals, risk alerts.
5. Finance and settlement: invoice lifecycle, disputes, remittance, payment history, aging, payroll/earnings.
6. Reporting and prediction: dashboards, KPI, forecasting, scenario planning.
Repeated examples across many sheets:
1. `Vendor Onboarding`, `Service Locations`, `Compliance`, `Certifications`.
2. `All Invoices (Open/Pending/Overdue/Paid...)`, `Payment Summary`, `Remittance Advice Download`.
3. Offense progression rules in `Offenses.csv` and `Employee App.csv` (warning -> suspension -> disable/block).
## 4) Stakeholder capability matrix (from roadmap exports)
| Stakeholder lane | Org network | Orders and shifts | Attendance and offense | Compliance docs | Finance | Reporting |
|---|---|---|---|---|---|---|
| Client (Google, Nvidia) | Yes | Yes | Partial (visibility) | Yes | Yes | Yes |
| Vendor (Legendary) | Yes | Yes | Yes | Yes | Yes | Yes |
| Workforce (Employee app) | Limited | Yes | Yes | Yes | Earnings focus | Limited |
| Operator (Compass) | Yes | Yes | KPI visibility | Yes | Yes | Yes |
| Procurement (FoodBuy) | Yes | KPI/SLA focus | KPI/SLA focus | Yes | Yes | Yes |
| KROW Dashboard | Cross-entity | Cross-entity | Cross-entity risk | Cross-entity | Cross-entity | Heavy |
| Partner | Basic | Basic | Minimal | Yes | Basic | Basic |
Implication:
1. This is a multi-tenant, multi-party workflow platform, not a single-role CRUD app.
2. Schema must separate party identity, party relationships, and role-based permissions from workflow records.
## 5) Reconciliation against current Data Connect schema
What already exists and is useful:
1. Core scheduling entities: `orders`, `shifts`, `shift_roles`, `applications`, `assignments`.
2. Workforce entities: `staffs`, `workforce`, `staff_roles`.
3. Financial entities: `invoices`, `recent_payments`, `vendor_rates`.
4. Compliance entities: `documents`, `staff_documents`, `certificates`.
Current structural gaps for roadmap scale:
1. No tenant boundary key on core tables (`tenant_id` missing).
2. No first-class business user partitioning table (`business_memberships` missing).
3. No first-class vendor user partitioning table (`vendor_memberships` missing).
4. No first-class stakeholder profile/link model for buyer/operator/partner/sector relationships.
5. Attendance history is not first-class (check in/out only inside `applications`).
6. No offense policy, offense event, or enforcement action tables.
7. Finance is coarse (invoice + recent payment), missing line items, payment runs, remittance artifact model.
8. Sensitive bank fields are currently modeled directly in `accounts` (`accountNumber`, `routeNumber`).
9. Many core workflow fields are JSON (`orders.assignedStaff`, `orders.shifts`, `shift.managers`, `assignment.managers`).
10. Money still uses float in critical tables.
Connector boundary gap:
1. 147 Data Connect mutation operations exist.
2. 36 of those are high-risk core workflow mutations (`order`, `shift`, `shiftRole`, `application`, `assignment`, `invoice`, `vendor`, `business`, `workForce`, `teamMember`, `account`).
## 6) Target schema additions required before full command rollout
### 6.1 Tenant and stakeholder graph
1. `tenants`
2. `tenant_memberships`
3. `business_memberships`
4. `vendor_memberships`
5. `stakeholder_types`
6. `stakeholder_profiles`
7. `stakeholder_links`
8. `role_bindings` (scoped to tenant/team/hub/business/vendor/resource)
### 6.2 Attendance and timesheet reliability
1. `attendance_events` (append-only clock-in/out/NFC/manual-corrected)
2. `attendance_sessions` (derived per shift role assignment)
3. `timesheets` (approval state and pay-eligible snapshot)
4. `timesheet_adjustments` (manual corrections with audit reason)
### 6.3 Offense and policy enforcement
1. `offense_policies` (per tenant or per business)
2. `offense_rules` (threshold and consequence ladder)
3. `offense_events` (who, what, when, evidence)
4. `enforcement_actions` (warning, suspension, disable, block-from-client)
### 6.4 Compliance and verification
1. `verification_jobs`
2. `verification_reviews`
3. `verification_events`
4. `compliance_requirements` (per role, tenant, business, or client contract)
### 6.5 Finance completeness
1. `invoice_line_items`
2. `invoice_status_history`
3. `payment_runs`
4. `payment_allocations`
5. `remittance_documents`
6. `account_token_refs` (tokenized provider refs, no raw account/routing)
## 7) Minimal target relationship view
```mermaid
erDiagram
TENANT ||--o{ TENANT_MEMBERSHIP : has
BUSINESS ||--o{ BUSINESS_MEMBERSHIP : has
VENDOR ||--o{ VENDOR_MEMBERSHIP : has
USER ||--o{ BUSINESS_MEMBERSHIP : belongs_to
USER ||--o{ VENDOR_MEMBERSHIP : belongs_to
TENANT ||--o{ STAKEHOLDER_PROFILE : has
STAKEHOLDER_PROFILE ||--o{ STAKEHOLDER_LINK : links_to
TENANT ||--o{ BUSINESS : owns
TENANT ||--o{ VENDOR : owns
BUSINESS ||--o{ ORDER : requests
VENDOR ||--o{ ORDER : fulfills
ORDER ||--o{ SHIFT : expands_to
SHIFT ||--o{ SHIFT_ROLE : requires
SHIFT_ROLE ||--o{ APPLICATION : receives
APPLICATION ||--o{ ASSIGNMENT : becomes
ASSIGNMENT ||--o{ ATTENDANCE_EVENT : emits
ASSIGNMENT ||--o{ TIMESHEET : settles
OFFENSE_POLICY ||--o{ OFFENSE_RULE : defines
ASSIGNMENT ||--o{ OFFENSE_EVENT : may_trigger
OFFENSE_EVENT ||--o{ ENFORCEMENT_ACTION : causes
ORDER ||--o{ INVOICE : bills
INVOICE ||--o{ INVOICE_LINE_ITEM : contains
PAYMENT_RUN ||--o{ PAYMENT_ALLOCATION : allocates
INVOICE ||--o{ PAYMENT_ALLOCATION : receives
PAYMENT_RUN ||--o{ REMITTANCE_DOCUMENT : publishes
```
## 8) First-principles rules we should lock now
1. Every command-critical table includes `tenant_id`.
2. High-risk writes go through command APIs only.
3. Money uses exact numeric type (or integer cents), never float.
4. Core workflow state is relational and constrained, not JSON blobs.
5. Every irreversible state change has append-only audit event rows.
## 9) Decision
This roadmap evidence supports continuing with the target architecture direction (command boundary + multi-tenant schema), but we should add attendance/offense/settlement/stakeholder-graph tables before full command rollout on mission-critical flows.

View File

@@ -0,0 +1,499 @@
# M4 Target Schema Blueprint (Command-Ready)
Status: Draft for team alignment
Date: 2026-02-25
Owner: Technical Lead
## 1) Goal
Define the target database shape we want **before** command-backend implementation, so critical flows are atomic, secure, and scalable.
## 1.1 Stakeholder and tenancy model
This product should be designed as a **multi-tenant platform**.
1. Tenant:
- One staffing company account (example: Legendary Event Staffing and Entertainment).
2. Business:
- A customer/client account owned by a tenant.
3. User:
- A human identity (auth account) that can belong to one or more tenants.
4. Staff:
- A workforce profile linked to a user identity and tenant-scoped operations.
Practical meaning:
1. The same platform can serve multiple staffing companies safely.
2. Data isolation is by `tenant_id`, not only by business/vendor IDs.
3. Not every record starts as a full active user:
- invite-first or pending onboarding records are valid,
- then bound to `user_id` when activation is completed.
4. Business-side users and vendor-side users are partitioned with dedicated membership tables, not only one `userId` owner field.
```mermaid
flowchart LR
U["User identity"] --> M["Tenant membership"]
M --> T["Tenant staffing company"]
T --> B["Business client"]
T --> V["Vendor partner"]
B --> O["Orders and shifts"]
V --> O
```
## 1.2 Stakeholder wheel mapping (current baseline)
The stakeholder labels from the customer workshop map to schema as follows:
1. Buyer (Procurements):
- Buyer users inside a business/client account.
- Schema anchor: `users` + `tenant_memberships` + `business_memberships`.
2. Enterprises (Operator):
- Tenant operator/admin users running staffing operations.
- Schema anchor: `tenants`, `tenant_memberships`, `role_bindings`.
3. Sectors (Execution):
- Operational segments or business units executing events.
- Schema anchor: `teams`, `team_hubs`, `team_hud_departments`, `roles`.
4. Approved Vendor:
- Supplier companies approved to fulfill staffing demand.
- Schema anchor: `vendors`, `vendor_memberships`, `workforce`, `vendor_rates`, `vendor_benefit_plans`.
5. Workforce:
- Individual workers/staff and their assignments.
- Schema anchor: `staffs`, `staff_roles`, `applications`, `assignments`, `certificates`, `staff_documents`.
6. Partner:
- External integration or service partner (future).
- Schema anchor: `stakeholder_profiles` extension path + scoped role bindings.
Rule:
1. Start with baseline stakeholders above.
2. Add new stakeholders via extension tables and role bindings, not by changing core scheduling and finance tables.
## 1.3 Future stakeholder expansion model
To add stakeholders later without breaking core schema:
1. Add `stakeholder_types` (registry).
2. Add `stakeholder_profiles` (`tenant_id`, `type`, `status`, `metadata`).
3. Add `stakeholder_links` (relationship graph across stakeholders).
4. Bind permissions through `role_bindings` with scope (`tenant`, `team`, `hub`, `business`, or specific resource).
## 1.4 Roadmap CSV evidence snapshot
Evidence source:
1. `docs/MILESTONES/M4/planning/m4-roadmap-csv-schema-reconciliation.md`
What the exports confirmed:
1. The product is multi-party and multi-tenant by design (client, operator, vendor, workforce, procurement, partner, dashboard).
2. Attendance and offense enforcement are core business workflows, not side features.
3. Finance requires more than invoices (payment runs, remittance, status history, dispute/audit trace).
4. Compliance requires asynchronous verification and requirement templates by tenant/business/role.
## 2) First-principles rules
1. Every critical write must be server-mediated and transactional.
2. Tenant boundaries must be explicit in data and queries.
3. Money and rates must use exact numeric types, not floating point.
4. Data needed for constraints should be relational, not hidden in JSON blobs.
5. Every high-risk state transition must be auditable and replayable.
## 3) Current anti-patterns we are removing
1. Direct client mutation of core entities.
2. Broad `USER`-auth CRUD without strict tenant scoping.
3. Financial values as `Float`.
4. Core workflow state embedded in generic `Any/jsonb` fields.
5. Missing uniqueness/index constraints on high-traffic paths.
## 4) Target modular schema
## 4.1 Identity and Access
Tables:
1. `users` (source identity, profile, auth linkage)
2. `tenant_memberships` (new; membership + base access per tenant)
3. `business_memberships` (new; user access to business account scope)
4. `vendor_memberships` (new; user access to vendor account scope)
5. `team_members` (membership + scope per team)
6. `roles` (new)
7. `permissions` (new)
8. `role_bindings` (new; who has which role in which scope)
Rules:
1. Unique tenant membership: `(tenant_id, user_id)`.
2. Unique business membership: `(business_id, user_id)`.
3. Unique vendor membership: `(vendor_id, user_id)`.
4. Unique team membership: `(team_id, user_id)`.
5. Access checks resolve through tenant membership first, then business/vendor/team scope.
## 4.2 Organization and Tenant
Tables:
1. `tenants` (new canonical boundary: business/vendor ownership root)
2. `businesses`
3. `vendors`
4. `teams`
5. `team_hubs`
6. `hubs`
Rules:
1. Every command-critical row references `tenant_id`.
2. All list queries must include tenant predicate.
3. Business and vendor routes must enforce membership scope before data access.
## 4.8 RBAC rollout strategy (deferred enforcement)
RBAC should be introduced in phases and **not enforced everywhere immediately**.
Phase A: Auth-first (now)
1. Require valid auth token.
2. Resolve tenant context.
3. Allow current work to continue while logging actor + tenant + action.
Phase B: Shadow RBAC
1. Evaluate permissions (`allow`/`deny`) in backend.
2. Log decisions but do not block most requests yet.
3. Start with warnings and dashboards for denied actions.
Phase C: Enforced RBAC on command writes
1. Enforce RBAC on `/commands/*` only.
2. Keep low-risk read flows in transition mode.
Phase D: Enforced RBAC on high-risk reads
1. Enforce tenant and role checks on sensitive read connectors.
2. Remove remaining broad user-level access.
```mermaid
flowchart LR
A["Auth only"] --> B["Shadow RBAC logging"]
B --> C["Enforce RBAC on command writes"]
C --> D["Enforce RBAC on sensitive reads"]
```
## 4.3 Scheduling and Orders
Tables:
1. `orders`
2. `order_schedule_rules` (new; replaces schedule JSON fields)
3. `shifts`
4. `shift_roles`
5. `shift_role_requirements` (optional extension for policy rules)
6. `shift_managers` (new; replaces `managers: [Any!]`)
Rules:
1. No denormalized `assignedStaff` or `shifts` JSON in `orders`.
2. Time constraints: `start_time < end_time`.
3. Capacity constraints: `assigned <= count`, `filled <= workers_needed`.
4. Canonical status names (single spelling across schema).
## 4.4 Staffing and Matching
Tables:
1. `staffs`
2. `staff_roles`
3. `workforce`
4. `applications`
5. `assignments`
6. `staff_reviews`
7. `staff_favorites`
Rules:
1. One active workforce relation per `(vendor_id, staff_id)`.
2. One application per `(shift_id, role_id, staff_id)` unless versioned intentionally.
3. Assignment state transitions only through command APIs.
4. Business quality signals are relational:
- `staff_reviews` stores rating and review text from businesses,
- `staff_favorites` stores reusable staffing preferences,
- aggregate rating is materialized on `staffs`.
## 4.5 Compliance and Verification
Tables:
1. `documents`
2. `staff_documents`
3. `certificates`
4. `verification_jobs`
5. `verification_reviews`
6. `verification_events`
Rules:
1. Verification is asynchronous and append-only for events.
2. Manual review is explicit and tracked.
3. Government ID and certification provider references are persisted.
## 4.6 Financial and Payout
Tables:
1. `invoices`
2. `invoice_templates`
3. `recent_payments`
4. `accounts` (refactor to tokenized provider references)
Rules:
1. Replace monetary `Float` with exact numeric (`DECIMAL(12,2)` or integer cents).
2. Do not expose raw account/routing values in query connectors.
3. Add one-primary-account constraint per owner.
## 4.7 Audit and Reliability
Tables:
1. `domain_events` (new)
2. `idempotency_keys` (already started in command API SQL)
3. `activity_logs`
Rules:
1. Every command write emits a domain event.
2. Idempotency scope: `(actor_uid, route, idempotency_key)`.
## 4.9 Attendance, Timesheets, and Offense Governance
Tables:
1. `clock_points` (approved tap and geo validation points per business or venue)
2. `attendance_events` (append-only: clock-in/out, source, NFC, geo, correction metadata)
3. `attendance_sessions` (derived work session per assignment)
4. `timesheets` (approval-ready payroll snapshot)
5. `timesheet_adjustments` (manual edits with reason and actor)
6. `offense_policies` (tenant/business scoped policy set)
7. `offense_rules` (threshold ladder and consequence)
8. `offense_events` (actual violation events)
9. `enforcement_actions` (warning, suspension, disable, block)
Rules:
1. Attendance corrections are additive events, not destructive overwrites.
2. NFC and geo validation happens against `clock_points`, not hardcoded client logic.
3. Rejected attendance attempts are still logged as events for audit.
4. Offense consequences are computed from policy + history and persisted as explicit actions.
5. Manual overrides require actor, reason, and timestamp in audit trail.
## 4.10 Stakeholder Network Extensibility
Tables:
1. `stakeholder_types` (buyer, operator, vendor, workforce, partner, future types)
2. `stakeholder_profiles` (tenant-scoped typed profile)
3. `stakeholder_links` (explicit relationship graph between profiles)
Rules:
1. New stakeholder categories are added by data, not by schema rewrites to core workflow tables.
2. Permission scope resolves through role bindings plus stakeholder links where needed.
3. Scheduling and finance records remain stable while stakeholder topology evolves.
## 5) Target core model (conceptual)
```mermaid
erDiagram
TENANT ||--o{ BUSINESS : owns
TENANT ||--o{ VENDOR : owns
TENANT ||--o{ TEAM : owns
TEAM ||--o{ TEAM_MEMBER : has
USER ||--o{ TEAM_MEMBER : belongs_to
USER ||--o{ BUSINESS_MEMBERSHIP : belongs_to
USER ||--o{ VENDOR_MEMBERSHIP : belongs_to
BUSINESS ||--o{ BUSINESS_MEMBERSHIP : has
VENDOR ||--o{ VENDOR_MEMBERSHIP : has
BUSINESS ||--o{ ORDER : requests
VENDOR ||--o{ ORDER : fulfills
ORDER ||--o{ ORDER_SCHEDULE_RULE : has
ORDER ||--o{ SHIFT : expands_to
SHIFT ||--o{ SHIFT_ROLE : requires
SHIFT ||--o{ SHIFT_MANAGER : has
USER ||--o{ STAFF : identity
STAFF ||--o{ STAFF_ROLE : skills
VENDOR ||--o{ WORKFORCE : contracts
STAFF ||--o{ WORKFORCE : linked
SHIFT_ROLE ||--o{ APPLICATION : receives
STAFF ||--o{ APPLICATION : applies
SHIFT_ROLE ||--o{ ASSIGNMENT : allocates
WORKFORCE ||--o{ ASSIGNMENT : executes
ASSIGNMENT ||--o{ ATTENDANCE_EVENT : emits
ASSIGNMENT ||--o{ TIMESHEET : settles
OFFENSE_POLICY ||--o{ OFFENSE_RULE : defines
ASSIGNMENT ||--o{ OFFENSE_EVENT : may_trigger
OFFENSE_EVENT ||--o{ ENFORCEMENT_ACTION : causes
STAFF ||--o{ CERTIFICATE : has
STAFF ||--o{ STAFF_DOCUMENT : uploads
DOCUMENT ||--o{ STAFF_DOCUMENT : references
STAFF ||--o{ VERIFICATION_JOB : subject
VERIFICATION_JOB ||--o{ VERIFICATION_REVIEW : reviewed_by
VERIFICATION_JOB ||--o{ VERIFICATION_EVENT : logs
ORDER ||--o{ INVOICE : billed_by
INVOICE ||--o{ RECENT_PAYMENT : settles
TENANT ||--o{ ACCOUNT_TOKEN_REF : payout_method
INVOICE ||--o{ INVOICE_LINE_ITEM : details
PAYMENT_RUN ||--o{ PAYMENT_ALLOCATION : allocates
INVOICE ||--o{ PAYMENT_ALLOCATION : receives
PAYMENT_RUN ||--o{ REMITTANCE_DOCUMENT : publishes
ORDER ||--o{ DOMAIN_EVENT : emits
SHIFT ||--o{ DOMAIN_EVENT : emits
ASSIGNMENT ||--o{ DOMAIN_EVENT : emits
STAKEHOLDER_TYPE ||--o{ STAKEHOLDER_PROFILE : classifies
STAKEHOLDER_PROFILE ||--o{ STAKEHOLDER_LINK : relates
```
## 6) Command write boundary on this schema
```mermaid
flowchart LR
A["Frontend app"] --> B["Command API"]
B --> C["Policy + validation"]
C --> D["Single database transaction"]
D --> E["orders, shifts, shift_roles, applications, assignments"]
D --> F["domain_events + idempotency_keys"]
E --> G["Read models and reports"]
```
## 7) Minimum constraints and indexes to add before command build
## 7.1 Constraints
1. `shift_roles`: check `assigned >= 0 AND assigned <= count`.
2. `shifts`: check `start_time < end_time`.
3. `applications`: unique `(shift_id, role_id, staff_id)`.
4. `workforce`: unique active `(vendor_id, staff_id)`.
5. `team_members`: unique `(team_id, user_id)`.
6. `accounts` (or token ref table): unique primary per owner.
7. `attendance_events`: unique idempotency tuple (for example `(assignment_id, source_event_id)`).
8. `offense_rules`: unique `(policy_id, trigger_type, threshold_count)`.
## 7.2 Indexes
1. `orders (tenant_id, status, date)`.
2. `shifts (order_id, date, status)`.
3. `shift_roles (shift_id, role_id, start_time)`.
4. `applications (shift_id, role_id, status, created_at)`.
5. `assignments (workforce_id, shift_id, role_id, status)`.
6. `verification_jobs (subject_id, type, status, created_at)`.
7. `invoices (business_id, vendor_id, status, due_date)`.
8. `attendance_events (assignment_id, event_time, event_type)`.
9. `offense_events (staff_id, occurred_at, offense_type, status)`.
10. `invoice_line_items (invoice_id, line_type, created_at)`.
## 8) Data type normalization
1. Monetary: `Float -> DECIMAL(12,2)` (or integer cents).
2. Generic JSON fields in core scheduling: split into relational tables.
3. Timestamps: store UTC and enforce server-generated creation/update fields.
## 9) Security boundary in schema/connectors
1. Remove broad list queries for sensitive entities unless tenant-scoped.
2. Strip sensitive fields from connector query payloads (bank/routing).
3. Keep high-risk mutations behind command API; Data Connect remains read-first for client.
## 10) Migration phases (schema-first)
```mermaid
flowchart TD
P0["Phase 0: Safety patch
- lock sensitive fields
- enforce tenant-scoped queries
- freeze new direct write connectors"] --> P1["Phase 1: Core constraints
- add unique/check constraints
- add indexes
- normalize money types"]
P1 --> P2["Phase 2: Tenant and RBAC base tables
- add tenants and tenant_memberships
- add roles permissions role_bindings
- run RBAC in shadow mode"]
P2 --> P3["Phase 3: Scheduling normalization
- remove order JSON workflow fields
- add order_schedule_rules and shift_managers
- add attendance and offense base tables"]
P3 --> P4["Phase 4: Command rollout
- command writes on hardened schema
- emit domain events + idempotency
- enforce RBAC for command routes
- add finance settlement tables for payment runs and remittance"]
P4 --> P5["Phase 5: Read migration + cleanup
- migrate frontend reads as needed
- enforce RBAC for sensitive reads
- retire deprecated connectors"]
```
## 11) Definition of ready for command backend
1. P0 and P1 complete in `dev`.
2. Tenant scoping verified in connector tests.
3. Sensitive field exposure removed.
4. Core transaction invariants enforced by schema constraints.
5. Command API contracts mapped to new normalized tables.
6. RBAC is in shadow mode with decision logs in place (not hard-blocking yet).
7. Attendance and offense tables are ready for policy-driven command routes.
8. Finance settlement tables (`invoice_line_items`, `payment_runs`, `payment_allocations`) are available.
## 12) Full current model relationship map (all models)
```mermaid
flowchart LR
Account["Account"]
ActivityLog["ActivityLog"]
Application["Application"]
Assignment["Assignment"]
AttireOption["AttireOption"]
BenefitsData["BenefitsData"]
Business["Business"]
Category["Category"]
Certificate["Certificate"]
ClientFeedback["ClientFeedback"]
Conversation["Conversation"]
Course["Course"]
CustomRateCard["CustomRateCard"]
Document["Document"]
EmergencyContact["EmergencyContact"]
FaqData["FaqData"]
Hub["Hub"]
Invoice["Invoice"]
InvoiceTemplate["InvoiceTemplate"]
Level["Level"]
MemberTask["MemberTask"]
Message["Message"]
Order["Order"]
RecentPayment["RecentPayment"]
Role["Role"]
RoleCategory["RoleCategory"]
Shift["Shift"]
ShiftRole["ShiftRole"]
Staff["Staff"]
StaffAvailability["StaffAvailability"]
StaffAvailabilityStats["StaffAvailabilityStats"]
StaffCourse["StaffCourse"]
StaffDocument["StaffDocument"]
StaffRole["StaffRole"]
Task["Task"]
TaskComment["TaskComment"]
TaxForm["TaxForm"]
Team["Team"]
TeamHub["TeamHub"]
TeamHudDepartment["TeamHudDepartment"]
TeamMember["TeamMember"]
User["User"]
UserConversation["UserConversation"]
Vendor["Vendor"]
VendorBenefitPlan["VendorBenefitPlan"]
VendorRate["VendorRate"]
Workforce["Workforce"]
Application --> Shift
Application --> ShiftRole
Application --> Staff
Assignment --> ShiftRole
Assignment --> Workforce
BenefitsData --> Staff
BenefitsData --> VendorBenefitPlan
Certificate --> Staff
ClientFeedback --> Business
ClientFeedback --> Vendor
Course --> Category
Invoice --> Business
Invoice --> Order
Invoice --> Vendor
InvoiceTemplate --> Business
InvoiceTemplate --> Order
InvoiceTemplate --> Vendor
MemberTask --> Task
MemberTask --> TeamMember
Message --> User
Order --> Business
Order --> TeamHub
Order --> Vendor
RecentPayment --> Application
RecentPayment --> Invoice
Shift --> Order
ShiftRole --> Role
ShiftRole --> Shift
StaffAvailability --> Staff
StaffAvailabilityStats --> Staff
StaffDocument --> Document
StaffRole --> Role
StaffRole --> Staff
TaskComment --> TeamMember
TeamHub --> Team
TeamHudDepartment --> TeamHub
TeamMember --> Team
TeamMember --> TeamHub
TeamMember --> User
UserConversation --> Conversation
UserConversation --> User
VendorBenefitPlan --> Vendor
VendorRate --> Vendor
Workforce --> Staff
Workforce --> Vendor
```

View File

@@ -0,0 +1,274 @@
# M4 Target Schema Models, Keys, and Relationships
Status: Draft for architecture workshop
Date: 2026-02-25
Owner: Technical Lead
## 1) Purpose
This document is the model-level view for slide creation:
1. Key fields per model (`PK`, `FK`, unique keys).
2. How models relate to each other.
3. A first-principles structure for scale across tenant, business, vendor, and workforce flows.
## 2) Identity and access models
### 2.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `users` | `id` | - | `email` (optional unique) |
| `tenants` | `id` | - | `slug` |
| `tenant_memberships` | `id` | `tenant_id -> tenants.id`, `user_id -> users.id` | `(tenant_id, user_id)` |
| `business_memberships` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id`, `user_id -> users.id` | `(business_id, user_id)` |
| `vendor_memberships` | `id` | `tenant_id -> tenants.id`, `vendor_id -> vendors.id`, `user_id -> users.id` | `(vendor_id, user_id)` |
| `roles` | `id` | `tenant_id -> tenants.id` | `(tenant_id, name)` |
| `permissions` | `id` | - | `code` |
| `role_bindings` | `id` | `tenant_id -> tenants.id`, `role_id -> roles.id`, `user_id -> users.id` | `(tenant_id, role_id, user_id, scope_type, scope_id)` |
### 2.2 Diagram
```mermaid
erDiagram
USERS ||--o{ TENANT_MEMBERSHIPS : has
TENANTS ||--o{ TENANT_MEMBERSHIPS : has
USERS ||--o{ BUSINESS_MEMBERSHIPS : has
BUSINESSES ||--o{ BUSINESS_MEMBERSHIPS : has
TENANTS ||--o{ BUSINESS_MEMBERSHIPS : scopes
USERS ||--o{ VENDOR_MEMBERSHIPS : has
VENDORS ||--o{ VENDOR_MEMBERSHIPS : has
TENANTS ||--o{ VENDOR_MEMBERSHIPS : scopes
TENANTS ||--o{ ROLES : defines
ROLES ||--o{ ROLE_BINDINGS : used_by
USERS ||--o{ ROLE_BINDINGS : receives
TENANTS ||--o{ ROLE_BINDINGS : scopes
```
```
## 3) Organization and stakeholder models
### 3.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `businesses` | `id` | `tenant_id -> tenants.id` | `(tenant_id, business_name)` |
| `vendors` | `id` | `tenant_id -> tenants.id` | `(tenant_id, company_name)` |
| `teams` | `id` | `tenant_id -> tenants.id` | `(tenant_id, team_name)` |
| `team_hubs` | `id` | `team_id -> teams.id` | `(team_id, hub_name)` |
| `team_hud_departments` | `id` | `team_hub_id -> team_hubs.id` | `(team_hub_id, name)` |
| `stakeholder_types` | `id` | - | `code` |
| `stakeholder_profiles` | `id` | `tenant_id -> tenants.id`, `stakeholder_type_id -> stakeholder_types.id` | `(tenant_id, stakeholder_type_id, name)` |
| `stakeholder_links` | `id` | `tenant_id -> tenants.id`, `from_profile_id -> stakeholder_profiles.id`, `to_profile_id -> stakeholder_profiles.id` | `(tenant_id, from_profile_id, to_profile_id, relation_type)` |
### 3.2 Diagram
```mermaid
erDiagram
TENANTS ||--o{ BUSINESSES : owns
TENANTS ||--o{ VENDORS : owns
TENANTS ||--o{ TEAMS : owns
TEAMS ||--o{ TEAM_HUBS : has
TEAM_HUBS ||--o{ TEAM_HUD_DEPARTMENTS : has
STAKEHOLDER_TYPES ||--o{ STAKEHOLDER_PROFILES : classifies
TENANTS ||--o{ STAKEHOLDER_PROFILES : owns
STAKEHOLDER_PROFILES ||--o{ STAKEHOLDER_LINKS : from
STAKEHOLDER_PROFILES ||--o{ STAKEHOLDER_LINKS : to
TENANTS ||--o{ STAKEHOLDER_LINKS : scopes
```
```
## 4) Workforce, orders, and assignments
### 4.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `staffs` | `id` | `tenant_id -> tenants.id`, `user_id -> users.id` | `(tenant_id, user_id)` (nullable until activation if needed) |
| `staff_roles` | `id` | `staff_id -> staffs.id`, `role_id -> roles.id` | `(staff_id, role_id)` |
| `workforce` | `id` | `tenant_id -> tenants.id`, `vendor_id -> vendors.id`, `staff_id -> staffs.id` | active `(vendor_id, staff_id)` |
| `orders` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id`, `vendor_id -> vendors.id` | `(tenant_id, external_ref)` optional |
| `order_schedule_rules` | `id` | `order_id -> orders.id` | `(order_id, rule_type, effective_from)` |
| `shifts` | `id` | `tenant_id -> tenants.id`, `order_id -> orders.id` | `(order_id, start_time, end_time)` |
| `shift_roles` | `id` | `shift_id -> shifts.id`, `role_id -> roles.id` | `(shift_id, role_id)` |
| `shift_managers` | `id` | `shift_id -> shifts.id`, `team_member_id -> team_members.id` | `(shift_id, team_member_id)` |
| `applications` | `id` | `tenant_id -> tenants.id`, `shift_id -> shifts.id`, `role_id -> roles.id`, `staff_id -> staffs.id` | `(shift_id, role_id, staff_id)` |
| `assignments` | `id` | `tenant_id -> tenants.id`, `shift_role_id -> shift_roles.id`, `workforce_id -> workforce.id` | `(shift_role_id, workforce_id)` active |
| `staff_reviews` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id`, `staff_id -> staffs.id`, `assignment_id -> assignments.id` | `(business_id, assignment_id, staff_id)` |
| `staff_favorites` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id`, `staff_id -> staffs.id` | `(business_id, staff_id)` |
### 4.2 Diagram
```mermaid
erDiagram
TENANTS ||--o{ STAFFS : owns
USERS ||--o| STAFFS : identity
STAFFS ||--o{ STAFF_ROLES : has
ROLES ||--o{ STAFF_ROLES : classifies
TENANTS ||--o{ ORDERS : scopes
BUSINESSES ||--o{ ORDERS : requests
VENDORS ||--o{ ORDERS : fulfills
ORDERS ||--o{ ORDER_SCHEDULE_RULES : configures
ORDERS ||--o{ SHIFTS : expands_to
SHIFTS ||--o{ SHIFT_ROLES : requires
ROLES ||--o{ SHIFT_ROLES : typed_as
SHIFTS ||--o{ SHIFT_MANAGERS : has
VENDORS ||--o{ WORKFORCE : contracts
STAFFS ||--o{ WORKFORCE : linked
SHIFT_ROLES ||--o{ APPLICATIONS : receives
STAFFS ||--o{ APPLICATIONS : applies
SHIFT_ROLES ||--o{ ASSIGNMENTS : allocates
WORKFORCE ||--o{ ASSIGNMENTS : executes
BUSINESSES ||--o{ STAFF_REVIEWS : rates
STAFFS ||--o{ STAFF_REVIEWS : receives
ASSIGNMENTS ||--o{ STAFF_REVIEWS : references
BUSINESSES ||--o{ STAFF_FAVORITES : favorites
STAFFS ||--o{ STAFF_FAVORITES : selected
```
```
## 5) Attendance and offense governance
### 5.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `clock_points` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id` | `(tenant_id, nfc_tag_uid)` nullable |
| `attendance_events` | `id` | `tenant_id -> tenants.id`, `assignment_id -> assignments.id`, `clock_point_id -> clock_points.id` | append-only event log |
| `attendance_sessions` | `id` | `tenant_id -> tenants.id`, `assignment_id -> assignments.id` | one open session per assignment |
| `timesheets` | `id` | `tenant_id -> tenants.id`, `assignment_id -> assignments.id`, `staff_id -> staffs.id` | `(assignment_id)` |
| `timesheet_adjustments` | `id` | `timesheet_id -> timesheets.id`, `actor_user_id -> users.id` | - |
| `offense_policies` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id` nullable | `(tenant_id, name, business_id)` |
| `offense_rules` | `id` | `policy_id -> offense_policies.id` | `(policy_id, trigger_type, threshold_count)` |
| `offense_events` | `id` | `tenant_id -> tenants.id`, `staff_id -> staffs.id`, `assignment_id -> assignments.id` nullable, `rule_id -> offense_rules.id` nullable | `(staff_id, occurred_at, offense_type)` |
| `enforcement_actions` | `id` | `offense_event_id -> offense_events.id`, `actor_user_id -> users.id` | - |
### 5.2 Diagram
```mermaid
erDiagram
BUSINESSES ||--o{ CLOCK_POINTS : defines
CLOCK_POINTS ||--o{ ATTENDANCE_EVENTS : validates
ASSIGNMENTS ||--o{ ATTENDANCE_EVENTS : emits
ASSIGNMENTS ||--o{ ATTENDANCE_SESSIONS : opens
ASSIGNMENTS ||--o{ TIMESHEETS : settles
TIMESHEETS ||--o{ TIMESHEET_ADJUSTMENTS : adjusts
USERS ||--o{ TIMESHEET_ADJUSTMENTS : made_by
TENANTS ||--o{ OFFENSE_POLICIES : defines
BUSINESSES ||--o{ OFFENSE_POLICIES : overrides
OFFENSE_POLICIES ||--o{ OFFENSE_RULES : contains
STAFFS ||--o{ OFFENSE_EVENTS : incurs
OFFENSE_RULES ||--o{ OFFENSE_EVENTS : triggered_by
OFFENSE_EVENTS ||--o{ ENFORCEMENT_ACTIONS : causes
USERS ||--o{ ENFORCEMENT_ACTIONS : applied_by
```
```
## 6) Compliance and verification
### 6.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `documents` | `id` | `tenant_id -> tenants.id` | `(tenant_id, document_type, name)` |
| `staff_documents` | `id` | `staff_id -> staffs.id`, `document_id -> documents.id` | `(staff_id, document_id)` |
| `certificates` | `id` | `staff_id -> staffs.id` | `(staff_id, certificate_number)` optional |
| `compliance_requirements` | `id` | `tenant_id -> tenants.id`, `business_id -> businesses.id` nullable, `role_id -> roles.id` nullable | `(tenant_id, requirement_type, business_id, role_id)` |
| `verification_jobs` | `id` | `tenant_id -> tenants.id`, `staff_id -> staffs.id`, `document_id -> documents.id` nullable | `(tenant_id, idempotency_key)` |
| `verification_reviews` | `id` | `verification_job_id -> verification_jobs.id`, `reviewer_user_id -> users.id` | - |
| `verification_events` | `id` | `verification_job_id -> verification_jobs.id` | - |
### 6.2 Diagram
```mermaid
erDiagram
STAFFS ||--o{ STAFF_DOCUMENTS : uploads
DOCUMENTS ||--o{ STAFF_DOCUMENTS : references
STAFFS ||--o{ CERTIFICATES : has
TENANTS ||--o{ COMPLIANCE_REQUIREMENTS : defines
BUSINESSES ||--o{ COMPLIANCE_REQUIREMENTS : overrides
ROLES ||--o{ COMPLIANCE_REQUIREMENTS : role_scope
STAFFS ||--o{ VERIFICATION_JOBS : subject
VERIFICATION_JOBS ||--o{ VERIFICATION_REVIEWS : reviewed
VERIFICATION_JOBS ||--o{ VERIFICATION_EVENTS : logs
USERS ||--o{ VERIFICATION_REVIEWS : reviewer
```
```
## 7) Finance and settlement
### 7.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `invoices` | `id` | `tenant_id -> tenants.id`, `order_id -> orders.id`, `business_id -> businesses.id`, `vendor_id -> vendors.id` | `(tenant_id, invoice_number)` |
| `invoice_line_items` | `id` | `invoice_id -> invoices.id`, `assignment_id -> assignments.id` nullable | `(invoice_id, line_number)` |
| `invoice_status_history` | `id` | `invoice_id -> invoices.id`, `actor_user_id -> users.id` | - |
| `payment_runs` | `id` | `tenant_id -> tenants.id` | `(tenant_id, run_reference)` |
| `payment_allocations` | `id` | `payment_run_id -> payment_runs.id`, `invoice_id -> invoices.id` | `(payment_run_id, invoice_id)` |
| `remittance_documents` | `id` | `payment_run_id -> payment_runs.id` | `(payment_run_id, document_url)` |
| `account_token_refs` | `id` | `tenant_id -> tenants.id`, `owner_business_id -> businesses.id` nullable, `owner_vendor_id -> vendors.id` nullable | one primary per owner |
### 7.2 Diagram
```mermaid
erDiagram
ORDERS ||--o{ INVOICES : billed
BUSINESSES ||--o{ INVOICES : billed_to
VENDORS ||--o{ INVOICES : billed_from
INVOICES ||--o{ INVOICE_LINE_ITEMS : contains
INVOICES ||--o{ INVOICE_STATUS_HISTORY : transitions
USERS ||--o{ INVOICE_STATUS_HISTORY : changed_by
PAYMENT_RUNS ||--o{ PAYMENT_ALLOCATIONS : allocates
INVOICES ||--o{ PAYMENT_ALLOCATIONS : receives
PAYMENT_RUNS ||--o{ REMITTANCE_DOCUMENTS : publishes
TENANTS ||--o{ ACCOUNT_TOKEN_REFS : scopes
BUSINESSES ||--o{ ACCOUNT_TOKEN_REFS : business_owner
VENDORS ||--o{ ACCOUNT_TOKEN_REFS : vendor_owner
```
```
## 8) Audit and reliability
### 8.1 Model keys
| Model | Primary key | Foreign keys | Important unique keys |
|---|---|---|---|
| `domain_events` | `id` | `tenant_id -> tenants.id`, `actor_user_id -> users.id` | `(tenant_id, aggregate_type, aggregate_id, sequence)` |
| `idempotency_keys` | `id` | `tenant_id -> tenants.id`, `actor_user_id -> users.id` | `(tenant_id, actor_user_id, route, key)` |
| `activity_logs` | `id` | `tenant_id -> tenants.id`, `user_id -> users.id` | `(tenant_id, created_at, id)` |
### 8.2 Diagram
```mermaid
erDiagram
TENANTS ||--o{ DOMAIN_EVENTS : scopes
USERS ||--o{ DOMAIN_EVENTS : actor
TENANTS ||--o{ IDEMPOTENCY_KEYS : scopes
USERS ||--o{ IDEMPOTENCY_KEYS : actor
TENANTS ||--o{ ACTIVITY_LOGS : scopes
USERS ||--o{ ACTIVITY_LOGS : actor
```
```
## 9) Practical note for current system
Current schema already has:
1. `businesses.userId` (single business owner user).
2. `vendors.userId` (single vendor owner user).
3. `team_members` (multi-user workaround).
Target schema improves this by adding explicit:
1. `business_memberships`
2. `vendor_memberships`
This is the key upgrade for clean client/vendor user partitioning.

View File

@@ -0,0 +1,10 @@
# Moved
The canonical frontend-facing v2 backend docs now live here:
- `docs/BACKEND/API_GUIDES/V2/README.md`
- `docs/BACKEND/API_GUIDES/V2/core-api.md`
- `docs/BACKEND/API_GUIDES/V2/command-api.md`
- `docs/BACKEND/API_GUIDES/V2/query-api.md`
This file is kept only as a compatibility pointer.

View File

@@ -0,0 +1,233 @@
# M4 Verification Architecture Contract (Attire, Government ID, Certification)
Status: Partially implemented in dev (core endpoints + async in-memory processor)
Date: 2026-02-24
Owner: Technical Lead
## Implementation status today (dev)
1. Implemented routes:
- `POST /core/verifications`
- `GET /core/verifications/{verificationId}`
- `POST /core/verifications/{verificationId}/review`
- `POST /core/verifications/{verificationId}/retry`
2. Current processor is in-memory and non-persistent (for fast frontend integration in dev).
3. Next hardening step is persistent job storage and worker execution before staging.
4. Attire uses a live Vertex vision model path with `gemini-2.0-flash-lite-001` by default.
5. Government ID and certification use third-party adapter contracts (provider URL/token envs) and fall back to `NEEDS_REVIEW` when providers are not configured.
## 1) Goal
Define a single backend verification pipeline for:
1. `attire`
2. `government_id`
3. `certification`
This contract gives the team exact endpoint behavior, state flow, and ownership before coding.
## 2) Principles
1. Upload is evidence intake, not final verification.
2. Verification runs asynchronously in backend workers.
3. Model output is a signal, not legal truth.
4. High-risk identity decisions require stronger validation and human audit trail.
5. Every decision is traceable (`who`, `what`, `when`, `why`).
## 3) Verification types and policy
## 3.1 Attire
1. Primary check: vision model + rule checks.
2. Typical output: `AUTO_PASS`, `AUTO_FAIL`, or `NEEDS_REVIEW`.
3. Manual override is always allowed.
## 3.2 Government ID
1. Required path for mission-critical use: third-party identity verification provider.
2. Model/OCR can pre-parse fields but does not replace identity verification.
3. Final status should require either provider success or manual approval by authorized reviewer.
## 3.3 Certification
1. Preferred path: verify against issuer API/registry when available.
2. If no issuer API: OCR extraction + manual review.
3. Keep evidence of the source used for validation.
## 4) State model
1. `PENDING`
2. `PROCESSING`
3. `AUTO_PASS`
4. `AUTO_FAIL`
5. `NEEDS_REVIEW`
6. `APPROVED`
7. `REJECTED`
8. `ERROR`
Rules:
1. `AUTO_*` and `NEEDS_REVIEW` are machine outcomes.
2. `APPROVED` and `REJECTED` are human outcomes.
3. All transitions are append-only in audit events.
## 5) API contract
## 5.1 Create verification job
1. Route: `POST /core/verifications`
2. Auth: required
3. Purpose: enqueue verification job for previously uploaded file.
4. Request:
```json
{
"type": "attire",
"subjectType": "staff",
"subjectId": "staff_123",
"fileUri": "gs://krow-workforce-dev-private/uploads/<uid>/item.jpg",
"rules": {
"attireType": "shoes",
"expectedColor": "black"
},
"metadata": {
"shiftId": "shift_123"
}
}
```
5. Success `202`:
```json
{
"verificationId": "ver_123",
"status": "PENDING",
"type": "attire",
"requestId": "uuid"
}
```
## 5.2 Get verification status
1. Route: `GET /core/verifications/{verificationId}`
2. Auth: required
3. Purpose: polling from frontend.
4. Success `200`:
```json
{
"verificationId": "ver_123",
"type": "attire",
"status": "NEEDS_REVIEW",
"confidence": 0.62,
"reasons": ["Color uncertain"],
"extracted": {
"detectedType": "shoe",
"detectedColor": "dark"
},
"provider": {
"name": "vertex-attire",
"reference": "gemini-2.0-flash-lite-001"
},
"review": null,
"createdAt": "2026-02-24T15:00:00Z",
"updatedAt": "2026-02-24T15:00:04Z",
"requestId": "uuid"
}
```
## 5.3 Review override
1. Route: `POST /core/verifications/{verificationId}/review`
2. Auth: required (reviewer role later; auth-first now + explicit reviewer id logging)
3. Purpose: final human decision and audit reason.
4. Request:
```json
{
"decision": "APPROVED",
"note": "Document matches required certification",
"reasonCode": "MANUAL_REVIEW"
}
```
5. Success `200`:
```json
{
"verificationId": "ver_123",
"status": "APPROVED",
"review": {
"decision": "APPROVED",
"reviewedBy": "user_456",
"reviewedAt": "2026-02-24T15:02:00Z",
"note": "Document matches required certification",
"reasonCode": "MANUAL_REVIEW"
},
"requestId": "uuid"
}
```
## 5.4 Retry verification job
1. Route: `POST /core/verifications/{verificationId}/retry`
2. Auth: required
3. Purpose: rerun failed or updated checks.
4. Success `202`: status resets to `PENDING`.
## 6) Worker execution flow
1. API validates payload and ownership of `fileUri`.
2. API writes `verification_jobs` row with `PENDING`.
3. Worker consumes job, marks `PROCESSING`.
4. Worker selects processor by type:
- `attire` -> model + rule scorer
- `government_id` -> provider adapter (+ optional OCR pre-check)
- `certification` -> issuer API adapter or OCR adapter
5. Worker writes machine outcome (`AUTO_PASS`, `AUTO_FAIL`, `NEEDS_REVIEW`, or `ERROR`).
6. Frontend polls status route.
7. Reviewer finalizes with `APPROVED` or `REJECTED` where needed.
## 7) Data model (minimal)
## 7.1 Table: `verification_jobs`
1. `id` (pk)
2. `type` (`attire|government_id|certification`)
3. `subject_type`, `subject_id`
4. `owner_uid`
5. `file_uri`
6. `status`
7. `confidence` (nullable)
8. `reasons_json`
9. `extracted_json`
10. `provider_name`, `provider_ref`
11. `created_at`, `updated_at`
## 7.2 Table: `verification_reviews`
1. `id` (pk)
2. `verification_id` (fk)
3. `decision` (`APPROVED|REJECTED`)
4. `reviewed_by`
5. `note`
6. `reason_code`
7. `reviewed_at`
## 7.3 Table: `verification_events`
1. `id` (pk)
2. `verification_id` (fk)
3. `from_status`, `to_status`
4. `actor_type` (`system|reviewer`)
5. `actor_id`
6. `details_json`
7. `created_at`
## 8) Security and compliance notes
1. Restrict verification file paths to owner-owned upload prefixes.
2. Never expose raw private bucket URLs directly.
3. Keep third-party provider secrets in Secret Manager.
4. Log request and decision IDs for every transition.
5. For government ID, keep provider response reference and verification timestamp.
## 9) Provider configuration (environment variables)
1. Attire model:
- `VERIFICATION_ATTIRE_PROVIDER=vertex`
- `VERIFICATION_ATTIRE_MODEL=gemini-2.0-flash-lite-001`
2. Government ID provider:
- `VERIFICATION_GOV_ID_PROVIDER_URL`
- `VERIFICATION_GOV_ID_PROVIDER_TOKEN` (Secret Manager recommended)
3. Certification provider:
- `VERIFICATION_CERT_PROVIDER_URL`
- `VERIFICATION_CERT_PROVIDER_TOKEN` (Secret Manager recommended)
4. Provider timeout:
- `VERIFICATION_PROVIDER_TIMEOUT_MS` (default `8000`)
## 10) Frontend integration pattern
1. Upload file via existing `POST /core/upload-file`.
2. Create verification job with returned `fileUri`.
3. Poll `GET /core/verifications/{id}` until terminal state.
4. Show machine status and confidence.
5. For `NEEDS_REVIEW`, show pending-review UI state.
## 11) Delivery split (recommended)
1. Wave A (fast): attire verification pipeline end-to-end.
2. Wave B: certification verification with issuer adapter + review.
3. Wave C: government ID provider integration + reviewer flow hardening.

View File

@@ -0,0 +1,95 @@
# Clarifications Required Project Discovery
During Milestone 4 (M5) planning, we identified several items that require clarification before development can proceed.
Please review the questions below and share any relevant documents, examples, or preferences.
---
## Issue: Research: Validate worker SSN number in the US
### Description
We need to identify a viable approach/service to validate a workers SSN for the US market, compare 23 options, and recommend one with cost and risk considerations.
### Existing Tools / Platforms
- Are you currently using any service or process to validate SSNs (in the legacy app or elsewhere)? If yes, which tool(s) and whats working/not working today?
---
## Issue: Research: Validate worker bank account details in the US
### Description
We need to identify a reliable, server-side way to validate worker bank account details for the US market (beyond basic UI checks), compare 23 options, and recommend one.
### Existing Tools / Platforms
- Do you currently use any tool/process for bank account validation or payouts? If yes, which platform(s) ?
---
## Issue: Research: Select payment platform for worker payouts
### Description
We need to select a payout/payment platform to pay workers, comparing options by cost, reliability, and integration effort, and then recommend a platform?
### Existing Tools / Platforms
- Are you already using a payments/payout platform today (or do you have a preferred vendor relationship)?
---
## Issue: Business: Create template model for PDF reports
### Description
We need to align PDF report formats across the client mobile and web platforms by defining a shared template model thats ready to implement in both.
### Existing Tools / Platforms
- Do you already have existing PDF templates (or examples) you use today? If yes, can you share them and how theyre currently produced?
---
## Issue: Business: Finalize terms of service and privacy policy for mobile apps
### Description
We need approved Terms of Service and Privacy Policy documents for mobile apps.
### Clarifications Needed
1. Do you already have Terms of Service and a Privacy Policy draft we should implement?
---
## Issue: Business: Handle worker data requests
### Description
We need a documented workflow to handle worker requests for their personal data, covering intake, identity verification, fulfillment, and timelines.
### Clarifications Needed
1. How should requests be submitted (in-app, email, support form, other)?
2. What verification steps are required before fulfilling a request?
### Existing Tools / Platforms
- Do you currently use a support/ticketing system or internal workflow for these requests?
---
## Issue: Business: Finalize key terminology used in the app
### Description
We need consistent, accurate product language across the app.
### Clarifications Needed
1. The "staff app" shall we call it “Worker App” or “Worker Mobile App” (or another term)?
2. For worker registration, should we use “signup” or “onboarding” (or another term)?
---
## Issue: RESEARCH: How to calculate the reliability score of a worker
### Description
We need to define the formula and logic for a workers reliability score, including which signals feed the score, its scale, display expectations, and its relationship to star rating.
### Clarifications Needed
1. Is the reliability score given by clients, system-derived, or a combination?
---
## Additional Context
If there are documents, workflows, screenshots, examples, policy notes, or tools related to these topics, please share them. Even rough notes are helpful — they will help us confirm requirements, choose the right integrations, and design the best user experience before implementation begins.

View File

@@ -0,0 +1,136 @@
# Agent Development Rules
These rules are **NON-NEGOTIABLE**. They are designed to prevent architectural degradation by automated agents.
## 1. File Creation & Structure
1. **Feature-First Packaging**:
* **DO**: Create new features as independent packages in `apps/mobile/packages/features/<app_name>/<feature_name>`.
* **DO NOT**: Add features to `apps/mobile/packages/core` or existing apps directly.
* **DO NOT**: Create cross-feature or cross-app dependencies.
2. **Path Conventions**:
* Entities: `apps/mobile/packages/domain/lib/src/entities/<entity>.dart`
* Repositories (Interface): `apps/mobile/packages/features/<app_name>/<feature>/lib/src/domain/repositories/<name>_repository_interface.dart`
* Repositories (Impl): `apps/mobile/packages/features/<app_name>/<feature>/lib/src/data/repositories_impl/<name>_repository_impl.dart`
* Use Cases: `apps/mobile/packages/features/<app_name>/<feature>/lib/src/application/<name>_usecase.dart`
* BLoCs: `apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/blocs/<name>_bloc.dart`
* Pages: `apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/pages/<name>_page.dart`
* Widgets: `apps/mobile/packages/features/<app_name>/<feature>/lib/src/presentation/widgets/<name>_widget.dart`
3. **Barrel Files**:
* **DO**: Use `export` in `lib/<package_name>.dart` only for public APIs.
* **DO NOT**: Export internal implementation details in the main package file.
## 2. Naming Conventions
Follow Dart standards strictly.
| Type | Convention | Example |
| :--- | :--- | :--- |
| **Files** | `snake_case` | `user_profile_page.dart` |
| **Classes** | `PascalCase` | `UserProfilePage` |
| **Variables** | `camelCase` | `userProfile` |
| **Interfaces** | terminate with `Interface` | `AuthRepositoryInterface` |
| **Implementations** | terminate with `Impl` | `AuthRepositoryImpl` |
## 3. Logic Placement (Strict Boundaries)
* **Business Rules**: MUST reside in **Use Cases** (Domain/Feature Application layer).
* *Forbidden*: Placing business rules in BLoCs or Widgets.
* **State Logic**: MUST reside in **BLoCs** or **StatefulWidgets** (only for ephemeral UI state).
* *Forbidden*: `setState` in Pages for complex state management.
* **Recommendation**: Pages should be `StatelessWidget` with state delegated to BLoCs.
* **Data Transformation**: MUST reside in **Repositories** (Data Connect layer).
* *Forbidden*: Parsing JSON in the UI or Domain.
* **Pattern**: Repositories map Data Connect models to Domain entities.
* **Navigation Logic**: MUST reside in **Flutter Modular Routes** and use **Safe Navigation**.
* *Forbidden*: `Navigator.push` with hardcoded widgets or direct `Modular.to.pop()` / `Modular.to.navigate()`.
* **Pattern**: Use `popSafe()`, `safeNavigate()`, `safePush()`, etc., from `NavigationExtensions`. Prefer **Typed Navigators** (e.g., `Modular.to.toHome()`).
* **Fallback**: All navigation MUST have a fallback to the Home page implemented in `NavigationExtensions`.
* **Session Management**: MUST reside in **DataConnectService** via **SessionHandlerMixin**.
* **Pattern**: Automatic token refresh, auth state listening, and role-based validation.
* **UI Reaction**: **SessionListener** widget wraps the entire app and responds to session state changes.
## 4. Localization (core_localization) Integration
All user-facing text MUST be localized using the centralized `core_localization` package:
1. **String Management**:
* Define all user-facing strings in `apps/mobile/packages/core_localization/lib/src/l10n/`
* Use `slang` or similar i18n tooling for multi-language support
* Access strings in presentation layer via `context.strings.<key>`
2. **BLoC Integration**:
* `LocaleBloc` manages the current locale state
* Apps import `core_localization.LocalizationModule()` in their module imports
* Wrap app with `BlocProvider<LocaleBloc>()` to expose locale state globally
3. **Feature Usage**:
* Pages and widgets access localized strings: `Text(context.strings.buttonLabel)`
* Build methods receive `BuildContext` with access to current locale
* No hardcoded English strings in feature packages
4. **Error Messages**:
* Use `ErrorTranslator` from `core_localization` to map domain failures to user-friendly messages
* **Pattern**: Failures emitted from BLoCs are translated to localized strings in the UI
## 5. Data Connect Integration Strategy
All backend access is centralized through `DataConnectService` in `apps/mobile/packages/data_connect`:
1. **Repository Interface First**: Define `abstract interface class <Name>RepositoryInterface` in the feature's `domain/repositories/` folder.
2. **Repository Implementation**: Implement the interface in `data/repositories_impl/` using `_service.run()` wrapper.
* **Pattern**: `await _service.run(() => connector.<query>().execute())`
* **Benefit**: Automatic auth validation, token refresh, and error handling.
3. **Session Handling**: Use `DataConnectService.instance.initializeAuthListener(allowedRoles: [...])` in app main.dart.
* **Automatic**: Token refresh with 5-minute expiry threshold.
* **Retry Logic**: 3 attempts with exponential backoff (1s → 2s → 4s) before emitting error.
* **Role Validation**: Configurable per app (e.g., Staff: `['STAFF', 'BOTH']`, Client: `['CLIENT', 'BUSINESS', 'BOTH']`).
4. **Session State Management**: Wrap app with `SessionListener` widget to react to session changes.
* **Dialogs**: Shows session expired or error dialogs for user-facing feedback.
* **Navigation**: Routes to login on session loss, to home on authentication.
## 5. Prototype Migration Rules
You have access to `prototypes/` folders. When migrating code:
1. **Extract Assets**:
* You MAY copy icons, images, and colors. But they should be tailored to the current design system. Do not change the colours and typgorahys in the design system. They are final. And you have to use these in the UI.
* When you matching colous and typography, from the POC match it with the design system and use the colors and typography from the design system. As mentioned in the `apps/mobile/docs/02-design-system-usage.md`.
2. **Extract Layouts**: You MAY copy `build` methods for UI structure.
3. **REJECT Architecture**: You MUST **NOT** copy the `GetX`, `Provider`, or `MVC` patterns often found in prototypes. Refactor immediately to **Bloc + Clean Architecture with Flutter Modular and Melos**.
## 6. Handling Ambiguity
If a user request is vague:
1. **STOP**: Do not guess domain fields or workflows.
2. **ANALYZE**:
- For architecture related questions, refer to `apps/mobile/docs/01-architecture-principles.md` or existing code.
- For design system related questions, refer to `apps/mobile/docs/02-design-system-usage.md` or existing code.
3. **DOCUMENT**: If you must make an assumption to proceed, add a comment `// ASSUMPTION: <explanation>` and mention it in your final summary.
4. **ASK**: Prefer asking the user for clarification on business rules (e.g., "Should a 'Job' have a 'status'?").
## 7. Dependencies
* **DO NOT** add 3rd party packages without checking `apps/mobile/packages/core` first.
* **DO NOT** add `firebase_auth` or `firebase_data_connect` to any Feature package. They belong in `data_connect` only.
* **Service Locator**: Use `DataConnectService.instance` for singleton access to backend operations.
* **Dependency Injection**: Use Flutter Modular for BLoC (never use `addSingleton` for Blocs, always use `add` method) and UseCase injection in `Module.routes()`.
## 8. Error Handling
* **Domain Failures**: Define custom `Failure` classes in `domain/failures/`.
* **Data Connect Errors**: Map Data Connect exceptions to Domain failures in repositories.
* **User Feedback**: BLoCs emit error states; UI displays snackbars or dialogs.
* **Session Errors**: SessionListener automatically shows dialogs for session expiration/errors.
## 9. Testing
* **Unit Tests**: Test use cases and repositories with real implementations.
* **Widget Tests**: Use `WidgetTester` to test UI widgets and BLoCs.
* **Integration Tests**: Test full feature flows end-to-end with Data Connect.
* **Pattern**: Use dependency injection via Modular to swap implementations if needed for testing.
## 10. Follow Clean Code Principles
* Add doc comments to all classes and methods you create.
* Keep methods and classes focused and single-responsibility.
* Use meaningful variable names that reflect intent.
* Keep widget build methods concise; extract complex widgets to separate files.

View File

@@ -0,0 +1,380 @@
# KROW Architecture Principles
This document is the **AUTHORITATIVE** source of truth for the KROW engineering architecture.
All agents and engineers must adhere strictly to these principles. Deviations are interpreted as errors.
## 1. High-Level Architecture
The KROW platform follows a strict **Clean Architecture** implementation within a **Melos Monorepo**.
Dependencies flow **inwards** towards the Domain.
```mermaid
graph TD
subgraph "Apps (Entry Points)"
ClientApp["apps/mobile/apps/client"]
StaffApp["apps/mobile/apps/staff"]
end
subgraph "Features"
ClientFeatures["apps/mobile/packages/features/client/*"]
StaffFeatures["apps/mobile/packages/features/staff/*"]
end
subgraph "Services"
DataConnect["apps/mobile/packages/data_connect"]
DesignSystem["apps/mobile/packages/design_system"]
CoreLocalization["apps/mobile/packages/core_localization"]
end
subgraph "Core Domain"
Domain["apps/mobile/packages/domain"]
Core["apps/mobile/packages/core"]
end
%% Dependency Flow
ClientApp --> ClientFeatures & DataConnect & CoreLocalization
StaffApp --> StaffFeatures & DataConnect & CoreLocalization
ClientFeatures & StaffFeatures --> Domain
ClientFeatures & StaffFeatures --> DesignSystem
ClientFeatures & StaffFeatures --> CoreLocalization
ClientFeatures & StaffFeatures --> Core
DataConnect --> Domain
DataConnect --> Core
DesignSystem --> Core
CoreLocalization --> Core
Domain --> Core
%% Strict Barriers
linkStyle default stroke-width:2px,fill:none,stroke:gray
```
## 2. Repository Structure & Package Roles
### 2.1 Apps (`apps/mobile/apps/`)
- **Role**: Application entry points and Dependency Injection (DI) roots.
- **Responsibilities**:
- Initialize Flutter Modular.
- Assemble features into a navigation tree.
- Inject concrete implementations (from `data_connect`) into Feature packages.
- Configure environment-specific settings.
- **RESTRICTION**: NO business logic. NO UI widgets (except `App` and `Main`).
### 2.2 Features (`apps/mobile/packages/features/<APP_NAME>/<FEATURE_NAME>`)
- **Role**: Vertical slices of user-facing functionality.
- **Internal Structure**:
- `domain/`: Feature-specific Use Cases(always extend the apps/mobile/packages/core/lib/src/domain/usecases/usecase.dart abstract clas) and Repository Interfaces.
- `data/`: Repository Implementations.
- `presentation/`:
- Pages, BLoCs, Widgets.
- For performance make the pages as `StatelessWidget` and move the state management to the BLoC (always use a BlocProvider when providing the BLoC to the widget tree) or `StatefulWidget` to an external separate widget file.
- **Responsibilities**:
- **Presentation**: UI Pages, Modular Routes.
- **State Management**: BLoCs / Cubits.
- **Application Logic**: Use Cases.
- **RESTRICTION**: Features MUST NOT import other features. Communication happens via shared domain events.
### 2.3 Domain (`apps/mobile/packages/domain`)
- **Role**: The stable heart of the system. Pure Dart.
- **Responsibilities**:
- **Entities**: Immutable data models (Data Classes).
- **Failures**: Domain-specific error types.
- **RESTRICTION**: NO Flutter dependencies. NO `json_annotation`. NO package dependencies (except `equatable`).
### 2.4 Data Connect (`apps/mobile/packages/data_connect`)
- **Role**: Interface Adapter for Backend Access (Datasource Layer).
- **Responsibilities**:
- **Connectors**: Centralized repository implementations for each backend connector (see `03-data-connect-connectors-pattern.md`)
- One connector per backend connector domain (staff, order, user, etc.)
- Repository interfaces and use cases defined at domain level
- Repository implementations query backend and map responses
- Implement Firebase Data Connect connector and service layer
- Map Domain Entities to/from Data Connect generated code
- Handle Firebase exceptions and map to domain failures
- Provide centralized `DataConnectService` with session management
- **RESTRICTION**:
- NO feature-specific logic. Connectors are domain-neutral and reusable.
- All queries must follow Clean Architecture (domain → data layers)
- See `03-data-connect-connectors-pattern.md` for detailed pattern documentation
### 2.5 Design System (`apps/mobile/packages/design_system`)
- **Role**: Visual language and component library.
- **Responsibilities**:
- UI components if needed. But mostly try to modify the theme file (apps/mobile/packages/design_system/lib/src/ui_theme.dart) so we can directly use the theme in the app, to use the default material widgets.
- If not possible, and if that specific widget is used in multiple features, then try to create a shared widget in the `apps/mobile/packages/design_system/widgets`.
- Theme definitions (Colors, Typography).
- Assets (Icons, Images).
- More details on how to use this package is available in the `apps/mobile/docs/02-design-system-usage.md`.
- **RESTRICTION**:
- CANNOT change colours or typography.
- Dumb widgets only. NO business logic. NO state management (Bloc).
- More details on how to use this package is available in the `apps/mobile/docs/02-design-system-usage.md`.
### 2.6 Core Localization (`apps/mobile/packages/core_localization`)
- **Role**: Centralized language and localization management.
- **Responsibilities**:
- Define all user-facing strings in `l10n/` with i18n tooling support
- Provide `LocaleBloc` for reactive locale state management
- Export `TranslationProvider` for BuildContext-based string access
- Map domain failures to user-friendly localized error messages via `ErrorTranslator`
- **Feature Integration**:
- Features access strings via `context.strings.<key>` in presentation layer
- BLoCs don't depend on localization; they emit domain failures
- Error translation happens in UI layer (pages/widgets)
- **App Integration**:
- Apps import `LocalizationModule()` in their module imports
- Apps wrap the material app with `BlocProvider<LocaleBloc>()` and `TranslationProvider`
- Apps initialize `MaterialApp` with locale from `LocaleState`
### 2.7 Core (`apps/mobile/packages/core`)
- **Role**: Cross-cutting concerns.
- **Responsibilities**:
- Extension methods.
- Logger configuration.
- Base classes for Use Cases or Result types (functional error handling).
## 3. Dependency Direction & Boundaries
1. **Domain Independence**: `apps/mobile/packages/domain` knows NOTHING about the outer world. It defines *what* needs to be done, not *how*.
2. **UI Agnosticism**: `apps/mobile/packages/features` depends on `apps/mobile/packages/design_system` for looks and `apps/mobile/packages/domain` for logic. It does NOT know about Firebase.
3. **Data Isolation**: `apps/mobile/packages/data_connect` depends on `apps/mobile/packages/domain` to know what interfaces to implement. It does NOT know about the UI.
## 4. Data Connect Service & Session Management
All backend access is unified through `DataConnectService` with integrated session management:
### 4.1 Session Handler Mixin
- **Location**: `apps/mobile/packages/data_connect/lib/src/services/mixins/session_handler_mixin.dart`
- **Responsibilities**:
- Automatic token refresh (triggered when token <5 minutes to expiry)
- Firebase auth state listening
- Role-based access validation
- Session state stream emissions
- 3-attempt retry logic with exponential backoff on token validation failure
- **Key Method**: `initializeAuthListener(allowedRoles: [...])` - call once on app startup
### 4.2 Session Listener Widget
- **Location**: `apps/mobile/apps/<app>/lib/src/widgets/session_listener.dart`
- **Responsibilities**:
- Wraps entire app to listen to session state changes
- Shows user-friendly dialogs for session expiration/errors
- Handles navigation on auth state changes
- **Pattern**: `SessionListener(child: AppWidget())`
### 4.3 Repository Pattern with Data Connect
1. **Interface First**: Define `abstract interface class <Name>RepositoryInterface` in feature domain layer.
2. **Implementation**: Use `_service.run()` wrapper that automatically:
- Validates user is authenticated (if required)
- Ensures token is valid and refreshes if needed
- Executes the Data Connect query
- Handles exceptions and maps to domain failures
3. **Session Store Population**: On successful auth, session stores are populated:
- Staff: `StaffSessionStore.instance.setSession(StaffSession(...))`
- Client: `ClientSessionStore.instance.setSession(ClientSession(...))`
4. **Lazy Loading**: If session is null, fetch data via `getStaffById()` or `getBusinessById()` and update store.
## 5. Feature Isolation & Cross-Feature Communication
- **Zero Direct Imports**: `import 'package:feature_a/...'` is FORBIDDEN inside `package:feature_b`.
- Exception: Shared packages like `domain`, `core`, and `design_system` are always accessible.
- **Navigation**: Use **Typed Navigators** and **Safe Navigation** via Flutter Modular:
- **Safe Methods**: ALWAYS use `safeNavigate()`, `safePush()`, `popSafe()`, and `safePushNamedAndRemoveUntil()` from `NavigationExtensions`.
- **Fallback**: All safe methods automatically fall back to the Home page (Staff or Client) if the target route is invalid or the operation fails.
- **Typed Navigator Pattern**: Prefer using typed methods on `Modular.to` (e.g., `Modular.to.toShiftDetails(id)`) which are implemented in `ClientNavigator` and `StaffNavigator` using these safe extensions.
- **Configuration**: Routes defined in `module.dart` files; constants in `paths.dart`.
- **Data Sharing**: Features do not share state directly. Shared data accessed through:
- **Domain Repositories**: Centralized data sources (e.g., `AuthRepository`)
- **Session Stores**: `StaffSessionStore` and `ClientSessionStore` for app-wide user context
- **Event Streams**: If needed, via `DataConnectService` streams for reactive updates
## 6. App-Specific Session Management
Each app (`staff` and `client`) has different role requirements and session patterns:
### 6.1 Staff App Session
- **Location**: `apps/mobile/apps/staff/lib/main.dart`
- **Initialization**: `DataConnectService.instance.initializeAuthListener(allowedRoles: ['STAFF', 'BOTH'])`
- **Session Store**: `StaffSessionStore` with `StaffSession(user: User, staff: Staff?, ownerId: String?)`
- **Lazy Loading**: `getStaffName()` fetches via `getStaffById()` if session null
- **Navigation**: On auth → `Modular.to.toStaffHome()`, on unauth → `Modular.to.toInitialPage()`
### 6.2 Client App Session
- **Location**: `apps/mobile/apps/client/lib/main.dart`
- **Initialization**: `DataConnectService.instance.initializeAuthListener(allowedRoles: ['CLIENT', 'BUSINESS', 'BOTH'])`
- **Session Store**: `ClientSessionStore` with `ClientSession(user: User, business: ClientBusinessSession?)`
- **Lazy Loading**: `getUserSessionData()` fetches via `getBusinessById()` if session null
- **Navigation**: On auth → `Modular.to.toClientHome()`, on unauth → `Modular.to.toInitialPage()`
## 7. Data Connect Connectors Pattern
See **`03-data-connect-connectors-pattern.md`** for comprehensive documentation on:
- How connector repositories work
- How to add queries to existing connectors
- How to create new connectors
- Integration patterns with features
- Benefits and anti-patterns
**Quick Reference**:
- All backend queries centralized in `apps/mobile/packages/data_connect/lib/src/connectors/`
- One connector per backend connector domain (staff, order, user, etc.)
- Each connector follows Clean Architecture (domain interfaces + data implementations)
- Features use connector repositories through dependency injection
- Results in zero query duplication and single source of truth
## 8. Prop Drilling Prevention & Direct BLoC Access
### 8.1 The Problem: Prop Drilling
Passing data through intermediate widgets creates maintenance headaches:
- Every intermediate widget must accept and forward props
- Changes to data structure ripple through multiple widget constructors
- Reduces code clarity and increases cognitive load
**Anti-Pattern Example**:
```dart
// ❌ BAD: Drilling status through 3 levels
ProfilePage(status: status)
ProfileHeader(status: status)
ProfileLevelBadge(status: status) // Only widget that needs it!
```
### 8.2 The Solution: Direct BLoC Access with BlocBuilder
Use `BlocBuilder` to access BLoC state directly in leaf widgets:
**Correct Pattern**:
```dart
// ✅ GOOD: ProfileLevelBadge accesses ProfileCubit directly
class ProfileLevelBadge extends StatelessWidget {
const ProfileLevelBadge({super.key});
@override
Widget build(BuildContext context) {
return BlocBuilder<ProfileCubit, ProfileState>(
builder: (context, state) {
final Staff? profile = state.profile;
if (profile == null) return const SizedBox.shrink();
final level = _mapStatusToLevel(profile.status);
return LevelBadgeUI(level: level);
},
);
}
}
```
### 8.3 Guidelines for Avoiding Prop Drilling
1. **Leaf Widgets Get Data from BLoC**: Widgets that need specific data should access it directly via BlocBuilder
2. **Container Widgets Stay Simple**: Parent widgets like `ProfileHeader` only manage layout and positioning
3. **No Unnecessary Props**: Don't pass data to intermediate widgets unless they need it for UI construction
4. **Single Responsibility**: Each widget should have one reason to exist
**Decision Tree**:
```
Does this widget need data?
├─ YES, and it's a leaf widget → Use BlocBuilder
├─ YES, and it's a container → Use BlocBuilder in child, not parent
└─ NO → Don't add prop to constructor
```
## 9. BLoC Lifecycle & State Emission Safety
### 9.1 The Problem: StateError After Dispose
When async operations complete after a BLoC is closed, attempting to emit state causes:
```
StateError: Cannot emit new states after calling close
```
**Root Causes**:
1. **Transient BLoCs**: `BlocProvider(create:)` creates new instance on every rebuild → disposed prematurely
2. **Singleton Disposal**: Multiple BlocProviders disposing same singleton instance
3. **Navigation During Async**: User navigates away while `loadProfile()` is still running
### 9.2 The Solution: Singleton BLoCs + Error Handler Defensive Wrapping
#### Step 1: Register as Singleton
```dart
// ✅ GOOD: ProfileCubit as singleton
i.addSingleton<ProfileCubit>(
() => ProfileCubit(useCase1, useCase2),
);
// ❌ BAD: Creates new instance each time
i.add(ProfileCubit.new);
```
#### Step 2: Use BlocProvider.value() for Singletons
```dart
// ✅ GOOD: Use singleton instance
ProfileCubit cubit = Modular.get<ProfileCubit>();
BlocProvider<ProfileCubit>.value(
value: cubit, // Reuse same instance
child: MyWidget(),
)
// ❌ BAD: Creates duplicate instance
BlocProvider<ProfileCubit>(
create: (_) => Modular.get<ProfileCubit>(), // Wrong!
child: MyWidget(),
)
```
#### Step 3: Defensive Error Handling in BlocErrorHandler Mixin
The `BlocErrorHandler<S>` mixin provides `_safeEmit()` wrapper:
**Location**: `apps/mobile/packages/core/lib/src/presentation/mixins/bloc_error_handler.dart`
```dart
void _safeEmit(void Function(S) emit, S state) {
try {
emit(state);
} on StateError catch (e) {
// Bloc was closed before emit - log and continue gracefully
developer.log(
'Could not emit state: ${e.message}. Bloc may have been disposed.',
name: runtimeType.toString(),
);
}
}
```
**Usage in Cubits/Blocs**:
```dart
Future<void> loadProfile() async {
emit(state.copyWith(status: ProfileStatus.loading));
await handleError(
emit: emit,
action: () async {
final profile = await getProfile();
emit(state.copyWith(status: ProfileStatus.loaded, profile: profile));
// ✅ If BLoC disposed before emit, _safeEmit catches StateError gracefully
},
onError: (errorKey) {
return state.copyWith(status: ProfileStatus.error);
},
);
}
```
### 9.3 Pattern Summary
| Pattern | When to Use | Risk |
|---------|------------|------|
| Singleton + BlocProvider.value() | Long-lived features (Profile, Shifts, etc.) | Low - instance persists |
| Transient + BlocProvider(create:) | Temporary widgets (Dialogs, Overlays) | Medium - requires careful disposal |
| Direct BlocBuilder | Leaf widgets needing data | Low - no registration needed |
**Remember**:
- Use **singletons** for feature-level cubits accessed from multiple pages
- Use **transient** only for temporary UI states
- Always wrap emit() in `_safeEmit()` via `BlocErrorHandler` mixin
- Test navigation away during async operations to verify graceful handling
```

View File

@@ -0,0 +1,157 @@
# 02 - Design System Usage Guide
This document defines the mandatory standards for designing and implementing user interfaces across all applications and feature packages using the shared `apps/mobile/packages/design_system`.
## 1. Introduction & Purpose
The Design System is the single source of truth for the visual identity of the project. Its purpose is to ensure UI consistency, reduce development velocity by providing reusable primitives, and eliminate "design drift" across multiple feature teams and applications.
**All UI implementation MUST consume values ONLY from the `design_system` package.**
### Core Principle
Design tokens (colors, typography, spacing, etc.) are immutable and defined centrally. Features consume these tokens but NEVER modify them. The design system maintains visual coherence across staff and client apps.
## 2. Design System Ownership & Responsibility
- **Centralized Authority**: The `apps/mobile/packages/design_system` is the owner of all brand assets, colors, typography, and core components.
- **No Local Overrides**: Feature packages (e.g., `staff_authentication`) are consumers. They are prohibited from defining their own global styles or overriding theme values locally.
- **Extension Policy**: If a required style (color, font, or icon) is missing, the developer must first add it to the `design_system` package following existing patterns before using it in a feature.
## 3. Package Structure Overview (`apps/mobile/packages/design_system`)
The package is organized to separate tokens from implementation:
- `lib/src/ui_colors.dart`: Color tokens and semantic mappings.
- `lib/src/ui_typography.dart`: Text styles and font configurations.
- `lib/src/ui_icons.dart`: Exported icon sets.
- `lib/src/ui_constants.dart`: Spacing, radius, and elevation tokens.
- `lib/src/ui_theme.dart`: Centralized `ThemeData` factory.
- `lib/src/widgets/`: Common "Smart Widgets" and reusable UI building blocks.
## 4. Colors Usage Rules
Feature packages **MUST NOT** define custom hex codes or `Color` constants.
### Usage Protocol
- **Primary Method**:Use `UiColors` from the design system for specific brand accents.
- **Naming Matching**: If an exact color is missing, use the closest existing semantic color (e.g., use `UiColors.mutedForeground` instead of a hardcoded grey).
```dart
// ❌ ANTI-PATTERN: Hardcoded color
Container(color: Color(0xFF1A2234))
// ✅ CORRECT: Design system token
Container(color: UiColors.background)
```
## 5. Typography Usage Rules
Custom `TextStyle` definitions in feature packages are **STRICTLY PROHIBITED**.
### Usage Protocol
- Use `UiTypography` from the design system for specific brand accents.
```dart
// ❌ ANTI-PATTERN: Custom TextStyle
Text('Hello', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold))
// ✅ CORRECT: Design system typography
Text('Hello', style: UiTypography.display1m)
```
## 6. Icons Usage Rules
Feature packages **MUST NOT** import icon libraries (like `lucide_icons`) directly. They should use the icons exposed via `UiIcons`.
- **Standardization**: Ensure the same icon is used for the same action across all features (e.g., always use `UiIcons.chevronLeft` for navigation).
- **Additions**: New icons must be added to the design system (only using the typedef _IconLib = LucideIcons or typedef _IconLib2 = FontAwesomeIcons; and nothing else) first to ensure they follow the project's stroke weight and sizing standards.
## 7. UI Constants & Layout Rules
Hardcoded padding, margins, and radius values are **PROHIBITED**.
- **Spacing**: Use `UiConstants.spacing` multiplied by tokens (e.g., `S`, `M`, `L`).
- **Border Radius**: Use `UiConstants.borderRadius`.
- **Elevation**: Use `UiConstants.elevation`.
```dart
// ✅ CORRECT: Spacing and Radius constants
Padding(
padding: EdgeInsets.all(UiConstants.spacingL),
child: Container(
borderRadius: BorderRadius.circular(UiConstants.radiusM),
),
)
```
## 8. Common Smart Widgets Guidelines
The design system provides "Smart Widgets" these are high-level UI components that encapsulate both styling and standard behavior.
- **Standard Widgets**: Prefer standard Flutter Material widgets (e.g., `ElevatedButton`) but styled via the central theme.
- **Custom Components**: Use `design_system` widgets for non-standard elements or widgets that have similar design across various features, if provided.
- **Navigation in Widgets**: Widgets that trigger navigation (e.g., Back buttons in `UiAppBar`) MUST use `Modular.to.popSafe()` or typed navigator methods to prevent blank screens or unexpected application states during stack pops.
- **Composition**: Prefer composing standard widgets over creating deep inheritance hierarchies in features.
## 9. Theme Configuration & Usage
Applications (`apps/mobile/apps/`) must initialize the theme once in the root `MaterialApp`.
```dart
MaterialApp.router(
theme: StaffTheme.light, // Mandatory: Consumption of centralized theme
// ...
)
```
**No application-level theme customization is allowed.**
## 10. Feature Development Workflow (POC → Themed)
To bridge the gap between rapid prototyping (POCs) and production-grade code, developers must follow this three-step workflow:
1. **Step 1: Structural Implementation**: Implement the UI logic and layout **exactly matching the POC**. Hardcoded values from the POC are acceptable in this transient state to ensure visual parity.
2. **Step 2: Architecture Refactor**: Immediately refactor the code to:
- Follow clean architecture principles from `apps/mobile/docs/00-agent-development-rules.md` and `01-architecture-principles.md`
- Move business logic from widgets to BLoCs and use cases
- Implement proper repository pattern with Data Connect
- Use dependency injection via Flutter Modular
3. **Step 3: Design System Integration**: Immediately refactor UI to consume design system primitives:
- Replace hex codes with `UiColors`
- Replace manual `TextStyle` with `UiTypography`
- Replace hardcoded padding/radius with `UiConstants`
- Upgrade icons to design system versions
- Use `ThemeData` from `design_system` instead of local theme overrides
## 11. Anti-Patterns & Common Mistakes
- **"Magic Numbers"**: Hardcoding `EdgeInsets.all(12.0)` instead of using design system constants.
- **Local Themes**: Using `Theme(data: ...)` to override colors for a specific section of a page.
- **Hex Hunting**: Copy-pasting hex codes from Figma or POCs into feature code.
- **Package Bypassing**: Importing `package:flutter/material.dart` and ignoring `package:design_system`.
- **Stateful Pages**: Pages with complex state logic instead of delegating to BLoCs.
- **Direct Data Queries**: Features querying Data Connect directly instead of through repositories.
- **Global State**: Using global variables for session/auth instead of `SessionStore` + `SessionListener`.
- **Hardcoded Routes**: Using `Navigator.push(context, MaterialPageRoute(...))` instead of Modular.
- **Feature Coupling**: Importing one feature package from another instead of using domain-level interfaces.
## 12. Enforcement & Review Checklist
Before any UI code is merged, it must pass this checklist:
### Design System Compliance
1. [ ] No hardcoded `Color(...)` or `0xFF...` in the feature package.
2. [ ] No custom `TextStyle(...)` definitions.
3. [ ] All spacing/padding/radius uses `UiConstants`.
4. [ ] All icons are consumed from the approved design system source.
5. [ ] The feature relies on the global `ThemeData` and does not provide local overrides.
6. [ ] The layout matches the POC visual intent while using design system primitives.
### Architecture Compliance
7. [ ] No direct Data Connect queries in widgets; all data access via repositories.
8. [ ] BLoCs handle all non-trivial state logic; pages are mostly stateless.
9. [ ] Session/auth accessed via `SessionStore` not global state.
10. [ ] Navigation uses Flutter Modular named routes.
11. [ ] Features don't import other feature packages directly.
12. [ ] All business logic in use cases, not BLoCs or widgets.
13. [ ] Repositories properly implement error handling and mapping.
14. [ ] Doc comments present on all public classes and methods.

View File

@@ -0,0 +1,289 @@
# Data Connect Connectors Pattern
> [!WARNING]
> This document describes the legacy V1 Data Connect connector pattern.
> For current backend work, use the V2 unified API docs under `docs/BACKEND/API_GUIDES/V2/`.
## Overview
This document describes the **Data Connect Connectors** pattern implemented in the KROW mobile app. This pattern centralizes all backend query logic by mirroring backend connector structure in the mobile data layer.
## Problem Statement
**Without Connectors Pattern:**
- Each feature creates its own repository implementation
- Multiple features query the same backend connector → duplication
- When backend queries change, updates needed in multiple places
- No reusability across features
**Example Problem:**
```
staff_main/
└── data/repositories/profile_completion_repository_impl.dart ← queries staff connector
profile/
└── data/repositories/profile_repository_impl.dart ← also queries staff connector
onboarding/
└── data/repositories/personal_info_repository_impl.dart ← also queries staff connector
```
## Solution: Connectors in Data Connect Package
All backend connector queries are implemented once in a centralized location, following the backend structure.
### Structure
```
apps/mobile/packages/data_connect/lib/src/connectors/
├── staff/
│ ├── domain/
│ │ ├── repositories/
│ │ │ └── staff_connector_repository.dart (interface)
│ │ └── usecases/
│ │ └── get_profile_completion_usecase.dart
│ └── data/
│ └── repositories/
│ └── staff_connector_repository_impl.dart (implementation)
├── order/
├── user/
├── emergency_contact/
└── ...
```
**Maps to legacy backend structure:**
```
legacy/dataconnect-v1/connector/
├── staff/
├── order/
├── user/
├── emergency_contact/
└── ...
```
## Clean Architecture Layers
Each connector follows Clean Architecture with three layers:
### Domain Layer (`connectors/{name}/domain/`)
**Repository Interface:**
```dart
// staff_connector_repository.dart
abstract interface class StaffConnectorRepository {
Future<bool> getProfileCompletion();
Future<Staff> getStaffById(String id);
// ... more queries
}
```
**Use Cases:**
```dart
// get_profile_completion_usecase.dart
class GetProfileCompletionUseCase {
GetProfileCompletionUseCase({required StaffConnectorRepository repository});
Future<bool> call() => _repository.getProfileCompletion();
}
```
**Characteristics:**
- Pure Dart, no framework dependencies
- Stable, business-focused contracts
- One interface per connector
- One use case per query or related query group
### Data Layer (`connectors/{name}/data/`)
**Repository Implementation:**
```dart
// staff_connector_repository_impl.dart
class StaffConnectorRepositoryImpl implements StaffConnectorRepository {
final DataConnectService _service;
@override
Future<bool> getProfileCompletion() async {
return _service.run(() async {
final staffId = await _service.getStaffId();
final response = await _service.connector
.getStaffProfileCompletion(id: staffId)
.execute();
return _isProfileComplete(response);
});
}
}
```
**Characteristics:**
- Implements domain repository interface
- Uses `DataConnectService` to execute queries
- Maps backend response types to domain models
- Contains mapping/transformation logic only
- Handles type safety with generated Data Connect types
## Integration Pattern
### Step 1: Feature Needs Data
Feature (e.g., `staff_main`) needs profile completion status.
### Step 2: Use Connector Repository
Instead of creating a local repository, feature uses the connector:
```dart
// staff_main_module.dart
class StaffMainModule extends Module {
@override
void binds(Injector i) {
// Register connector repository from data_connect
i.addSingleton<StaffConnectorRepository>(
StaffConnectorRepositoryImpl.new,
);
// Feature creates its own use case wrapper if needed
i.addSingleton(
() => GetProfileCompletionUseCase(
repository: i.get<StaffConnectorRepository>(),
),
);
// BLoC uses the use case
i.addSingleton(
() => StaffMainCubit(
getProfileCompletionUsecase: i.get<GetProfileCompletionUseCase>(),
),
);
}
}
```
### Step 3: BLoC Uses It
```dart
class StaffMainCubit extends Cubit<StaffMainState> {
StaffMainCubit({required GetProfileCompletionUseCase usecase}) {
_loadProfileCompletion();
}
Future<void> _loadProfileCompletion() async {
final isComplete = await _getProfileCompletionUsecase();
emit(state.copyWith(isProfileComplete: isComplete));
}
}
```
## Export Pattern
Connectors are exported from `krow_data_connect` for easy access:
```dart
// lib/krow_data_connect.dart
export 'src/connectors/staff/domain/repositories/staff_connector_repository.dart';
export 'src/connectors/staff/domain/usecases/get_profile_completion_usecase.dart';
export 'src/connectors/staff/data/repositories/staff_connector_repository_impl.dart';
```
**Features import:**
```dart
import 'package:krow_data_connect/krow_data_connect.dart';
```
## Adding New Queries to Existing Connector
When backend adds `getStaffById()` query to staff connector:
1. **Add to interface:**
```dart
abstract interface class StaffConnectorRepository {
Future<Staff> getStaffById(String id);
}
```
2. **Implement in repository:**
```dart
@override
Future<Staff> getStaffById(String id) async {
return _service.run(() async {
final response = await _service.connector
.getStaffById(id: id)
.execute();
return _mapToStaff(response.data.staff);
});
}
```
3. **Use in features:**
```dart
// Any feature can now use it
final staff = await i.get<StaffConnectorRepository>().getStaffById(id);
```
## Adding New Connector
When backend adds new connector (e.g., `order`):
1. Create directory: `apps/mobile/packages/data_connect/lib/src/connectors/order/`
2. Create domain layer with repository interface and use cases
3. Create data layer with repository implementation
4. Export from `krow_data_connect.dart`
5. Features can immediately start using it
## Benefits
✅ **No Duplication** - Query implemented once, used by many features
✅ **Single Source of Truth** - Backend change → update one place
✅ **Clean Separation** - Connector logic separate from feature logic
✅ **Reusability** - Any feature can request any connector data
✅ **Testability** - Mock the connector repo to test features
✅ **Scalability** - Easy to add new connectors as backend grows
✅ **Mirrors Backend** - Mobile structure mirrors backend structure
## Anti-Patterns
❌ **DON'T**: Implement query logic in feature repository
❌ **DON'T**: Duplicate queries across multiple repositories
❌ **DON'T**: Put mapping logic in features
❌ **DON'T**: Call `DataConnectService` directly from BLoCs
**DO**: Use connector repositories through use cases in features.
## Current Implementation
### Staff Connector
**Location**: `apps/mobile/packages/data_connect/lib/src/connectors/staff/`
**Available Queries**:
- `getProfileCompletion()` - Returns bool indicating if profile is complete
- Checks: personal info, emergency contacts, tax forms, experience (skills/industries)
**Used By**:
- `staff_main` - Guards bottom nav items requiring profile completion
**Backend Queries Used**:
- `legacy/dataconnect-v1/connector/staff/queries/profile_completion.gql`
### Shifts Connector
**Location**: `apps/mobile/packages/data_connect/lib/src/connectors/shifts/`
**Available Queries**:
- `listShiftRolesByVendorId()` - Fetches shifts for a specific vendor with status mapping
- `applyForShifts()` - Handles shift application with error tracking
**Backend Queries Used**:
- `legacy/dataconnect-v1/connector/shifts/queries/list_shift_roles_by_vendor.gql`
- `legacy/dataconnect-v1/connector/shifts/mutations/apply_for_shifts.gql`
## Future Expansion
As the app grows, additional connectors will be added:
- `order_connector_repository` (queries from `legacy/dataconnect-v1/connector/order/`)
- `user_connector_repository` (queries from `legacy/dataconnect-v1/connector/user/`)
- `emergency_contact_connector_repository` (queries from `legacy/dataconnect-v1/connector/emergencyContact/`)
- etc.
Each following the same Clean Architecture pattern implemented for Staff Connector.

View File

@@ -0,0 +1,323 @@
# 📊 Use Case Completion Audit
**Generated:** 2026-03-06
**Auditor Role:** System Analyst / Flutter Architect
**Source of Truth:** `docs/ARCHITECTURE/client-mobile-application/use-case.md`, `docs/ARCHITECTURE/staff-mobile-application/use-case.md`
**Codebase Checked:** `apps/mobile/packages/features/` and `apps/mobile/apps/` (actual production apps)
**Latest Milestone:** M4 (released 2026-03-05)
---
## 📌 How to Read This Document
| Symbol | Meaning |
|:---:|:--- |
| ✅ | Fully implemented with all 4 architecture layers |
| 🟡 | Partially implemented — Some layers missing or functionality incomplete |
| ❌ | Defined in use case docs but entirely missing in production app |
| 🚫 | Exists in production app but **not** documented in use cases (extra feature) |
---
## 🧑‍💼 CLIENT APP
### Feature Module: `authentication`
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 1.1 Initial Startup & Auth Check | System checks session on launch | ✅ | ✅ Completed | Auth BLoC + navigation guards handle routing. |
| 1.1 Initial Startup & Auth Check | Route to Home if authenticated | ✅ | ✅ Completed | Modular routing configured with auth state checks. |
| 1.1 Initial Startup & Auth Check | Route to Get Started if unauthenticated | ✅ | ✅ Completed | `get_started_page.dart` + `intro_page.dart` implemented. |
| 1.2 Register Business Account | Enter company name & industry | ✅ | ✅ Completed | `client_sign_up_page.dart` with full BLoC implementation. |
| 1.2 Register Business Account | Enter contact info & password | ✅ | ✅ Completed | Form validation + use cases properly wired. |
| 1.2 Register Business Account | Registration success → Main App | ✅ | ✅ Completed | Post-registration navigation functional. |
| 1.3 Business Sign In | Enter email & password | ✅ | ✅ Completed | `client_sign_in_page.dart` with AuthBLoC. |
| 1.3 Business Sign In | System validates credentials | ✅ | ✅ Completed | Use cases: `sign_in_with_email`, `sign_in_with_social`. |
| 1.3 Business Sign In | Grant access to dashboard | ✅ | ✅ Completed | Navigation to `client_main` on success. |
---
### Feature Module: `orders` (Order Management)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 2.1 Rapid Order | Tap RAPID → Select Role → Set Qty → Post | ✅ | ✅ Completed | `rapid_order_page.dart` + RapidOrderBloc + 3 use cases (create, parse, transcribe). Voice recognition integrated. |
| 2.2 Scheduled Orders — One-Time | Create single shift (date, time, role, location) | ✅ | ✅ Completed | `one_time_order_page.dart` + OneTimeOrderBloc + use case. |
| 2.2 Scheduled Orders — Recurring | Create recurring shifts (e.g., every Monday) | ✅ | ✅ Completed | `recurring_order_page.dart` + RecurringOrderBloc + use case. |
| 2.2 Scheduled Orders — Permanent | Long-term staffing placement | ✅ | ✅ Completed | `permanent_order_page.dart` + PermanentOrderBloc + use case. |
| 2.2 Scheduled Orders | Review cost before posting | ✅ | ✅ Completed | Cost calculation integrated in order creation flows. |
| View & Browse Active Orders | Search & toggle between views | ✅ | ✅ Completed | `view_orders_page.dart` + ViewOrdersCubit with filters. |
| Modify Posted Orders | Edit or cancel orders | ✅ | ✅ Completed | `order_edit_sheet.dart` with hub updates + cancel flow. |
| Reorder Functionality | Quickly recreate past orders | ✅ | 🚫 Completed | `ReorderUseCase` + recent reorders widget on home. |
---
### Feature Module: `client_coverage` (Operations & Workforce Management)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 3.1 Monitor Today's Coverage | View coverage tab | ✅ | ✅ Completed | `coverage_page.dart` + CoverageCubit. |
| 3.1 Monitor Today's Coverage | View percentage filled | ✅ | ✅ Completed | `coverage_header.dart` displays fill rate stats. |
| 3.1 Monitor Today's Coverage | Identify open gaps | ✅ | ✅ Completed | `coverage_shift_list.dart` shows unfilled shifts. |
| 3.1 Monitor Today's Coverage | Re-post unfilled shifts | ✅ | 🟡 Partial | Re-post event exists but mutation noted as stub (needs backend wiring). |
| 3.2 Live Activity Tracking | Real-time feed of worker clock-ins | ✅ | ✅ Completed | `live_activity_widget.dart` in home module, wired to Data Connect. |
| 3.3 Verify Worker Attire | Select shift → Select worker → Check attire | ✅ | 🟡 Partial | Verify attire button exists in coverage but full flow needs verification. |
| 3.4 Review & Approve Timesheets | Navigate to Timesheets section | ✅ | ✅ Completed | Integrated in billing module with `shift_completion_review_bloc`. |
| 3.4 Review & Approve Timesheets | Review actual vs. scheduled hours | ✅ | ✅ Completed | `completion_review_page.dart` displays timesheet data. |
| 3.4 Review & Approve Timesheets | Tap Approve / Dispute | ✅ | ✅ Completed | Approve/dispute use cases implemented. |
---
### Feature Module: `reports` (Reports & Analytics)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 4.1 Business Intelligence Reporting | Daily Ops Report | ✅ | ✅ Completed | `daily_ops_report_page.dart` + DailyOpsReportBloc. |
| 4.1 Business Intelligence Reporting | Spend Report | ✅ | ✅ Completed | `spend_report_page.dart` + SpendReportBloc. |
| 4.1 Business Intelligence Reporting | Forecast Report | ✅ | ✅ Completed | `forecast_report_page.dart` + ForecastReportBloc. |
| 4.1 Business Intelligence Reporting | Performance Report | ✅ | ✅ Completed | `performance_report_page.dart` + PerformanceReportBloc. |
| 4.1 Business Intelligence Reporting | No-Show Report | ✅ | ✅ Completed | `no_show_report_page.dart` + NoShowReportBloc. |
| 4.1 Business Intelligence Reporting | Coverage Report | ✅ | ✅ Completed | `coverage_report_page.dart` + CoverageReportBloc. |
---
### Feature Module: `billing` (Billing & Administration)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 5.1 Financial Management | View current balance | ✅ | ✅ Completed | `billing_page.dart` with current bill amount use case. |
| 5.1 Financial Management | View pending invoices | ✅ | ✅ Completed | `pending_invoices_page.dart` + use case. |
| 5.1 Financial Management | Download past invoices | ✅ | ✅ Completed | Invoice history use case implemented. |
| 5.1 Financial Management | Update payment methods | ✅ | ✅ Completed | Bank accounts use case + payment method management. |
---
### Feature Module: `hubs` (Manage Business Locations)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 5.2 Manage Business Locations | View list of client hubs | ✅ | ✅ Completed | `client_hubs_page.dart` + HubManagementBloc. |
| 5.2 Manage Business Locations | Add new hub | ✅ | ✅ Completed | Add hub use case + form in edit hub page. |
| 5.2 Manage Business Locations | Edit existing hub | ✅ | ✅ Completed | `edit_hub_page.dart` + `hub_details_page.dart`. |
| NFC Tag Assignment | Assign NFC tags to hubs | ✅ | 🚫 Completed | Assign NFC tag use case exists (extra feature). |
| Cost Centers | Manage hub cost centers | ✅ | 🚫 Completed | Get cost centers use case exists (extra feature). |
---
### Feature Module: `settings` (Profile & Settings)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 5.3 Profile & Settings Management | Edit personal contact info | ✅ | ✅ Completed | `edit_profile_page.dart` implemented. |
| 5.3 Profile & Settings Management | Toggle notification preferences | ✅ | ✅ Completed | Push, Email, SMS notification toggles + events in SettingsBloc. |
| Sign Out | Log out of application | ✅ | 🚫 Completed | Sign out use case implemented. |
---
### Feature Module: `home` (Home Tab)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| Home Dashboard | View customizable dashboard | ✅ | ✅ Completed | `client_home_page.dart` with multiple widgets. |
| Quick Actions | Access frequent operations | ✅ | ✅ Completed | `actions_widget.dart` with navigation shortcuts. |
| Create Order Entry Point | Launch order creation flows | ✅ | ✅ Completed | Order creation integrated via `shift_order_form_sheet.dart`. |
| Dashboard Widgets | Coverage, Spending, Live Activity | ✅ | 🚫 Completed | `coverage_dashboard.dart`, `spending_widget.dart`, `live_activity_widget.dart`. |
| Widget Reordering | Drag and reorder dashboard widgets | ✅ | 🚫 Completed | `draggable_widget_wrapper.dart` + `reorder_widget.dart` implemented. |
| Recent Reorders | Quick access to past orders | ✅ | 🚫 Completed | Recent reorders widget on home dashboard. |
---
### ❌ Missing Feature: Workers Directory
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| View Workers Directory | Browse and manage staff roster | ❌ | ❌ Missing | No dedicated workers module. Worker info only visible in order details. |
---
## 👷 STAFF APP
### Feature Module: `authentication`
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 1.1 App Initialization | Check auth token on startup | ✅ | ✅ Completed | Auth state management via BLoC + Modular routing. |
| 1.1 App Initialization | Route to Home if valid | ✅ | ✅ Completed | Navigation guards properly configured. |
| 1.1 App Initialization | Route to Get Started if invalid | ✅ | ✅ Completed | `intro_page.dart` + `get_started_page.dart`. |
| 1.2 Onboarding & Registration | Enter phone number | ✅ | ✅ Completed | `phone_verification_page.dart` + AuthBloc. |
| 1.2 Onboarding & Registration | Receive & verify SMS OTP | ✅ | ✅ Completed | OTP verification use case + BLoC wired to Firebase Auth. |
| 1.2 Onboarding & Registration | Check if profile exists | ✅ | ✅ Completed | Profile completeness check in auth flow. |
| 1.2 Onboarding & Registration | Profile Setup Wizard — Personal Info | ✅ | ✅ Completed | `profile_setup_page.dart` with all form steps. |
| 1.2 Onboarding & Registration | Profile Setup Wizard — Role & Experience | ✅ | ✅ Completed | Experience selection integrated in setup wizard. |
| 1.2 Onboarding & Registration | Profile Setup Wizard — Attire Sizes | ✅ | ✅ Completed | Attire sizing as part of profile setup (also available in profile sections). |
| 1.2 Onboarding & Registration | Enter Main App after profile setup | ✅ | ✅ Completed | Wizard completion routes to staff main shell. |
---
### Feature Module: `home` (Job Discovery)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 2.1 Browse & Filter Jobs | View available jobs list | ✅ | ✅ Completed | `worker_home_page.dart` with job listings. |
| 2.1 Browse & Filter Jobs | Filter by Role | ✅ | ✅ Completed | Role filtering via search and job type tabs (shifts module). |
| 2.1 Browse & Filter Jobs | Filter by Distance | ✅ | ✅ Completed | Distance/radius filtering implemented in shifts module. |
| 2.1 Browse & Filter Jobs | View job card details | ✅ | ✅ Completed | Comprehensive job cards with pay, location, requirements. |
| 2.3 Set Availability | Select dates/times → Save preferences | ✅ | ✅ Completed | `availability_page.dart` + AvailabilityBloc with 3 use cases. |
| View Benefits | Browse available benefits | ✅ | ✅ Completed | `benefits_overview_page.dart` in home module. Documented in M4 milestone. |
| Upcoming Shift Quick-Link | Next shift banner on home | ✅ | 🚫 Completed | Upcoming shifts display on worker home page. |
---
### Feature Module: `shifts` (Find Shifts + My Schedule)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 2.2 Claim Open Shift | Tap "Claim Shift" from Job Details | ✅ | ✅ Completed | `shift_details_page.dart` with accept shift use case. |
| 2.2 Claim Open Shift | System validates eligibility | ✅ | ✅ Completed | Eligibility validation in ShiftsBloc (certificates, conflicts). |
| 2.2 Claim Open Shift | Prompt to Upload Compliance Docs if missing | ✅ | ✅ Completed | Error handling redirects to certificates/documents on failure. |
| 3.1 View Schedule | View list of claimed shifts | ✅ | ✅ Completed | `my_shifts_tab.dart` with dedicated BLoC. |
| 3.1 View Schedule | View Shift Details | ✅ | ✅ Completed | `shift_details_page.dart` (348 lines) with comprehensive info. |
| Browse Available Shifts | Find and apply for new shifts | ✅ | ✅ Completed | `find_shifts_tab.dart` with search/filter + 9 use cases. |
| Shift History | View past worked shifts | ✅ | 🚫 Completed | `history_shifts_tab.dart` with get_history_shifts use case. |
---
### Feature Module: `clock_in` (Shift Execution)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 3.2 GPS-Verified Clock In | Navigate to Clock In tab | ✅ | ✅ Completed | `clock_in_page.dart` as dedicated tab in main navigation. |
| 3.2 GPS-Verified Clock In | System checks GPS location vs job site | ✅ | ✅ Completed | GPS verification via `isLocationVerified` in ClockInCubit state. |
| 3.2 GPS-Verified Clock In | "Swipe to Clock In" active when On Site | ✅ | ✅ Completed | `swipe_to_check_in.dart` with location-based activation. |
| 3.2 GPS-Verified Clock In | Show error if Off Site | ✅ | ✅ Completed | Location error state handling in cubit. |
| 3.2 GPS-Verified Clock In | Contactless NFC Clock-In mode | ✅ | 🚫 Completed | NFC mode supported in swipe widget + i18n strings. |
| 3.3 Submit Timesheet | Swipe to Clock Out | ✅ | ✅ Completed | Clock out use case + CheckOutRequested event. |
| 3.3 Submit Timesheet | Confirm total hours & break times | ✅ | ✅ Completed | `lunch_break_modal.dart` for break time entry. |
| 3.3 Submit Timesheet | Submit timesheet for client approval | ✅ | ✅ Completed | Timesheet submission integrated in clock out flow. |
---
### Feature Module: `payments` (Financial Management)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 4.1 Track Earnings | View Pending Pay (unpaid earnings) | ✅ | ✅ Completed | `payments_page.dart` with pending earnings display. |
| 4.1 Track Earnings | View Total Earned (paid earnings) | ✅ | ✅ Completed | Payment summary use case shows total earned. |
| 4.1 Track Earnings | View Payment History | ✅ | ✅ Completed | Payment history use case + list view. |
| 4.2 Request Early Pay | Tap "Request Early Pay" | ✅ | ✅ Completed | Navigation to early pay page from payments. |
| 4.2 Request Early Pay | Select amount to withdraw | ✅ | ✅ Completed | `early_pay_page.dart` (111 lines) with amount selection. |
| 4.2 Request Early Pay | Confirm transfer fee | ✅ | ✅ Completed | Fee confirmation integrated in early pay flow. |
| 4.2 Request Early Pay | Funds transferred to bank account | ✅ | ✅ Completed | Early pay submission use case implemented. |
---
### Feature Module: `profile` + `profile_sections` (Profile & Compliance)
| Use Case | Sub-Use Case | Production App | Status | Notes |
|:---|:---|:---:|:---:|:---|
| 5.1 Manage Compliance Documents | Navigate to Compliance Menu | ✅ | ✅ Completed | Compliance section in `staff_profile_page.dart`. |
| 5.1 Manage Compliance Documents | Upload Certificates | ✅ | ✅ Completed | `profile_sections/compliance/certificates/` module with 4 use cases + 2 pages. M4 feature. |
| 5.1 Manage Compliance Documents | View/Manage Identity Documents | ✅ | ✅ Completed | `profile_sections/compliance/documents/` module with camera/gallery upload. M4 feature. |
| 5.2 Manage Tax Forms | Complete W-4 digitally & submit | ✅ | ✅ Completed | `profile_sections/finances/tax_forms/form_w4_page.dart` + FormW4Cubit + use cases. |
| 5.2 Manage Tax Forms | Complete I-9 digitally & submit | ✅ | ✅ Completed | `profile_sections/finances/tax_forms/form_i9_page.dart` + FormI9Cubit + use cases. |
| 5.4 Account Settings | Update Bank Details | ✅ | ✅ Completed | `profile_sections/finances/staff_bank_account/` module with page + cubit. |
| 5.4 Account Settings | Access Support / FAQs | ✅ | ✅ Completed | `profile_sections/support/faqs/` module with search functionality + 2 use cases. |
| Personal Info Management | Update profile information | ✅ | ✅ Completed | `profile_sections/onboarding/profile_info/` module with 3 pages. Documented in M4. |
| Emergency Contact | Manage emergency contacts | ✅ | ✅ Completed | `profile_sections/onboarding/emergency_contact/` module. Documented in M4. |
| Experience Management | Update industries and skills | ✅ | ✅ Completed | `profile_sections/onboarding/experience/` module with 3 use cases. Documented in M4. |
| Attire Management | Upload attire photos & verification | ✅ | ✅ Completed | `profile_sections/compliance/attire/` module with camera/gallery support. Documented in M4. |
| Timecard Viewing | View clock-in/out history | ✅ | 🚫 Completed | `profile_sections/finances/time_card/` module with get_time_cards use case. |
| Privacy & Security | Manage privacy settings & visibility | ✅ | ✅ Completed | `profile_sections/support/privacy_security/` module with 4 use cases + 2 pages. Documented in M4. |
---
### ❌ Missing Features
| Feature | Status | Notes |
|:---|:---:|:---|
| 5.3 KROW University Training | ❌ Missing | No training module exists. Module, video/quiz functionality not implemented. |
| In-App Support Chat | ❌ Missing | No messaging module (only push notification support). |
| Leaderboard | ❌ Missing | No competitive tracking/gamification module. |
---
---
## 1⃣ Summary Statistics
### Client App
| Metric | Count |
---
## 📊 Summary Statistics
### Client App Completion: 89% (8/9 major categories)
- ✅ Authentication: 100%
- ✅ Order Management: 100%
- 🟡 Coverage: 90% (re-post stub exists, attire verification unclear)
- ✅ Reports: 100%
- ✅ Billing & Timesheets: 100%
- ✅ Hub Management: 100%
- ✅ Settings: 100%
- ✅ Home Dashboard: 100%
- ❌ Workers Directory: 0% (completely missing — highest priority gap)
### Staff App Completion: 87.5% (7/8 major categories)
- ✅ Authentication & Onboarding: 100%
- ✅ Home (Job Discovery): 100%
- ✅ Shifts & Scheduling: 100%
- ✅ Clock In/Out (GPS + NFC): 100%
- ✅ Payments & Early Pay: 100%
- ✅ Availability: 100%
- ✅ Profile & Compliance: 100% (13 subsections via modular `profile_sections` structure)
- ❌ KROW University: 0% (training module not implemented)
---
## 🚨 Critical Gaps (High Priority Missing Features)
| Feature | App | Impact | Notes |
|:---|:---:|:---|:---|
| **Workers Directory** | Client | 🔴 High | Documented use case 6.1 completely missing. No module, no pages, no BLoC. |
| **KROW University** | Staff | 🟠 Medium | Training module with videos/quizzes documented in 5.3 but not implemented. |
| **In-App Messaging** | Staff | 🟡 Low | Support chat documented but not implemented. FAQ module exists as alternative. |
| **Leaderboard** | Staff | 🟡 Low | Competitive tracking/gamification not implemented. |
---
## ⚙️ Architecture Notes
### Confirmed: Clean Architecture Compliance
- **All implemented features** follow the proper 4-layer structure:
- **Presentation** (pages, widgets, BLoCs)
- **Domain** (use cases, entities)
- **Data** (repositories, models, data sources)
- **Dependency injection** via Flutter Modular
- **Modular Profile Sections** (M4): Staff profile features organized in `profile_sections/` with 4 sub-modules:
- `onboarding/` - Profile info, experience, emergency contacts
- `compliance/` - Documents, certificates, attire
- `finances/` - Bank account, tax forms, timecard
- `support/` - FAQs, privacy & security
### Known Technical Debt
- **Coverage Re-post**: Mutation exists but noted as stub in code (needs backend wiring)
- **Reports Module**: All 6 report types implemented but lacks explicit `use_cases/` directory
- **Attire Verification**: Unclear if client-side attire verification is fully wired
---
## 🎯 Recommendations for Sprint Planning
### Priority Order
| Priority | Feature | App | Effort | Notes |
|:---:|:---|:---:|:---:|:---|
| 🔴 P1 | Implement Workers Directory | Client | Large | Critical missing feature with documented use case. Includes list, filter, profile views. |
| 🟠 P2 | Implement KROW University | Staff | Large | Training module with video player, quiz engine, XP tracking, badge system. |
| 🟡 P3 | Wire Coverage Re-post | Client | Small | Backend mutation exists as stub — needs GraphQL wiring. |
| 🟡 P3 | Implement In-App Messaging | Staff | Medium | Support chat with message threads. FAQ module currently serves as alternative. |
| 🟡 P3 | Implement Leaderboard | Staff | Medium | Competitive tracking module with rankings and achievements. |
---
*This document was generated by comprehensive code analysis of `apps/mobile/apps/` and `apps/mobile/packages/features/` cross-referenced against use case documentation in `docs/ARCHITECTURE/`. All status determinations are based on actual implementation presence: feature packages, page files, BLoC/Cubit classes, use case classes, and data layer components.*

View File

@@ -0,0 +1,64 @@
# Mobile Release Process
**For complete release documentation, see: [docs/RELEASE/mobile-releases.md](../RELEASE/mobile-releases.md)**
---
## Quick Links
### Release Workflows
- **Product Release**: Trigger at: [GitHub Actions](https://github.com/Oloodi/krow-workforce/actions/workflows/product-release.yml)
- **Hotfix Creation**: Trigger at: [GitHub Actions](https://github.com/Oloodi/krow-workforce/actions/workflows/hotfix-branch-creation.yml)
### Key Concepts
**Versioning**: We use semantic versioning with milestone suffixes (e.g., `0.0.1-m4`)
- Defined in: `apps/mobile/apps/staff/pubspec.yaml` or `apps/mobile/apps/client/pubspec.yaml`
- Auto-extracted by workflows (no manual input required)
**CHANGELOGs**:
- Staff: `apps/mobile/apps/staff/CHANGELOG.md`
- Client: `apps/mobile/apps/client/CHANGELOG.md`
- Format: `## [v0.0.1-m4] - Milestone 4 - 2026-03-05`
**Git Tags**: `krow-withus-<app>-mobile/<env>-vX.Y.Z`
- Example: `krow-withus-worker-mobile/dev-v0.0.1-m4`
---
## Quick Start
### Standard Release
1. **Update CHANGELOG** with user-facing changes
2. **Update version** in `pubspec.yaml`
3. **Commit and push** to dev branch
4. **Trigger workflow**:
- Go to GitHub Actions → "📦 Product Release"
- Select app (worker/client) and environment (dev/stage/prod)
- Click "Run workflow"
### Hotfix Release
1. **Trigger workflow**:
- Go to GitHub Actions → "🚨 Product Hotfix - Create Branch"
- Enter current production version and issue description
- Workflow creates branch and updates version/CHANGELOG
2. **Fix bug** on hotfix branch
3. **Merge to main** and release to production
---
## For Complete Details
See the comprehensive documentation: **[docs/RELEASE/mobile-releases.md](../RELEASE/mobile-releases.md)**
This includes:
- ✅ Detailed versioning strategy
- ✅ CHANGELOG format guidelines
- ✅ Step-by-step release procedures
- ✅ APK signing setup (24 GitHub Secrets)
- ✅ Helper scripts reference
- ✅ Hotfix process
- ✅ Troubleshooting guide
- ✅ Release cadence (dev/stage/prod)

View File

@@ -0,0 +1,727 @@
# Mobile App Release Process
**For Staff Mobile & Client Mobile Apps**
**Document Version**: 2.0
**Last Updated**: 2026-03-06
**Status**: ✅ Production Ready
---
## 📱 Overview
This document covers the complete release process for both mobile applications:
- **Staff Mobile App** (Worker Mobile) - `krow-withus-worker-mobile`
- **Client Mobile App** - `krow-withus-client-mobile`
Both apps:
- Built with Flutter
- Distributed via iOS App Store & Google Play Store
- Maintain independent versions
- Have independent CHANGELOGs
- Released via GitHub Actions workflows
---
## 📐 Versioning Strategy
### Semantic Versioning with Milestones
We use **Semantic Versioning 2.0.0** with milestone suffixes:
```
MAJOR.MINOR.PATCH-milestone
```
**Examples:**
- `0.0.1-m3` - Milestone 3 release
- `0.0.1-m4` - Milestone 4 release
- `1.0.0` - First production release (no suffix)
- `1.0.1` - Production patch release
**Version Rules:**
- **MAJOR**: Breaking changes, major architectural updates
- **MINOR**: New features, backward-compatible changes
- **PATCH**: Bug fixes, minor improvements
- **SUFFIX**: `-m3`, `-m4`, etc. for milestone tracking
### Version Location
Versions are defined in `pubspec.yaml`:
**Staff Mobile:** `apps/mobile/apps/staff/pubspec.yaml`
```yaml
version: 0.0.1-m4+1
```
**Client Mobile:** `apps/mobile/apps/client/pubspec.yaml`
```yaml
version: 0.0.1-m4+1
```
**Format:** `X.Y.Z-suffix+buildNumber`
- `0.0.1-m4` = version with milestone
- `+1` = build number (for app stores)
### Version Auto-Extraction
GitHub Actions workflows automatically extract the version from `pubspec.yaml` using `.github/scripts/extract-version.sh`. **No manual version input required.**
---
## 📝 CHANGELOG Management
### File Locations
- **Staff Mobile:** `apps/mobile/apps/staff/CHANGELOG.md`
- **Client Mobile:** `apps/mobile/apps/client/CHANGELOG.md`
### Format Standard
```markdown
# [App Name] - Change Log
## [v0.0.1-m4] - Milestone 4 - 2026-03-05
### Added - [Category Name]
- Feature description
- Another feature
### Fixed
- Bug fix description
### Changed
- Changed behavior
---
## [v0.0.1-m3] - Milestone 3 - 2026-02-15
### Added - [Category Name]
...
```
### Section Guidelines
Use these standard categories:
- **Added**: New features
- **Fixed**: Bug fixes
- **Changed**: Changes to existing functionality
- **Deprecated**: Soon-to-be removed features
- **Removed**: Removed features
- **Security**: Security fixes
### When to Update CHANGELOG
**Update BEFORE release:**
- When milestone is complete
- Document all user-facing changes
- Include technical features if relevant
**Don't document:**
- Internal refactoring (unless architecturally significant)
- Development-only changes
- Code formatting/linting
---
## 🏷️ Git Tag Format
### Tag Structure
```
krow-withus-<app>-mobile/<env>-v<version>
```
### Examples
**Staff Mobile (Worker):**
```
krow-withus-worker-mobile/dev-v0.0.1-m3
krow-withus-worker-mobile/stage-v0.0.1-m4
krow-withus-worker-mobile/prod-v1.0.0
```
**Client Mobile:**
```
krow-withus-client-mobile/dev-v0.0.1-m3
krow-withus-client-mobile/stage-v0.0.1-m4
krow-withus-client-mobile/prod-v1.0.0
```
### Tag Components
| Component | Values | Example |
|-----------|--------|---------|
| Product | `worker`, `client` | `worker` |
| Type | `mobile` | `mobile` |
| Environment | `dev`, `stage`, `prod` | `dev` |
| Version | From pubspec.yaml | `v0.0.1-m3` |
**Note:** Tags include the full version with milestone suffix (e.g., `v0.0.1-m4`, not just `v0.0.1`)
---
## 🚀 Release Workflows
### Release Types
We have **2 GitHub Actions workflows** for releases:
1. **Product Release** (`.github/workflows/product-release.yml`) - Standard releases
2. **Hotfix Branch Creation** (`.github/workflows/hotfix-branch-creation.yml`) - Emergency fixes
Both workflows use **manual triggers only** (`workflow_dispatch`) - no automatic releases.
---
## 📦 Standard Release Process
### Step 1: Prepare Release
1. **Ensure milestone is complete**
- All features implemented
- All tests passing
- Code reviews completed
2. **Update CHANGELOG**
```bash
# Edit the appropriate CHANGELOG file
vi apps/mobile/apps/staff/CHANGELOG.md
# OR
vi apps/mobile/apps/client/CHANGELOG.md
```
3. **Update version in pubspec.yaml**
```yaml
# apps/mobile/apps/staff/pubspec.yaml
version: 0.0.1-m4+1
```
4. **Commit changes**
```bash
git add apps/mobile/apps/staff/CHANGELOG.md apps/mobile/apps/staff/pubspec.yaml
git commit -m "docs(mobile): prepare staff app v0.0.1-m4 release"
git push origin dev
```
### Step 2: Trigger Release Workflow
1. **Navigate to GitHub Actions**
- Go to: https://github.com/Oloodi/krow-workforce/actions
- Select **"📦 Product Release"** workflow
2. **Click "Run workflow"**
3. **Select parameters:**
- **Branch**: `dev` (or release branch)
- **Product**: `worker-mobile-app` or `client-mobile-app`
- **Environment**: `dev`, `stage`, or `prod`
- **Pre-release**: Check if this is not a production release
4. **Click "Run workflow"**
### Step 3: Monitor Workflow
The workflow performs these steps automatically:
1. ✅ **Validate & Create Release** (Job 1)
- Extract version from pubspec.yaml
- Validate version format
- Generate tag name
- Create Git tag
- Extract release notes from CHANGELOG
- Create GitHub Release with formatted notes
2. 🔨 **Build Mobile Artifacts** (Job 2)
- Setup Node.js 20
- Install Firebase CLI
- Generate Data Connect SDK
- Setup Java 17
- Setup Flutter 3.38.x
- Bootstrap with Melos
- Decode keystore from secrets
- Build signed APK
- Verify APK signature
- Upload APK to GitHub Release
### Step 4: Verify Release
1. **Check GitHub Releases page**
- URL: https://github.com/Oloodi/krow-workforce/releases
- Verify release was created with correct tag
- Verify release notes display correctly
- Verify APK is attached (if applicable)
2. **Test the release**
- Download APK (dev releases)
- Install on test device
- Verify app launches and core features work
---
## 🔥 Hotfix Process
### When to Use Hotfix
✅ **Use hotfix for:**
- Critical bug in production affecting users
- Data loss or security vulnerability
- Service unavailable or major feature broken
- Customer-blocking issue
❌ **Don't use hotfix for:**
- Minor bugs (can wait for next release)
- Feature requests
- UI/UX improvements
- Styling issues
### Hotfix Workflow
1. **Navigate to GitHub Actions**
- Go to: https://github.com/Oloodi/krow-workforce/actions
- Select **"🚨 Product Hotfix - Create Branch"** workflow
2. **Click "Run workflow"**
3. **Fill in parameters:**
- **Product**: `worker-mobile-app` or `client-mobile-app`
- **Current Production Version**: e.g., `1.0.0` (without 'v' prefix)
- **Issue Description**: Brief description of the bug (used in CHANGELOG and branch name)
4. **The workflow automatically:**
- Creates hotfix branch: `hotfix/krow-withus-worker-mobile/prod-v1.0.1`
- Increments PATCH version: `1.0.0` → `1.0.1`
- Updates `pubspec.yaml` with new version
- Updates CHANGELOG.md with hotfix entry
- Creates Pull Request with hotfix instructions
5. **Fix the bug:**
```bash
# Checkout the hotfix branch
git fetch origin
git checkout hotfix/krow-withus-worker-mobile/prod-v1.0.1
# Make your fix
# ... edit files ...
# Test thoroughly
flutter test
# Commit your fix
git add .
git commit -m "fix(mobile): resolve critical production bug"
git push origin hotfix/krow-withus-worker-mobile/prod-v1.0.1
```
6. **Merge and Release:**
- Review and merge the Pull Request to `main` (or production branch)
- Trigger **Product Release** workflow with `prod` environment
- Workflow will create tag `krow-withus-worker-mobile/prod-v1.0.1`
- Deploy hotfix to production
7. **Backport to dev:**
```bash
git checkout dev
git merge hotfix/krow-withus-worker-mobile/prod-v1.0.1
git push origin dev
```
---
## 🔐 APK Signing Setup
### Overview
All Android builds require signing with keystores. We use **24 GitHub Secrets** (12 per app × 2 apps):
- 6 keystores (2 apps × 3 environments)
- 4 secrets per keystore (base64, password, alias, key password)
### Keystore Files
**Worker Mobile (Staff App):**
- `krow_with_us_staff_dev.jks` - ✅ Committed to repo
- `krow_staff_staging.jks` - ⚠️ Store in GitHub Secrets only
- `krow_staff_prod.jks` - ⚠️ Store in GitHub Secrets only
**Client Mobile:**
- `krow_with_us_client_dev.jks` - ✅ Committed to repo
- `krow_client_staging.jks` - ⚠️ Store in GitHub Secrets only
- `krow_client_prod.jks` - ⚠️ Store in GitHub Secrets only
### Required GitHub Secrets
#### Worker Mobile - 12 Secrets
**Dev Environment:**
- `WORKER_KEYSTORE_DEV_BASE64`
- `WORKER_KEYSTORE_PASSWORD_DEV`
- `WORKER_KEY_ALIAS_DEV`
- `WORKER_KEY_PASSWORD_DEV`
**Staging Environment:**
- `WORKER_KEYSTORE_STAGING_BASE64`
- `WORKER_KEYSTORE_PASSWORD_STAGING`
- `WORKER_KEY_ALIAS_STAGING`
- `WORKER_KEY_PASSWORD_STAGING`
**Production Environment:**
- `WORKER_KEYSTORE_PROD_BASE64`
- `WORKER_KEYSTORE_PASSWORD_PROD`
- `WORKER_KEY_ALIAS_PROD`
- `WORKER_KEY_PASSWORD_PROD`
#### Client Mobile - 12 Secrets
**Dev Environment:**
- `CLIENT_KEYSTORE_DEV_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_DEV`
- `CLIENT_KEY_ALIAS_DEV`
- `CLIENT_KEY_PASSWORD_DEV`
**Staging Environment:**
- `CLIENT_KEYSTORE_STAGING_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_STAGING`
- `CLIENT_KEY_ALIAS_STAGING`
- `CLIENT_KEY_PASSWORD_STAGING`
**Production Environment:**
- `CLIENT_KEYSTORE_PROD_BASE64`
- `CLIENT_KEYSTORE_PASSWORD_PROD`
- `CLIENT_KEY_ALIAS_PROD`
- `CLIENT_KEY_PASSWORD_PROD`
### Setup Using Helper Script
We provide an interactive script to configure all secrets:
```bash
.github/scripts/setup-mobile-github-secrets.sh
```
This script will:
1. Prompt for keystore file paths
2. Convert keystores to base64
3. Prompt for passwords and aliases
4. Display GitHub CLI commands to set secrets
5. Optionally execute the commands
### Manual Setup
If you prefer manual setup:
```bash
# 1. Convert keystore to base64
base64 -i /path/to/keystore.jks | pbcopy
# 2. Add to GitHub Secrets via web UI
# Go to: Repository → Settings → Secrets and variables → Actions
# Click "New repository secret"
# Name: WORKER_KEYSTORE_PROD_BASE64
# Value: Paste the base64 string
# 3. Repeat for all 24 secrets
```
Or use GitHub CLI:
```bash
# Set a secret using gh CLI
gh secret set WORKER_KEYSTORE_PROD_BASE64 < /path/to/keystore_base64.txt
# Set multiple secrets
gh secret set WORKER_KEYSTORE_PASSWORD_PROD -b "your_password"
gh secret set WORKER_KEY_ALIAS_PROD -b "your_alias"
gh secret set WORKER_KEY_PASSWORD_PROD -b "your_key_password"
```
### Verifying APK Signature
After build, the workflow automatically verifies the APK signature using:
```bash
.github/scripts/verify-apk-signature.sh <path-to-apk> <expected-alias>
```
---
## 📅 Release Cadence
### Development Releases (dev)
- **Frequency**: As needed (daily/weekly)
- **Purpose**: Test features, integration testing
- **Stability**: Unstable, may have bugs
- **Distribution**: Internal testing only
- **APK**: Signed with dev keystore
- **Tag example**: `krow-withus-worker-mobile/dev-v0.0.1-m3`
### Staging Releases (stage)
- **Frequency**: Bi-weekly (end of sprints)
- **Purpose**: QA testing, client demos
- **Stability**: Stable, feature-complete
- **Distribution**: QA team, stakeholders
- **APK**: Signed with staging keystore
- **Tag example**: `krow-withus-worker-mobile/stage-v0.0.1-m4`
### Production Releases (prod)
- **Frequency**: Monthly or milestone-based
- **Purpose**: Public release to app stores
- **Stability**: Production-grade, thoroughly tested
- **Distribution**: Public (App Store, Play Store)
- **APK**: Signed with production keystore
- **Tag example**: `krow-withus-worker-mobile/prod-v1.0.0`
---
## 🛠️ Helper Scripts Reference
All scripts are located in `.github/scripts/` and are used by workflows:
### 1. extract-version.sh
**Purpose**: Extract version from pubspec.yaml
**Usage**:
```bash
.github/scripts/extract-version.sh <path-to-pubspec.yaml>
```
**Example**:
```bash
VERSION=$(.github/scripts/extract-version.sh apps/mobile/apps/staff/pubspec.yaml)
echo $VERSION # Output: 0.0.1-m4
```
### 2. generate-tag-name.sh
**Purpose**: Generate consistent Git tag names
**Usage**:
```bash
.github/scripts/generate-tag-name.sh <app> <env> <version>
```
**Example**:
```bash
TAG=$(.github/scripts/generate-tag-name.sh worker dev 0.0.1-m4)
echo $TAG # Output: krow-withus-worker-mobile/dev-v0.0.1-m4
```
### 3. extract-release-notes.sh
**Purpose**: Extract CHANGELOG section for a specific version
**Usage**:
```bash
.github/scripts/extract-release-notes.sh <app> <env> <version> <tag>
```
**Example**:
```bash
NOTES=$(.github/scripts/extract-release-notes.sh worker dev 0.0.1-m4 krow-withus-worker-mobile/dev-v0.0.1-m4)
```
**Output format**:
```
**Environment:** DEV
**Tag:** krow-withus-worker-mobile/dev-v0.0.1-m4
## What is new in this release
[CHANGELOG content for v0.0.1-m4]
```
### 4. create-release-summary.sh
**Purpose**: Generate GitHub Step Summary with emojis
**Usage**:
```bash
.github/scripts/create-release-summary.sh <app> <env> <version> <tag>
```
**Creates**: Formatted summary in GitHub Actions UI
### 5. setup-apk-signing.sh
**Purpose**: Setup APK signing environment variables
**Usage** (in workflow):
```bash
.github/scripts/setup-apk-signing.sh <app> <env>
```
**What it does**:
- Decodes base64 keystore to file
- Sets `CM_KEYSTORE_PATH_<APP>` environment variable
- Sets keystore password, alias, and key password
### 6. verify-apk-signature.sh
**Purpose**: Verify APK is properly signed
**Usage**:
```bash
.github/scripts/verify-apk-signature.sh <apk-path> <expected-alias>
```
**Example**:
```bash
.github/scripts/verify-apk-signature.sh build/app/outputs/apk/release/app-release.apk androidreleasekey
```
### 7. attach-apk-to-release.sh
**Purpose**: Upload APK to existing GitHub Release
**Usage**:
```bash
.github/scripts/attach-apk-to-release.sh <tag> <apk-path> <app>
```
**Example**:
```bash
.github/scripts/attach-apk-to-release.sh krow-withus-worker-mobile/dev-v0.0.1-m4 build/app/outputs/apk/release/app-release.apk worker
```
### 8. setup-mobile-github-secrets.sh
**Purpose**: Interactive helper to configure all GitHub Secrets
**Usage**:
```bash
.github/scripts/setup-mobile-github-secrets.sh
```
**Interactive prompts for**:
- Keystore file paths
- Passwords and aliases
- Generates GitHub CLI commands
- Optionally executes commands
---
## 📋 Pre-Release Checklist
Before triggering a release, ensure:
### Code Quality
- [ ] All automated tests pass
- [ ] No critical linting errors
- [ ] Code review completed (for stage/prod)
- [ ] Security audit passed (for prod)
### Documentation
- [ ] CHANGELOG.md updated with all changes
- [ ] Version in pubspec.yaml matches CHANGELOG
- [ ] Breaking changes documented
- [ ] Migration guide created (if needed)
### Testing
- [ ] Feature testing completed
- [ ] Regression testing passed
- [ ] Performance testing acceptable
- [ ] Device compatibility verified
### Configuration
- [ ] Environment variables configured
- [ ] API endpoints correct for environment
- [ ] Feature flags set appropriately
- [ ] Analytics tracking verified
### GitHub Secrets (First-time setup)
- [ ] All 24 secrets configured
- [ ] Keystore passwords verified
- [ ] Test build succeeded with signing
---
## 🐛 Troubleshooting
### Workflow Fails: "Version not found in pubspec.yaml"
**Cause**: Invalid version format or missing version
**Solution**:
```yaml
# Ensure version line in pubspec.yaml looks like:
version: 0.0.1-m4+1
# Not:
version: 0.0.1 # Missing build number
version: "0.0.1-m4+1" # Don't quote the version
```
### Workflow Fails: "Secret not found"
**Cause**: Missing GitHub Secret
**Solution**:
1. Check secret name matches exactly (case-sensitive)
2. Run `.github/scripts/setup-mobile-github-secrets.sh`
3. Verify secrets at: Repository → Settings → Secrets and variables → Actions
### APK Signing Fails
**Cause**: Invalid keystore or wrong password
**Solution**:
1. Verify keystore base64 encoding: `base64 -i keystore.jks | base64 -d > test.jks`
2. Test password locally: `keytool -list -keystore test.jks`
3. Verify alias: `keytool -list -v -keystore test.jks | grep "Alias name"`
### CHANGELOG Not Extracted
**Cause**: Version format doesn't match in CHANGELOG
**Solution**:
```markdown
# CHANGELOG.md must have this EXACT format:
## [v0.0.1-m4] - Milestone 4 - 2026-03-05
# OR
## [0.0.1-m4] - Milestone 4 - 2026-03-05
# The script tries both [vX.Y.Z] and [X.Y.Z] formats
```
### Tag Already Exists
**Cause**: Trying to create a duplicate tag
**Solution**:
```bash
# Delete the existing tag (CAREFUL!)
git tag -d krow-withus-worker-mobile/dev-v0.0.1-m4
git push origin :refs/tags/krow-withus-worker-mobile/dev-v0.0.1-m4
# Then re-run the workflow
```
---
## 📚 Additional Resources
### Related Documentation
- [Agent Development Rules](../MOBILE/00-agent-development-rules.md)
- [Architecture Principles](../MOBILE/01-architecture-principles.md)
- [Mobile CI Workflow](../../.github/workflows/mobile-ci.yml)
### GitHub Actions Workflows
- **Product Release**: `.github/workflows/product-release.yml`
- **Hotfix Branch Creation**: `.github/workflows/hotfix-branch-creation.yml`
- **Mobile CI**: `.github/workflows/mobile-ci.yml`
### Useful Commands
```bash
# View current version
grep "^version:" apps/mobile/apps/staff/pubspec.yaml
# List all mobile tags
git tag -l "krow-withus-*-mobile/*"
# View latest releases
gh release list --limit 10
# Download APK from release
gh release download krow-withus-worker-mobile/dev-v0.0.1-m4 --pattern "*.apk"
```
---
## 🔄 Version History
| Version | Date | Changes |
|---------|------|---------|
| 2.0 | 2026-03-06 | Consolidated all release docs into single file |
| 1.0 | 2026-03-05 | Initial separate documentation files |
---
**Questions or Issues?**
Contact the DevOps team or create an issue in the repository.

View File

@@ -0,0 +1,85 @@
# 📱 Research: Flutter Integration Testing Evaluation
**Issue:** #533
**Focus:** Maestro vs. Marionette MCP (LeanCode)
**Status:** ✅ Completed
**Target Apps:** `KROW Client App` & `KROW Staff App`
---
## 1. Executive Summary & Recommendation
Following a technical spike implementing full authentication flows (Login/Signup) for both KROW platforms, **Maestro is the recommended integration testing framework.**
While **Marionette MCP** offers an innovative LLM-driven approach for exploratory debugging, it lacks the determinism required for a production-grade CI/CD pipeline. Maestro provides the stability, speed, and native OS interaction necessary to gate our releases effectively.
### Why Maestro Wins for KROW:
* **Zero-Flake Execution:** Built-in wait logic handles Firebase Auth latency without hard-coded `sleep()` calls.
* **Platform Parity:** Single `.yaml` definitions drive both iOS and Android build variants.
* **Non-Invasive:** Maestro tests the compiled `.apk` or `.app` (Black-box), ensuring we test exactly what the user sees.
* **System Level Access:** Handles native OS permission dialogs (Camera/Location/Notifications) which Marionette cannot "see."
---
## 2. Technical Evaluation Matrix
| Criteria | Maestro | Marionette MCP | Winner |
| :--- | :--- | :--- | :--- |
| **Test Authoring** | **High Speed:** Declarative YAML; Maestro Studio recorder. | **Variable:** Requires precise Prompt Engineering. | **Maestro** |
| **Execution Latency** | **Low:** Instantaneous interaction (~5s flows). | **High:** LLM API roundtrips (~45s+ flows). | **Maestro** |
| **Environment** | Works on Release/Production builds. | Restricted to Debug/Profile modes. | **Maestro** |
| **CI/CD Readiness** | Native CLI; easy GitHub Actions integration. | High overhead; depends on external AI APIs. | **Maestro** |
| **Context Awareness** | Interacts with Native OS & Bottom Sheets. | Limited to the Flutter Widget Tree. | **Maestro** |
---
## 3. Spike Analysis & Findings
### Tool A: Maestro (The Standard)
We verified the `login.yaml` and `signup.yaml` flows across both apps. Maestro successfully abstracted the asynchronous nature of our **Data Connect** and **Firebase** backends.
* **Pros:** * **Semantics Driven:** By targeting `Semantics(identifier: '...')` in our `/design_system/`, tests remain stable even if the UI text changes for localization.
* **Automatic Tolerance:** It detects spinning loaders and waits for destination widgets automatically.
* **Cons:** * Requires strict adherence to adding `Semantics` wrappers on all interactive components.
### Tool B: Marionette MCP (The Experiment)
We spiked this using the `marionette_flutter` binding and executing via **Cursor/Claude**.
* **Pros:** * Phenomenal for visual "smoke testing" and live-debugging UI issues via natural language.
* **Cons:** * **Non-Deterministic:** Prone to "hallucinations" during heavy network traffic.
* **Architecture Blocker:** Requires the Dart VM Service to be active, making it impossible to test against hardened production builds.
---
## 4. Implementation & Migration Blueprint
### Phase 1: Semantics Enforcement
We must enforce a linting rule or PR checklist: All interactive widgets in `@krow/design_system` must include a unique `identifier`.
```dart
// Standardized Implementation
Semantics(
identifier: 'login_submit_button',
child: KrowPrimaryButton(
onPressed: _handleLogin,
label: 'Sign In',
),
)
```
### Phase 2: Repository Structure (Implemented)
Maestro flows are co-located with each app under `auth/`:
* `apps/mobile/apps/client/maestro/auth/sign_in.yaml` — Client sign-in
* `apps/mobile/apps/client/maestro/auth/sign_up.yaml` — Client sign-up
* `apps/mobile/apps/staff/maestro/auth/sign_in.yaml` — Staff sign-in (phone + OTP)
* `apps/mobile/apps/staff/maestro/auth/sign_up.yaml` — Staff sign-up (phone + OTP)
Credentials are injected via env variables (never hardcoded). Use `make test-e2e` to run the suite.
### Phase 3: CI/CD Integration
The Maestro CLI will be added to our **GitHub Actions** workflow to automate quality gates.
* **Trigger:** Every PR targeting `main` or `develop`.
* **Action:** Generate a build, execute `maestro test`, and block merge on failure.

View File

@@ -0,0 +1,267 @@
# How to Run Maestro Integration Tests
Credentials are injected via env variables — **never hardcoded** in YAML.
**E2E Happy Path test cases (purpose, steps, expected outcomes):** see [docs/testing/maestro-e2e-happy-paths.md](../testing/maestro-e2e-happy-paths.md) (#572).
**Maestro conventions / standards:** see [docs/testing/maestro-e2e-conventions.md](../testing/maestro-e2e-conventions.md).
## Env variables
| Flow | Env variables |
|------|---------------|
| **Client sign-in** | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD` |
| **Client sign-up** | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY` |
| **Client sign_in_invalid_password** | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_INVALID_PASSWORD` (default: wrongpass) |
| **Staff sign-in** | `TEST_STAFF_PHONE`, `TEST_STAFF_OTP` |
| **Staff sign-up** | `TEST_STAFF_SIGNUP_PHONE`, `TEST_STAFF_OTP` |
| **Staff sign_in_invalid_otp** | `TEST_STAFF_PHONE`, `TEST_STAFF_INVALID_OTP` (default: 000000) |
**Sign-in credentials:**
| App | Email/Phone | Password/OTP |
|-----|-------------|--------------|
| **Client** | testclient@gmail.com | testclient! |
| **Staff** | +1 555-555-1234 (use `5555551234` in env) | 123123 |
---
## Step-by-step
### 1. Install Maestro CLI
**Windows:** Download from [Maestro releases](https://github.com/mobile-dev-inc/maestro/releases), extract, add to PATH.
**macOS/Linux:**
```bash
curl -Ls "https://get.maestro.mobile.dev" | bash
```
### 2. Add Firebase test phone (Staff app)
Firebase Console → **Authentication****Sign-in method****Phone****Phone numbers for testing**:
- Add **+1 555-555-1234** with verification code **123123**
### 3. Build and install apps
```bash
make mobile-client-build PLATFORM=apk MODE=debug
adb install apps/mobile/apps/client/build/app/outputs/flutter-apk/app-debug.apk
make mobile-staff-build PLATFORM=apk MODE=debug
adb install apps/mobile/apps/staff/build/app/outputs/flutter-apk/app-debug.apk
```
### 4. Run E2E tests via Makefile
**Export credentials, then run:**
```bash
# Client login credentials
export TEST_CLIENT_EMAIL=testclient@gmail.com
export TEST_CLIENT_PASSWORD=testclient!
export TEST_CLIENT_COMPANY="Test Company"
# Staff login credentials
export TEST_STAFF_PHONE=5555551234
export TEST_STAFF_OTP=123123
export TEST_STAFF_SIGNUP_PHONE=5555550000 # use a new number for signup
# Run full suite
make test-e2e
# Run CLIENT only (auth flows)
make test-e2e-client
# Run CLIENT extended (auth + navigation + orders + settings)
make test-e2e-client-extended
# Run STAFF only (auth flows)
make test-e2e-staff
# Run STAFF extended (auth + navigation + profile + compliance + shifts + benefits)
make test-e2e-staff-extended
```
### 5. Run Client only (Windows PowerShell)
```powershell
$env:TEST_CLIENT_EMAIL = "testclient@gmail.com"
$env:TEST_CLIENT_PASSWORD = "testclient!"
$env:TEST_CLIENT_COMPANY = "Test Company"
# Auth only
make test-e2e-client
# Extended (auth + navigation + orders + settings)
make test-e2e-client-extended
```
### 6. Run Staff only (Windows PowerShell)
```powershell
$env:TEST_STAFF_PHONE = "5555551234"
$env:TEST_STAFF_OTP = "123123"
$env:TEST_STAFF_SIGNUP_PHONE = "5555550000"
# Auth only
make test-e2e-staff
# Extended (auth + navigation + profile + compliance + shifts + benefits)
make test-e2e-staff-extended
```
---
## Folder structure
```
apps/mobile/apps/client/maestro/
auth/
sign_in.yaml
sign_up.yaml
sign_out.yaml
sign_in_invalid_password.yaml
navigation/
home.yaml
orders.yaml
billing.yaml
coverage.yaml
reports.yaml
orders/
view_orders.yaml
completed_no_edit_icon.yaml # #492
create_order_entry.yaml
settings/
settings_page.yaml
edit_profile.yaml
apps/mobile/apps/staff/maestro/
auth/
sign_in.yaml
sign_up.yaml
sign_out.yaml
sign_in_invalid_otp.yaml
navigation/
home.yaml
shifts.yaml
profile.yaml
payments.yaml
clock_in.yaml
profile/
personal_info.yaml
documents_list.yaml
certificates_list.yaml
time_card.yaml
bank_account.yaml
faqs.yaml
privacy_security.yaml
emergency_contact.yaml
compliance/
document_upload_banner.yaml # #550
certificate_upload_banner.yaml # #551
attire_upload_banner.yaml # #552
shifts/
find_shifts.yaml
incomplete_profile_banner.yaml # #549 (requires incomplete-profile user)
home/
benefits.yaml # #524
```
### Direct Maestro commands
To run flows like `sign_in` with explicit paths and env vars:
```bash
# Single flow
maestro test apps/mobile/apps/staff/maestro/auth/sign_in.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
# Multiple flows (use --shard-split=1; if tcp:7001 persists, run as 2 commands)
maestro test --shard-split=1 apps/mobile/apps/staff/maestro/auth/sign_in.yaml apps/mobile/apps/staff/maestro/compliance/document_upload_banner.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
# Workaround: run sign_in first, then the feature flow (avoids tcp:7001 between flows)
maestro test apps/mobile/apps/staff/maestro/auth/sign_in.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
maestro test apps/mobile/apps/staff/maestro/compliance/document_upload_banner.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
```
### Make targets
| Target | Description |
|--------|-------------|
| `make test-e2e` | Auth flows (sign_in, sign_up for both apps) |
| `make test-e2e-client` | Client auth flows |
| `make test-e2e-client-extended` | Client full suite (auth + nav + orders + settings) |
| `make test-e2e-client-smoke` | Client smoke suite (deterministic) |
| `make test-e2e-client-orders-smoke` | Client orders smoke (RAPID → One-Time draft) |
| `make test-e2e-client-hubs-e2e` | Client hubs E2E (manage + create/edit/delete) |
| `make test-e2e-client-billing-smoke` | Client billing smoke (overview + invoice details/empty state) |
| `make test-e2e-client-reports-smoke` | Client reports smoke (dashboard + export placeholder) |
| `make test-e2e-client-settings-e2e` | Client settings E2E (edit profile save + logout) |
| `make test-e2e-client-orders-data` | Client orders data-dependent (edit active order) |
| `make test-e2e-client-happy-path` | Client happy path (auth + hubs + create order E2E + billing + reports + logout) — #572 |
| `make test-e2e-client-auth` | Client auth (sign_in, sign_up) |
| `make test-e2e-client-navigation` | Client navigation (sign_in + home, orders, billing, coverage, reports) |
| `make test-e2e-client-orders` | Client orders (sign_in + view_orders, completed_no_edit_icon, create_order_entry) |
| `make test-e2e-client-settings` | Client settings (sign_in + settings_page, edit_profile) |
| `make test-e2e-client-sign-out` | Client sign out flow |
| `make test-e2e-staff` | Staff auth flows |
| `make test-e2e-staff-extended` | Staff full suite |
| `make test-e2e-staff-smoke` | Staff smoke suite (deterministic) |
| `make test-e2e-staff-profile-smoke` | Staff profile smoke (timecard/bank/tax/attire validation) |
| `make test-e2e-staff-payments-smoke` | Staff payments smoke (earnings history) |
| `make test-e2e-staff-shifts-smoke` | Staff shifts smoke (find shifts; optionally apply) |
| `make test-e2e-staff-compliance-e2e` | Staff compliance E2E (document + certificate uploads) |
| `make test-e2e-staff-happy-path` | Staff happy path (auth + clock in/out + availability + document upload + payments + sign out) — #572 |
| `make test-e2e-staff-auth` | Staff auth (sign_in, sign_up) |
| `make test-e2e-staff-navigation` | Staff navigation (sign_in + home, shifts, profile, payments, clock_in) |
| `make test-e2e-staff-profile` | Staff profile (sign_in + personal_info, documents_list, certificates_list) |
| `make test-e2e-staff-profile-extended` | Staff profile + time_card, bank_account |
| `make test-e2e-staff-sign-out` | Staff sign out flow |
| `make test-e2e-staff-shifts` | Staff shifts (sign_in + find_shifts, incomplete_profile_banner) |
| `make test-e2e-staff-compliance` | Staff compliance (sign_in + document/certificate/attire upload banners) |
| `make test-e2e-staff-home` | Staff home (sign_in + benefits) |
| `make test-e2e-extended` | Full suite (both apps, auth + all feature flows) |
---
## Troubleshooting
**`tcp:7001: closed` or `device offline` when running flows**
1. Restart ADB before running: `adb kill-server && adb start-server`
2. Try `--shard-split=1` when running multiple flows: `maestro test --shard-split=1 flow1.yaml flow2.yaml -e ...`
3. If the error persists between flows, run each flow as a **separate command**. The app stays logged in between runs (Firebase Auth persists):
```powershell
maestro test apps/mobile/apps/staff/maestro/auth/sign_in.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
maestro test apps/mobile/apps/staff/maestro/compliance/document_upload_banner.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
```
**Client and Staff flows use sign_in-first pattern**
All flows assume `auth/sign_in.yaml` runs first (via Make targets). Flows use `launchApp` and expect the app to be already logged in. Example:
```bash
maestro test apps/mobile/apps/staff/maestro/auth/sign_in.yaml apps/mobile/apps/staff/maestro/compliance/document_upload_banner.yaml -e TEST_STAFF_PHONE=5555551234 -e TEST_STAFF_OTP=123123
```
---
## Checklist
- [ ] Maestro CLI installed
- [ ] Firebase test phone +1 555-555-1234 / 123123 added
- [ ] Client & Staff apps built and installed
- [ ] Env vars exported
- [ ] `make test-e2e-client` or `make test-e2e-staff` run from project root
---
## GitHub Actions
A `.github/workflows/maestro-e2e.yml` workflow runs Maestro E2E on:
- Manual trigger (`workflow_dispatch`)
- PR/push when maestro flows change
**Required secrets** (Repository Settings → Secrets):
- `TEST_STAFF_PHONE`, `TEST_STAFF_OTP`, `TEST_STAFF_SIGNUP_PHONE`
- `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY`
The workflow builds both APKs, starts an Android emulator, installs the apps, and runs auth flows.

View File

@@ -0,0 +1,138 @@
# Manual End-to-End (E2E) Test Report
**Project:** KROW Workforce Mobile Applications (Staff & Client)
**Milestone:** M4
**Document Version:** 1.0
**Date:** March 2, 2026
**Status:** DRAFT *(Pending Execution)*
---
## Table of Contents
1. [Executive Summary](#1-executive-summary)
2. [Test Scope: M4 Features Completed](#2-test-scope-m4-features-completed)
3. [Test Environment & Accounts](#3-test-environment--accounts)
4. [Test Execution Results](#4-test-execution-results)
5. [Defect Summary](#5-defect-summary)
6. [Sign-off & Approvals](#6-sign-off--approvals)
---
## 1. Executive Summary
This document serves as the formal record of manual End-to-End (E2E) testing conducted for all features completed in Milestone 4 (M4) across the KROW Workforce mobile applications. The objective of this testing phase is to thoroughly test all new functionalities manually, ensuring they meet the acceptance criteria and function seamlessly across both iOS and Android platforms prior to client delivery.
---
## 2. Test Scope: M4 Features Completed
The scope of this test cycle includes the core features implemented during the M4 development phase, as outlined in the underlying M4 documentation. Below is the detailed breakdown of the functionality to be validated.
### 2.1 Staff Mobile Application Features
| Feature Name | Description |
| :--- | :--- |
| **Show Google Maps Location in Shift Details** | Navigate to the shift details page and verify the shift location renders correctly on Google Maps. |
| **Show Shift Requirements in Shift Details** | Verify that requirements (such as required attire) are visible to the worker before accepting a shift. |
| **Implement Attire Screen** | Verify the new attire screen lists "Must Have" and "Nice to Have" items. Ensure the image upload flow for attires works and images link to the worker profile. |
| **Implement FAQ Screen** | Verify the FAQ screen is accessible from the appropriate navigation menu and contents display correctly. |
| **Privacy and Security Screen** | Verify the privacy and security screen exists and contains profile visibility options, Terms of Service (TOS), and Privacy Policy. |
| **Restrict Navigation When Profile is Incomplete** | For incomplete profiles, verify that navigation is severely restricted (showing only **Profile** and **Home** screens). |
| **Preferred Location Edit** | Verify workers can navigate to a separate page to edit their preferred working locations. |
| **Maintain Auth Session** | Restart the app after login and verify the worker remains authenticated without being prompted to log in again. |
| **Enable iOS Deployment** | Ensure the iOS build compiles, deploys, and behaves on par with the Android build without platform-specific issues. |
### 2.2 Client Mobile Application Features
| Feature Name | Description |
| :--- | :--- |
| **Hide Edit Icon for Past/Completed Orders** | Verify the edit icon is hidden when viewing orders that are already in the past or have a "Completed" status. |
| **Implement Rapid Order Creation** | Test using voice/text input to rapidly describe a same-day order and verify the one-time order creation screen is populated correctly. |
| **Implement Recurring Order** | Test the complete UI flow to successfully create and submit a recurring order. |
| **Implement Permanent Order** | Test the complete UI flow to successfully create and submit a permanent order. |
| **Update Reorder Modal** | Verify the reorder modal correctly maps fields across one-time, recurring, and permanent order types. |
| **Complete Reports Interface with AI Insights** | Verify the main reports UI shows correct data and generates the 3 required AI insights without using placeholder UI. |
| **Daily Ops Report** | Verify the "Daily Ops" report renders real backend data. |
| **Spend Report** | Verify the "Spend" report renders real backend data. |
| **Coverage Report** | Verify the "Coverage" report renders real backend data. |
| **No-Show Report** | Verify the "No-Show" report renders real backend data. |
| **Performance Report** | Verify the "Performance" report renders real backend data. |
| **Display Hub Details Interface** | Verify there is a dedicated UI page to view Hub Details. |
| **Enable Hub Editing** | Verify Hub Details can be edited successfully on a separate, dedicated view. |
| **Maintain Auth Session** | Restart the app after login and verify the client remains authenticated without being prompted to log in again. |
| **Enable iOS Deployment** | Ensure the iOS build compiles, deploys, and behaves on par with the Android build without platform-specific issues. |
---
## 3. Test Environment & Accounts
### 3.1 Devices under Test
*Testing should be performed on the latest stable releases unless otherwise specified. Test across iOS and Android.*
- **Android Target:** `[Insert Device Model & OS Version]`
- **iOS Target:** `[Insert Device Model & OS Version]`
### 3.2 Key Test Accounts
To thoroughly evaluate the M4 acceptance criteria, the following test data and accounts are required:
**Incomplete Profile Staff Account**
*(Used specifically to validate the "Restrict Navigation When Profile Is Incomplete" feature)*
- **Email / Phone:** `[Fill Out Before Testing]`
- **Password / OTP:** `[Fill Out Before Testing]`
- **Configuration:** This account must bypass completing onboarding profile steps to trigger the mandated restriction constraint on the mobile application interface. If needed, use a backend script/dataconnect command to strip the required profile parameters before testing.
**Standard Client Tester Account**
- **Email / Phone:** `[Fill Out Before Testing]`
- **Password / OTP:** `[Fill Out Before Testing]`
---
## 4. Test Execution Results
*Instructions for QA: Mark status as 'Pass', 'Fail', or 'Blocked'. Device & OS Version should be specified if different from above. Add a ticket link if a defect is found.*
### 4.1 Staff App Execution
| Feature | Pass / Fail | Device & OS Version | Defect / Issue Link | Tester Notes & Edge Cases |
| :--- | :--- | :--- | :--- | :--- |
| Google Maps Location | `[ ]` | | | |
| Shift Requirements | `[ ]` | | | |
| Attire Screen & Upload | `[ ]` | | | |
| FAQ Screen | `[ ]` | | | |
| Privacy and Security | `[ ]` | | | |
| Incomplete Profile Restrictions | `[ ]` | | | |
| Preferred Location Edit | `[ ]` | | | |
| Maintain Auth Session | `[ ]` | | | |
| Enable iOS Deployment | `[ ]` | | | |
### 4.2 Client App Execution
| Feature | Pass / Fail | Device & OS Version | Defect / Issue Link | Tester Notes & Edge Cases |
| :--- | :--- | :--- | :--- | :--- |
| Hide Edit Icon (Past Orders) | `[ ]` | | | |
| Rapid Order Creation | `[ ]` | | | |
| Recurring Order | `[ ]` | | | |
| Permanent Order | `[ ]` | | | |
| Update Reorder Modal | `[ ]` | | | |
| Reports w/ AI Insights | `[ ]` | | | |
| Daily Ops Report | `[ ]` | | | |
| Spend Report | `[ ]` | | | |
| Coverage Report | `[ ]` | | | |
| No-Show Report | `[ ]` | | | |
| Performance Report | `[ ]` | | | |
| Display Hub Details | `[ ]` | | | |
| Enable Hub Editing | `[ ]` | | | |
| Maintain Auth Session | `[ ]` | | | |
| Enable iOS Deployment | `[ ]` | | | |
---
## 5. Defect Summary
All bugs identified during E2E testing must map back to an issue raised in the repository's tracker. Ensure all failed/blocked tests above have a corresponding row here.
| Defect ID / Link | Severity | Feature | Description | Status |
| :--- | :--- | :--- | :--- | :--- |
| `[#XXX](url)` | `[High/Med/Low]` | `[Feature]` | `[Brief description of the bug]` | `[Open]` |
| `[#XXX](url)` | `[High/Med/Low]` | `[Feature]` | `[Brief description of the bug]` | `[Open]` |
*(Add rows as necessary during test execution)*
---
## 6. Sign-off & Approvals
By signing below, the internal testing team confirms that the E2E manual testing for M4 has been executed according to the scope defined in this document, that both the Client and Staff apps have been evaluated, and that all discovered defects have been formally documented.

View File

@@ -0,0 +1,138 @@
# Maestro E2E Conventions (Professional Standard)
This document defines **how we write and maintain Maestro E2E tests** in this repo, so they stay stable, readable, and useful as a regression safety net—**without** relying on fragile patterns.
Applies to:
- Client: `apps/mobile/apps/client/maestro/**`
- Staff: `apps/mobile/apps/staff/maestro/**`
Related:
- Happy-path catalog: `docs/testing/maestro-e2e-happy-paths.md`
- Run guide + troubleshooting: `docs/research/maestro-test-run-instructions.md`
---
## Test taxonomy (what “professional” means here)
We maintain 3 tiers of flows:
- **Smoke (deterministic)**: fast, minimal prerequisites, should pass for a standard test account most of the time.
- Targets: `make test-e2e-client-smoke`, `make test-e2e-staff-smoke`
- **Happy path (business-critical)**: core “golden paths”, may have real-data dependencies (invoices, shifts, etc.).
- Targets: `make test-e2e-client-happy-path`, `make test-e2e-staff-happy-path`
- **Data-dependent / state-change flows**: require seeded data (pending invoice, scheduled shift, pending compliance doc).
- These are valuable but should be explicitly documented as prerequisites.
Rule of thumb:
- If a flow is **time/location/data dependent**, do **not** include it in smoke.
---
## File naming & structure
- **File name**: use verbs + scope + suffix.
- Good: `create_hub_e2e.yaml`, `invoice_approval_e2e.yaml`, `tab_bar_roundtrip.yaml`
- Avoid: `test1.yaml`, `new.yaml`
- **Folders map to product areas**: `auth/`, `navigation/`, `orders/`, `billing/`, `hubs/`, `profile/`, `compliance/`, `shifts/`, `availability/`, `home/`, `payments/`.
---
## YAML header standard (required)
Each flow should start with:
- A short description: **what** and **why**
- **Prerequisites** (if any)
- **Run command** including required env vars
- `appId: ...`
Example header shape (keep short):
```yaml
# Client App — E2E: <Flow Name>
# Purpose: <why this matters>
# Prerequisite: <only if needed>
# Run: maestro test auth/sign_in.yaml <this flow> -e ...
appId: com.krowwithus.client
---
```
---
## Selector strategy (stability rules)
Priority order:
1. **`id:` selectors** (best)
2. **Accessible text labels** that are stable (good)
3. **Coordinates / `point:`** (last resort; document why)
If you must use coordinates:
- Prefer *relative* safe coordinates inside a stable container (not global corners).
- Add a comment explaining what UI element it targets and why theres no better selector.
---
## Waiting strategy (reduce flakes)
Use explicit waits around network UI and animations:
- Prefer `extendedWaitUntil` for content that depends on API/network.
- Use `waitForAnimationToEnd` after navigation transitions.
- Avoid long fixed sleeps; wait for a **specific UI marker**.
Guideline timeouts:
- 1015s typical
- 20s only when you know the call is slow (uploads, approvals)
---
## Assertions (what “comprehensive” should mean)
Every flow should have:
- **Entry assertion**: confirms you are on the expected starting screen (e.g., `assertVisible: "Home"`).
- **Critical path assertions**: confirm key steps actually happened (not just taps).
- **Exit assertion**: confirms the expected final state (success message, returned screen, etc.).
Avoid “silent passes” where taps happen but no success state is asserted.
---
## Data prerequisites (must be explicit)
If a flow needs data:
- Document it in the YAML header and in `docs/testing/maestro-e2e-happy-paths.md`.
- Prefer using a dedicated “test account” with predictable fixtures.
Examples in this repo:
- Client invoice approval requires “Awaiting Approval” invoices.
- Staff clock-in/out requires an active shift and location constraints.
- Staff document upload requires pushing `fixture.pdf` to the device.
---
## Fixtures & helper scripts
If a flow needs a file fixture:
- Put it alongside the flow (e.g. `compliance/fixture.pdf`).
- Provide a script to push it to the emulator/device.
Current helper scripts:
- `apps/mobile/apps/staff/maestro/compliance/push_fixture.sh`
- `apps/mobile/apps/staff/maestro/compliance/push_upload_fixture.sh` (compat wrapper)
---
## Suite composition rules
Professional suites should:
- Start with a **single** `sign_in.yaml`
- Prefer sequential execution: `--shard-split=1` (already defaulted)
- Avoid mixing flows that fight over navigation state unless theyre designed to run back-to-back
Recommended usage:
- Developers run **smoke** on local changes.
- QA runs **happy path** before release.

View File

@@ -0,0 +1,118 @@
# Maestro E2E Happy Path & Extended Coverage Test Cases
This document describes the End-to-End (E2E) test cases for the KROW mobile applications (Client and Staff), implemented with [Maestro](https://maestro.mobile.dev/). It supports **ticket #572** (Happy Paths) and **ticket #636** (Extended Coverage, Negative Paths, and Structural Refactor).
## Overview
| Item | Description |
|------|-------------|
| **Framework** | Maestro |
| **Apps** | Client (`com.krowwithus.client`), Staff (`com.krowwithus.staff`) |
| **Structure** | Organized by Feature → Scenario Type (Happy Path, Smoke, Negative, Edge Cases) |
| **Total Flows** | 93 (47 Client, 46 Staff) |
| **Run locally** | See [How to run](#how-to-run) and [docs/research/maestro-test-run-instructions.md](../research/maestro-test-run-instructions.md) |
## Prerequisites
- **Maestro CLI** installed ([Install guide](../research/maestro-test-run-instructions.md#1-install-maestro-cli))
- **Firebase test phone** for Staff app (e.g. +1 555-555-1234 / OTP 123123)
- **Client & Staff APKs** built and installed on device/emulator
- **Env variables** set for credentials (never hardcode; see [Credentials](#credentials))
## Credentials
| App | Flow | Env variables |
|-----|------|----------------|
| Client | sign_in / sign_up | `TEST_CLIENT_EMAIL`, `TEST_CLIENT_PASSWORD`, `TEST_CLIENT_COMPANY` (sign_up only) |
| Staff | sign_in / sign_up | `TEST_STAFF_PHONE`, `TEST_STAFF_OTP`, `TEST_STAFF_SIGNUP_PHONE` (sign_up only) |
Example (Powershell):
`$env:TEST_CLIENT_EMAIL="testclient@gmail.com"; $env:TEST_CLIENT_PASSWORD="testclient!"`
`$env:TEST_STAFF_PHONE="5555551234"; $env:TEST_STAFF_OTP="123123"`
---
## Client App — Test Cases
All client flows assume the app is **not** logged in at start unless noted.
### Auth
| ID | Test | Purpose | Path |
|----|------|----------|------------|
| C-AUTH-1 | **sign_in** | Verify user can sign in | `auth/happy_path/sign_in.yaml` |
| C-AUTH-2 | **sign_up** | Verify new client registration | `auth/happy_path/sign_up.yaml` |
| C-AUTH-3 | **sign_out** | Verify user can log out | `auth/happy_path/sign_out.yaml` |
| C-AUTH-N | **sign_in_invalid** | Negative: invalid password | `auth/negative/sign_in_invalid_password.yaml` |
### Navigation (Smoke)
| ID | Test | Purpose | Path |
|----|------|----------|------------|
| C-NAV-1 | **home** | Home tab loads | `navigation/smoke/home.yaml` |
| C-NAV-2 | **orders** | Orders tab opens | `navigation/smoke/orders.yaml` |
| C-NAV-3 | **billing** | Billing tab opens | `navigation/smoke/billing.yaml` |
| C-NAV-4 | **coverage** | Coverage tab opens | `navigation/smoke/coverage.yaml` |
| C-NAV-5 | **reports** | Reports tab opens | `navigation/smoke/reports.yaml` |
### Orders
| ID | Test | Purpose | Path |
|----|------|----------|------------|
| C-ORD-1 | **view_orders** | Orders list loads | `orders/happy_path/view_orders.yaml` |
| C-ORD-2 | **create_order_one_time** | Full flow: create order | `orders/happy_path/create_order_one_time_e2e.yaml` |
| C-ORD-3 | **orders_empty_state** | Edge: verify empty tabs | `orders/edge_cases/orders_empty_state.yaml` |
| C-ORD-4 | **validation_errors** | Negative: required fields | `orders/negative/create_order_validation_errors.yaml` |
---
## Staff App — Test Cases
### Auth
| ID | Test | Purpose | Path |
|----|------|----------|------------|
| S-AUTH-1 | **sign_in** | Staff signs in with phone | `auth/happy_path/sign_in.yaml` |
| S-AUTH-2 | **sign_up** | New staff registers | `auth/happy_path/sign_up.yaml` |
| S-AUTH-3 | **sign_out** | Staff logs out | `auth/happy_path/sign_out.yaml` |
### Shifts
| ID | Test | Purpose | Path |
|----|------|----------|------------|
| S-SHF-1 | **find_shifts** | Find shifts list loads | `shifts/happy_path/find_shifts.yaml` |
| S-SHF-2 | **clock_in_e2e** | Clock in workflow | `shifts/happy_path/clock_in_e2e.yaml` |
| S-SHF-3 | **shifts_empty** | Edge: no shifts found | `shifts/edge_cases/shifts_empty_state.yaml` |
---
## How to run
### Make targets (Recommended)
| Target | Description |
|--------|-------------|
| `make test-e2e-setup` | Check Maestro CLI installation |
| `make test-e2e-client-auth` | Client: Sign In, Sign Up, Invalid Password |
| `make test-e2e-client-orders-negative`| Client: Form validation errors + empty states |
| `make test-e2e-staff-compliance-full` | Staff: Banners + Doc/Cert/Attire upload E2E |
### Windows Stability Note
If you encounter `java.io.IOException: Command failed (tcp:7001): closed`, it is due to ADB connection instability on Windows. Fix:
1. **Restart Emulator** software.
2. Use `--shard-split=1` (default in Makefile).
3. Ensure timeouts are set to at least 45000ms.
## CI/CD
E2E runs in GitHub Actions: [.github/workflows/maestro-e2e.yml](../../.github/workflows/maestro-e2e.yml).
**Trigger Change:** Automated triggers (push/PR) have been **disabled** to conserve free-tier build minutes. The workflow MUST be triggered manually via the "Actions" tab.
---
## References
- [Maestro Documentation](https://maestro.mobile.dev/)
- [Maestro Test Run Instructions](../research/maestro-test-run-instructions.md)
- [Project Makefile](../../makefiles/mobile.mk)