Skip to content

Catalog instantiation — apply a position's duty catalog to a person #5

Description

@os-warren

The onboarding path, and the single biggest adoption risk in the product. Customers arrive with their catalog already written — usually a spreadsheet. If taking a position means hand-typing 26 duties, the rollout dies in week one.

Files you own

  • src/actions/catalog.actions.ts (new), added to dulyActions in src/actions/index.ts
  • src/actions/catalog.handlers.ts (new)
  • src/actions/register-handlers.ts — add your registration call inside the existing function
  • test/catalog-instantiate.test.ts (new)

duly_catalog_apply — global action

Input: a position_code and one or more sys_user ids.

For each active duly_catalog_item with that position_code, create a duly_duty for each selected user:

Duty field From
name, description, form, frequency the catalog item
due_anchor, due_offset_days, lead_days, grace_days the catalog item
owner the selected user
business_unit the user's sys_user_position.business_unit_id anchor
timezone the user's zone if resolvable, else the org default, else UTC
source 'catalog'
catalog_item the item, so edits can be replayed
status 'active'

Idempotent. Applying twice creates nothing the second time — skip any item that already has a duty for that (catalog_item, owner) pair. Report counts: created, skipped.

duly_catalog_sync — global action

Replays cadence edits from the catalog onto duties already instantiated from it. Updates frequency, due_anchor, due_offset_days, lead_days, grace_days on every duly_duty where source = 'catalog' and catalog_item points at a changed item.

Does not touch owner, status, timezone or effective_* — those are local decisions the catalog has no business overwriting. Does not delete duties for retired catalog items; report them instead so a human decides.

Return a summary of what changed, per duty. Sync is destructive to authored cadence, so it must be legible after the fact.

Notes

  • position_code is free text on purpose: a customer can load their catalog on day one, before positions are modelled in the platform. Do not require a sys_user_position row to exist.
  • role is a reserved word in the platform vocabulary and the author-time linter rejects it — the field is position_code, and any new field you add must avoid the word too.

Acceptance

  • applying a 26-item catalog to 3 users creates 78 duties, all source: 'catalog' with catalog_item set
  • applying the same input again creates 0 and reports 78 skipped
  • editing an item's due_offset_days then syncing updates every derived duty and leaves owner/status untouched
  • a duty whose source is 'self' is never touched by sync, even if its catalog_item is somehow set
  • deactivating a catalog item and syncing reports it and changes nothing

Gates

pnpm validate && pnpm typecheck && pnpm test && pnpm build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions