Atlas Forms
Group Definition Schema
Each Form Group is described by a typed JSON contract — the FormGroupDefinition — that lives alongside the application code. This contract is the single source of truth for the group's ID range, ownership, and generation policy. It also acts as the input to registerFormGroup().
FormGroupDefinition Type
// packages/types-js/src/FormGroupDefinition.ts
interface FormGroupDefinition {
/** Stable kebab-case identifier — matches CategoryName in the database */
formGroupId: string;
/** Human-readable label shown in Studio */
label: string;
/** The owning application's package or project name */
ownerApp: string;
/** Database FormCategoryID — must equal formIdRange.start / 100 */
categoryId: number;
/** Inclusive FormID range owned by this group */
formIdRange: {
start: number; // Inclusive
end: number; // Inclusive
};
/** Allow the AI generation pipeline to create forms in this group */
aiGenerationEnabled: boolean;
/** Allow tenant-level overrides on forms in this group */
tenantOverrideable: boolean;
/** Optional: default PrimaryUsage written to all new forms in this group */
defaultPrimaryUsage?: string;
}
GuardRails — Complete Example
// src/formGroups/guardRailsGroup.ts
import type { FormGroupDefinition } from '@atlas-forms/types-js';
export const guardRailsGroup: FormGroupDefinition = {
formGroupId: 'guard-rails',
label: 'GuardRails',
ownerApp: 'BizFirst.Ai.ProcessSecurity',
categoryId: 130,
formIdRange: {
start: 13000,
end: 13099,
},
aiGenerationEnabled: true,
tenantOverrideable: true,
defaultPrimaryUsage: 'guardrails',
};
Field Reference
| Field | Required | Constraint | Notes |
|---|---|---|---|
formGroupId | Yes | Unique, kebab-case | Stable — never rename after first form is created |
label | Yes | — | Shown in Studio UI dropdowns |
ownerApp | Yes | — | Identifies the responsible team for support routing |
categoryId | Yes | Must equal formIdRange.start / 100 | Validated at registration time |
formIdRange.start | Yes | Multiple of 100; non-overlapping | Checked against registry at startup |
formIdRange.end | Yes | = start + 99 | Each group always gets exactly 100 IDs |
aiGenerationEnabled | Yes | Boolean | When false the AI pipeline refuses to generate in this group |
tenantOverrideable | Yes | Boolean | When false, tenant override rows are rejected |
defaultPrimaryUsage | No | — | Pre-fills PrimaryUsage in Atlas Forms Studio when creating a new form in this group |
Validation at Registration
registerFormGroup() validates the definition before writing it to the registry. Violations throw immediately at application startup so they cannot go unnoticed:
// Validations performed by registerFormGroup()
// 1. formGroupId is unique in the registry
// 2. categoryId === Math.floor(formIdRange.start / 100)
// 3. formIdRange.end === formIdRange.start + 99
// 4. formIdRange does not overlap any already-registered group
// 5. formGroupId matches /^[a-z][a-z0-9-]*$/ (kebab-case)
// If any check fails:
// throw new Error(`[AtlasForms] registerFormGroup: ${reason}`);
Keep the Definition File Small
The
FormGroupDefinition JSON contract should contain only group-level metadata. Individual form schemas belong in separate SQL data files, not in this definition. The definition is loaded at startup; form schemas are loaded on demand.