Job titles (YAML)
A job title (Cargo) is the bridge between a person and what they can do. It links a user to a set of access roles, property-type extensions, and inherited properties. Assign a user a job title, and they inherit everything the job title grants. Because job titles depend on roles and the data model, they're applied after those — and before users.
The shape of a job title
kind: JobTitle
code: store_manager
display: "Jefe de Tienda"
isActive: true
accessRoles:
- "ordenes-compra:manager"
- "ventas:reader"
allowedExtensions:
- "perfil_jefe"
elements:
- "elemento_inventario_default"
| Field | Required | Notes |
|---|---|---|
kind | Yes | Always JobTitle |
code | Yes | Unique per company, 3–50 chars. Must start with a lowercase letter, then lowercase letters, digits and underscores (^[a-z]+([_a-z0-9]+)*$). Immutable after creation |
display | Yes | Human-readable label (mutable) |
id | No | The 24-character record ID. Optional — normally omitted, since code is the upsert key |
isActive | No | Defaults to true |
accessRoles | No | AccessRole names (case-sensitive), max 50 |
allowedExtensions | No | PropertyType codes, max 50 |
elements | No | Property codes inherited by users |
When an old code doesn't match the current rule. The code format is enforced strictly on create. On update, if the existing record's code already violates the current rule (an old cargo created before the rule tightened), --lax-code downgrades that check to a warning so you can still edit the record's other fields. It never relaxes the check on create, and never lets you introduce a new non-conforming code.
The three list fields each reference a different resource by name or code:
accessRoles→ role names the user inherits.allowedExtensions→ property types a user may attach as a profile extension.elements→ specific properties (e.g. a default location) the user inherits.
These lists are REPLACE-on-update, not merge. When you update a job title, the array you send replaces the one on the server. Omit a role that was already there, and it's removed. Always export before a partial edit:
cotctl jobtitles export store_manager -c acme -o store_manager.yaml
Role names are case-sensitive. cotctl matches accessRoles exactly. If a name isn't found, the error includes a "did you mean…?" suggestion — usually a casing slip. List the real names with cotctl roles list -c <profile>.
Renaming
Like several resources, code is immutable, and there's no in-place rename for job titles. To change a code: deactivate the old one, create a new one, then re-point the affected users with cotctl users apply setting their job to the new code.
Deactivation and reactivation
Deactivate with the dedicated command (or isActive: false in YAML):
cotctl jobtitles deactivate store_manager -c acme
Reactivating is deliberately guarded: applying isActive: true to a currently-inactive job title requires the explicit --allow-reactivate flag, so you never bring one back by accident.
There is no delete for job titles — deactivation is the only removal path, in keeping with Cotalker's soft-delete model.
Apply job titles before users
Order matters here for a subtle reason. If you apply a user whose job code doesn't yet exist as a job title, the backend may silently create a placeholder job title — often malformed or inactive — which then breaks later user applies. Applying job titles first avoids this entirely, and cotctl apply --dir enforces the order for you.
See also
- Roles, Property types — what a job title references
- Users — reference job titles via
job - apply — job titles are applied fourth, before users