Skip to content

Commit 3368a39

Browse files
committed
refactor: separate schema-forge engine from ILR domain types
- Create IlrMappingConfig extending generic MappingConfig for ILR-specific fields (famTemplates, appFinTemplates, employmentStatuses, aimDetectionField) - Rename ColumnMapping.aimNumber to generic .group - Narrow csvValidator parameter to { mappings: ColumnMapping[] } - Move ILR-specific xmlGenerator.legacy.ts and xmlParser.ts to mappings/legacy/ - Remove all ILR/ESFA references from engine comments - Engine files now contain zero domain-specific code or comments https://claude.ai/code/session_01Di85VVVGikJ1vnpwjmF6H4
1 parent d87f778 commit 3368a39

34 files changed

Lines changed: 167 additions & 152 deletions

src/lib/mappings/aimUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export function generateAimMappings(templates: AimFieldTemplate[]): ColumnMappin
3333
csvColumn: template.csv.replace('{n}', String(aimNumber)),
3434
xsdPath: template.xsd,
3535
transform: template.transform,
36-
aimNumber,
36+
group: aimNumber,
3737
});
3838
}
3939
}

src/lib/mappings/builders.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
AppFinTemplate,
1010
EmploymentStatusConfig,
1111
EsmField,
12-
} from '../types/schemaTypes';
12+
} from '../types/ilrMappingTypes';
1313
import { getTransform } from '../transforms/registry';
1414

1515
/**

src/lib/mappings/compatibility.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Loads schema, builds registry, and validates compatibility in one call.
44
*/
55

6-
import type { MappingConfig } from '../types/schemaTypes';
6+
import type { IlrMappingConfig } from '../types/ilrMappingTypes';
77
import type { IrisStorage } from '../storage';
88
import { buildSchemaRegistry } from '../schema/registryBuilder';
99
import { validateSchemaCompatibility, type CompatibilityResult } from '../schema/schemaCompatibility';
@@ -20,7 +20,7 @@ export interface MappingCompatibilityResult {
2020
* Loads the schema, builds registry, and checks compatibility.
2121
*/
2222
export async function validateMappingCompatibility(params: {
23-
mapping: MappingConfig;
23+
mapping: IlrMappingConfig;
2424
schemaFile: string;
2525
storage: IrisStorage;
2626
}): Promise<MappingCompatibilityResult> {

src/lib/mappings/fac-airtable-2025.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
* |================================================================|
55
*/
66

7-
import type { MappingConfig } from '../types/schemaTypes';
7+
import type { IlrMappingConfig } from '../types/ilrMappingTypes';
88
import { generateAimMappings } from './aimUtils';
99

10-
export const facAirtableMapping: MappingConfig = {
10+
export const facAirtableMapping: IlrMappingConfig = {
1111
id: 'fac-airtable-2025',
1212
name: 'Founders and Coders Airtable Export (2025-26)',
1313
mappingVersion: '2.0.0',

src/lib/mappings/ilrColumnMapper.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { ColumnMapping, MappingConfig } from '../types/schemaTypes';
1+
import type { ColumnMapping } from '../types/schemaTypes';
2+
import type { IlrMappingConfig } from '../types/ilrMappingTypes';
23
import type { SchemaRegistry } from '../types/interpreterTypes';
34
import { mapCsvToSchema } from '../schema/columnMapper';
45
import { getTransform } from '../transforms/registry';
@@ -24,21 +25,21 @@ import { generateUUID } from '../utils/uuid';
2425
*/
2526
export function mapCsvToSchemaWithAims(
2627
csvRow: Record<string, string>,
27-
config: MappingConfig,
28+
config: IlrMappingConfig,
2829
registry: SchemaRegistry
2930
): Record<string, unknown> {
3031
// Separate learner-level and aim-specific mappings
31-
const learnerMappings = config.mappings.filter((m) => !m.aimNumber);
32-
const aimMappings = config.mappings.filter((m) => m.aimNumber);
32+
const learnerMappings = config.mappings.filter((m) => !m.group);
33+
const aimMappings = config.mappings.filter((m) => m.group);
3334

3435
// Group aim mappings by aim number
3536
const aimGroups = new Map<number, ColumnMapping[]>();
3637
for (const mapping of aimMappings) {
37-
if (!mapping.aimNumber) continue;
38-
if (!aimGroups.has(mapping.aimNumber)) {
39-
aimGroups.set(mapping.aimNumber, []);
38+
if (!mapping.group) continue;
39+
if (!aimGroups.has(mapping.group)) {
40+
aimGroups.set(mapping.group, []);
4041
}
41-
aimGroups.get(mapping.aimNumber)!.push(mapping);
42+
aimGroups.get(mapping.group)!.push(mapping);
4243
}
4344

4445
// Apply learner-level mappings using generic mapper

src/lib/mappings/ilrValidation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import { hasAimData } from './aimUtils';
1111
*/
1212
export function createAimSkipFilter(detectionField: string = 'Programme aim {n} Learning ref') {
1313
return (mapping: ColumnMapping, row?: Record<string, string>): boolean => {
14-
if (!mapping.aimNumber) return false;
14+
if (!mapping.group) return false;
1515
if (!row) return true; // header-level: skip all aim mappings
16-
return !hasAimData(row, mapping.aimNumber, detectionField);
16+
return !hasAimData(row, mapping.group, detectionField);
1717
};
1818
}
File renamed without changes.

src/lib/mappings/validate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export function validateMappingStructure(mapping: unknown): MappingValidationRes
8686
if (typeof e.xsdPath !== 'string' || e.xsdPath.trim() === '') {
8787
issues.push({ field: `mappings[${index}].xsdPath`, message: 'Must be a non-empty string' });
8888
}
89-
// transform and aimNumber are optional, no validation needed
89+
// transform and group are optional, no validation needed
9090
});
9191
}
9292

src/lib/schema/columnMapper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ export function mapCsvToSchema(
4242
* - Uses registry to determine if an element should be an array
4343
*
4444
* @example
45-
* setNestedValue({}, "Message.Learner.LearnRefNumber", "12345", registry)
46-
* // Returns: { Message: { Learner: [{ LearnRefNumber: "12345" }] } }
45+
* setNestedValue({}, "Root.Parent.Field", "12345", registry)
46+
* // Returns: { Root: { Parent: [{ Field: "12345" }] } }
4747
*/
4848
function setNestedValue(
4949
obj: Record<string, unknown>,

0 commit comments

Comments
 (0)