docs(m4): add business/vendor memberships and clean planning docs

This commit is contained in:
zouantchaw
2026-02-25 11:58:21 -05:00
parent 67cf5e0e4c
commit b645927429
5 changed files with 135 additions and 117 deletions

View File

@@ -24,3 +24,6 @@
| 2026-02-24 | 0.1.19 | Added customer stakeholder-wheel mapping and future stakeholder extension model to the M4 schema blueprint. |
| 2026-02-25 | 0.1.20 | Added roadmap CSV schema-reconciliation document with stakeholder capability matrix and concrete schema gap analysis. |
| 2026-02-25 | 0.1.21 | Updated target schema blueprint with roadmap-evidence section plus attendance/offense, stakeholder-network, and settlement-table coverage. |
| 2026-02-25 | 0.1.22 | Updated core actor scenarios with explicit business and vendor user partitioning via membership tables. |
| 2026-02-25 | 0.1.23 | Updated schema blueprint and reconciliation docs to add `business_memberships` and `vendor_memberships` as first-class data actors. |
| 2026-02-25 | 0.1.24 | Removed stale `m4-discrepencies.md` document from M4 planning docs cleanup. |

View File

@@ -9,20 +9,38 @@ Owner: Technical Lead
2. `User`: human identity that signs in.
3. `TenantMembership`: user role/context inside one tenant.
4. `Business`: client account served by the tenant.
5. `Vendor`: supplier account that can fulfill staffing demand.
6. `Workforce/Staff`: worker profile used for assignment and attendance.
7. `StakeholderType`: typed category (`buyer`, `operator`, `vendor_partner`, `workforce`, `partner`).
8. `StakeholderProfile`: typed actor record inside a tenant.
9. `StakeholderLink`: relationship between stakeholder profiles.
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"]
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
@@ -40,38 +58,48 @@ Context:
Actor mapping (text):
1. Tenant: `Legendary Event Staffing and Entertainment` (the company using Krow).
2. User: `Wil` (ops lead), `Maria` (client manager), `Ana` (worker).
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 `manager` in Legendary tenant.
6. `Ana` is `member` in Legendary tenant.
7. Business: `Google Mountain View Cafes` (client account under the tenant).
8. Vendor: `Legendary Staffing Pool A` (or an external approved vendor).
9. Workforce/Staff: `Ana` is a staff profile in workforce, linked to certifications and assignments.
10. StakeholderType: `buyer`, `operator`, `vendor_partner`, `workforce`, `procurement_partner`.
11. StakeholderProfile:
12. `Google Procurement` = `buyer`.
13. `Legendary Ops` = `operator`.
14. `FoodBuy` = `procurement_partner`.
15. StakeholderLink:
16. `Google Procurement` `contracts_with` `Legendary Ops`.
17. `Legendary Ops` `sources_from` `Vendor`.
18. `Google Procurement` `reports_through` `FoodBuy`.
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 Biz as "Business (Google Cafes)"
participant Ops as "User + TenantMembership (Ops Lead)"
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"
Biz->>Ops: "Create staffing request"
BizUser->>Ops: "Create staffing request"
Ops->>Tenant: "Create order under tenant scope"
Ops->>StakeRel: "Resolve business-to-vendor/workforce relationships"
Ops->>Staff: "Assign qualified worker"
Ops->>VendorUser: "Dispatch role demand"
VendorUser->>Staff: "Confirm worker assignment"
Staff-->>Ops: "Clock in/out and complete shift"
Ops-->>Biz: "Invoice/report generated with audit trail"
Ops-->>BizUser: "Invoice/report generated with audit trail"
```
## 4) Scenario B: Another tenant (external vendor-heavy)
@@ -82,41 +110,57 @@ Context:
Actor mapping (text):
1. Tenant: `Peakline Events` (another staffing company using Krow).
2. User: `Chris` (operations coordinator), `Nina` (client manager), `Leo` (worker).
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 `manager` in Peakline tenant.
6. `Leo` is `member` in Peakline tenant.
7. Business: `NVIDIA Campus Dining` (client account under the tenant).
8. Vendor: `Metro Staffing LLC` (approved external vendor for this tenant).
9. Workforce/Staff: `Leo` is a workforce profile fulfilled through Metro Staffing for assignment and attendance.
10. StakeholderType: `buyer`, `operator`, `vendor_partner`, `workforce`, `procurement_partner`.
11. StakeholderProfile:
12. `NVIDIA Procurement` = `buyer`.
13. `Peakline Ops` = `operator`.
14. `FoodBuy Regional` = `procurement_partner`.
15. StakeholderLink:
16. `NVIDIA Procurement` `contracts_with` `Peakline Ops`.
17. `Peakline Ops` `sources_from` `Metro Staffing LLC`.
18. `NVIDIA Procurement` `reports_through` `FoodBuy Regional`.
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 Biz as "Business (NVIDIA Dining)"
participant Ops as "User + TenantMembership (Coordinator)"
participant Vendor as "Vendor (Metro Staffing)"
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)"
Biz->>Ops: "Request recurring event staffing"
BizUser->>Ops: "Request recurring event staffing"
Ops->>Tenant: "Create recurring order"
Ops->>Vendor: "Dispatch required roles"
Vendor->>Staff: "Provide available workers"
Ops->>VendorUser: "Dispatch required roles"
VendorUser->>Staff: "Provide available workers"
Staff-->>Ops: "Attendance and completion events"
Ops-->>Biz: "Settlement + performance reports"
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. Multi-tenant isolation stays strict because all critical records resolve through `Tenant`.
3. Legendary and non-Legendary operating models both fit the same structure.
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

@@ -1,47 +0,0 @@
# M4 Planning Phase: Identified Discrepancies and Enhancements
## Feedback and Discrepancies (Based on M3 Review done by Iliana)
### Mobile Application (Client & Staff)
- **Flexible Shift Locations:** Feedback from the M3 review indicated a need for the ability to specify different locations for individual positions within an order on the mobile app. Currently, the web application handles this by requiring a separate shift for each location.
- **Order Visibility Management:** Currently, when an order is created with multiple positions, the "View Order" page displays them as separate orders. This is due to UI (prototype) cannot support multi-position views in the order. We should consider adopting the "legacy" app's approach to group these positions under a single order for better clarity.
- **Cost Center Clarification:** The purpose and functionality of the "Cost Center" field in the Hub creation process is not clear.
- **Tax Form Data Completeness:** Feedback noted that while tax forms are visible in the Staff mobile application, they appear to be missing critical information. This not clear.
### Web Dashboard
- **Role-Based Content Logic:** The current web dashboard prototype contains some logical inconsistencies regarding user roles:
- **Client Dashboard:** Currently includes Staff Availability, Staff Directory, and Staff Onboarding. Since workers (Staff) are managed by Vendors, these pages should be moved to the Vendor dashboard.
- **Vendor Dashboard:** Currently includes "Teams and Hubs." Since Hubs are client-specific locations where staff clock in/out, these management pages should be moved to the Client dashboard.
- **Admin Dashboard Filtering:** The Admin dashboard requires improved filtering capabilities. Admins should be able to select specific Clients or Vendors to filter related data, such as viewing only the orders associated with a chosen partner.
## Proposed Features and Enhancements (Post-M3 Identification)
- **Feature: Navigation to Hub Details from Coverage Screen (#321)**
- **Description:** Allow users to navigate directly to the Hub Details page by clicking on a hub within the Coverage Screen.
- **Feature: Dedicated Hub Details Screen with Order History (#320)**
- **Description:** Develop a comprehensive Hub Details view that aggregates all hub-specific data, including historical order records.
- **Benefit:** Centralizes information for better decision-making and easier access to historical data.
- **Feature: Dedicated Order Details Screen**
- **Description:** Transition from displaying all order information on the primary "View Order" page to a dedicated "Order Details" screen. This screen will support viewing multiple positions within a single order.
- **Benefit:**
- **Improved UX:** Reduces complexity by grouping associated positions together and presenting them in a structured way.
- **Performance:** Optimizes data loading by fetching detailed position information only when requested.
- **Feature: Optimized Clock-In Page (#350)**
- **Description:** Remove the calendar component from the Clock-In page. Since workers only clock in for current-day assignments, the calendar is unnecessary.
- **Benefit:** Simplifies the interface and reduces user confusion.
- **Feature: Contextual Shift Actions**
- **Description:** Restrict the Clock-In page to show only active or upcoming shifts (starting within 30 minutes). Shift-specific actions (Clock-In/Clock-Out) should be performed within the specific Shift Details page.
- **Reasoning:** This solves issues where staff cannot clock out of overnight shifts (shifts starting one day and ending the next) due to the current day-based UI.
- **Feature: Dedicated Emergency Contact Management (#356)**
- **Description:** Replace the inline form in the "View Emergency Contact" page with a dedicated "Create Emergency Contact" screen.
- **Benefit:** Standardizes the data entry process and improves UI organization within the Staff app.

View File

@@ -71,13 +71,15 @@ What already exists and is useful:
Current structural gaps for roadmap scale:
1. No tenant boundary key on core tables (`tenant_id` missing).
2. No first-class stakeholder profile/link model for buyer/operator/partner/sector relationships.
3. Attendance history is not first-class (check in/out only inside `applications`).
4. No offense policy, offense event, or enforcement action tables.
5. Finance is coarse (invoice + recent payment), missing line items, payment runs, remittance artifact model.
6. Sensitive bank fields are currently modeled directly in `accounts` (`accountNumber`, `routeNumber`).
7. Many core workflow fields are JSON (`orders.assignedStaff`, `orders.shifts`, `shift.managers`, `assignment.managers`).
8. Money still uses float in critical tables.
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.
@@ -88,10 +90,12 @@ Connector boundary gap:
### 6.1 Tenant and stakeholder graph
1. `tenants`
2. `tenant_memberships`
3. `stakeholder_types`
4. `stakeholder_profiles`
5. `stakeholder_links`
6. `role_bindings` (scoped to tenant/team/hub/business/vendor/resource)
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)
@@ -124,6 +128,10 @@ Connector boundary gap:
```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

View File

@@ -25,6 +25,7 @@ Practical meaning:
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
@@ -41,16 +42,16 @@ 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` + `team_members` (procurement team scope).
- Schema anchor: `users` + `tenant_memberships` + `business_memberships`.
2. Enterprises (Operator):
- Tenant operator/admin users running staffing operations.
- Schema anchor: `tenants`, `team_members`, command-side permissions.
- 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`, `workforce`, `vendor_rates`, `vendor_benefit_plans`.
- 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`.
@@ -99,15 +100,19 @@ What the exports confirmed:
Tables:
1. `users` (source identity, profile, auth linkage)
2. `tenant_memberships` (new; membership + base access per tenant)
3. `team_members` (membership + scope per team)
4. `roles` (new)
5. `permissions` (new)
6. `role_bindings` (new; who has which role in which scope)
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 team membership: `(team_id, user_id)`.
3. Access checks resolve through tenant membership first, then optional team/hub scope.
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:
@@ -121,6 +126,7 @@ Tables:
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**.
@@ -250,6 +256,10 @@ erDiagram
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