# CreateWorker

## Permission Scope

`worker`

## Overview

CreateWorker registers a Worker as a 1:1 HR extension of an existing user-management User, establishing the stable person identity that everything else in the platform — employment, assignment, time, leave — is built on.

## Business Rules

- Every Worker references exactly one user-management User; `userId` is required and unique — a User has at most one Worker
- `workerCode` is a stable, human-facing identifier unique across Workers and independent of the User's login identity
- Registering a Worker for a non-existent User is rejected
- Registering a second Worker for a User that already has one is rejected
- Host-defined custom fields on the Worker model are accepted and persisted alongside the builtin columns; a builtin column always wins over a custom field of the same name

## Process Flow

```mermaid
flowchart TD
    A[Admin initiates Worker registration for a User] --> B{User exists in user-management?}
    B -- No --> E[Reject: USER_NOT_FOUND]
    B -- Yes --> C{User already has a Worker?}
    C -- Yes --> F[Reject: WORKER_ALREADY_EXISTS]
    C -- No --> D{workerCode unique?}
    D -- No --> G[Reject: WORKER_CODE_TAKEN]
    D -- Yes --> H[Create Worker linked 1:1 to User]
    H --> I[Worker available for employment, assignment, time, leave]
```

## External Dependencies

- user-management::User (cross-module) — the login identity the Worker extends 1:1

## Error Scenarios

- **USER_NOT_FOUND**: the specified user-management User does not exist
- **WORKER_ALREADY_EXISTS**: the specified User already has a linked Worker
- **WORKER_CODE_TAKEN**: workerCode is already in use by another Worker

## Test Cases

- registering a Worker for an existing User with a unique worker code succeeds and links 1:1
- registering a second Worker for a User that already has one is rejected
- registering a Worker with a worker code already in use is rejected
- host-defined custom fields are persisted alongside the builtin columns

Note: "registering a Worker for a non-existent User is rejected" (USER_NOT_FOUND) is not
covered by an application-level test — user-management exposes no `getUser` query to
inject, so `userId` existence is enforced only by the DB-level FK constraint, which the
mocked DB in these unit tests cannot exercise. See the NOTE in createWorker.test.ts.

