# Phase 0 Handoff - Live Dev Schema State

**Spec:** 050 - Everee Payroll Foundations  
**Date captured:** 2026-06-01  
**Scope:** Phase 0 close-out context for Phase 1a implementers

---

## Summary

Phase 0 engineering work is committed and the payroll foundation schema has been applied to dev. The remaining blockers are human sign-offs / CS actions, not engineering implementation gaps.

| Task | Commit(s) | Status |
|---|---|---|
| T1 Employee consolidation | `f429d715b` | Done |
| T2 Foundational schema migrations | `24c1d7467`, `03f06baa9` | Done; live on dev |
| T3 Person-centric verification CLI + report | `5eceaf15e` | Done; CON-22 still needs human decision/sign-off |
| T4 TaskEngine audit test | `c0e1074eb` | Done; needs second-engineer sign-off |
| T5 Pre-flight checklist test | `5d1df2f14` | Done; CS-owned actions pending |

Validation recorded for Phase 0:

- 92 tests / 1,511 assertions green.
- Full `conductor run` applied cleanly after the T2 fix commit.
- Re-running conductor was idempotent: zero applied / zero errors.
- Dev state confirmed: 11 central payroll/PTO tables, `userPayrollProfiles`, 12/12 permission hooks, and 141 users legal-name backfilled.

---

## Live Schema State

### `kiosk_buykiosk`

The following central payroll/PTO tables are live:

- `payrollTenants`
- `payrollRuns`
- `payrollRunLines`
- `payrollRunSnapshots`
- `payrollWebhookEvents`
- `payrollAuditLog`
- `payRateHistory`
- `payrollCoaMappings`
- `ptoAccrualPolicies`
- `ptoAccrualBalances`
- `ptoRequests`

Central store extension:

- `stores.payrollTenantId` links N stores to one `payrollTenants` row.

### `kiosk_users`

Payroll identity/profile table:

- `userPayrollProfiles`

User extensions:

- Legal-name and onboarding-prefill PII columns from `20260522_009_users_legal_pii_columns.json`.
- Legal-name best-effort backfill from `20260522_015_display_name_migration_helper.json`.

Assignment/permission extensions:

- `userStoreAssignments.employmentClassification`
- 12 payroll permission hooks in `uf_authorize_group`

### Per-Store Databases

Scheduling/payroll extensions are live per dev store:

- `schedulePositions.workersCompClassCode`
- `schedulePositions.qboWageAccountId`
- `scheduleTimePunches.cashTipsCents`
- `scheduleTimePunches.creditTipsCents`
- `scheduleTimePunches.submittedToEvereeAt`

---

## Schema-Drift Gotcha

Two SDD names were wrong and were only caught by the live `conductor run`.

1. The SDD said to alter `kiosk_buykiosk.positions`. That table does not exist. The actual table is per-store `schedulePositions`, created by `20251220_013_004_schedule_positions.json`. Phase 1a code must target `schedulePositions`, not `positions`.

2. The SDD said to split `users.display_name`. The real column is `users.displayName`, and `users.firstName` / `users.lastName` already exist. Phase 1a legal-name prefill logic should treat `firstName` / `lastName` as the primary source and `displayName` as fallback only.

The fixed migrations are:

- `userfrosting/migrations/input/20260522_012_positions_payroll_columns.json`
- `userfrosting/migrations/input/20260522_015_display_name_migration_helper.json`

The detailed deviation entry is in `implementation-plan.md` under "2026-05-29 - T2 migrations 012 & 015".

---

## Remaining Human Gates

Phase 1a should not be treated as fully unblocked until these are closed:

1. **T3 / CON-22:** spec owner decides whether the verified `HomegrownProvider::createEmployee()` duplicate-risk gap expands Phase 0 scope or is accepted with operational mitigation; second engineer signs the report.
2. **T4:** second engineer signs off on the TaskEngine audit.
3. **T5:** CS sends the Everee partner kickoff email, collects five pilot-store rate CSVs, and names owners for the operational checklist.

---

## Phase 1a Notes

- Always run `php userfrosting/conductor run` after pulling this work; conductor is the source of truth for schema state.
- Do not reintroduce a central `positions` table assumption.
- Do not reference `users.display_name`; use `displayName` only when needed as a fallback.
- Do not treat `userPayrollProfiles` as a central-DB table; it lives in `kiosk_users`.
- Keep CON-22 visible when implementing any `users.id -> evereeWorkerId` mapping.
