Skip to main content

COD_ON_OFF Flags

Overview

COD_ON_OFF is a visibility bitmask stored in TB_COST that controls field accessibility across different operations. Each flag represents a specific context where the field can be accessed.

Five Flags:

  • L - List view (GET collection)
  • D - Detail view (GET single record)
  • N - New record (POST create)
  • M - Modify record (PUT/PATCH update)
  • R - Search/filter (query parameters)

Key Principle: A field is only accessible in an operation if the corresponding flag is present in its COD_ON_OFF value.


Flag Definitions

L - List View

Context: GET /api/v4/core/{dim} (collection query)

Meaning: Field is included in list view responses

Usage:

GET /api/v4/core/PRD?$num_rows=10

# Response includes fields with 'L' flag
{
"data": [
{
"PRD_ID": 1,
"XPRD01": "Product Name", # Has 'L' flag
"XPRD02": 99.99, # Has 'L' flag
# XPRD99 (internal notes) not returned - no 'L' flag
}
]
}

Examples:

  • COD_ON_OFF = "LDRNM" - ✅ Visible in list
  • COD_ON_OFF = "DRN" - ❌ Not visible in list
  • COD_ON_OFF = "" - ❌ Not visible in list

D - Detail View

Context: GET /api/v4/core/{dim}/{id} (single record query)

Meaning: Field is included in detail view responses

Usage:

GET /api/v4/core/PRD/123

# Response includes fields with 'D' flag
{
"data": {
"PRD_ID": 123,
"XPRD01": "Product Name", # Has 'D' flag
"XPRD02": 99.99, # Has 'D' flag
"XPRD99": "Internal notes...", # Has 'D' but not 'L' (detail-only)
}
}

Examples:

  • COD_ON_OFF = "LDRNM" - ✅ Visible in detail
  • COD_ON_OFF = "LNM" - ❌ Not visible in detail
  • COD_ON_OFF = "D" - ✅ Visible only in detail (not in list)

Pattern - Detail-Only Fields:

-- XPRD99 (internal notes) - visible in detail only, not in list
COD_ON_OFF = "D" -- or "DR", "DNM", etc.

N - New Record

Context: POST /api/v4/core/{dim} (create operation)

Meaning: Field can be set during record creation

Usage:

POST /api/v4/core/PRD
{
"data": {
"XPRD01": "New Product", # Has 'N' flag - allowed
"XPRD02": 99.99, # Has 'N' flag - allowed
"XPRD03": "PRD-001" # No 'N' flag - ERROR!
}
}

# Error response
{
"error": "FieldNotAllowedOnCreate",
"field": "XPRD03",
"message": "Field XPRD03 cannot be set on creation (COD_ON_OFF missing 'N' flag)"
}

Examples:

  • COD_ON_OFF = "LDRNM" - ✅ Can be set on creation
  • COD_ON_OFF = "LDRM" - ❌ Cannot be set on creation (read-only on create)
  • COD_ON_OFF = "N" - ✅ Can only be set on creation (immutable after)

Pattern - Immutable After Creation:

-- XPRD03 (SKU) - can be set on creation, but read-only after
COD_ON_OFF = "LDN" -- List, Detail, New (no M flag = immutable)

M - Modify Record

Context: PUT/PATCH /api/v4/core/{dim}/{id} (update operations)

Meaning: Field can be updated after creation

Usage:

PATCH /api/v4/core/PRD/123
{
"data": {
"XPRD02": 89.99, # Has 'M' flag - allowed
"XPRD03": "NEW" # No 'M' flag - ERROR!
}
}

# Error response
{
"error": "FieldNotModifiable",
"field": "XPRD03",
"message": "Field XPRD03 cannot be modified (COD_ON_OFF missing 'M' flag)"
}

Examples:

  • COD_ON_OFF = "LDRNM" - ✅ Can be modified
  • COD_ON_OFF = "LDRN" - ❌ Cannot be modified (immutable after creation)
  • COD_ON_OFF = "M" - ✅ Can only be modified (not set on creation)

Pattern - Modify-Only Fields:

-- XPRD_STATUS (order status) - can only be changed via workflow, not on creation
COD_ON_OFF = "LDM" -- List, Detail, Modify (no N flag = can't set on create)

R - Search/Filter

Context: Query parameters ?filter[field]=value

Meaning: Field can be used in filter conditions

Usage:

# Search by product name (has 'R' flag) - allowed
GET /api/v4/core/PRD?filter[XPRD01][$like]=Widget%

# Search by internal notes (no 'R' flag) - ERROR!
GET /api/v4/core/PRD?filter[XPRD99]=something

# Error response
{
"error": "FieldNotSearchable",
"field": "XPRD99",
"message": "Field XPRD99 cannot be used in filters (COD_ON_OFF missing 'R' flag)"
}

Examples:

  • COD_ON_OFF = "LDRNM" - ✅ Can be used in filters
  • COD_ON_OFF = "LDNM" - ❌ Cannot be used in filters
  • COD_ON_OFF = "R" - ✅ Can only be used in filters (not visible)

Pattern - Searchable But Hidden:

-- Searchable foreign key, but dimension name shown instead
COD_ON_OFF = "R" -- Can filter by ID, but not displayed (use $expand instead)

Common COD_ON_OFF Patterns

Full Access (Most Common)

COD_ON_OFF = "LDRNM"

Meaning:

  • ✅ Visible in list views
  • ✅ Visible in detail views
  • ✅ Can be set on creation
  • ✅ Can be modified
  • ✅ Can be used in searches

Use Cases:

  • Standard editable fields (name, description, price, quantity)
  • User-controlled attributes
  • Most business data fields

Example:

-- Product name - full access
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, REQUIRED)
VALUES ('PRD', 1, 'XPRD01', 'LDRNM', TRUE);

