85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
|
|
"""Domain constants: roles, workflow stages, and the transition map.
|
||
|
|
|
||
|
|
Workflow note: an NCR in the "New Request" stage is awaiting Initial
|
||
|
|
Disposition — the initial-disposition review is the action a Disposition
|
||
|
|
Authority performs on a New Request, and it moves the NCR either to
|
||
|
|
Secondary Disposition (when secondary review is required) or straight to
|
||
|
|
Operations. All transitions are validated server-side against
|
||
|
|
ALLOWED_TRANSITIONS; anything else is rejected with HTTP 409.
|
||
|
|
"""
|
||
|
|
from enum import Enum
|
||
|
|
|
||
|
|
|
||
|
|
class Role(str, Enum):
|
||
|
|
REQUESTER = "requester"
|
||
|
|
DISPOSITION_AUTHORITY = "disposition_authority"
|
||
|
|
SECONDARY_DISPOSITION_AUTHORITY = "secondary_disposition_authority"
|
||
|
|
OPERATIONS = "operations"
|
||
|
|
QC_INSPECTOR = "qc_inspector"
|
||
|
|
COSTING = "costing"
|
||
|
|
ADMIN = "admin"
|
||
|
|
|
||
|
|
|
||
|
|
ALL_ROLES: set[str] = {r.value for r in Role}
|
||
|
|
|
||
|
|
ROLE_LABELS: dict[str, str] = {
|
||
|
|
Role.REQUESTER: "Requester",
|
||
|
|
Role.DISPOSITION_AUTHORITY: "Disposition Authority",
|
||
|
|
Role.SECONDARY_DISPOSITION_AUTHORITY: "Secondary Disposition Authority",
|
||
|
|
Role.OPERATIONS: "Operations",
|
||
|
|
Role.QC_INSPECTOR: "QC Inspector",
|
||
|
|
Role.COSTING: "Costing",
|
||
|
|
Role.ADMIN: "Admin",
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
class Stage(str, Enum):
|
||
|
|
NEW_REQUEST = "new_request"
|
||
|
|
SECONDARY_DISPOSITION = "secondary_disposition"
|
||
|
|
OPERATIONS = "operations"
|
||
|
|
QC_INSPECTION = "qc_inspection"
|
||
|
|
COSTING = "costing"
|
||
|
|
CLOSED = "closed"
|
||
|
|
|
||
|
|
|
||
|
|
STAGE_LABELS: dict[str, str] = {
|
||
|
|
Stage.NEW_REQUEST: "New Request",
|
||
|
|
Stage.SECONDARY_DISPOSITION: "Secondary Disposition",
|
||
|
|
Stage.OPERATIONS: "Operations",
|
||
|
|
Stage.QC_INSPECTION: "QC Inspection",
|
||
|
|
Stage.COSTING: "Costing",
|
||
|
|
Stage.CLOSED: "Closed",
|
||
|
|
}
|
||
|
|
|
||
|
|
# Stages an admin may reopen a closed NCR back into.
|
||
|
|
REOPEN_TARGET_STAGES: list[Stage] = [
|
||
|
|
Stage.NEW_REQUEST,
|
||
|
|
Stage.SECONDARY_DISPOSITION,
|
||
|
|
Stage.OPERATIONS,
|
||
|
|
Stage.QC_INSPECTION,
|
||
|
|
Stage.COSTING,
|
||
|
|
]
|
||
|
|
|
||
|
|
ALLOWED_TRANSITIONS: dict[Stage, set[Stage]] = {
|
||
|
|
Stage.NEW_REQUEST: {Stage.SECONDARY_DISPOSITION, Stage.OPERATIONS},
|
||
|
|
Stage.SECONDARY_DISPOSITION: {Stage.OPERATIONS},
|
||
|
|
Stage.OPERATIONS: {Stage.QC_INSPECTION},
|
||
|
|
Stage.QC_INSPECTION: {Stage.COSTING},
|
||
|
|
Stage.COSTING: {Stage.CLOSED},
|
||
|
|
# Reopen (admin only, reason required) — enforced separately.
|
||
|
|
Stage.CLOSED: set(REOPEN_TARGET_STAGES),
|
||
|
|
}
|
||
|
|
|
||
|
|
# Role allowed to act on the NCR in each stage (Admin is always allowed;
|
||
|
|
# Secondary Disposition additionally requires being an assigned authority).
|
||
|
|
STAGE_ACTING_ROLE: dict[Stage, Role] = {
|
||
|
|
Stage.NEW_REQUEST: Role.DISPOSITION_AUTHORITY,
|
||
|
|
Stage.SECONDARY_DISPOSITION: Role.SECONDARY_DISPOSITION_AUTHORITY,
|
||
|
|
Stage.OPERATIONS: Role.OPERATIONS,
|
||
|
|
Stage.QC_INSPECTION: Role.QC_INSPECTOR,
|
||
|
|
Stage.COSTING: Role.COSTING,
|
||
|
|
}
|
||
|
|
|
||
|
|
# Owners to notify when an admin reopens an NCR into a given stage.
|
||
|
|
STAGE_OWNER_ROLE: dict[Stage, Role] = STAGE_ACTING_ROLE
|