Status Naming Convention
This document defines the standard naming convention for status constants in the PRS system.
General Rules
- Constant Keys: All constant keys will use UPPERCASE with underscores (SCREAMING_SNAKE_CASE)
- Constant Values: All constant values will use lowercase with underscores (snake_case)
- Constant Usage: All status comparisons will use constants, not raw strings
Example
| JavaScript |
|---|
| // CORRECT
const REQUISITION_STATUS = Object.freeze({
DRAFT: 'draft',
SUBMITTED: 'submitted',
APPROVED: 'approved',
// ...
});
// INCORRECT - Inconsistent values
const REQUISITION_STATUS = Object.freeze({
DRAFT: 'DRAFT',
SUBMITTED: 'Submitted',
APPROVED: 'approved',
// ...
});
// INCORRECT - Missing Object.freeze()
const REQUISITION_STATUS = {
DRAFT: 'draft',
SUBMITTED: 'submitted',
APPROVED: 'approved',
// ...
};
|
Usage in Code
| JavaScript |
|---|
| // CORRECT
if (requisition.status === REQUISITION_STATUS.DRAFT) {
// ...
}
// INCORRECT - Using raw string
if (requisition.status === 'draft') {
// ...
}
|
Standard Status Constants (Current PRS Implementation)
Requisition Status
| JavaScript |
|---|
| // From: src/domain/constants/requisitionConstants.js
const REQUISITION_STATUS = {
DRAFT: 'draft',
SUBMITTED: 'submitted',
APPROVED: 'approved',
ASSIGNED: 'assigned',
ASSIGNING: 'assigning',
CANVASS_FOR_APPROVAL: 'canvass_for_approval',
FOR_DELIVERY: 'for_delivery',
FOR_PO_REVIEW: 'for_po_review',
FOR_PR_APPROVAL: 'for_pr_approval',
PARTIALLY_CANVASSED: 'partially_canvassed',
REJECTED: 'rejected',
CLOSED: 'closed',
};
|
Canvass Status
| JavaScript |
|---|
| // From: src/domain/constants/canvassConstants.js
const CANVASS_STATUS = Object.freeze({
DRAFT: 'draft',
PARTIAL: 'partially_canvassed', // cascade to RS
FOR_APPROVAL: 'for_approval', // cascade to RS
REJECTED: 'rejected',
APPROVED: 'approved',
});
const CANVASS_APPROVER_STATUS = Object.freeze({
PENDING: 'pending',
REJECTED: 'rejected',
APPROVED: 'approved',
});
const CANVASS_ITEM_STATUS = Object.freeze({
NEW: 'new',
FOR_APPROVAL: 'for_approval',
FOR_SUBMISSION: 'for_submission',
CANCELLED: 'cancelled',
APPROVED: 'approved',
});
|
Purchase Order Status
| JavaScript |
|---|
| // From: src/domain/constants/purchaseOrderConstants.js
const PO_STATUS = Object.freeze({
FOR_PO_REVIEW: 'for_po_review', // Cascade to RS
FOR_PO_APPROVAL: 'for_po_approval', // After review (assigned purchase staff to submit)
FOR_SENDING: 'for_sending',
FOR_DELIVERY: 'for_delivery', // After approval of (supervisor of purchase staff and purchase head)
CLOSED_PO: 'closed_po',
CANCELLED_PO: 'cancelled_po', // Can only cancel if status is from PO_REVIEW
REJECT_PO: 'reject_po', // Cascaded from PO_APPROVER_STATUS (if one of the approvers reject the PO)
});
const PO_APPROVER_STATUS = Object.freeze({
PENDING: 'pending',
REJECTED: 'rejected',
APPROVED: 'approved',
});
const PO_ITEM_STATUS = Object.freeze({
NEW: 'new',
FOR_APPROVAL: 'for_approval',
APPROVED: 'approved',
});
|
Payment Request Status
| JavaScript |
|---|
| // From: src/domain/constants/rsPaymentRequestConstants.js
const RS_PAYMENT_REQUEST_STATUS = Object.freeze({
DRAFT: 'draft',
REJECTED: 'rejected',
FOR_PR_APPROVAL: 'for_pr_approval',
SUBMITTED: 'submitted',
APPROVED: 'approved',
});
const PR_APPROVER_STATUS = Object.freeze({
PENDING: 'pending',
REJECTED: 'rejected',
APPROVED: 'approved',
CLOSED: 'closed',
});
|
Non-Requisition Status
| JavaScript |
|---|
| // From: src/domain/constants/nonRSConstants.js
const NON_RS_STATUS = Object.freeze({
DRAFT: 'draft',
FOR_APPROVAL: 'for_approval',
CLOSED: 'closed',
REJECTED: 'rejected',
CANCELLED: 'cancelled',
});
const NON_RS_APPROVER_STATUS = Object.freeze({
PENDING: 'pending',
REJECTED: 'rejected',
APPROVED: 'approved',
});
|
User Status
| JavaScript |
|---|
| // From: src/domain/constants/userConstants.js
const USER_STATUS = Object.freeze({
INACTIVE: 'inactive',
ACTIVE: 'active',
ON_LEAVE: 'on-leave',
});
|
Frontend Status Display
| JavaScript |
|---|
| // From: prs-frontend/src/features/dashboard/components/Status.jsx
const STATUSES = {
draft: 'Draft',
for_approval: 'For Approval',
assigning: 'Assigning',
assigned: 'Assigned',
// CANVASSING
partially_canvassed: 'Partially Canvassed',
canvass_approval: 'Canvass Approval',
canvass_for_approval: 'Canvass Approval',
cs_draft: 'CS Draft',
cs_approval: 'For CS Approval',
cs_rejected: 'CS Rejected',
cs_approved: 'CS Approved',
// Purchase Order
po_approval: 'PO Approval',
purchase_order: 'Purchase Order',
for_po_review: 'For PO Review',
for_po_approval: 'For PO Approval',
for_delivery: 'For Delivery',
cancelled_po: 'Cancelled PO',
reject_po: 'PO Rejected',
for_po_sending: 'For Sending',
// Payment Request
approved: 'Approved',
for_pr_approval: 'For PR Approval',
// Other statuses
submitted: 'Submitted',
closed: 'Closed',
rejected: 'Rejected',
cancelled: 'Cancelled',
// ... more statuses
};
|
Current Issues & Inconsistencies
Backend vs Frontend Alignment
Issue: The backend uses Object.freeze() for most constants, but the requisition constants are missing it:
| JavaScript |
|---|
| // ❌ Missing Object.freeze() - needs to be updated
const REQUISITION_STATUS = {
DRAFT: 'draft',
// ...
};
// ✅ Properly frozen
const CANVASS_STATUS = Object.freeze({
DRAFT: 'draft',
// ...
});
|
Frontend Status Display Inconsistencies
Issue: Frontend status display components use different status keys than backend constants:
| JavaScript |
|---|
| // Backend constant
CANVASS_FOR_APPROVAL: 'canvass_for_approval'
// Frontend display (inconsistent)
canvass_approval: 'Canvass Approval'
canvass_for_approval: 'Canvass Approval'
|
Recommendations for Improvement
- Add Object.freeze() to all backend constants
- Create shared status constants between frontend and backend
- Standardize frontend status display mapping
- Add TypeScript types for better type safety
- Create status validation utilities
Migration Strategy
When updating status constants, follow these steps:
- Update the constant definition in the constants file
- Search for all usages of the constant in the codebase
- Update all comparisons to use the constant instead of raw strings
- Update any database queries that use the status values
- Update any frontend code that depends on these status values
- Add tests to verify that the status transitions still work correctly
Database Considerations
If the status values are stored in the database, consider:
- For new systems: Use the standardized values from the beginning
- For existing systems: Create a migration script to update existing records
- For hybrid approach: Add mapping functions to convert between old and new values
Frontend Considerations
Ensure that the frontend code is updated to handle the standardized status values:
- Update any status display components
- Update any status-based conditional rendering
- Update any API requests that filter by status