Fields
Field metadata schema used in SolidX.
Field Metadata
Where it lives
JSON Pointer: /moduleMetadata/models/fields
JSONPath: $.moduleMetadata.models[*].fields[*]
Parent: models inside moduleMetadata
Overview
Field metadata defines what a field is.
It is the source of truth for the field's semantic type, validation rules, storage intent, relation behavior, computed value configuration, and platform-level flags such as privacy, auditing, and system ownership.
If you are deciding how a field should behave as part of a model, this is the page to use.
If you are deciding how that field should appear in a form, list, or tree view, use View Metadata.
What Belongs On This Page
Use this page to answer questions such as:
- Which attrs can be authored on a field definition?
- Which of those attrs are meaningful for a specific field type?
- How does SolidX validate the field at runtime?
- How does the field participate in persistence and filtering?
- Which attrs are structural, and which are cross-cutting platform flags?
This page explains the authored field contract and how that contract affects runtime behavior across validation, persistence, and querying.
Field Metadata Attributes
The full field metadata schema spans many field types, but most attrs fall into a few consistent families:
| Attribute family | What it controls |
|---|---|
| Identity | Field naming and user-facing labels such as name, displayName, and description |
| Type and storage | Semantic type and persistence hints such as type, ormType, columnName, defaultValue, min, max, and length |
| Validation | Runtime constraints such as required, regexPattern, and regexPatternNotMatchingErrorMsg |
| Query and lookup | Attributes that shape how a field is used in filtering, search, or as a business key, such as index and isUserKey |
| Security and auditing | Attributes such as private and enableAuditTracking |
| Lifecycle and ownership | Attributes such as isSystem, isMarkedForRemoval, and isPrimaryKey |
| Specialized behavior | Relation, selection, media, and computed-field attrs that apply only to the matching field families |
The per-field sections below are the authoritative reference for when each attr matters.
Field Types
shortText
Use shortText for short scalar strings such as names, titles, identifiers, labels, codes, and other compact text values.
In SolidX, shortText is a string-backed field. It supports length and pattern validation, persists as scalar text, and participates naturally in text-oriented filtering and search flows.
| Attr | Required | Purpose | Notes for shortText |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be shortText |
ormType | No | Persistence-layer storage hint | Commonly varchar for short text |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
min | No | Minimum length | Enforced in generated form validation |
max | No | Maximum length | Enforced in generated form validation and used as the effective backend length limit |
length | No | Generic storage-length attribute | Not the primary runtime length constraint for shortText; use max when you need validation-level length enforcement |
regexPattern | No | Pattern constraint | Enforced in generated forms and in backend validation |
regexPatternNotMatchingErrorMsg | No | Custom regex validation message | Used by generated form validation; backend validation currently returns a generic regex error |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful for frequently filtered or searched fields |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Often used when a model needs a stable business identifier rather than a numeric id |
enableAuditTracking | No | Audit-tracking flag | Marks the field for field-level auditing concerns |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Important when the field doubles as the model's primary identifier |
For shortText, SolidX validates in two places:
- The generated form layer validates
required,min,max, andregexPattern. - The backend validation layer checks requiredness, string type, maximum length, and regex compliance.
Two important behaviors to note:
maxis the effective length limit enforced by backend validationminis enforced in generated form validation
shortText is persisted as a scalar string field.
The submitted value is validated and then stored without field-specific transformation.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because shortText is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including:
- equality and inequality
inandnotIncontainsandnotContains- case-insensitive contains variants
startsWithandendsWith- null and not-null checks
This makes shortText a natural fit for searchable list views, user keys, codes, names, and other text-oriented query flows.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "bankUserId",
"displayName": "Bank User ID",
"description": "Bank UserId (MER followed by customer CIF)",
"type": "shortText",
"ormType": "varchar",
"defaultValue": null,
"required": true,
"min": 9,
"max": 16,
"regexPattern": null,
"regexPatternNotMatchingErrorMsg": null,
"unique": false,
"index": true,
"columnName": null,
"private": false,
"isUserKey": false,
"enableAuditTracking": true,
"isSystem": false,
"isMarkedForRemoval": false,
"isPrimaryKey": false
}This is a representative shortText field because it combines a clear business purpose with required validation, explicit length limits, and index intent.
For rendering, widgets, and layout attrs related to shortText, see View Metadata.
longText
Use longText for extended text such as descriptions, notes, instructions, configuration blobs stored as text, or any other content that benefits from a multiline editing experience.
In SolidX, longText is a string-backed field intended for larger textual values. It supports pattern validation, persists as scalar text, and participates in the same text-oriented filtering and search flows as other scalar text fields.
| Attr | Required | Purpose | Notes for longText |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be longText |
ormType | No | Persistence-layer storage hint | Commonly text for multiline content |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend validation |
min | No | Minimum length | Enforced in generated form validation |
max | No | Maximum length | Enforced in generated form validation |
length | No | Generic storage-length attribute | Not used as the primary runtime length control for longText |
regexPattern | No | Pattern constraint | Enforced in generated forms and in backend validation |
regexPatternNotMatchingErrorMsg | No | Custom regex validation message | Used by generated form validation; backend validation currently returns a generic regex error |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when long-text values participate in targeted query flows |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Uncommon for longText, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Marks the field for field-level auditing concerns |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for multiline text fields |
For longText, SolidX validates in two places:
- The generated form layer validates
required,min,max, andregexPattern. - The backend validation layer checks requiredness, string type, and regex compliance.
Two important behaviors to note:
minandmaxare enforced in generated form validation- backend validation does not currently enforce
minormaxforlongText
longText is persisted as a scalar text field.
The submitted value is validated and then stored without field-specific transformation.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because longText is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including:
- equality and inequality
inandnotIncontainsandnotContains- case-insensitive contains variants
startsWithandendsWith- null and not-null checks
This makes longText suitable for description-style filters, notes, instructions, and text-driven administrative search flows.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "description",
"displayName": "Description",
"description": null,
"type": "longText",
"ormType": "text",
"isSystem": false,
"regexPattern": "",
"regexPatternNotMatchingErrorMsg": "Invalid regex pattern",
"defaultValue": null,
"min": null,
"max": null,
"required": true,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": false
}This is a representative longText field because it shows the usual multiline text contract: semantic text storage, optional regex support, and standard required handling.
For rendering, widgets, and layout attrs related to longText, see View Metadata.
richText
Use richText for formatted content such as article bodies, policy text, message templates, or any other field where users need headings, emphasis, lists, links, or other rich formatting.
In SolidX, richText is a string-backed field that stores formatted content as text. It supports pattern validation, persists as scalar text, and participates in the same text-oriented filtering and search flows as other scalar text fields.
| Attr | Required | Purpose | Notes for richText |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be richText |
ormType | No | Persistence-layer storage hint | Commonly text for formatted content |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend validation |
min | No | Minimum length | Enforced in generated form validation |
max | No | Maximum length | Enforced in generated form validation |
length | No | Generic storage-length attribute | Not used as the primary runtime length control for richText |
regexPattern | No | Pattern constraint | Enforced in generated forms and in backend validation |
regexPatternNotMatchingErrorMsg | No | Custom regex validation message | Used by generated form validation; backend validation currently returns a generic regex error |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when rich-text values participate in targeted query flows |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Uncommon for richText, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Marks the field for field-level auditing concerns |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for rich formatted content |
For richText, SolidX validates in two places:
- The generated form layer validates
required,min,max, andregexPattern. - The backend validation layer checks requiredness, string type, and regex compliance.
Two important behaviors to note:
minandmaxare enforced in generated form validation- backend validation does not currently enforce
minormaxforrichText
richText is persisted as a scalar text field.
The submitted value is validated and then stored without field-specific transformation.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because richText is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX, including:
- equality and inequality
inandnotIncontainsandnotContains- case-insensitive contains variants
startsWithandendsWith- null and not-null checks
This makes richText suitable for administrative search and text-driven query flows, even though end-user presentation is usually richer than plain text.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "content",
"displayName": "Content",
"description": null,
"type": "richText",
"ormType": "text",
"isSystem": false,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null
}This is a representative richText field because it captures the typical contract: formatted content stored as text and rendered through the rich-text form experience.
For rendering, widgets, and layout attrs related to richText, see View Metadata.
json
Use json for structured values that should be stored and transported as JSON rather than as free-form text.
This field type is appropriate when the value is naturally object- or array-shaped and should remain machine-structured instead of being treated as plain text or formatted rich content.
In SolidX, json is a structured data field with JSON-specific backend validation. It is intended for persisted JSON payloads, metadata blocks, configuration objects, and other structured content.
| Attr | Required | Purpose | Notes for json |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be json |
ormType | No | Persistence-layer storage hint | Common values include simple-json and jsonb, depending on storage needs |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend validation |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful only when the underlying storage/query model supports the intended access pattern |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Uncommon for json, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Marks the field for field-level auditing concerns |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for structured JSON values |
For json, SolidX validates in two places:
- The generated form layer checks requiredness.
- The backend validation layer checks requiredness and validates that the submitted value is valid JSON.
One important behavior to note:
- unlike text-based field types, the backend validator explicitly checks whether the submitted value is valid JSON rather than only checking its scalar type
json is persisted as structured JSON data according to the configured ormType.
The submitted value is validated and then stored without field-specific transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
json is structurally different from scalar text and numeric fields.
At the field-contract level, it can participate in standard persistence and retrieval flows, but JSON-aware filtering behavior depends heavily on the storage model and the query path being used. For this reason, JSON fields should be treated more conservatively than ordinary scalar fields when designing search and list experiences.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "metadata",
"displayName": "Metadata",
"type": "json",
"ormType": "simple-json",
"required": false,
"unique": false,
"index": false,
"private": false
}This is a representative json field because it shows the core contract clearly: structured data storage, JSON-specific validation, and a persistence-oriented ormType.
For rendering, widgets, and layout attrs related to json, see View Metadata.
int
Use int for whole-number values where fractional precision is not required.
This field type is appropriate for counts, sequence numbers, rankings, durations measured as whole units, and other numeric values that should behave like integers rather than as free-form text.
In SolidX, int is a scalar whole-number field. It supports numeric requiredness and numeric bounds, persists as an integer-style value, and participates naturally in numeric filtering, sorting, and reporting flows.
| Attr | Required | Purpose | Notes for int |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be int |
ormType | No | Persistence-layer storage hint | Commonly int or integer |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
min | No | Minimum numeric value | Enforced in generated forms and in backend CRUD validation |
max | No | Maximum numeric value | Enforced in generated forms and in backend CRUD validation |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when the value is frequently sorted or filtered |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for int, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when numeric changes should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Common for identity-style integer fields |
For int, SolidX validates in two places:
- The generated form layer validates requiredness and numeric bounds using a number-aware schema.
- The backend validation layer checks requiredness, integer shape, and numeric bounds.
Three important behaviors to note:
intexpects whole-number values rather than decimal valuesminandmaxrepresent numeric bounds, not string lengthintdoes not use text-oriented attrs such aslengthorregexPattern
int is persisted as a scalar integer-style value.
The submitted value is validated and then stored without field-specific transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because int represents a numeric scalar, it works naturally with numeric sorting, exact-match filtering, and bounded comparisons.
Typical use cases include:
- sorting records by sequence or rank
- filtering by counts and operational thresholds
- reporting on durations, quantities, or other whole-number metrics
In practice, int is the natural choice when business meaning depends on numeric ordering rather than on text search.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "totalCopies",
"displayName": "Total Copies",
"description": null,
"type": "int",
"ormType": "integer",
"defaultValue": null,
"min": 1,
"max": null,
"required": true,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": true,
"isPrimaryKey": false
}This is a representative int field because it shows the common contract clearly: a persisted whole-number value, a numeric minimum bound, and a business rule where fractional precision would not make sense.
For rendering, widgets, and layout attrs related to int, see View Metadata.
bigint
Use bigint for whole-number values that may exceed the normal range or intent of ordinary integer fields.
This field type is appropriate for large identifiers, large-duration counters, imported legacy numeric keys, and other whole-number values that should remain integers but may need a larger persistence footprint.
In SolidX, bigint is a large whole-number field. It is intended for persisted integer-like values with a bigger numeric envelope than int, while still participating in the same broad category of numeric filtering and sorting flows.
| Attr | Required | Purpose | Notes for bigint |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be bigint |
ormType | No | Persistence-layer storage hint | Commonly bigint |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when the value is frequently sorted or filtered |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Common for legacy or external numeric identifiers |
enableAuditTracking | No | Audit-tracking flag | Useful when large numeric values should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Common for imported or legacy numeric identities |
For bigint, SolidX validates requiredness and numeric shape at the CRUD boundary, and generated forms reuse the same whole-number editing experience used for int.
Two important behaviors to note:
- backend validation accepts string or number inputs and coerces them into a bigint-aware value before applying the numeric checks
- the generated UI currently reuses the integer field path, so very large values should be reviewed carefully when they may exceed JavaScript safe-integer handling
bigint is intended to persist a large whole-number value.
The submitted value is validated and then stored without field-specific transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because bigint remains a numeric scalar, it fits the same broad query patterns as int.
Typical use cases include:
- sorting by imported numeric identifiers
- exact lookup by large request or transaction keys
- operational reporting on large-duration counters and legacy numeric values
In practice, bigint is most useful where whole-number semantics matter but ordinary integer assumptions are too small or too implementation-specific.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "timeRequestInMillisecond",
"displayName": "Time Request In Millisecond",
"description": null,
"type": "bigint",
"ormType": "bigint",
"defaultValue": null,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": "TimeReqInMillsec",
"enableAuditTracking": true,
"isPrimaryKey": false
}This is a representative bigint field because it shows the intended contract clearly: a persisted large whole-number value, a bigint-specific storage hint, and a business metric that should remain numeric rather than textual.
For rendering, widgets, and layout attrs related to bigint, see View Metadata.
decimal
Use decimal for numeric values where fractional precision matters.
This field type is appropriate for amounts, rates, balances, measurements, and other numeric values that should support decimal precision rather than only whole-number input.
In SolidX, decimal is a scalar numeric field. It supports numeric requiredness and numeric bounds, persists as a decimal-style value, and participates naturally in numeric filtering, sorting, and reporting flows.
| Attr | Required | Purpose | Notes for decimal |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be decimal |
ormType | No | Persistence-layer storage hint | Commonly decimal, numeric, or another precision-aware database type |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
min | No | Minimum numeric value | Enforced in generated forms and in backend CRUD validation |
max | No | Maximum numeric value | Enforced in generated forms and in backend CRUD validation |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when the value is frequently sorted or filtered |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for decimal, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when precision-sensitive values should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a decimal field |
For decimal, SolidX validates in two places:
- The generated form layer validates requiredness and numeric bounds using a number-aware schema.
- The backend validation layer checks requiredness, numeric shape, and numeric bounds.
Three important behaviors to note:
decimalaccepts numeric values with fractional precisionminandmaxrepresent numeric bounds, not string lengthdecimaldoes not use text-oriented attrs such aslengthorregexPattern
decimal is persisted as a scalar precision-aware numeric value.
The submitted value is validated and then stored without field-specific transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because decimal represents a numeric scalar, it works naturally with sorting, exact-match filtering, and bounded comparisons.
Typical use cases include:
- filtering records by amount thresholds
- sorting balances, prices, or rates
- reporting on numeric values where fractional precision matters
In practice, decimal is the natural choice whenever business meaning depends on numeric precision rather than on textual formatting.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "latePaymentFees",
"displayName": "Late Payment Fees",
"description": null,
"type": "decimal",
"ormType": "decimal",
"defaultValue": "0",
"min": null,
"max": null,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": true
}This is a representative decimal field because it shows the common contract clearly: a persisted precision-aware numeric value, a decimal-oriented storage hint, and a default that fits amount-style workflows.
For rendering, widgets, and layout attrs related to decimal, see View Metadata.
boolean
Use boolean for fields that represent a binary state such as enabled or disabled, active or inactive, approved or not approved, or any other yes-or-no decision.
In SolidX, boolean is a scalar true-or-false field. It is intended for toggles, switches, flags, and simple state markers that should be stored and queried as boolean data rather than as text.
| Attr | Required | Purpose | Notes for boolean |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be boolean |
ormType | No | Persistence-layer storage hint | Commonly boolean |
defaultValue | No | Default value for metadata-driven consumers | Often used to initialize generated form state for a new record |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon for boolean, but still part of the field contract |
index | No | Indexing intent | Useful when the flag is frequently used in filtering |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Uncommon for boolean, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when state changes should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though rarely appropriate for a boolean field |
For boolean, SolidX validates in two places:
- The generated form layer validates requiredness using a boolean-aware schema.
- The backend validation layer checks requiredness and boolean type.
Two important behaviors to note:
booleandoes not use text-oriented attrs such asmin,max,length, orregexPattern- at the CRUD boundary, the runtime value is treated as a true-or-false field rather than as free-form text
boolean is persisted as a scalar boolean field.
The submitted value is validated and then stored without any field-specific persistence transformation.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because boolean represents a binary state, it is most useful in exact-match style filtering and operational list views.
Typical use cases include:
- filtering records by enabled versus disabled state
- separating approved and unapproved records
- narrowing operational queues by simple flags such as duplicate, active, verified, or system-owned
In practice, boolean fits best where users need to quickly slice a dataset by state rather than search inside a textual value.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "isPBLEnabled",
"displayName": "PBL",
"description": null,
"type": "boolean",
"ormType": "boolean",
"defaultValue": "true",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": true,
"isSystem": false
}This is a representative boolean field because it captures the common contract clearly: a persisted state flag, an explicit storage intent, and a default value used by metadata-driven experiences.
For rendering, widgets, and layout attrs related to boolean, see View Metadata.
date
Use date for calendar dates where the day matters but the time of day does not.
This field type is appropriate for values such as date of joining, approval date, effective date, due date, or any other business date that should be treated as a date rather than as free-form text.
In SolidX, date is a scalar date field. It is intended for persisted calendar values and participates naturally in date-oriented filtering and reporting flows.
| Attr | Required | Purpose | Notes for date |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be date |
ormType | No | Persistence-layer storage hint | Commonly date |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when the date is frequently used in filtering or sorting |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for date, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when date changes should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a date field |
For date, SolidX validates in two places:
- The generated form layer validates requiredness using a date-aware schema.
- The backend validation layer checks requiredness and date type.
Two important behaviors to note:
datedoes not use text-oriented attrs such asmin,max,length, orregexPattern- the same CRUD validation path is also reused for
datetime, so date-like fields share a common backend date-validation contract
date is persisted as a scalar date value.
The submitted value is validated and then stored without any field-specific persistence transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because date represents a calendar value, it is well suited to time-oriented filtering and reporting.
Typical use cases include:
- sorting records by chronology
- filtering records by a specific day
- narrowing datasets by effective date, approval date, or joining date
In practice, date works best where users need consistent calendar semantics rather than free-form text search.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "doj",
"displayName": "DOJ",
"description": "date of joining",
"type": "date",
"ormType": "date",
"defaultValue": null,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": true,
"isSystem": false
}This is a representative date field because it captures the typical contract clearly: a persisted calendar value, a date-specific storage intent, and a business use case that benefits from consistent date handling.
For rendering, widgets, and layout attrs related to date, see View Metadata.
datetime
Use datetime for values where both the calendar date and the time of day matter.
This field type is appropriate for timestamps such as approval time, publication time, expiry time, login events, and other business events that should preserve both date and time semantics.
In SolidX, datetime is a scalar date-time field. It is intended for persisted timestamp-style values and participates naturally in time-oriented filtering, sorting, and reporting flows.
| Attr | Required | Purpose | Notes for datetime |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be datetime |
ormType | No | Persistence-layer storage hint | Commonly datetime or timestamp |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when the timestamp is frequently used in filtering or sorting |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for datetime, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when timestamp changes should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a datetime field |
For datetime, SolidX validates in two places:
- The generated form layer validates requiredness using a date-aware schema.
- The backend validation layer checks requiredness and date type through the shared date-time validation path.
Two important behaviors to note:
datetimedoes not use text-oriented attrs such asmin,max,length, orregexPattern- the same CRUD validation path is currently shared with
date, so both field types rely on the same backend date-validation contract
datetime is persisted as a scalar timestamp-like value.
The submitted value is validated and then stored without any field-specific persistence transformation in the CRUD manager itself.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because datetime represents a timestamp-like value, it is well suited to chronological reporting and operational history flows.
Typical use cases include:
- ordering records by event time
- filtering by publication, approval, or execution time
- presenting audit-style timelines and process timestamps
In practice, datetime is the natural choice whenever time-of-day matters as much as the date itself.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "startTime",
"displayName": "Start Time",
"description": null,
"type": "datetime",
"ormType": "datetime",
"defaultValue": null,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": "StartTime",
"enableAuditTracking": true,
"isSystem": false
}This is a representative datetime field because it captures the common contract clearly: a persisted timestamp, a timestamp-oriented storage intent, and a business use case that benefits from time-aware presentation and sorting.
For rendering, widgets, and layout attrs related to datetime, see View Metadata.
time
Use time for clock-time values where the time of day matters but the calendar date does not.
This field type is appropriate for business hours, schedule boundaries, opening and closing times, and other values that should behave like times rather than full timestamps.
In SolidX, time has clear UI support as a time-oriented field in forms and views. It is intended for persisted clock-time values, but its backend CRUD support is currently less complete than date and datetime.
| Attr | Required | Purpose | Notes for time |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be time |
ormType | No | Persistence-layer storage hint | Commonly time |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when the time value participates in sorting or filtering |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for time, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when time changes should be tracked explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a time field |
For time, SolidX currently validates requiredness in the generated form layer using a date-like schema.
One important behavior to note:
- core UI support for
timeis present, butcrud.service.tsdoes not currently routeSolidFieldType.timethrough a dedicated backend field manager, so the backend runtime contract is not yet as complete as the contracts fordateanddatetime
time is intended to persist a clock-time value.
At the UI layer, the selected time is normalized into a submitted value during form-data generation. At the backend layer, the field contract is present, but the dedicated CRUD-manager path is not currently wired in the same way as other mature scalar field types.
Attrs such as ormType, columnName, unique, and index should therefore be understood as persistence and schema intent, with the current implementation maturity taken into account.
Because time represents a clock-time value, it is most useful for schedule-style displays and ordering within a business day.
Typical use cases include:
- start and end times for scheduled jobs
- opening and closing times
- time-only display in generated forms and reports
In practice, time is best used where the UI experience is valuable today and the backend behavior is known and reviewed as part of implementation.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "startTime",
"displayName": "Start Time",
"description": null,
"type": "time",
"ormType": "time",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"isSystem": false
}This is a representative time field because it shows the intended contract clearly: a clock-time value with a dedicated UI experience and a time-specific storage intent.
For rendering, widgets, and layout attrs related to time, see View Metadata.
email
Use email for values that should represent an email address rather than general free-form text.
This field type is appropriate for customer emails, notification targets, login identifiers, contact addresses, and other values that should follow email-specific validation expectations.
In SolidX, email is a string-backed field with email-aware backend validation. It persists as scalar text and participates naturally in text-oriented search, filtering, and lookup flows.
| Attr | Required | Purpose | Notes for email |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be email |
ormType | No | Persistence-layer storage hint | Commonly varchar |
defaultValue | No | Default value for metadata-driven consumers | Used by generated form initialization when no existing value is present |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
min | No | Minimum length | Enforced in generated form validation |
max | No | Maximum length | Enforced in generated form validation and in backend validation |
regexPattern | No | Pattern constraint | Can further restrict acceptable email shapes beyond the core email validator |
regexPatternNotMatchingErrorMsg | No | Custom regex validation message | Used by generated form validation; backend validation currently returns a generic regex error |
unique | No | Uniqueness intent | Relevant to generated schema and persistence constraints rather than to field-level validation alone |
index | No | Indexing intent | Useful when the email address participates in search or lookup flows |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Useful when email also acts as a user-facing identifier |
enableAuditTracking | No | Audit-tracking flag | Marks the field for field-level auditing concerns |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for an email field |
For email, SolidX validates in two places:
- The generated form layer validates requiredness,
min,max, andregexPattern. - The backend validation layer checks requiredness, email shape, maximum length, and regex compliance.
Three important behaviors to note:
- backend validation uses an email-aware validator even when no custom regex is authored
- generated form validation relies on
regexPatternwhen stricter email-format checks are needed maxdefaults to the email-safe core limit when it is not authored explicitly
email is persisted as a scalar text field.
The submitted value is validated and then stored without any field-specific persistence transformation.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because email is a scalar textual field, it works naturally with the standard text-oriented filter operators available in SolidX.
Typical use cases include:
- exact lookup by email address
- partial search in operational lists
- identifying records by a stable contact identifier
In practice, email combines the searchability of text with stronger validation expectations than a generic short string.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "payByLinkCustomerEmailAddress",
"displayName": "Pay By Link Customer Email Address",
"description": null,
"type": "email",
"ormType": "varchar",
"regexPattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
"regexPatternNotMatchingErrorMsg": "Invalid regex pattern",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"enableAuditTracking": false,
"isSystem": false
}This is a representative email field because it shows the email-specific validation intent clearly while still behaving like a persisted scalar string field.
For rendering, widgets, and layout attrs related to email, see View Metadata.
password
Use password for secret values that should be authored securely, validated strongly, and stored as hashes rather than plain text.
This field type is appropriate for authentication secrets and other credential-like values that should never be displayed or persisted as ordinary scalar text.
In SolidX, password is a security-sensitive string-backed field. It supports requiredness, length constraints, pattern validation, confirmation matching, and hashing before persistence when a password value is supplied.
| Attr | Required | Purpose | Notes for password |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be password |
ormType | No | Persistence-layer storage hint | Commonly varchar with a storage length sized for hashes |
defaultValue | No | Default value for metadata-driven consumers | Rare in practice for secure passwords |
required | No | Marks the field as mandatory | Enforced on create flows; update flows can omit the value when no password change is intended |
min | No | Minimum length | Enforced in generated forms and in backend validation |
max | No | Maximum length | Enforced in generated forms and in backend validation |
regexPattern | No | Pattern constraint | Used for password-strength style requirements |
regexPatternNotMatchingErrorMsg | No | Custom regex validation message | Used by generated form validation; backend validation currently returns a generic password-regex error |
unique | No | Uniqueness intent | Usually not meaningful for passwords, but still part of the field contract |
index | No | Indexing intent | Typically avoided for password fields |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Especially relevant for password-like secrets |
enableAuditTracking | No | Audit-tracking flag | Should be considered carefully for secret-bearing fields |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Not a practical choice for password fields |
For password, SolidX validates in two places:
- The generated form layer validates requiredness,
min,max, regex compliance, and password-confirmation matching. - The backend validation layer checks string type, password-strength regex compliance,
min,max, and password-confirmation matching.
Three important behaviors to note:
- backend requiredness is applied on create rather than on ordinary update flows
- password confirmation is treated as part of the contract when a password value is supplied
- when no custom regex is authored, the backend falls back to a strong-password default pattern
password is not intended to persist as raw text.
When a password value is supplied, the password manager hashes it before persistence and also records the active password scheme and hash version metadata used by the hashing service.
Attrs such as ormType, columnName, unique, and index should therefore be understood carefully in the context of hashed secret storage rather than ordinary text persistence.
password is not intended for ordinary filtering, search, or list presentation.
In practice, password fields are authored and updated through controlled form flows rather than surfaced in searchable operational views.
Attrs such as private, enableAuditTracking, and isSystem matter more here than for most scalar field types because the field carries secret-like data. Documentation and implementation should continue to treat password values as highly sensitive.
{
"name": "password",
"displayName": "Password",
"type": "password",
"ormType": "varchar",
"length": 512,
"required": false,
"unique": false,
"index": false,
"private": false,
"isSystem": true
}This is a representative password field because it captures the typical secret-field contract clearly: string input, secure validation expectations, and persistence sized for hashed storage rather than raw display.
For rendering, widgets, and layout attrs related to password, see View Metadata.
selectionStatic
Use selectionStatic when a field should allow users to choose from a fixed, authored set of values.
This field type is appropriate when the option set is known in advance and should travel with the metadata itself rather than being fetched from another model or service at runtime.
In SolidX, selectionStatic is a constrained scalar or multi-value selection field. It stores authored option values, validates submissions against the allowed set, and uses the metadata-defined mapping between stored values and human-readable labels.
| Attr | Required | Purpose | Notes for selectionStatic |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be selectionStatic |
ormType | No | Persistence-layer storage hint | Commonly varchar for single-select values |
defaultValue | No | Default stored value | Should use the stored value token, not the human-readable label |
selectionStaticValues | Yes | Authored option set | Each entry follows the value:label pattern |
selectionValueType | Yes | Type of the stored value | Core support currently expects string or int |
isMultiSelect | No | Multi-select flag | Allows the field to accept more than one authored value |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when the selection is frequently used in filtering |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for selectionStatic, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when changes in selected state should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a static selection field |
For selectionStatic, SolidX validates in two places:
- The generated form layer validates requiredness and the expected selection shape.
- The backend validation layer checks requiredness, stored value type, and whether the submitted value belongs to the authored option set.
Three important behaviors to note:
selectionStaticValuesdefines the allowed set usingvalue:labelentries, where the left-hand side is the stored value and the right-hand side is the display labelselectionValueTypecontrols how the submitted value is interpreted at validation time- when
isMultiSelectis enabled, the backend accepts an array or a JSON-stringified array and validates each submitted value against the authored set
selectionStatic persists the stored value token rather than the human-readable label.
For single-select fields, that typically means a scalar value such as Draft or active. For multi-select fields, the value is treated as a collection of authored stored values.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because selectionStatic stores a constrained set of known values, it is well suited to operational filtering and reporting.
Typical use cases include:
- filtering by status, stage, type, or category
- segmenting records by workflow state
- narrowing records by authored option sets such as day of week, product type, or review outcome
In practice, selectionStatic is most valuable where consistency matters more than free-form input.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "status",
"displayName": "Status",
"description": "Status of the application",
"type": "selectionStatic",
"ormType": "varchar",
"defaultValue": "Draft",
"selectionStaticValues": [
"Draft:Draft",
"With Checker:With Checker",
"Approved:Approved",
"Rejected:Rejected",
"Discrepancy:Discrepancy"
],
"selectionValueType": "string",
"isMultiSelect": false,
"required": false,
"unique": false,
"index": true,
"private": false,
"columnName": null,
"enableAuditTracking": true,
"isSystem": false
}This is a representative selectionStatic field because it shows the authored option set, the stored-value contract, and a common status-style use case that benefits from indexing and consistent querying.
For rendering, widgets, and layout attrs related to selectionStatic, see View Metadata.
selectionDynamic
Use selectionDynamic when a field should allow users to choose from a provider-backed option set that is resolved at runtime.
This field type is appropriate when the available options depend on a list-of-values provider, a model-backed provider, or other runtime context that cannot be authored as a fixed metadata array.
In SolidX, selectionDynamic is a constrained provider-backed selection field. It stores submitted provider values, validates the submitted value type, and can optionally validate the selected value against the active provider during save.
| Attr | Required | Purpose | Notes for selectionDynamic |
|---|---|---|---|
name | Yes | Internal field key | Used as the request, response, and persistence key |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be selectionDynamic |
ormType | No | Persistence-layer storage hint | Commonly varchar for provider-backed string values |
selectionDynamicProvider | Yes | Provider name | Identifies the runtime selection provider used to resolve valid options |
selectionDynamicProviderCtxt | Yes | Provider context | JSON-serialized provider context passed into the runtime provider |
selectionValueType | Yes | Type of the stored value | Core support currently expects string or int |
isMultiSelect | No | Multi-select flag | Allows the field to accept more than one provider-backed value |
required | No | Marks the field as mandatory | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when the selected provider value participates in filtering or lookup |
columnName | No | Physical column override | Overrides the generated column name |
private | No | Visibility flag | Signals that the field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Rare for selectionDynamic, but still part of the field contract |
enableAuditTracking | No | Audit-tracking flag | Useful when provider-backed state changes should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Technically possible, though uncommon for a dynamic selection field |
For selectionDynamic, SolidX validates in two places:
- The generated form layer validates requiredness and the expected selection shape.
- The backend validation layer checks requiredness, stored value type, and provider-backed value validity.
Three important behaviors to note:
selectionDynamicProviderchooses the provider used to resolve valid options at runtimeselectionDynamicProviderCtxtis JSON-decoded before validation and can shape provider behavior- when the provider context sets
validateOnSavetofalse, save-time provider validation is skipped and only the value-type contract is enforced
selectionDynamic persists the stored provider value rather than the provider's human-readable label.
For single-select fields, that typically means a scalar provider value. For multi-select fields, the value is treated as a collection of provider-backed stored values.
Attrs such as ormType, columnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the field is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because selectionDynamic stores constrained provider-backed values, it is well suited to operational filtering and provider-driven workflows.
Typical use cases include:
- choosing values from a list-of-values provider
- selecting records from a provider-backed business catalog
- narrowing workflows based on provider-defined state or category values
In practice, selectionDynamic is most useful when the option set must remain dynamic without giving up structured persistence.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "couponVenueType",
"displayName": "Coupon Venue Type",
"description": null,
"type": "selectionDynamic",
"ormType": "varchar",
"selectionDynamicProvider": "ListOfValuesSelectionProvider",
"selectionDynamicProviderCtxt": "{\"type\": \"COUPON_VENUE_TYPE\", \"validateOnSave\": false}",
"selectionValueType": "string",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"isSystem": false
}This is a representative selectionDynamic field because it shows the core dynamic-selection contract clearly: provider-backed values, provider context, and a runtime-resolved option set.
For rendering, widgets, and layout attrs related to selectionDynamic, see View Metadata.
many-to-one
Use many-to-one when each record should point to one record in another model, while that related model can be referenced by many records.
This relation subtype is appropriate for parent-child lookups such as student -> institute, invoice -> customer, or ticket -> assignee.
In SolidX, many-to-one is authored as a relation field with relationType: "many-to-one". It persists a single related reference, validates incoming relation identifiers or user keys, and resolves the related entity before persistence.
| Attr | Required | Purpose | Notes for many-to-one |
|---|---|---|---|
name | Yes | Internal field key | Used as the logical relation name and as the base for generated request fields such as <name>Id and <name>UserKey |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field family | Must be relation |
relationType | Yes | Relation subtype | Must be many-to-one |
ormType | No | Persistence-layer storage hint | Commonly an integer-style foreign-key column |
relationCoModelSingularName | Yes | Related model name | Identifies the model this field points to |
relationModelModuleName | Yes | Related module name | Identifies the module that owns the related model |
relationCoModelFieldName | No | Inverse field name on the related model | Useful when the inverse relation is created or referenced explicitly |
relationCoModelColumnName | No | Related-side column override | Overrides the generated related column name when needed |
relationCreateInverse | No | Inverse-generation flag | When true, metadata generation may create the inverse relation on the related model |
relationCascade | No | Cascade intent | Common values include cascade, restrict, and set null |
relationFieldFixedFilter | No | Relation option filter | JSON-templated filter applied when resolving candidate records in metadata-driven UI |
required | No | Mandatory relation flag | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Makes the foreign-key reference behave more like a one-to-one constraint at the persistence level |
index | No | Indexing intent | Useful for frequently filtered or joined relations |
columnName | No | Physical column override | Overrides the generated local column name |
private | No | Visibility flag | Signals that the relation should not be exposed in ordinary read flows |
enableAuditTracking | No | Audit-tracking flag | Useful when changes to the linked record should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed relations from business-authored relations |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Rare for a relation field, but still part of the field contract |
For many-to-one, SolidX validates in two places:
- The generated form layer validates requiredness and ensures the user selects a valid related record from the relation control.
- The backend validation layer accepts either
<fieldName>Idor<fieldName>UserKey, checks requiredness, validates the identifier shape, and verifies that user-key based resolution is possible.
Three important behaviors to note:
- the request contract accepts either an integer-style id or the related model's user key
- required validation fails only when both the id and the user key are absent
- if a user key is submitted, the related model must expose a user-key field that can be used for lookup
many-to-one persists a single related reference.
Before persistence, SolidX resolves the submitted id or user key into the related entity and assigns that entity to the DTO. Once resolved, the relation is stored using the configured foreign-key mapping.
Attrs such as ormType, columnName, relationCoModelColumnName, unique, and index are therefore best understood as persistence and schema intent. They shape how the relation is represented in the generated model and storage layer, even when they are not enforced by the validation rules described above.
Because many-to-one points to a single related record, it is a natural fit for relation-aware filters and joins.
Typical use cases include:
- filtering child records by a parent entity such as institute, branch, or customer
- populating related records in form and list flows
- using the related model's user key as the display or search value in metadata-driven UI
In practice, many-to-one is the relation subtype most often used for simple lookup-style business relationships.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "institute",
"displayName": "Institute",
"description": null,
"type": "relation",
"ormType": "integer",
"isSystem": false,
"relationType": "many-to-one",
"relationCoModelFieldName": "feeTypes",
"relationCreateInverse": true,
"relationCoModelSingularName": "institute",
"relationCoModelColumnName": null,
"relationModelModuleName": "fees-portal",
"relationCascade": "cascade",
"required": true,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"relationJoinTableName": null,
"isRelationManyToManyOwner": null,
"relationFieldFixedFilter": "",
"enableAuditTracking": true
}This is a representative many-to-one field because it shows the core lookup contract clearly: a single related model, an authored inverse field name, required relation validation, and standard persistence intent.
For rendering, widgets, and layout attrs related to many-to-one, see View Metadata.
one-to-many
Use one-to-many when one record should own or expose a collection of records from another model.
This relation subtype is appropriate for parent-child collections such as question -> possible answers, report -> daily logs, or employee -> detail rows.
In SolidX, one-to-many is authored as a relation field with relationType: "one-to-many". It represents a collection-shaped relation, uses command-driven mutation semantics in backend CRUD flows, and is often paired with embedded list or inline create experiences in metadata-driven UI.
| Attr | Required | Purpose | Notes for one-to-many |
|---|---|---|---|
name | Yes | Internal field key | Used as the logical collection name and as the base for generated command fields such as <name>Command and <name>Ids |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field family | Must be relation |
relationType | Yes | Relation subtype | Must be one-to-many |
ormType | No | Persistence-layer storage hint | Commonly an integer-style relation mapping |
relationCoModelSingularName | Yes | Child model name | Identifies the model that will appear many times under the current record |
relationModelModuleName | Yes | Child module name | Identifies the module that owns the child model |
relationCoModelFieldName | Yes | Inverse field name on the child model | Tells SolidX which child-side field points back to the current parent |
relationCoModelColumnName | No | Child-side column override | Overrides the generated child-side column name when needed |
relationCreateInverse | No | Inverse-generation flag | When true, metadata generation may create the inverse relation on the child model |
relationCascade | No | Cascade intent | Common values include cascade, restrict, and set null |
relationFieldFixedFilter | No | Relation option filter | JSON-templated filter applied when building metadata-driven relation experiences |
required | No | Mandatory collection flag | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Uncommon, but still part of the field contract |
index | No | Indexing intent | Useful when child rows are retrieved frequently through relation-oriented queries |
columnName | No | Physical column override | Overrides the generated local column name when relevant |
private | No | Visibility flag | Signals that the relation should not be exposed in ordinary read flows |
enableAuditTracking | No | Audit-tracking flag | Useful when changes to the collection membership or child rows should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed relations from business-authored relations |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Rare for a collection relation, but still part of the field contract |
For one-to-many, SolidX validates the relation using command-style mutation semantics.
The generated form layer validates requiredness and collection shape. The backend CRUD layer validates the command field and then expects one of two payload styles:
- for
create,update, anddelete, the payload is array-shaped and submitted through the relation value field itself - for
set,link, andunlink, the payload is submitted through<fieldName>Ids
Three important behaviors to note:
<fieldName>Commandcontrols how the relation should be processedclearis a special command that removes all linked children without requiring ids or child payloadslinkandunlinkare update-only operations because they need an existing parent record id
one-to-many persists a collection of related child records or links, depending on the chosen command.
In create and update flows, SolidX can create new child entities, preload and update existing child entities, delete child entities, replace the current collection, or perform differential link and unlink operations against an existing parent record.
This makes one-to-many more operationally expressive than scalar fields: it is not just a stored value, but a mutation surface for managing a related collection.
one-to-many is usually queried as a populated child collection rather than as a simple scalar field.
Typical use cases include:
- rendering child rows inside embedded forms or detail pages
- loading child collections through relation-aware populate flows
- applying parent-scoped filters so that only the current record's children are shown or edited
In practice, one-to-many works best when the relation is treated as a managed collection rather than as a list-search field.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "questionPossibleAnswersMaster",
"displayName": "Possible Response",
"description": "QuestionPossibleAnswersMaster",
"type": "relation",
"ormType": "integer",
"isSystem": false,
"relationType": "one-to-many",
"relationCoModelFieldName": "questionMaster",
"relationCreateInverse": true,
"relationCoModelSingularName": "questionPossibleAnswerMaster",
"relationCoModelColumnName": null,
"relationModelModuleName": "sapphire",
"relationCascade": "cascade",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"relationJoinTableName": null,
"isRelationManyToManyOwner": null,
"relationFieldFixedFilter": null,
"enableAuditTracking": true
}This is a representative one-to-many field because it shows the parent-to-collection contract clearly: a named child model, an explicit child-side inverse field, and the collection semantics needed for embedded CRUD flows.
For rendering, widgets, and layout attrs related to one-to-many, see View Metadata.
many-to-many
Use many-to-many when records on both sides of the relationship can be linked to many records on the other side.
This relation subtype is appropriate for relationships such as question -> domains, user -> roles, or survey -> respondents.
In SolidX, many-to-many is authored as a relation field with relationType: "many-to-many". It persists links through a join-style relation, supports command-driven mutation semantics, and distinguishes between owner-side and inverse-side relation metadata.
| Attr | Required | Purpose | Notes for many-to-many |
|---|---|---|---|
name | Yes | Internal field key | Used as the logical relation name and as the base for generated command fields such as <name>Command and <name>Ids |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field family | Must be relation |
relationType | Yes | Relation subtype | Must be many-to-many |
ormType | No | Persistence-layer storage hint | Commonly an integer-style relation mapping |
relationCoModelSingularName | Yes | Related model name | Identifies the model on the other side of the relation |
relationModelModuleName | Yes | Related module name | Identifies the module that owns the related model |
relationCoModelFieldName | No | Inverse field name on the related model | Important when the relation is authored or operated from the inverse side |
relationJoinTableName | No | Join-table override | Overrides the generated join table name when needed |
isRelationManyToManyOwner | Yes | Owner-side flag | Determines whether the current field owns the relation mapping or represents the inverse side |
relationCreateInverse | No | Inverse-generation flag | When true, metadata generation may create the inverse relation automatically |
relationCascade | No | Cascade intent | Common values include cascade, restrict, and set null |
relationFieldFixedFilter | No | Relation option filter | JSON-templated filter applied when resolving relation candidates in metadata-driven UI |
required | No | Mandatory relation flag | Enforced in generated forms and in backend CRUD validation |
unique | No | Uniqueness intent | Usually uncommon for many-to-many relations |
index | No | Indexing intent | Useful when the relation is frequently traversed through join queries |
columnName | No | Physical column override | Overrides the generated local column name when relevant |
private | No | Visibility flag | Signals that the relation should not be exposed in ordinary read flows |
enableAuditTracking | No | Audit-tracking flag | Useful when relation membership changes should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed relations from business-authored relations |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Rare for a many-to-many relation, but still part of the field contract |
For many-to-many, SolidX validates the relation using the same command-style mutation pattern used for collection relations.
The generated form layer validates requiredness and collection shape. The backend CRUD layer validates the command field, then expects one of two payload styles:
- for
create,update, anddelete, the payload is array-shaped and submitted through the relation value field itself - for
set,link, andunlink, the payload is submitted through<fieldName>Idson the owner side, or through the resolved inverse field name on the inverse side
Three important behaviors to note:
<fieldName>Commanddetermines how the relation should be mutated- owner-side versus inverse-side metadata affects which effective field names are used internally
linkandunlinkare update-only operations because they need an existing parent record id
many-to-many persists relation membership through a join-style mapping.
In create and update flows, SolidX can create related entities, update or delete related entities, replace the current relation set, or perform differential link and unlink operations against existing records.
The owner-side flag matters here: it determines which side is responsible for the primary relation mapping and how CRUD operations resolve the effective field names.
many-to-many is most valuable when records need to be segmented or navigated through shared tags, categories, permissions, or memberships.
Typical use cases include:
- tagging records with multiple domains or categories
- assigning users, reviewers, or approvers to the same business record
- traversing relation membership through join-aware list and detail experiences
In practice, many-to-many is best treated as a managed membership surface rather than as a scalar search field.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "domains",
"displayName": "Domains",
"description": "Domains",
"type": "relation",
"ormType": "integer",
"isSystem": false,
"relationType": "many-to-many",
"relationCoModelFieldName": null,
"relationCreateInverse": false,
"relationCoModelSingularName": "domain",
"relationCoModelColumnName": null,
"relationModelModuleName": "sapphire",
"relationCascade": "cascade",
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"relationJoinTableName": null,
"isRelationManyToManyOwner": true,
"relationFieldFixedFilter": null,
"enableAuditTracking": true
}This is a representative many-to-many field because it shows the shared-membership contract clearly: a co-model, owner-side metadata, and the join-oriented semantics used by relation-heavy business workflows.
For rendering, widgets, and layout attrs related to many-to-many, see View Metadata.
mediaSingle
Use mediaSingle when a field should hold exactly one uploaded media asset such as a logo, profile image, signed document, or generated file.
This field type is appropriate when the business meaning is singular: one photo, one file, one attachment slot, or one primary media asset.
In SolidX, mediaSingle is an upload-backed field. It validates the incoming file collection, checks size and media-type constraints, persists media through the media subsystem, and exposes the stored asset back through the record's _media payload.
| Attr | Required | Purpose | Notes for mediaSingle |
|---|---|---|---|
name | Yes | Internal field key | Used as the multipart field name and as the metadata key for the stored media slot |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be mediaSingle |
ormType | No | Persistence-layer storage hint | Commonly varchar for stored media references |
mediaTypes | No | Allowed media families | Core media validation understands image, audio, video, and file |
mediaMaxSizeKb | No | Maximum file size in KB | Enforced by backend CRUD validation for single-file uploads |
mediaStorageProviderUserKey | No | Storage-provider selector | Chooses the authored storage provider used for the field's uploaded asset |
required | No | Mandatory upload flag | Enforced on create when no media file is supplied |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Rare for media fields because querying usually happens through business attrs rather than media slots |
columnName | No | Physical column override | Overrides the generated local column name |
private | No | Visibility flag | Signals that the media slot should not be exposed in ordinary read flows |
enableAuditTracking | No | Audit-tracking flag | Useful when changes to the uploaded asset should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed media fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Rare for a media field, but still part of the field contract |
For mediaSingle, SolidX validates the uploaded file collection in the backend CRUD layer.
Three important behaviors to note:
- on create, a required
mediaSinglefield must receive exactly one uploaded file - if more than one file is submitted, validation fails because the field is single-valued
- when
mediaMaxSizeKbormediaTypesare authored, the backend validates the uploaded file against those constraints
On update, required validation is intentionally more permissive so that existing media can remain in place when no replacement file is uploaded.
mediaSingle persists through the media subsystem rather than behaving like an ordinary scalar text field.
The uploaded file is stored using the configured storage provider and is then associated back to the business record under the field's media slot. In record responses, the field's asset is typically surfaced through _media.<fieldName> rather than through the plain scalar field value alone.
This makes mediaSingle a hybrid field contract: metadata is authored on the field, but the underlying persistence flow is handled by the platform's media layer.
mediaSingle is usually not used as a direct filter field.
Typical use cases include:
- displaying a primary asset such as a logo or cover image in a list or form
- opening, previewing, or downloading the uploaded file in metadata-driven UI
- populating media payloads alongside the rest of the business record
In practice, media fields are usually queried for display and retrieval rather than for text- or number-style filtering.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "logo",
"displayName": "Logo",
"description": null,
"type": "mediaSingle",
"ormType": "varchar",
"isSystem": false,
"mediaTypes": [
"image"
],
"mediaMaxSizeKb": 5120,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"mediaStorageProviderUserKey": "default-aws-s3"
}This is a representative mediaSingle field because it shows the usual single-asset contract clearly: one authored slot, an allowed media family, a size limit, and an explicit storage provider.
For rendering, widgets, and layout attrs related to mediaSingle, see View Metadata.
mediaMultiple
Use mediaMultiple when a field should hold a collection of uploaded assets rather than a single file.
This field type is appropriate for attachment galleries, supporting documents, invoice bundles, or any workflow where multiple files belong to the same record.
In SolidX, mediaMultiple is an upload-backed collection field. It persists multiple uploaded assets through the media subsystem and exposes the stored asset list back through the record's _media payload.
| Attr | Required | Purpose | Notes for mediaMultiple |
|---|---|---|---|
name | Yes | Internal field key | Used as the multipart field name and as the metadata key for the stored media collection |
displayName | Yes | Human-readable label | Used in generated UI and validation messaging |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be mediaMultiple |
ormType | No | Persistence-layer storage hint | Commonly varchar for stored media references |
mediaTypes | No | Allowed media families | Intended to constrain the collection to families such as image, audio, video, and file |
mediaMaxSizeKb | No | Maximum file size in KB | Intended to constrain individual uploads in the collection |
mediaStorageProviderUserKey | No | Storage-provider selector | Chooses the authored storage provider used for the uploaded assets |
required | No | Mandatory upload flag | Enforced on create when no files are supplied |
unique | No | Uniqueness intent | Usually uncommon, but still part of the field contract |
index | No | Indexing intent | Rare for media collections because querying usually happens through business attrs rather than media slots |
columnName | No | Physical column override | Overrides the generated local column name |
private | No | Visibility flag | Signals that the media collection should not be exposed in ordinary read flows |
enableAuditTracking | No | Audit-tracking flag | Useful when changes to the attachment collection should be tracked |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed media fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Rare for a media collection, but still part of the field contract |
For mediaMultiple, SolidX validates requiredness in the backend CRUD layer.
Two important behaviors to note:
- on create, a required
mediaMultiplefield must receive at least one uploaded file - unlike
mediaSingle, the current backend implementation does not yet apply the same file-type and file-size checks to every uploaded file in the collection
That second behavior is important operationally: mediaTypes and mediaMaxSizeKb express the intended contract for the field, but collection-level enforcement is not yet as complete as it is for mediaSingle.
mediaMultiple persists through the media subsystem rather than behaving like an ordinary scalar field.
Each uploaded file is stored using the configured storage provider and then associated back to the business record under the field's media collection slot. In record responses, the collection is typically surfaced through _media.<fieldName>.
This makes mediaMultiple a natural fit for document bundles, image sets, and attachment-heavy workflows.
mediaMultiple is usually not used as a direct filter field.
Typical use cases include:
- previewing the first item in the collection in list views
- opening the full media bundle in a dialog or lightbox-driven experience
- downloading document-style attachments from the record detail view
In practice, media collections are queried for retrieval and presentation rather than for scalar-style filtering.
Attrs such as private, enableAuditTracking, isSystem, and isPrimaryKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "payByLinkInvoiceFile",
"displayName": "Pay By Link Invoice File",
"description": null,
"type": "mediaMultiple",
"ormType": "varchar",
"isSystem": false,
"mediaTypes": [
"image",
"file"
],
"mediaMaxSizeKb": 20480,
"required": false,
"unique": false,
"index": false,
"private": false,
"columnName": null,
"mediaStorageProviderUserKey": "default-filesystem"
}This is a representative mediaMultiple field because it shows the collection-style media contract clearly: multiple attachments, a mixed allowed-media policy, and a storage-provider-backed upload slot.
For rendering, widgets, and layout attrs related to mediaMultiple, see View Metadata.
computed
Use computed when a field's value should be derived by the platform rather than authored directly by the user.
This field type is appropriate for generated transaction ids, derived external ids, slugs, concatenated business keys, counters, and other values that should be computed consistently from runtime context.
In SolidX, computed is a provider-backed field. It does not rely on end-user input, can invoke a named computed-field provider during CRUD flows, and can also be deferred to trigger-driven subscriber flows when trigger configuration is authored.
| Attr | Required | Purpose | Notes for computed |
|---|---|---|---|
name | Yes | Internal field key | Used as the persisted column key and as the provider target field |
displayName | Yes | Human-readable label | Used in generated UI and metadata tooling |
description | No | Help text for the field | Exposed to metadata-driven UI and tooling |
type | Yes | Semantic field type | Must be computed |
ormType | No | Persistence-layer storage hint | Commonly varchar, but should match the authored computed value type |
computedFieldValueType | Yes | Computed value shape | Core support currently includes string, int, decimal, boolean, date, and datetime |
computedFieldValueProvider | Yes | Provider name | Identifies the computed-field provider responsible for generating the value |
computedFieldValueProviderCtxt | No | Provider context | JSON-serialized provider configuration passed into the provider at runtime |
computedFieldTriggerConfig | No | Trigger-driven execution config | Defines when computation should be delegated to subscriber-style event flows instead of inline CRUD computation |
required | No | Requiredness flag | Usually true from a business perspective, but not treated like ordinary user-input validation |
unique | No | Uniqueness intent | Common for generated external ids, codes, and slugs |
index | No | Indexing intent | Useful when the computed value is used for lookup or filtering |
columnName | No | Physical column override | Overrides the generated local column name |
private | No | Visibility flag | Signals that the computed field should not be exposed in ordinary read flows |
isUserKey | No | Human-facing record identifier flag | Common when the computed value serves as a generated business identifier |
enableAuditTracking | No | Audit-tracking flag | Useful when computed changes should be recorded explicitly |
isSystem | No | Platform-owned field flag | Distinguishes framework-managed computed fields from business-authored fields |
isMarkedForRemoval | No | Lifecycle flag | Used during metadata evolution and cleanup |
isPrimaryKey | No | Primary-key flag | Uncommon, but still part of the field contract |
For computed, SolidX does not apply ordinary end-user field validation.
Two important behaviors to note:
- the backend computed-field flow does not apply ordinary user-input validation and therefore returns no direct field errors for submitted values
- generated forms treat the field as read-only and optional because the value is not expected to be provided by the user
This is by design: correctness comes from provider logic and trigger configuration rather than from normal user-input validation rules.
computed persists as an ordinary column value after the platform computes it.
In inline CRUD flows, SolidX parses computedFieldValueProviderCtxt, resolves the named provider, asks that provider to compute the field value, and then assigns the result to the DTO before persistence.
There are two cases where inline computation is intentionally skipped:
- partial updates
- fields that define
computedFieldTriggerConfig, because those are expected to be handled by trigger-driven subscriber flows instead
Once computed, the field behaves like any other persisted scalar of the authored computedFieldValueType.
Typical use cases include:
- filtering or searching by generated transaction ids and external ids
- sorting or reporting on derived numeric or date values
- exposing stable business keys that are derived automatically rather than entered manually
In practice, computed is best understood as a generated persisted field rather than as a transient view-only value.
Attrs such as private, enableAuditTracking, isSystem, isPrimaryKey, and isUserKey are part of the field contract even though they are broader than validation alone. They communicate platform-level intent that other parts of SolidX rely on.
{
"name": "feeTypeUserKey",
"displayName": "Fee Type User Key",
"description": "Concatenation of fee type and institute name",
"type": "computed",
"ormType": "varchar",
"isSystem": false,
"computedFieldValueType": "string",
"computedFieldTriggerConfig": [
{
"modelName": "feeType",
"moduleName": "fees-portal",
"operations": [
"before-insert"
]
}
],
"computedFieldValueProvider": "ConcatEntityComputedFieldProvider",
"computedFieldValueProviderCtxt": "{\"fields\":[\"feeType\",\"institute.instituteName\"],\"separator\":\"-\",\"slugify\":true}",
"required": true,
"unique": true,
"index": false,
"private": false,
"columnName": null,
"isUserKey": true
}This is a representative computed field because it shows the full provider-backed contract clearly: an authored value type, a named provider, provider context, trigger configuration, and a generated business key outcome.
For rendering, widgets, and layout attrs related to computed, see View Metadata.