Read-Only (Display Only)

COD_ON_OFF = "LDR"

Meaning:

  • ✅ Visible in list views
  • ✅ Visible in detail views
  • ❌ Cannot be set on creation
  • ❌ Cannot be modified
  • ✅ Can be used in searches

Use Cases:

  • System-generated fields (timestamps, counters)
  • Calculated/derived fields
  • Auto-populated fields (via pre-insert functions)

Example:

-- Created timestamp - read-only
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, VALUE_TEMP)
VALUES ('PRD', 99, 'CREATED_AT', 'LDR', '{timestamp}');

Immutable After Creation

COD_ON_OFF = "LDRN"

Meaning:

  • ✅ Visible in list views
  • ✅ Visible in detail views
  • ✅ Can be set on creation
  • ❌ Cannot be modified after creation
  • ✅ Can be used in searches

Use Cases:

  • Unique identifiers (SKU, reference numbers)
  • Immutable configuration (record type, category on creation)
  • Audit fields that shouldn't change

Example:

-- Product SKU - immutable after creation
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, REQUIRED)
VALUES ('PRD', 3, 'XPRD03', 'LDRN', TRUE);

Modify-Only (Workflow Fields)

COD_ON_OFF = "LDRM"

Meaning:

  • ✅ Visible in list views
  • ✅ Visible in detail views
  • ❌ Cannot be set on creation
  • ✅ Can be modified
  • ✅ Can be used in searches

Use Cases:

  • Workflow status fields (updated via state machine)
  • Approval flags (set by reviewers, not creators)
  • System-managed state

Example:

-- Order status - set by workflow, not on creation
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, VALUE_TEMP)
VALUES ('ORD', 10, 'XORD_STATUS', 'LDRM', '{default:pending}');

Detail-Only (Sensitive Data)

COD_ON_OFF = "DNMR"

Meaning:

  • ❌ Not visible in list views
  • ✅ Visible in detail views
  • ✅ Can be set on creation
  • ✅ Can be modified
  • ✅ Can be used in searches

Use Cases:

  • Sensitive fields (internal notes, comments)
  • Large text fields (descriptions, specifications)
  • Fields too detailed for list view

Example:

-- Internal notes - detail only
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 99, 'XPRD99', 'DNMR');

Hidden (Internal Use)

COD_ON_OFF = ""

Meaning:

  • ❌ Not visible in any view
  • ❌ Cannot be set on creation
  • ❌ Cannot be modified
  • ❌ Cannot be used in searches

Use Cases:

  • Internal system fields
  • Deprecated fields (backward compatibility)
  • Technical metadata

Example:

-- Internal processing flag - hidden from API
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 998, 'XPRD_INTERNAL_FLAG', '');

Searchable But Not Visible

COD_ON_OFF = "R"

Meaning:

  • ❌ Not visible in list views
  • ❌ Not visible in detail views
  • ❌ Cannot be set directly
  • ❌ Cannot be modified directly
  • ✅ Can be used in searches

Use Cases:

  • Foreign key IDs (use $expand to show related dimension)
  • Technical identifiers for filtering
  • Search-only lookup fields

Example:

-- Category ID - searchable but show category name via $expand
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 5, 'XPRD_CATEGORY_ID', 'R');

Validation Rules

Creation (POST)

Rule: Field can only be included in POST body if COD_ON_OFF contains 'N' flag

Validation:

// CoreWrite validation
function validateCreateFields(data, configs) {
const errors = [];

for (const [field, value] of Object.entries(data)) {
const config = configs.find(c => c.COD_VAR === field);

if (!config) {
errors.push(`Unknown field: ${field}`);
} else if (!config.COD_ON_OFF.includes('N')) {
errors.push(`Field ${field} cannot be set on creation (missing 'N' flag)`);
}
}

return errors;
}

Example:

# ❌ ERROR - XPRD03 has COD_ON_OFF="LDR" (no 'N' flag)
POST /api/v4/core/PRD
{
"data": {
"XPRD01": "Product",
"XPRD03": "SKU-001" # Error: cannot set on creation
}
}

Update (PUT/PATCH)

Rule: Field can only be included in PUT/PATCH body if COD_ON_OFF contains 'M' flag

