{"openapi":"3.1.0","info":{"title":"Green Orbit — Identity, records and audit","version":"0.1.0"},"paths":{"/healthz":{"get":{"tags":["ops"],"summary":"Healthz","description":"Liveness. Deliberately touches nothing — if this needs the database\nto answer, a database blip takes every container out of the pool.","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/readyz":{"get":{"tags":["ops"],"summary":"Readyz","description":"Readiness. This one is allowed to check dependencies.","operationId":"readyz_readyz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/sign-in":{"post":{"tags":["auth"],"summary":"Sign In","description":"Exchange credentials for a session.\n\nThe claims in the response are read from the account, never from the\nrequest: the body carries an email and a password and nothing else, so\nthere is no field here a client could use to choose its own tenancy, role\nor clearance.","operationId":"sign_in_auth_sign_in_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/refresh":{"post":{"tags":["auth"],"summary":"Refresh","operationId":"refresh_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/me":{"get":{"tags":["auth"],"summary":"Me","description":"Who you are, and what you may currently do.\n\nCarries no `authorize` requirement on purpose: reading your own session is\nnot a privilege, and requiring one would lock out an account whose roles\nwere just revoked — leaving it unable to discover why.\n\nRe-reads the grants rather than echoing the token, so a client that polls\nthis sees a role change without waiting for a refresh. That is what makes\n\"permission changes take effect immediately\" true on the frontend as well\nas the server.\n\nUses the anchored session, unlike sign-in and refresh either side of it.\nThose two have no tenant yet — finding the account is how they learn it.\nThis one does: the middleware put an actor on the request. Reading roles\nunanchored returned an empty set, because row-level security correctly hid\nevery row, and an empty set is indistinguishable from \"this account has no\nroles\" — which is what signed people out on a page reload.","operationId":"me_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActorOut"}}}}}}},"/users":{"get":{"tags":["identity"],"summary":"List Users","operationId":"list_users_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserOut"},"type":"array","title":"Response List Users Users Get"}}}}}}},"/roles":{"get":{"tags":["identity"],"summary":"List Roles","description":"The role templates and the permissions each grants.\n\nThe console draws its matrix from this, so a custom role added later shows\nup without a frontend change — which is the point of roles being rows.","operationId":"list_roles_roles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/RoleOut"},"type":"array","title":"Response List Roles Roles Get"}}}}}}},"/users/{user_id}/roles":{"put":{"tags":["identity"],"summary":"Set User Roles","description":"Replace this person's roles with the set given.\n\nA full set rather than assign/revoke calls: dual roles make \"revoke\" mean\ntwo different things depending on what else is held, and a delta API makes\nthe zero-roles state easy to reach by accident. An account with no roles\ncannot sign in at all.","operationId":"set_user_roles_users__user_id__roles_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetRolesIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/managers":{"post":{"tags":["identity"],"summary":"Create Manager","description":"Create somebody and allocate the organisations they will manage.\n\nThe administrator sets the password, so the account works the moment it is\ncreated — nobody waits on an email that has not been built yet. The person\nis made to replace it at first sign-in, which is what stops two people\nknowing one credential permanently.","operationId":"create_manager_managers_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagerIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/managers/{manager_id}/organisations":{"get":{"tags":["identity"],"summary":"List Allocations","operationId":"list_allocations_managers__manager_id__organisations_get","parameters":[{"name":"manager_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Manager Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AllocatedOrganisation"},"title":"Response List Allocations Managers  Manager Id  Organisations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["identity"],"summary":"Set Allocations","description":"Replace the whole allocation.\n\nAn empty list is allowed and means exactly what it says: no organisations.\nThat is a real state — somebody between desks — and it fails closed, since\nan empty scope grants nothing rather than everything.","operationId":"set_allocations_managers__manager_id__organisations_put","parameters":[{"name":"manager_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Manager Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManagerOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/change-password":{"post":{"tags":["identity","auth"],"summary":"Change Password","description":"Replace your own password.\n\nThe current one is required even though the caller is already\nauthenticated: a session left open on an unlocked machine should not be\nenough to lock its owner out of their own account.\n\nAnchored, unlike sign-in — the middleware has already put an actor on the\nrequest, so the tenancy is known. An unanchored UPDATE here would match\nzero rows and report success.","operationId":"change_password_auth_change_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Change Password Auth Change Password Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/organisations":{"get":{"tags":["records"],"summary":"List Organisations","operationId":"list_organisations_organisations_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Trading name, legal name or ABN","title":"Search"},"description":"Trading name, legal name or ABN"},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/services__core_api__records__router__Page"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["records"],"summary":"Create Organisation","operationId":"create_organisation_organisations_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/organisations/{organisation_id}":{"get":{"tags":["records"],"summary":"Get Organisation","operationId":"get_organisation_organisations__organisation_id__get","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["records"],"summary":"Update Organisation","operationId":"update_organisation_organisations__organisation_id__put","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganisationDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/organisations/{organisation_id}/sites":{"get":{"tags":["records"],"summary":"List Sites","operationId":"list_sites_organisations__organisation_id__sites_get","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SiteOut"},"title":"Response List Sites Organisations  Organisation Id  Sites Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["records"],"summary":"Add Site","operationId":"add_site_organisations__organisation_id__sites_post","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/organisations/{organisation_id}/sites/{site_id}":{"put":{"tags":["records"],"summary":"Update Site","operationId":"update_site_organisations__organisation_id__sites__site_id__put","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SitePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["records"],"summary":"Remove Site","operationId":"remove_site_organisations__organisation_id__sites__site_id__delete","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Organisation Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers":{"get":{"tags":["records"],"summary":"List Workers","description":"Every worker this caller may see.\n\nNothing sensitive is returned here under any role — not because listing is\nless trusted, but because a list is the shape that gets exported and\npasted into a spreadsheet. `WorkerSummary` has no sensitive fields to\npopulate, so this is structural rather than a filter somebody has to\nremember.","operationId":"list_workers_workers_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name or email","title":"Search"},"description":"Name or email"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"engagement_model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engagement Model"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/services__core_api__workers__router__Page"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["records"],"summary":"Create Worker","operationId":"create_worker_workers_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers/{worker_id}":{"get":{"tags":["records"],"summary":"Get Worker","operationId":"get_worker_workers__worker_id__get","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["records"],"summary":"Update Worker","operationId":"update_worker_workers__worker_id__put","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers/{worker_id}/engagement-models":{"get":{"tags":["records"],"summary":"List Engagements","operationId":"list_engagements_workers__worker_id__engagement_models_get","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EngagementOut"},"title":"Response List Engagements Workers  Worker Id  Engagement Models Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["records"],"summary":"Add Engagement","description":"Add a PAYG or IC engagement.\n\nA worker may hold several at once — on the books with one employer and\ninvoicing another — so this appends rather than replacing. Ending one is an\nupdate that sets `effective_to`, not a delete: an ended engagement is what\nlast year's payslip refers to.","operationId":"add_engagement_workers__worker_id__engagement_models_post","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers/{worker_id}/engagement-models/{engagement_id}":{"put":{"tags":["records"],"summary":"Update Engagement","description":"Update an engagement — in practice, a worker entering their own payroll\ndetails during onboarding.\n\n`own` scope, because this is the endpoint a worker uses on themselves. A\nmanager reaching somebody else's engagement satisfies it through their\nwider grant, and `_load` refuses a worker they may not see; the per-field\nclearance below then decides what they may actually write, which for a\nmanager is none of the payroll fields.","operationId":"update_engagement_workers__worker_id__engagement_models__engagement_id__put","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}},{"name":"engagement_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Engagement Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngagementOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers/me/onboarding":{"get":{"tags":["records"],"summary":"The signed-in worker's own journey","description":"What the portal calls on sign-in to decide between the wizard and the\ndashboard.","operationId":"my_onboarding_workers_me_onboarding_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerOnboardingOut"}}}}}}},"/workers/me/onboarding/steps":{"post":{"tags":["records"],"summary":"Record a completed step","description":"Mark one step done, and remember where they are.\n\nIdempotent: completing a step twice is a page refresh or a double tap, not\nan error worth showing somebody mid-form.","operationId":"complete_step_workers_me_onboarding_steps_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StepIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerOnboardingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/workers/{worker_id}/onboarding":{"get":{"tags":["records"],"summary":"A worker's onboarding progress","description":"What a manager sees. The acceptance criterion is a percentage, and it is\nthe same number the worker sees on their own progress bar — computed in one\nplace so the two cannot disagree.","operationId":"worker_onboarding_workers__worker_id__onboarding_get","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Worker Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerOnboardingOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/imports/templates/{entity_type}":{"get":{"tags":["imports"],"summary":"Download a CSV template","description":"Header row, a description row, and one filled example.\n\nThe description row starts with `#` so the parser can drop it if somebody\nfills the file in beneath the guidance rather than replacing it — which is\nwhat most people do, and what would otherwise be a mystifying first error.","operationId":"template_imports_templates__entity_type__get","parameters":[{"name":"entity_type","in":"path","required":true,"schema":{"type":"string","title":"Entity Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/imports/validate":{"post":{"tags":["imports"],"summary":"Dry run — parse and check, writing nothing","operationId":"validate_upload_imports_validate_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_validate_upload_imports_validate_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/imports/{job_id}/execute":{"post":{"tags":["imports"],"summary":"Write the valid rows from a validated import","operationId":"execute_imports__job_id__execute_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/imports/{job_id}":{"get":{"tags":["imports"],"summary":"An import's status","operationId":"status_imports__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/imports/{job_id}/errors.csv":{"get":{"tags":["imports"],"summary":"The errors, as a CSV to work through","description":"One line per error, not per row.\n\nA row with three bad fields is three lines, because the person fixing it\nworks field by field. `original_value` carries what they actually typed, so\nthe file can be corrected without cross-referencing the upload.","operationId":"error_report_imports__job_id__errors_csv_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenancies":{"post":{"tags":["tenancies"],"summary":"Provision a tenancy, its reference data and its first Admin","description":"Everything or nothing.\n\nA tenancy with roles but no document types is worse than no tenancy: the\ncustomer signs in, finds half a system, and reports it as a bug rather than\nas a failed provision. One transaction, and a failure anywhere rolls back\nthe tenancy itself.\n\nThis opens its own transaction rather than taking the request-scoped\nsession, because that session is anchored to the caller's tenancy — and\nthis caller has none.","operationId":"create_tenancy_tenancies_post","parameters":[{"name":"x-platform-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Platform-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenancyIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenancyOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/tenancies/{tenancy_id}/setup-status":{"get":{"tags":["tenancies"],"summary":"How far this tenancy's setup has got","description":"Read by the Admin's own dashboard, so it is authorised as a session\nrather than by the platform token — an administrator asking about their own\ntenancy needs no special standing.\n\nRow-level security does the scoping: a tenancy id that is not the caller's\nreads as absent rather than forbidden, which is also the right answer,\nsince confirming it exists would leak across the boundary.","operationId":"setup_status_tenancies__tenancy_id__setup_status_get","parameters":[{"name":"tenancy_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tenancy Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupStatusOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ActorOut":{"properties":{"tenant_id":{"type":"string","format":"uuid","title":"Tenant Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"full_name":{"type":"string","title":"Full Name"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions"},"worker_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Worker Id"},"may_see_sensitive":{"type":"boolean","title":"May See Sensitive"},"org_scope":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Org Scope"},"must_change_password":{"type":"boolean","title":"Must Change Password","default":false}},"type":"object","required":["tenant_id","user_id","email","full_name","roles","permissions","worker_id","may_see_sensitive","org_scope"],"title":"ActorOut","description":"What the frontend needs to render the shell: who this is, what they may\nsee, and which organisations. Nothing here is accepted back from the client\non a later request — it is a view of the session, not a handle to it."},"AdminOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"full_name":{"type":"string","title":"Full Name"},"initial_password":{"type":"string","title":"Initial Password"},"must_change_password":{"type":"boolean","title":"Must Change Password"}},"type":"object","required":["id","email","full_name","initial_password","must_change_password"],"title":"AdminOut"},"AllocatedOrganisation":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"trading_name":{"type":"string","title":"Trading Name"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"}},"type":"object","required":["id","trading_name","industry"],"title":"AllocatedOrganisation"},"Body_validate_upload_imports_validate_post":{"properties":{"entity_type":{"type":"string","title":"Entity Type"},"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["entity_type","file"],"title":"Body_validate_upload_imports_validate_post"},"ChangePasswordIn":{"properties":{"current_password":{"type":"string","minLength":1,"title":"Current Password"},"new_password":{"type":"string","maxLength":200,"minLength":12,"title":"New Password"}},"type":"object","required":["current_password","new_password"],"title":"ChangePasswordIn"},"ChecklistItem":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"done":{"type":"boolean","title":"Done"},"href":{"type":"string","title":"Href"},"hint":{"type":"string","title":"Hint"}},"type":"object","required":["key","label","done","href","hint"],"title":"ChecklistItem"},"EngagementIn":{"properties":{"model":{"type":"string","title":"Model"},"employment_organisation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Employment Organisation Id"},"effective_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective From"},"tax_file_number":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Tax File Number"},"super_fund":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Super Fund"},"super_member_number":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Super Member Number"},"bank_account":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Bank Account"},"abn":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Abn"}},"type":"object","required":["model"],"title":"EngagementIn"},"EngagementOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"model":{"type":"string","title":"Model"},"employment_organisation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Employment Organisation Id"},"employment_organisation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employment Organisation"},"effective_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective From"},"effective_to":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective To"},"required_documents":{"items":{"type":"string"},"type":"array","title":"Required Documents"},"tax_file_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tax File Number"},"super_fund":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Super Fund"},"super_member_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Super Member Number"},"bank_account":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bank Account"},"abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abn"}},"type":"object","required":["id","model","employment_organisation_id","employment_organisation","effective_from","effective_to","required_documents"],"title":"EngagementOut"},"EngagementPatch":{"properties":{"employment_organisation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Employment Organisation Id"},"effective_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective From"},"effective_to":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective To"},"tax_file_number":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Tax File Number"},"super_fund":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Super Fund"},"super_member_number":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Super Member Number"},"bank_account":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Bank Account"},"abn":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Abn"}},"type":"object","title":"EngagementPatch","description":"Updating an engagement — chiefly the worker's own payroll details.\n\nThe model itself is not here. Changing a PAYG engagement into an IC one\nwould silently change which documents are required and what has already\nbeen verified against the old set; ending one and adding the other says\nwhat actually happened."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JourneyOut":{"properties":{"engagement_id":{"type":"string","format":"uuid","title":"Engagement Id"},"model":{"type":"string","title":"Model"},"status":{"type":"string","title":"Status"},"current_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Step"},"steps":{"items":{"$ref":"#/components/schemas/StepOut"},"type":"array","title":"Steps"},"completed":{"type":"integer","title":"Completed"},"total":{"type":"integer","title":"Total"},"percent_complete":{"type":"integer","title":"Percent Complete"}},"type":"object","required":["engagement_id","model","status","current_step","steps","completed","total","percent_complete"],"title":"JourneyOut","description":"One engagement's journey.\n\nBoth `completed` and `total` are returned alongside the percentage. A\nprogress bar needs the fraction, and \"3 of 5\" is what a person reads."},"ManagerIn":{"properties":{"full_name":{"type":"string","maxLength":200,"minLength":1,"title":"Full Name"},"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Phone"},"password":{"type":"string","maxLength":200,"minLength":12,"title":"Password"},"role":{"type":"string","title":"Role","default":"Manager"},"organisation_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Organisation Ids"},"may_see_sensitive":{"type":"boolean","title":"May See Sensitive","default":false}},"type":"object","required":["full_name","email","password"],"title":"ManagerIn"},"ManagerOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"type":"string","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"status":{"type":"string","title":"Status"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"may_see_sensitive":{"type":"boolean","title":"May See Sensitive"},"organisations":{"items":{"$ref":"#/components/schemas/AllocatedOrganisation"},"type":"array","title":"Organisations"},"must_change_password":{"type":"boolean","title":"Must Change Password","default":false}},"type":"object","required":["id","full_name","email","phone","status","roles","may_see_sensitive","organisations"],"title":"ManagerOut"},"Metrics":{"properties":{"active_assignments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Active Assignments"},"workers_assigned":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Workers Assigned"},"weekly_margin":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Weekly Margin"},"compliance_health_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Compliance Health Pct"},"site_count":{"type":"integer","title":"Site Count","default":0}},"type":"object","title":"Metrics","description":"The detail page's summary strip.\n\nEvery value is null until the table behind it exists. Nulls rather than\nzeroes on purpose: a confident \"0% compliance health\" for an organisation\nthe system cannot yet assess reads as a measurement, and someone will make\na decision on it."},"OrganisationDetail":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"trading_name":{"type":"string","title":"Trading Name"},"legal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Name"},"abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abn"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"status":{"type":"string","title":"Status"},"site_count":{"type":"integer","title":"Site Count"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"active_assignments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Active Assignments"},"company_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Number"},"gst_registered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Gst Registered"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"primary_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Contact"},"billing_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Contact"},"po_required":{"type":"boolean","title":"Po Required"},"invoice_cycle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Cycle"},"invoice_format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invoice Format"},"invoice_margin_pct":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Invoice Margin Pct"},"payment_terms_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Payment Terms Days"},"default_pay_cycle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Pay Cycle"},"default_margin_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Default Margin Rule"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"metrics":{"$ref":"#/components/schemas/Metrics"},"sites":{"items":{"$ref":"#/components/schemas/SiteOut"},"type":"array","title":"Sites"}},"type":"object","required":["id","trading_name","legal_name","abn","industry","region","status","site_count","roles","active_assignments","company_number","gst_registered","address","email","phone","primary_contact","billing_contact","po_required","invoice_cycle","invoice_format","invoice_margin_pct","payment_terms_days","default_pay_cycle","default_margin_rule","created_at","updated_at","metrics","sites"],"title":"OrganisationDetail"},"OrganisationIn":{"properties":{"trading_name":{"type":"string","maxLength":200,"minLength":1,"title":"Trading Name"},"legal_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Legal Name"},"abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abn"},"company_number":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Company Number"},"gst_registered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Gst Registered"},"industry":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Industry"},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Region"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"email":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Phone"},"primary_contact":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Primary Contact"},"billing_contact":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Billing Contact"},"po_required":{"type":"boolean","title":"Po Required","default":false},"invoice_cycle":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Invoice Cycle"},"invoice_format":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Invoice Format"},"invoice_margin_pct":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Invoice Margin Pct"},"payment_terms_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":0.0},{"type":"null"}],"title":"Payment Terms Days"},"default_pay_cycle":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Default Pay Cycle"},"default_margin_rule":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Default Margin Rule"},"status":{"type":"string","title":"Status","default":"active"}},"type":"object","required":["trading_name"],"title":"OrganisationIn","description":"Step one of the wizard. Only the trading name is required.\n\nEverything else is configured from the detail page afterwards, which is the\npoint of the wizard: an organisation exists after one screen, and the\ncommercial terms nobody has agreed yet do not block creating it."},"OrganisationPatch":{"properties":{"trading_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Trading Name"},"legal_name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Legal Name"},"abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abn"},"company_number":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Company Number"},"gst_registered":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Gst Registered"},"industry":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Industry"},"region":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Region"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"email":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"title":"Email"},"phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Phone"},"primary_contact":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Primary Contact"},"billing_contact":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Billing Contact"},"po_required":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Po Required"},"invoice_cycle":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Invoice Cycle"},"invoice_format":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Invoice Format"},"invoice_margin_pct":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Invoice Margin Pct"},"payment_terms_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":0.0},{"type":"null"}],"title":"Payment Terms Days"},"default_pay_cycle":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Default Pay Cycle"},"default_margin_rule":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Default Margin Rule"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"OrganisationPatch","description":"Every field optional, so an update carries only what changed.\n\nA full replace would mean the client sending back fields it never showed,\nand any field it forgot would be silently cleared."},"OrganisationSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"trading_name":{"type":"string","title":"Trading Name"},"legal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Name"},"abn":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Abn"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"status":{"type":"string","title":"Status"},"site_count":{"type":"integer","title":"Site Count"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"active_assignments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Active Assignments"}},"type":"object","required":["id","trading_name","legal_name","abn","industry","region","status","site_count","roles","active_assignments"],"title":"OrganisationSummary","description":"The list row."},"OrganisationsIn":{"properties":{"organisation_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Organisation Ids"}},"type":"object","required":["organisation_ids"],"title":"OrganisationsIn"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","minLength":1,"title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"ReportOut":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"entity_type":{"type":"string","title":"Entity Type"},"total":{"type":"integer","title":"Total"},"valid":{"type":"integer","title":"Valid"},"errors":{"type":"integer","title":"Errors"},"rows":{"items":{"$ref":"#/components/schemas/RowOut"},"type":"array","title":"Rows"},"unknown_columns":{"items":{"type":"string"},"type":"array","title":"Unknown Columns"},"blocked_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blocked On"}},"type":"object","required":["job_id","entity_type","total","valid","errors","rows","unknown_columns"],"title":"ReportOut"},"ResultOut":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"entity_type":{"type":"string","title":"Entity Type"},"status":{"type":"string","title":"Status"},"total":{"type":"integer","title":"Total"},"created":{"type":"integer","title":"Created"},"skipped":{"type":"integer","title":"Skipped"},"rows":{"items":{"$ref":"#/components/schemas/RowOut"},"type":"array","title":"Rows"}},"type":"object","required":["job_id","entity_type","status","total","created","skipped","rows"],"title":"ResultOut"},"RoleOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"is_system":{"type":"boolean","title":"Is System"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions"},"user_count":{"type":"integer","title":"User Count"}},"type":"object","required":["id","name","description","is_system","permissions","user_count"],"title":"RoleOut"},"RowErrorOut":{"properties":{"row":{"type":"integer","title":"Row"},"field":{"type":"string","title":"Field"},"message":{"type":"string","title":"Message"},"value":{"type":"string","title":"Value"}},"type":"object","required":["row","field","message","value"],"title":"RowErrorOut"},"RowOut":{"properties":{"row":{"type":"integer","title":"Row"},"valid":{"type":"boolean","title":"Valid"},"errors":{"items":{"$ref":"#/components/schemas/RowErrorOut"},"type":"array","title":"Errors"},"values":{"additionalProperties":true,"type":"object","title":"Values"}},"type":"object","required":["row","valid","errors","values"],"title":"RowOut"},"SessionOut":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"actor":{"$ref":"#/components/schemas/ActorOut"}},"type":"object","required":["access_token","refresh_token","expires_in","actor"],"title":"SessionOut"},"SetRolesIn":{"properties":{"roles":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Roles"}},"type":"object","required":["roles"],"title":"SetRolesIn"},"SetupStatusOut":{"properties":{"tenancy_id":{"type":"string","format":"uuid","title":"Tenancy Id"},"name":{"type":"string","title":"Name"},"items":{"items":{"$ref":"#/components/schemas/ChecklistItem"},"type":"array","title":"Items"},"completed":{"type":"integer","title":"Completed"},"total":{"type":"integer","title":"Total"},"percent_complete":{"type":"integer","title":"Percent Complete"},"seeded":{"additionalProperties":{"type":"integer"},"type":"object","title":"Seeded"},"next_periods":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Next Periods"}},"type":"object","required":["tenancy_id","name","items","completed","total","percent_complete","seeded","next_periods"],"title":"SetupStatusOut"},"SignInRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"password":{"type":"string","minLength":1,"title":"Password"}},"type":"object","required":["email","password"],"title":"SignInRequest"},"SiteIn":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"branch_code":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Branch Code"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["name"],"title":"SiteIn"},"SiteOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"branch_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Branch Code"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["id","name","address","branch_code","notes"],"title":"SiteOut"},"SitePatch":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"branch_code":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Branch Code"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"SitePatch"},"StepIn":{"properties":{"step":{"type":"string","maxLength":60,"minLength":1,"title":"Step"}},"type":"object","required":["step"],"title":"StepIn"},"StepOut":{"properties":{"key":{"type":"string","title":"Key"},"kind":{"type":"string","title":"Kind"},"label":{"type":"string","title":"Label"},"complete":{"type":"boolean","title":"Complete"},"blocked_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Blocked On"}},"type":"object","required":["key","kind","label","complete"],"title":"StepOut"},"TenancyIn":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"industry":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Industry"},"primary_contact_name":{"type":"string","maxLength":200,"minLength":1,"title":"Primary Contact Name"},"primary_contact_email":{"type":"string","maxLength":320,"minLength":3,"title":"Primary Contact Email"}},"type":"object","required":["name","primary_contact_name","primary_contact_email"],"title":"TenancyIn"},"TenancyOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"admin":{"$ref":"#/components/schemas/AdminOut"},"seeded":{"additionalProperties":{"type":"integer"},"type":"object","title":"Seeded"},"delivery_note":{"type":"string","title":"Delivery Note"}},"type":"object","required":["id","name","industry","admin","seeded","delivery_note"],"title":"TenancyOut"},"UserOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"full_name":{"type":"string","title":"Full Name"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"status":{"type":"string","title":"Status"},"roles":{"items":{"type":"string"},"type":"array","title":"Roles"},"organisations":{"items":{"type":"string"},"type":"array","title":"Organisations"},"may_see_sensitive":{"type":"boolean","title":"May See Sensitive"},"last_login_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login At"}},"type":"object","required":["id","email","full_name","phone","status","roles","organisations","may_see_sensitive","last_login_at"],"title":"UserOut"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WorkerDetail":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"type":"string","title":"Email"},"mobile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile"},"job_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Title"},"status":{"type":"string","title":"Status"},"engagement_models":{"items":{"type":"string"},"type":"array","title":"Engagement Models"},"has_account":{"type":"boolean","title":"Has Account"},"active_assignments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Active Assignments"},"emergency_contact":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emergency Contact"},"working_rights_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Working Rights Status"},"background_check_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Background Check Status"},"leave_balance_hours":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Leave Balance Hours"},"engagements":{"items":{"$ref":"#/components/schemas/EngagementOut"},"type":"array","title":"Engagements"},"date_of_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Of Birth"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"visa_reference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Visa Reference"}},"type":"object","required":["id","full_name","email","mobile","job_title","status","engagement_models","has_account","active_assignments","emergency_contact","working_rights_status","background_check_status","leave_balance_hours","engagements"],"title":"WorkerDetail"},"WorkerIn":{"properties":{"full_name":{"type":"string","maxLength":200,"minLength":1,"title":"Full Name"},"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"mobile":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Mobile"}},"type":"object","required":["full_name","email"],"title":"WorkerIn","description":"What the creation dialog asks for, and nothing else.\n\nThree fields. The engagement model, the employing organisation and the\nstart date are configured from the detail page afterwards — a manager\nshould be able to add somebody in one screen rather than gathering\npaperwork before they can begin."},"WorkerOnboardingOut":{"properties":{"worker_id":{"type":"string","format":"uuid","title":"Worker Id"},"full_name":{"type":"string","title":"Full Name"},"status":{"type":"string","title":"Status"},"journeys":{"items":{"$ref":"#/components/schemas/JourneyOut"},"type":"array","title":"Journeys"},"percent_complete":{"type":"integer","title":"Percent Complete"}},"type":"object","required":["worker_id","full_name","status","journeys","percent_complete"],"title":"WorkerOnboardingOut"},"WorkerPatch":{"properties":{"full_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Full Name"},"email":{"anyOf":[{"type":"string","maxLength":320,"minLength":3},{"type":"null"}],"title":"Email"},"mobile":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Mobile"},"job_title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Job Title"},"emergency_contact":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Emergency Contact"},"working_rights_status":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Working Rights Status"},"background_check_status":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Background Check Status"},"status":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Status"},"date_of_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Of Birth"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"visa_reference":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Visa Reference"}},"type":"object","title":"WorkerPatch","description":"Every field optional, so an update carries only what changed.\n\nA full replace would mean the client sending back fields it never showed,\nand anything it forgot would be silently cleared."},"WorkerSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"full_name":{"type":"string","title":"Full Name"},"email":{"type":"string","title":"Email"},"mobile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mobile"},"job_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Title"},"status":{"type":"string","title":"Status"},"engagement_models":{"items":{"type":"string"},"type":"array","title":"Engagement Models"},"has_account":{"type":"boolean","title":"Has Account"},"active_assignments":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Active Assignments"}},"type":"object","required":["id","full_name","email","mobile","job_title","status","engagement_models","has_account","active_assignments"],"title":"WorkerSummary","description":"The list row. Carries nothing sensitive under any role."},"services__core_api__records__router__Page":{"properties":{"items":{"items":{"$ref":"#/components/schemas/OrganisationSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"Page"},"services__core_api__workers__router__Page":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WorkerSummary"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"Page"}}}}