Atlas Forms
Override Schema
A tenant override is described by a formGroupOverride document that specifies which tenant, which base group, which forms to modify (overrides), and which new forms to add (additions). This document is translated into SQL rows in dbo.Atlas_Forms during deployment.
FormGroupOverride Type
// packages/types-js/src/TenantOverride.ts
interface FormGroupOverride {
/** The FormCategoryID of the group being overridden */
baseCategoryId: number;
/** The tenant receiving these customisations */
tenantId: number;
/** Modifications to existing base forms */
overrides: FormOverrideEntry[];
/** Net-new forms visible only to this tenant */
additions: FormAdditionEntry[];
}
interface FormOverrideEntry {
/** FormID of the base form being modified */
formId: number;
/** Disable the form for this tenant (IsActive = 0 in the tenant row) */
disable?: boolean;
/** JSONPath-style key/value patches applied to the base schema */
overrideSchema?: Record<string, any>;
}
interface FormAdditionEntry {
/** FormID from the tenant's private range (tenantId × 100000 + groupStart) */
formId: number;
formCode: string;
formTypeId: number;
primaryUsage: string;
nodeUsage?: string;
schema: object; // Full form schema JSON
}
Complete Example
// Tenant 9 (Acme Corp) customisations to the GuardRails group
const acmeGuardRailsOverride: FormGroupOverride = {
baseCategoryId: 130, // GuardRails
tenantId: 9,
overrides: [
// Modify GuardRail_Edit (13001): rename 'Policy Name' to 'Rule Name', change player
{
formId: 13001,
overrideSchema: {
"metadata.playerOverride": "gov-accessible",
"controls[id=policy-name].label": "Rule Name",
"controls[id=policy-name].placeholder": "Enter rule name",
}
},
// Disable GuardRail_Audit dashboard for this tenant (they have their own)
{
formId: 13007,
disable: true,
}
],
additions: [
// Add a tenant-specific IP allowlist form (see Guide on Tenant FormID Ranges)
{
formId: 913008,
formCode: 'Acme_GuardRail_IpAllowlist_Edit',
formTypeId: 2,
primaryUsage: 'guardrails',
nodeUsage: 'acme-guardrail-ip-allowlist',
schema: {
"metadata": { "formId": 913008, "title": "Edit IP Allowlist (Acme)" },
"controls": [ /* ... */ ],
"actions": [ /* ... */ ]
}
}
]
};
overrideSchema — JSONPath Targeting
Keys in overrideSchema are JSONPath-style expressions that target a specific location in the base schema JSON. The value replaces the current value at that path:
| Key Pattern | Targets | Example |
|---|---|---|
metadata.{field} | Top-level metadata field | metadata.playerOverride |
controls[id={controlId}].{field} | Named control's field | controls[id=policy-name].label |
sections[id={sectionId}].{field} | Named section's field | sections[id=details].title |
controls[id={controlId}].validation.{rule} | Specific validation rule | controls[id=email].validation.required |
controls[id={controlId}].options | Full options array (replaced) | controls[id=currency].options |
overrideSchema Is Applied After parseSchema
The base schema is first normalised by
parseSchema(), then the overrideSchema patches are applied. This means you can use the stable, normalised field names rather than worrying about raw JSON quirks in the base schema.