Validation:

// CoreWrite validation
function validateUpdateFields(data, configs) {
const errors = [];

for (const [field, value] of Object.entries(data)) {
const config = configs.find(c => c.COD_VAR === field);

if (!config) {
errors.push(`Unknown field: ${field}`);
} else if (!config.COD_ON_OFF.includes('M')) {
errors.push(`Field ${field} cannot be modified (missing 'M' flag)`);
}
}

return errors;
}

Example:

# ❌ ERROR - XPRD03 has COD_ON_OFF="LDRN" (no 'M' flag = immutable)
PATCH /api/v4/core/PRD/123
{
"data": {
"XPRD03": "NEW-SKU" # Error: field is immutable
}
}

Rule: Field can only be used in ?filter[field]=value if COD_ON_OFF contains 'R' flag

Validation:

// CoreQuery validation
function validateFilterFields(filters, configs) {
const errors = [];

for (const field of Object.keys(filters)) {
const config = configs.find(c => c.COD_VAR === field);

if (!config) {
errors.push(`Unknown field: ${field}`);
} else if (!config.COD_ON_OFF.includes('R')) {
errors.push(`Field ${field} cannot be used in filters (missing 'R' flag)`);
}
}

return errors;
}

Example:

# ❌ ERROR - XPRD99 has COD_ON_OFF="DN" (no 'R' flag = not searchable)
GET /api/v4/core/PRD?filter[XPRD99]=notes

Response Filtering

List View (GET collection): Only include fields with 'L' flag

Detail View (GET single): Only include fields with 'D' flag

Implementation:

// CoreQuery response filtering
function filterResponseFields(record, configs, viewType) {
const flag = viewType === 'list' ? 'L' : 'D';
const filtered = {};

for (const [field, value] of Object.entries(record)) {
const config = configs.find(c => c.COD_VAR === field);

if (config && config.COD_ON_OFF.includes(flag)) {
filtered[field] = value;
}
}

return filtered;
}

Decision Matrix

Want to...Flag RequiredExample COD_ON_OFF
Show in list viewL"LDRNM", "L", "LDR"
Show in detail viewD"LDRNM", "D", "DNM"
Set on creationN"LDRNM", "N", "LDRN"
Modify after creationM"LDRNM", "M", "LDRM"
Use in search filtersR"LDRNM", "R", "LDR"
Make field read-onlyNo N or M"LDR", "DR", "L"
Make field immutableN but no M"LDRN", "LN", "LDRN"
Hide from list, show in detailD but no L"DNMR", "D", "DNM"
Hide completelyEmpty string""
Allow search onlyR alone"R"

Common Mistakes

❌ Mistake 1: Wrong Flags for Immutable Fields

-- ❌ BAD - Has 'M' flag, so it can be modified
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 3, 'XPRD03', 'LDRNM'); -- Can be modified!

-- ✅ CORRECT - No 'M' flag, immutable after creation
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 3, 'XPRD03', 'LDRN'); -- Immutable

❌ Mistake 2: System Fields With Write Flags

-- ❌ BAD - Timestamp should be system-managed
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, VALUE_TEMP)
VALUES ('PRD', 99, 'CREATED_AT', 'LDRNM', '{timestamp}'); -- User can override!

-- ✅ CORRECT - Read-only, system-managed
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF, VALUE_TEMP)
VALUES ('PRD', 99, 'CREATED_AT', 'LDR', '{timestamp}'); -- System-only

❌ Mistake 3: Missing 'R' Flag for Searchable Fields

-- ❌ BAD - Can't filter by category
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 5, 'XPRD05', 'LDNM'); -- No 'R' flag

-- ✅ CORRECT - Searchable
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 5, 'XPRD05', 'LDRNM'); -- Has 'R' flag

❌ Mistake 4: Detail-Only Fields Missing 'D' Flag

-- ❌ BAD - Not visible anywhere
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 99, 'XPRD99', 'NMR'); -- No 'L' or 'D' = invisible

-- ✅ CORRECT - Visible in detail view
INSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF)
VALUES ('PRD', 99, 'XPRD99', 'DNMR'); -- Detail-only

Summary

  • COD_ON_OFF controls field visibility across five contexts (L/D/N/M/R)
  • L = List view, D = Detail view, N = New (create), M = Modify (update), R = Search
  • ✅ Most common patterns: "LDRNM" (full access), "LDR" (read-only), "LDRN" (immutable)
  • ✅ Validation enforced by CoreWrite (create/update) and CoreQuery (search)
  • ✅ Fields without required flags are rejected with clear error messages

Key Takeaways:

  1. Check COD_ON_OFF before attempting operations
  2. Read-only fields: exclude 'N' and 'M' flags
  3. Immutable fields: include 'N' but exclude 'M'
  4. Detail-only fields: include 'D' but exclude 'L'
  5. Hidden fields: empty string ""

Best Practice: Always query TB_COST to check COD_ON_OFF before rendering forms or building queries.