# KROW Workforce API Specification (Legacy Reference)

> [!WARNING]
> **Status: LEGACY / ARCHIVED REFERENCE**
> This document is based on a historical export from the Base44 platform. 
> It is maintained in this repository solely for reference purposes during the rebuild and is **not** to be considered the definitive or active API specification for the production system.
> The historical V1 Data Connect schemas and operations now live in `legacy/dataconnect-v1/`.
> The active V2 backend source of truth is the unified/backend service stack under `backend/command-api`, `backend/query-api`, `backend/core-api`, and `backend/unified-api`.

**Original Version:** 3.0  
**Original Date:** 2025-11-20  
**Objective:** This document defines the backend API to be built on the Firebase/GCP ecosystem, replacing the Base44 backend. It is based on the comprehensive Base44 API documentation (v3.0) and will guide the development of the new backend using Firebase Data Connect and Cloud Functions.

---

## Table of Contents
1. [General Conventions](#1-general-conventions)
2. [Authentication](#2-authentication-firebase-auth)
3. [Data API (Firebase Data Connect)](#3-data-api-firebase-data-connect)
4. [Services API (Cloud Functions)](#4-services-api-cloud-functions)
5. [Security & Access Control](#5-security--access-control)
6. [Migration Notes from v2.0](#6-migration-notes-from-v20)
7. [Implementation Priority](#7-implementation-priority)

---

## 1. General Conventions

### API Architecture
The backend will be composed of two main layers:

1. **Firebase Data Connect (GraphQL):** For all data-centric (CRUD) operations
2. **Cloud Functions (REST/HTTP):** For all service-centric operations (emails, AI, file processing)

### Common Standards

-   **Authentication:** Every request must include `Authorization: Bearer <Firebase-Auth-Token>` header
-   **Data Format:** All requests/responses use `application/json` (except file uploads: `multipart/form-data`)
-   **Error Responses:** Standard HTTP status codes with JSON body:
    ```json
    {
      "error": "Error description",
      "code": "ERROR_CODE",
      "details": {} // Optional additional context
    }
    ```
-   **Common Entity Fields:** Auto-managed by backend:
    ```javascript
    {
      "id": "string (UUID)",
      "created_date": "ISO 8601 timestamp",
      "updated_date": "ISO 8601 timestamp",
      "created_by": "string (user email)"
    }
    ```

### GraphQL Conventions

-   **Queries:** `list<Entity>`, `get<Entity>ById`, `filter<Entity>`
-   **Mutations:** `create<Entity>`, `update<Entity>`, `delete<Entity>`, `bulkCreate<Entity>`
-   **Filtering:** Support operators: `$eq`, `$gte`, `$lte`, `$in`, `$contains`
-   **Sorting:** Prefix with `-` for descending (e.g., `-created_date`)
-   **Pagination:** `limit` and `offset` parameters

---

## 2. Authentication (Firebase Auth)

Authentication is handled entirely by **Firebase Authentication**. Client applications manage sign-up/sign-in flows using Firebase SDK. The backend validates auth tokens for all requests.

### User Entity (Managed by Firebase Auth & Data Connect)

| Field        | Type     | Description                                      | Validation            |
| ------------ | -------- | ------------------------------------------------ | --------------------- |
| `id`         | `string` | Firebase User ID (UID)                           | Auto-generated        |
| `email`      | `string` | User's email                                     | Required, unique      |
| `full_name`  | `string` | Full name                                        | Required              |
| `role`       | `string` | Base role                                        | Enum: `admin`, `user` |
| `user_role`  | `string` | Custom application role                          | Optional              |

**Security Rules:**
- Only admin users can list/update/delete other users
- Regular users can only view/update their own record
- Enforced at Firebase Data Connect rule level

---

## 3. Data API (Firebase Data Connect)

All entities will be managed via GraphQL API powered by Firebase Data Connect. Schema definitions will be in `firebase/dataconnect/schema/` directory.

### 3.1. Event Entity

**Description:** Core event/order management with multi-day support and conflict detection.

#### Schema Definition

| Field                        | Type      | Description                                   | Validation                              |
| ---------------------------- | --------- | --------------------------------------------- | --------------------------------------- |
| `event_name`                 | `string`  | Name of the event                             | Required                                |
| `is_rapid`                   | `boolean` | RAPID/urgent order flag                       | Default: false                          |
| `is_recurring`               | `boolean` | Whether event recurs                          | Default: false                          |
| `is_multi_day`               | `boolean` | Multi-day event flag                          | Default: false                          |
| `recurrence_type`            | `string`  | Type of recurrence                            | Enum: `single`, `date_range`, `scatter` |
| `recurrence_start_date`      | `string`  | Start date for recurring events               | ISO 8601 date                           |
| `recurrence_end_date`        | `string`  | End date for recurring events                 | ISO 8601 date                           |
| `scatter_dates`              | `jsonb`   | Specific dates for scatter recurring          | Array of ISO 8601 dates                 |
| `multi_day_start_date`       | `string`  | Multi-day start date                          | ISO 8601 date                           |
| `multi_day_end_date`         | `string`  | Multi-day end date                            | ISO 8601 date                           |
| `buffer_time_before`         | `number`  | Buffer time before (minutes)                  | Default: 0, Min: 0                      |
| `buffer_time_after`          | `number`  | Buffer time after (minutes)                   | Default: 0, Min: 0                      |
| `conflict_detection_enabled` | `boolean` | Enable conflict detection                     | Default: true                           |
| `detected_conflicts`         | `jsonb`   | Array of detected conflicts                   | See conflict structure below            |
| `business_id`                | `string`  | Associated business ID                        | Foreign key → Business                  |
| `business_name`              | `string`  | Business name                                 | -                                       |
| `vendor_id`                  | `string`  | Vendor ID if created by vendor                | Foreign key → Vendor                    |
| `vendor_name`                | `string`  | Vendor name                                   | -                                       |
| `hub`                        | `string`  | Hub location                                  | -                                       |
| `event_location`             | `string`  | Event location address                        | -                                       |
| `contract_type`              | `string`  | Contract type                                 | Enum: `W2`, `1099`, `Temp`, `Contract`  |
| `po_reference`               | `string`  | Purchase order reference                      | -                                       |
| `status`                     | `string`  | Event status                                  | Enum: `Draft`, `Active`, `Pending`, `Assigned`, `Confirmed`, `Completed`, `Canceled` |
| `date`                       | `string`  | Event date                                    | ISO 8601 date                           |
| `shifts`                     | `jsonb`   | Array of shift objects                        | See shift structure below               |
| `addons`                     | `jsonb`   | Additional services/features                  | Object                                  |
| `total`                      | `number`  | Total cost                                    | Min: 0                                  |
| `client_name`                | `string`  | Client contact name                           | -                                       |
| `client_email`               | `string`  | Client email                                  | Email format                            |
| `client_phone`               | `string`  | Client phone                                  | -                                       |
| `invoice_id`                 | `string`  | Associated invoice ID                         | Foreign key → Invoice                   |
| `notes`                      | `string`  | Additional notes                              | -                                       |
| `requested`                  | `number`  | Total staff requested                         | Default: 0, Min: 0                      |
| `assigned_staff`             | `jsonb`   | Array of assigned staff                       | See assigned staff structure below      |

#### Nested Structures

**Detected Conflicts Structure:**
```json
{
  "conflict_type": "staff_overlap | venue_overlap | time_buffer",
  "severity": "low | medium | high | critical",
  "description": "string",
  "conflicting_event_id": "string",
  "staff_id": "string (optional)",
  "detected_at": "ISO 8601 timestamp"
}
```

**Shift Structure:**
```json
{
  "shift_name": "string",
  "shift_contact": "string",
  "location_address": "string",
  "roles": [
    {
      "role": "string",
      "department": "string",
      "count": "number",
      "start_time": "string (HH:MM)",
      "end_time": "string (HH:MM)",
      "hours": "number",
      "uniform": "string",
      "break_minutes": "number",
      "cost_per_hour": "number",
      "total_value": "number",
      "vendor_name": "string",
      "vendor_id": "string"
    }
  ]
}
```

**Assigned Staff Structure:**
```json
{
  "staff_id": "string",
  "staff_name": "string",
  "role": "string",
  "confirmed": "boolean"
}
```

#### GraphQL Operations

```graphql
# Queries
query ListEvents($limit: Int, $offset: Int, $orderBy: String) {
  listEvents(limit: $limit, offset: $offset, orderBy: $orderBy) {
    id
    event_name
    status
    date
    # ... all fields
  }
}

query GetEventById($id: ID!) {
  getEventById(id: $id) {
    id
    event_name
    # ... all fields
  }
}

query FilterEvents($filter: EventFilterInput!, $orderBy: String, $limit: Int) {
  filterEvents(filter: $filter, orderBy: $orderBy, limit: $limit) {
    id
    event_name
    # ... all fields
  }
}

# Mutations
mutation CreateEvent($input: CreateEventInput!) {
  createEvent(input: $input) {
    id
    event_name
    # ... all fields
  }
}

mutation UpdateEvent($id: ID!, $input: UpdateEventInput!) {
  updateEvent(id: $id, input: $input) {
    id
    event_name
    # ... all fields
  }
}

mutation DeleteEvent($id: ID!) {
  deleteEvent(id: $id) {
    success
    message
  }
}
```

---

### 3.2. Staff Entity

**Description:** Employee/workforce member management.

#### Schema Definition

| Field                      | Type      | Description                      | Validation                                |
| -------------------------- | --------- | -------------------------------- | ----------------------------------------- |
| `employee_name`            | `string`  | Full name                        | Required                                  |
| `vendor_id`                | `string`  | Associated vendor ID             | Foreign key → Vendor                      |
| `vendor_name`              | `string`  | Vendor company name              | -                                         |
| `manager`                  | `string`  | Manager's name                   | -                                         |
| `contact_number`           | `string`  | Primary contact number           | -                                         |
| `email`                    | `string`  | Email address                    | Email format                              |
| `department`               | `string`  | Department                       | Enum: `Operations`, `Sales`, `HR`, `Finance`, `IT`, `Marketing`, `Customer Service`, `Logistics` |
| `hub_location`             | `string`  | Hub/office location              | -                                         |
| `track`                    | `string`  | Track information                | -                                         |
| `position`                 | `string`  | Primary job position/skill       | -                                         |
| `profile_type`             | `string`  | Skill profile level              | Enum: `Skilled`, `Beginner`, `Cross-Trained` |
| `employment_type`          | `string`  | Employment type                  | Enum: `Full Time`, `Part Time`, `On call`, `Weekends`, `Specific Days`, `Seasonal`, `Medical Leave` |
| `english`                  | `string`  | English proficiency              | Enum: `Fluent`, `Intermediate`, `Basic`, `None` |
| `rating`                   | `number`  | Performance rating (0-5 stars)   | Min: 0, Max: 5                            |
| `reliability_score`        | `number`  | Overall reliability score        | Min: 0, Max: 100                          |
| `background_check_status`  | `string`  | Background check status          | Enum: `pending`, `cleared`, `failed`, `expired`, `not_required` |

**Note:** Many fields from v2.0 have been removed (phone, address, city, position_2, certifications array, etc.). See migration notes.

#### GraphQL Operations

```graphql
query ListStaff($limit: Int, $offset: Int, $orderBy: String) {
  listStaff(limit: $limit, offset: $offset, orderBy: $orderBy) {
    id
    employee_name
    rating
    # ... all fields
  }
}

query FilterStaff($filter: StaffFilterInput!) {
  filterStaff(filter: $filter) {
    id
    employee_name
    # ... all fields
  }
}

mutation CreateStaff($input: CreateStaffInput!) {
  createStaff(input: $input) {
    id
    employee_name
    # ... all fields
  }
}

mutation BulkCreateStaff($inputs: [CreateStaffInput!]!) {
  bulkCreateStaff(inputs: $inputs) {
    id
    employee_name
  }
}
```

---

### 3.3. Vendor Entity

**Description:** Vendor/supplier management (simplified in v3.0).

#### Schema Definition

| Field                    | Type      | Description                      | Validation                          |
| ------------------------ | --------- | -------------------------------- | ----------------------------------- |
| `vendor_number`          | `string`  | Vendor Number (VN-####)          | Required, Pattern: `^VN-[0-9]{4}$`  |
| `legal_name`             | `string`  | Legal business name              | Required                            |
| `region`                 | `string`  | Geographic region                | Enum: `National`, `Bay Area`, `Southern California`, `Northern California`, `West`, `East`, `Midwest`, `South` |
| `platform_type`          | `string`  | Technology integration level     | Enum: `Full Platform`, `Building platform (KROW)`, `Partial Tech`, `Traditional` |
| `primary_contact_email`  | `string`  | Primary email                    | Required, Email format              |
| `approval_status`        | `string`  | Vendor approval status           | Enum: `pending`, `approved`, `suspended`, `terminated` |
| `is_active`              | `boolean` | Is vendor currently active       | Default: true                       |

**Note:** Significantly simplified from v2.0 (removed 20+ fields). Store additional vendor details in a separate `VendorDetails` entity if needed.

---

### 3.4. VendorRate Entity

**Description:** Vendor pricing and rate management (simplified in v3.0).

#### Schema Definition

| Field                     | Type      | Description                 | Validation                          |
| ------------------------- | --------- | --------------------------- | ----------------------------------- |
| `vendor_name`             | `string`  | Vendor name                 | Required                            |
| `category`                | `string`  | Service category            | Enum: `Kitchen and Culinary`, `Concessions`, `Facilities`, `Bartending`, `Security`, `Event Staff`, `Management`, `Technical`, `Other` |
| `role_name`               | `string`  | Role/position name          | Required                            |
| `employee_wage`           | `number`  | Employee base wage/hour     | Required, Min: 0                    |
| `markup_percentage`       | `number`  | Markup percentage           | Min: 0, Max: 100                    |
| `vendor_fee_percentage`   | `number`  | Vendor fee percentage       | Min: 0, Max: 100                    |
| `client_rate`             | `number`  | Final rate to client        | Required, Min: 0                    |

---

### 3.5. VendorDefaultSettings Entity (NEW in v3.0)

**Description:** Default markup and fee settings for vendors.

#### Schema Definition

| Field                            | Type      | Description                      | Validation              |
| -------------------------------- | --------- | -------------------------------- | ----------------------- |
| `vendor_name`                    | `string`  | Name of the vendor               | Required                |
| `default_markup_percentage`      | `number`  | Default markup percentage        | Required, Min: 0, Max: 100 |
| `default_vendor_fee_percentage`  | `number`  | Default vendor fee percentage    | Required, Min: 0, Max: 100 |

---

### 3.6. Invoice Entity

**Description:** Invoice and billing management with dispute tracking.

#### Schema Definition

| Field              | Type      | Description                      | Validation                          |
| ------------------ | --------- | -------------------------------- | ----------------------------------- |
| `invoice_number`   | `string`  | Unique invoice number            | Required                            |
| `amount`           | `number`  | Grand total invoice amount       | Required, Min: 0                    |
| `status`           | `string`  | Current invoice status           | Enum: `Draft`, `Pending Review`, `Approved`, `Disputed`, `Under Review`, `Resolved`, `Overdue`, `Paid`, `Reconciled`, `Cancelled` |
| `issue_date`       | `string`  | Invoice issue date               | Required, ISO 8601 date             |
| `due_date`         | `string`  | Payment due date                 | Required, ISO 8601 date             |
| `disputed_items`   | `jsonb`   | List of disputed staff entry indices | Array of numbers                    |
| `is_auto_generated`| `boolean` | Whether invoice was auto-generated | Default: false                      |

**⚠️ BREAKING CHANGE:** Status enum values have changed from v2.0. Migration required.

**Removed fields from v2.0:** manager_name, hub, cost_center, event_id, event_name, vendor_name, item_count, paid_date, payment_method, notes

---

### 3.7. Business Entity

**Description:** Client business/company management (simplified in v3.0).

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `business_name`  | `string`  | Business/client company name| Required                            |
| `contact_name`   | `string`  | Primary contact person      | Required                            |
| `email`          | `string`  | Business email              | Email format                        |
| `sector`         | `string`  | Sector/industry             | Enum: `Bon Appétit`, `Eurest`, `Aramark`, `Epicurean Group`, `Chartwells`, `Other` |
| `rate_group`     | `string`  | Pricing tier                | Required, Enum: `Standard`, `Premium`, `Enterprise`, `Custom` |
| `status`         | `string`  | Business status             | Enum: `Active`, `Inactive`, `Pending` |

**Removed fields from v2.0:** company_logo, phone, hub_building, address, city, area, notes

---

### 3.8. Certification Entity

**Description:** Employee certification and compliance tracking (simplified in v3.0).

#### Schema Definition

| Field                  | Type      | Description                 | Validation                          |
| ---------------------- | --------- | --------------------------- | ----------------------------------- |
| `employee_name`        | `string`  | Staff member name           | Required                            |
| `certification_name`   | `string`  | Certification name          | Required                            |
| `certification_type`   | `string`  | Type of certification       | Enum: `Legal`, `Operational`, `Safety`, `Training`, `License`, `Other` |
| `status`               | `string`  | Current status              | Enum: `current`, `expiring_soon`, `expired`, `pending_validation` |
| `expiry_date`          | `string`  | Expiration date             | Required, ISO 8601 date             |
| `validation_status`    | `string`  | Validation status           | Enum: `approved`, `pending_expert_review`, `rejected`, `ai_verified`, `ai_flagged`, `manual_review_needed` |

**Removed fields from v2.0:** employee_id, vendor_id, vendor_name, issue_date, issuer, certificate_number, document_url, ai_validation_result, validated_by, validated_date, is_required_for_role, days_until_expiry, alert_sent, notes

---

### 3.9. Team Entity

**Description:** Team and organization management with role-based isolation.

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `team_name`      | `string`  | Name of the team            | Required                            |
| `owner_id`       | `string`  | Team owner user ID          | Required, Foreign key → User        |
| `owner_name`     | `string`  | Team owner name             | Required                            |
| `owner_role`     | `string`  | Role of team owner          | Required, Enum: `admin`, `procurement`, `operator`, `sector`, `client`, `vendor`, `workforce` |
| `favorite_staff` | `jsonb`   | Array of favorite staff     | Array of staff objects              |
| `blocked_staff`  | `jsonb`   | Array of blocked staff      | Array of staff objects              |

**Security Note:** Complete data isolation across organizational layers enforced via `owner_id` filtering.

**Removed fields from v2.0:** company_logo, full_name, email, phone, address, city, zip_code, vendor_id, departments, total_members, active_members, total_hubs, favorite_staff_count, blocked_staff_count

---

### 3.10. TeamMember Entity (NEW in v3.0)

**Description:** Team member management within teams.

#### Schema Definition

| Field          | Type      | Description                      | Validation                          |
| -------------- | --------- | -------------------------------- | ----------------------------------- |
| `team_id`      | `string`  | ID of the team                   | Required, Foreign key → Team        |
| `member_name`  | `string`  | Name of the team member          | Required                            |
| `email`        | `string`  | Member email                     | Required, Email format              |
| `role`         | `string`  | Role in the team                 | Enum: `admin`, `manager`, `member`, `viewer` |
| `is_active`    | `boolean` | Whether the member is active     | Default: true                       |

---

### 3.11. TeamHub Entity (NEW in v3.0)

**Description:** Team hub/location management.

#### Schema Definition

| Field          | Type      | Description                      | Validation                          |
| -------------- | --------- | -------------------------------- | ----------------------------------- |
| `team_id`      | `string`  | ID of the team                   | Required, Foreign key → Team        |
| `hub_name`     | `string`  | Name of the hub/location         | Required                            |
| `departments`  | `jsonb`   | Departments within this hub      | Array of objects: `{department_name, cost_center}` |

---

### 3.12. TeamMemberInvite Entity (NEW in v3.0)

**Description:** Team member invitation management.

#### Schema Definition

| Field           | Type      | Description                 | Validation                          |
| --------------- | --------- | --------------------------- | ----------------------------------- |
| `team_id`       | `string`  | Team ID                     | Required, Foreign key → Team        |
| `invite_code`   | `string`  | Unique invite code          | Required, Auto-generated UUID       |
| `email`         | `string`  | Invitee email               | Required, Email format              |
| `invite_status` | `string`  | Invite status               | Enum: `pending`, `accepted`, `expired`, `cancelled` |

---

### 3.13. Conversation Entity

**Description:** Messaging and communication management (simplified in v3.0).

#### Schema Definition

| Field               | Type      | Description                 | Validation                          |
| ------------------- | --------- | --------------------------- | ----------------------------------- |
| `participants`      | `jsonb`   | Array of participant IDs/emails | Required, Array of strings          |
| `conversation_type` | `string`  | Type of conversation        | Required, Enum: `client-vendor`, `staff-client`, `staff-admin`, `vendor-admin`, `client-admin`, `group-staff`, `group-event-staff` |
| `related_to`        | `string`  | ID of related entity        | Foreign key (generic)               |
| `status`            | `string`  | Conversation status         | Enum: `active`, `archived`, `closed` |

**Removed fields from v2.0:** is_group, group_name, related_type, subject, last_message, last_message_at, unread_count

---

### 3.14. Message Entity

**Description:** Individual messages within conversations (simplified in v3.0).

#### Schema Definition

| Field              | Type      | Description                      | Validation                          |
| ------------------ | --------- | -------------------------------- | ----------------------------------- |
| `conversation_id`  | `string`  | ID of the conversation           | Required, Foreign key → Conversation|
| `sender_name`      | `string`  | Name of the sender               | Required                            |
| `content`          | `string`  | Message content                  | Required                            |
| `read_by`          | `jsonb`   | User IDs who have read           | Array of strings                    |

**Removed fields from v2.0:** sender_id, sender_role, attachments

---

### 3.15. ActivityLog Entity

**Description:** Activity and notification tracking (simplified in v3.0).

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `title`          | `string`  | Notification title          | Required                            |
| `description`    | `string`  | Detailed description        | Required                            |
| `activity_type`  | `string`  | Type of activity            | Required, Enum: `event_created`, `event_updated`, `staff_assigned`, `invoice_paid`, etc. |
| `user_id`        | `string`  | User this is for            | Required, Foreign key → User        |
| `is_read`        | `boolean` | Read status                 | Default: false                      |

**Removed fields from v2.0:** related_entity_type, related_entity_id, action_link, action_label, icon_type, icon_color

---

### 3.16. Enterprise Entity

**Description:** Enterprise organization management (unchanged from v2.0).

#### Schema Definition

| Field                | Type      | Description                 | Validation                          |
| -------------------- | --------- | --------------------------- | ----------------------------------- |
| `enterprise_number`  | `string`  | Enterprise Number (EN-####) | Required, Pattern: `^EN-[0-9]{4}$`  |
| `enterprise_name`    | `string`  | Enterprise name             | Required                            |
| `enterprise_code`    | `string`  | Short code identifier       | Required                            |

---

### 3.17. Sector Entity

**Description:** Sector/branch management (unchanged from v2.0).

#### Schema Definition

| Field          | Type      | Description                 | Validation                          |
| -------------- | --------- | --------------------------- | ----------------------------------- |
| `sector_number`| `string`  | Sector Number (SN-####)     | Required, Pattern: `^SN-[0-9]{4}$`  |
| `sector_name`  | `string`  | Sector/brand name           | Required                            |
| `sector_type`  | `string`  | Sector business type        | Enum: `Food Service`, `Facilities`, `Healthcare`, `Education`, `Corporate`, `Sports & Entertainment` |

---

### 3.18. Partner Entity

**Description:** Partner/client organization management (unchanged from v2.0).

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `partner_name`   | `string`  | Partner/client name         | Required                            |
| `partner_number` | `string`  | Partner Number (PN-####)    | Required, Pattern: `^PN-[0-9]{4}$`  |
| `partner_type`   | `string`  | Partner type                | Enum: `Corporate`, `Education`, `Healthcare`, `Sports & Entertainment`, `Government` |

---

### 3.19. Order Entity

**Description:** Order management system (unchanged from v2.0).

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `order_number`   | `string`  | Order Number (ORD-####)     | Required, Pattern: `^ORD-[0-9]{4,6}$` |
| `partner_id`     | `string`  | Partner/Client ID           | Required, Foreign key → Partner     |
| `order_type`     | `string`  | Type of order               | Enum: `Standard`, `Last Minute`, `Emergency`, `Recurring` |
| `order_status`   | `string`  | Order status                | Enum: `Draft`, `Submitted`, `Confirmed`, `In Progress`, `Completed`, `Cancelled` |

---

### 3.20. Shift Entity

**Description:** Shift scheduling and management (unchanged from v2.0).

#### Schema Definition

| Field            | Type      | Description                 | Validation                          |
| ---------------- | --------- | --------------------------- | ----------------------------------- |
| `shift_name`     | `string`  | Name of the shift           | Required                            |
| `start_date`     | `string`  | Shift start date/time       | Required, ISO 8601 timestamp        |
| `end_date`       | `string`  | Shift end date/time         | ISO 8601 timestamp                  |
| `assigned_staff` | `jsonb`   | List of assigned staff      | Array of objects                    |

---

### 3.21. Assignment Entity (NEW in v3.0)

**Description:** Worker assignment and tracking.

#### Schema Definition

| Field                | Type      | Description                 | Validation                          |
| -------------------- | --------- | --------------------------- | ----------------------------------- |
| `assignment_number`  | `string`  | Assignment Number (ASN-####)| Pattern: `^ASN-[0-9]{4,6}$`         |
| `order_id`           | `string`  | Associated order ID         | Required, Foreign key → Order       |
| `workforce_id`       | `string`  | Assigned worker ID          | Required, Foreign key → Workforce   |
| `vendor_id`          | `string`  | Vendor providing the worker | Required, Foreign key → Vendor      |
| `role`               | `string`  | Role assigned               | Required                            |
| `assignment_status`  | `string`  | Assignment status           | Enum: `Pending`, `Confirmed`, `Checked In`, `In Progress`, `Completed`, `Cancelled`, `No Show` |
| `scheduled_start`    | `string`  | Scheduled start time        | Required, ISO 8601 timestamp        |

---

### 3.22. Workforce Entity (NEW in v3.0)

**Description:** Worker/contractor management.

#### Schema Definition

| Field              | Type      | Description                 | Validation                          |
| ------------------ | --------- | --------------------------- | ----------------------------------- |
| `workforce_number` | `string`  | Worker Number (WF-####)     | Required, Pattern: `^WF-[0-9]{4,6}$`|
| `vendor_id`        | `string`  | Vendor who manages worker   | Required, Foreign key → Vendor      |
| `first_name`       | `string`  | Worker first name           | Required                            |
| `last_name`        | `string`  | Worker last name            | Required                            |
| `employment_type`  | `string`  | Employment classification   | Enum: `W2`, `1099`, `Temporary`, `Contract` |

---

## 4. Services API (Cloud Functions)

These endpoints are for service-oriented tasks, not CRUD operations. Each will be implemented as an individual HTTP-triggered Cloud Function.

### 4.1. Send Email

**Endpoint:** `POST /sendEmail`  
**Description:** Sends an email via SendGrid or similar service.

**Request Body:**
```json
{
  "to": "recipient@example.com",
  "subject": "Email Subject",
  "body": "<h1>HTML Email Body</h1>",
  "from_name": "KROW Workforce" // Optional
}
```

**Response (200 OK):**
```json
{
  "status": "sent",
  "message_id": "msg_123456"
}
```

**Error Response (400/500):**
```json
{
  "error": "Failed to send email",
  "code": "EMAIL_SEND_FAILED",
  "details": {
    "reason": "Invalid recipient email"
  }
}
```

**Implementation Notes:**
- Use SendGrid API or Firebase Extensions for email
- Validate email format before sending
- Log all email sends to ActivityLog
- Implement rate limiting (1000 emails/day per user)

---

### 4.2. Invoke LLM

**Endpoint:** `POST /invokeLLM`  
**Description:** Calls Vertex AI (Gemini) for AI-powered responses.

**Request Body:**
```json
{
  "prompt": "Analyze this event and recommend staff...",
  "add_context_from_internet": false,
  "response_json_schema": {
    "type": "object",
    "properties": {
      "recommendations": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "staff_id": { "type": "string" },
            "score": { "type": "number" },
            "reasoning": { "type": "string" }
          }
        }
      }
    }
  },
  "file_urls": [] // Optional
}
```

**Response (200 OK):**
```json
{
  "result": {
    "recommendations": [
      {
        "staff_id": "stf_123",
        "score": 0.95,
        "reasoning": "High rating and reliability..."
      }
    ]
  }
}
```

**Implementation Notes:**
- Use Vertex AI Gemini 1.5 Pro or Flash
- Support structured output via JSON schema
- Implement context from Google Search if `add_context_from_internet` is true
- Support file analysis (PDFs, images) via `file_urls`
- Rate limit: 100 requests/minute per user
- Cache common requests for 5 minutes

---

### 4.3. Upload File (Public)

**Endpoint:** `POST /uploadFile`  
**Description:** Uploads a file to Google Cloud Storage (public bucket) and returns public URL.

**Request:** `multipart/form-data`
```
Content-Type: multipart/form-data
file: [binary file data]
```

**Response (200 OK):**
```json
{
  "file_url": "https://storage.googleapis.com/krow-public/files/abc123.pdf"
}
```

**Implementation Notes:**
- Upload to public GCS bucket with public-read ACL
- Generate unique filename with UUID
- Validate file type and size (max 100 MB)
- Return public HTTPS URL
- Support image compression/optimization for images

---

### 4.4. Upload Private File

**Endpoint:** `POST /uploadPrivateFile`  
**Description:** Uploads a file to Google Cloud Storage (private bucket) and returns secure URI.

**Request:** `multipart/form-data`
```
Content-Type: multipart/form-data
file: [binary file data]
```

**Response (200 OK):**
```json
{
  "file_uri": "gs://krow-private/vendor-docs/w9_abc123.pdf"
}
```

**Implementation Notes:**
- Upload to private GCS bucket (no public access)
- Generate unique filename with UUID
- Store metadata (uploader, timestamp) in Firestore
- Use for sensitive documents (W9, COI, insurance certs)

---

### 4.5. Create Signed URL

**Endpoint:** `POST /createSignedUrl`  
**Description:** Creates a temporary signed URL for accessing a private file.

**Request Body:**
```json
{
  "file_uri": "gs://krow-private/vendor-docs/w9_abc123.pdf",
  "expires_in": 3600 // Seconds (optional, default: 300)
}
```

**Response (200 OK):**
```json
{
  "signed_url": "https://storage.googleapis.com/krow-private/vendor-docs/w9_abc123.pdf?X-Goog-Algorithm=...",
  "expires_at": "2025-11-20T15:30:00Z"
}
```

**Implementation Notes:**
- Use GCS signed URL API
- Default expiration: 5 minutes (300 seconds)
- Max expiration: 1 hour (3600 seconds)
- Validate user has permission to access file

---

### 4.6. Extract Data from File

**Endpoint:** `POST /extractDataFromFile`  
**Description:** Extracts structured data from uploaded files (CSV, PDF, images) using AI.

**Request Body:**
```json
{
  "file_url": "https://storage.googleapis.com/krow-public/files/staff_import.csv",
  "json_schema": {
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "employee_name": { "type": "string" },
        "email": { "type": "string" },
        "position": { "type": "string" }
      }
    }
  }
}
```

**Response (200 OK):**
```json
{
  "status": "success",
  "output": [
    {
      "employee_name": "John Doe",
      "email": "john@example.com",
      "position": "Server"
    },
    {
      "employee_name": "Jane Smith",
      "email": "jane@example.com",
      "position": "Cook"
    }
  ]
}
```

**Error Response (400):**
```json
{
  "status": "error",
  "details": "Failed to parse CSV: Invalid format at row 3",
  "output": null
}
```

**Implementation Notes:**
- Use Vertex AI Document AI for PDFs
- Use Vertex AI Vision for images
- Use Papa Parse or similar for CSVs
- Validate against provided JSON schema
- Return structured data or detailed error

---

### 4.7. Detect Event Conflicts (NEW in v3.0)

**Endpoint:** `POST /detectEventConflicts`  
**Description:** Analyzes an event and detects scheduling conflicts.

**Request Body:**
```json
{
  "event_id": "evt_123456",
  "check_types": ["staff_overlap", "venue_overlap", "time_buffer"]
}
```

**Response (200 OK):**
```json
{
  "conflicts": [
    {
      "conflict_type": "staff_overlap",
      "severity": "high",
      "description": "Staff member John Doe is already assigned to Event #456 at the same time",
      "conflicting_event_id": "evt_456",
      "staff_id": "stf_111",
      "detected_at": "2025-11-20T10:30:00Z"
    },
    {
      "conflict_type": "time_buffer",
      "severity": "medium",
      "description": "Event starts within 30 minutes of Event #789 at the same venue",
      "conflicting_event_id": "evt_789",
      "detected_at": "2025-11-20T10:30:00Z"
    }
  ],
  "conflict_count": 2,
  "has_critical_conflicts": false
}
```

**Implementation Notes:**
- Check against all active events in date range
- Consider buffer_time_before/after
- Check staff availability across all events
- Check venue double-booking
- Store results in Event.detected_conflicts
- Trigger notifications for critical conflicts

---

## 5. Security & Access Control

### 5.1. Firebase Security Rules

Implement Firestore Security Rules for all Data Connect operations:

```javascript
// Example rule for Event entity
match /events/{eventId} {
  // Anyone authenticated can read
  allow read: if request.auth != null;
  
  // Only admins and event creators can update
  allow update: if request.auth != null && 
    (request.auth.token.user_role == 'admin' || 
     resource.data.created_by == request.auth.token.email);
  
  // Only admins can delete
  allow delete: if request.auth != null && 
    request.auth.token.user_role == 'admin';
  
  // Authenticated users can create
  allow create: if request.auth != null;
}
```

### 5.2. Team Isolation

Implement strict team isolation via `owner_id`:

- Vendors can only see their own events, staff, rates
- Procurement can see all vendors and events
- Operators can see specific client data
- Clients can only see their own events

**Implementation:**
```javascript
// In GraphQL resolvers
const filterEventsByTeam = (userId, userRole) => {
  if (userRole === 'admin' || userRole === 'procurement') {
    return {}; // No filter, see all
  }
  
  if (userRole === 'vendor') {
    return { vendor_id: userId };
  }
  
  if (userRole === 'client') {
    return { business_id: userId };
  }
  
  // Default: only own created records
  return { created_by: userEmail };
};
```

### 5.3. Rate Limiting

Implement rate limits on all Cloud Functions:

| Function               | Limit                  |
| ---------------------- | ---------------------- |
| sendEmail              | 1000/day per user      |
| invokeLLM              | 100/minute per user    |
| uploadFile             | 100/hour per user      |
| extractDataFromFile    | 50/hour per user       |
| detectEventConflicts   | 500/hour per user      |

---

## 6. Migration Notes from v2.0

### 6.1. Breaking Changes

#### Event Entity
- **Added fields:** `is_rapid`, `is_multi_day`, `multi_day_start_date`, `multi_day_end_date`, `buffer_time_before`, `buffer_time_after`, `conflict_detection_enabled`, `detected_conflicts`, `event_location`, `invoice_id`
- **Modified:** `requested` now defaults to 0

#### Staff Entity
- **Removed fields:** `phone`, `event_location`, `address`, `city`, `position_2`, `initial`, `check_in`, `shift_coverage_percentage`, `cancellation_count`, `no_show_count`, `total_shifts`, `background_check_date`, `certifications`, `notes`
- **Added fields:** `track`

#### Vendor Entity
- **Removed 20+ fields** - Significantly simplified
- **Kept only:** `vendor_number`, `legal_name`, `region`, `platform_type`, `primary_contact_email`, `approval_status`, `is_active`

#### Invoice Entity
- **Status values changed:** Old statuses removed, new ones added
- **Added:** `disputed_items`, `is_auto_generated`
- **Removed:** `manager_name`, `hub`, `cost_center`, `event_id`, `event_name`, `vendor_name`, `item_count`, `paid_date`, `payment_method`, `notes`

### 6.2. New Entities in v3.0

- VendorDefaultSettings
- TeamMember
- TeamHub
- TeamMemberInvite
- Assignment
- Workforce

### 6.3. Data Migration Strategy

1. **Phase 1 - Schema Migration:**
   - Create new Firebase Data Connect schema with v3.0 entities
   - Deploy Cloud Functions for services API
   - Keep v2.0 API running in parallel

2. **Phase 2 - Data Migration:**
   - Export data from Base44
   - Transform to v3.0 schema
   - Import to Firebase Data Connect
   - Run validation scripts

3. **Phase 3 - Client Migration:**
   - Update web/mobile clients to use new API
   - Test all workflows
   - Gradual rollout with feature flags

4. **Phase 4 - Cleanup:**
   - Decommission Base44 backend
   - Remove legacy code
   - Update documentation

---

## 7. Implementation Priority

### Phase 1 - Critical (Week 1-2)
**Goal:** Core CRUD operations working

1. ✅ Firebase project setup
2. ✅ Firebase Authentication configuration
3. ✅ Firebase Data Connect schema for:
   - User
   - Event (with all v3.0 fields)
   - Staff
   - Vendor
   - Invoice
4. ✅ GraphQL resolvers for list, get, create, update, delete
5. ✅ Basic security rules

### Phase 2 - Essential Services (Week 3-4)
**Goal:** Service functions operational

1. ✅ sendEmail Cloud Function
2. ✅ uploadFile Cloud Function
3. ✅ uploadPrivateFile Cloud Function
4. ✅ createSignedUrl Cloud Function
5. ✅ invokeLLM Cloud Function (basic)

### Phase 3 - Extended Entities (Week 5-6)
**Goal:** All entities implemented

1. ✅ Business, Certification, Team entities
2. ✅ TeamMember, TeamHub, TeamMemberInvite entities
3. ✅ Conversation, Message, ActivityLog entities
4. ✅ Enterprise, Sector, Partner, Order, Shift entities
5. ✅ Assignment, Workforce entities

### Phase 4 - Advanced Features (Week 7-8)
**Goal:** AI and conflict detection

1. ✅ extractDataFromFile Cloud Function
2. ✅ detectEventConflicts Cloud Function
3. ✅ Advanced LLM features (context from internet, file analysis)
4. ✅ Conflict detection automation (triggers)

### Phase 5 - Optimization & Testing (Week 9-10)
**Goal:** Production-ready

1. ✅ Performance optimization
2. ✅ Comprehensive testing
3. ✅ Security audit
4. ✅ Documentation finalization
5. ✅ Client SDK generation

---

## 8. GraphQL Schema Template

For developers implementing Firebase Data Connect:

```graphql
# firebase/dataconnect/schema/event.gql

type Event @table {
  id: ID!
  event_name: String!
  is_rapid: Boolean @default(value: false)
  is_recurring: Boolean @default(value: false)
  is_multi_day: Boolean @default(value: false)
  recurrence_type: RecurrenceType @default(value: SINGLE)
  recurrence_start_date: Date
  recurrence_end_date: Date
  scatter_dates: [Date]
  multi_day_start_date: Date
  multi_day_end_date: Date
  buffer_time_before: Int @default(value: 0)
  buffer_time_after: Int @default(value: 0)
  conflict_detection_enabled: Boolean @default(value: true)
  detected_conflicts: [Conflict]
  business_id: String
  business_name: String
  vendor_id: String
  vendor_name: String
  hub: String
  event_location: String
  contract_type: ContractType
  po_reference: String
  status: EventStatus @default(value: DRAFT)
  date: Date
  shifts: [Shift]
  addons: JSON
  total: Float
  client_name: String
  client_email: String
  client_phone: String
  invoice_id: String
  notes: String
  requested: Int @default(value: 0)
  assigned_staff: [AssignedStaff]
  created_date: Timestamp!
  updated_date: Timestamp!
  created_by: String!
}

enum RecurrenceType {
  SINGLE
  DATE_RANGE
  SCATTER
}

enum ContractType {
  W2
  _1099
  TEMP
  CONTRACT
}

enum EventStatus {
  DRAFT
  ACTIVE
  PENDING
  ASSIGNED
  CONFIRMED
  COMPLETED
  CANCELED
}

type Conflict {
  conflict_type: ConflictType!
  severity: Severity!
  description: String!
  conflicting_event_id: String
  staff_id: String
  detected_at: Timestamp!
}

enum ConflictType {
  STAFF_OVERLAP
  VENUE_OVERLAP
  TIME_BUFFER
}

enum Severity {
  LOW
  MEDIUM
  HIGH
  CRITICAL
}

type Shift {
  shift_name: String!
  shift_contact: String
  location_address: String
  roles: [Role!]!
}

type Role {
  role: String!
  department: String
  count: Int!
  start_time: String
  end_time: String
  hours: Float
  uniform: String
  break_minutes: Int
  cost_per_hour: Float
  total_value: Float
  vendor_name: String
  vendor_id: String
}

type AssignedStaff {
  staff_id: String!
  staff_name: String!
  role: String!
  confirmed: Boolean!
}
```

---

## 9. Cloud Function Template

For developers implementing Cloud Functions:

```typescript
// functions/src/sendEmail.ts

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as sgMail from '@sendgrid/mail';

sgMail.setApiKey(process.env.SENDGRID_API_KEY!);

export const sendEmail = functions.https.onRequest(async (req, res) => {
  // Validate authentication
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    res.status(401).json({ error: 'Unauthorized' });
    return;
  }

  const token = authHeader.split('Bearer ')[1];
  
  try {
    const decodedToken = await admin.auth().verifyIdToken(token);
    const userId = decodedToken.uid;
    const userEmail = decodedToken.email;

    // Validate request body
    const { to, subject, body, from_name } = req.body;
    
    if (!to || !subject || !body) {
      res.status(400).json({ 
        error: 'Missing required fields',
        code: 'INVALID_REQUEST'
      });
      return;
    }

    // Send email via SendGrid
    const msg = {
      to: to,
      from: {
        email: 'noreply@krow.com',
        name: from_name || 'KROW Workforce'
      },
      subject: subject,
      html: body,
    };

    const [response] = await sgMail.send(msg);

    // Log to ActivityLog
    await admin.firestore().collection('activity_logs').add({
      title: 'Email Sent',
      description: `Email sent to ${to}: ${subject}`,
      activity_type: 'email_sent',
      user_id: userId,
      is_read: false,
      created_date: admin.firestore.FieldValue.serverTimestamp(),
      updated_date: admin.firestore.FieldValue.serverTimestamp(),
      created_by: userEmail
    });

    res.status(200).json({
      status: 'sent',
      message_id: response.headers['x-message-id']
    });

  } catch (error) {
    console.error('Error sending email:', error);
    res.status(500).json({
      error: 'Failed to send email',
      code: 'EMAIL_SEND_FAILED',
      details: error.message
    });
  }
});
```

---

## 10. Testing Checklist

### Unit Tests
- [ ] All GraphQL queries return correct data
- [ ] All GraphQL mutations create/update/delete correctly
- [ ] All Cloud Functions handle valid inputs
- [ ] All Cloud Functions handle invalid inputs
- [ ] Authentication validation works
- [ ] Authorization rules enforced

### Integration Tests
- [ ] Create Event → Assign Staff → Generate Invoice flow
- [ ] Bulk import Staff from CSV
- [ ] AI staff recommendations
- [ ] Conflict detection accuracy
- [ ] Email sending end-to-end
- [ ] File upload/download with signed URLs

### Performance Tests
- [ ] GraphQL queries under 500ms for <100 records
- [ ] GraphQL queries under 2s for <1000 records
- [ ] Cloud Functions respond under 5s (excluding AI calls)
- [ ] AI calls complete under 30s
- [ ] File uploads handle 100MB files

### Security Tests
- [ ] Unauthenticated requests rejected
- [ ] Cross-team data access blocked
- [ ] SQL injection attempts blocked
- [ ] File upload size limits enforced
- [ ] Rate limits enforced

---

## 11. Deployment Guide

### Prerequisites
1. Google Cloud Project created
2. Firebase project linked to GCP
3. Billing enabled
4. APIs enabled:
   - Firebase Data Connect
   - Cloud Functions
   - Cloud Storage
   - Vertex AI
   - Firebase Authentication

### Deployment Steps

```bash
# 1. Install Firebase CLI
npm install -g firebase-tools

# 2. Login to Firebase
firebase login

# 3. Initialize Firebase project
firebase init

# Select:
# - Data Connect
# - Functions
# - Storage

# 4. Deploy Data Connect schema
cd firebase/dataconnect
firebase dataconnect:deploy

# 5. Deploy Cloud Functions
cd functions
npm install
npm run build
firebase deploy --only functions

# 6. Configure Storage rules
firebase deploy --only storage

# 7. Verify deployment
firebase dataconnect:describe
```

### Environment Variables

Set in Firebase Functions config:

```bash
firebase functions:config:set \
  sendgrid.api_key="SG.xxx" \
  vertex.project_id="krow-workforce" \
  vertex.location="us-central1"
```

---

## 12. Support & Resources

### Documentation
- Firebase Data Connect: https://firebase.google.com/docs/data-connect
- Cloud Functions: https://firebase.google.com/docs/functions
- Vertex AI: https://cloud.google.com/vertex-ai/docs

---

**Document Version:** 3.0  
**Last Updated:** 2025-11-20  
**Status:** Ready for Implementation

---

© 2025 KROW Workforce / Oloodi Technologies Inc. All rights reserved.
