diff --git a/src/lib/components/ApiConfigModal.svelte b/src/lib/components/ApiConfigModal.svelte new file mode 100644 index 0000000..23ff598 --- /dev/null +++ b/src/lib/components/ApiConfigModal.svelte @@ -0,0 +1,298 @@ + + + + + diff --git a/src/lib/components/ExcelTable.svelte b/src/lib/components/ExcelTable.svelte index 67c675d..2747e39 100644 --- a/src/lib/components/ExcelTable.svelte +++ b/src/lib/components/ExcelTable.svelte @@ -1,15 +1,23 @@ + + + + diff --git a/src/lib/converter.ts b/src/lib/converter.ts index 03c38ab..04b3270 100644 --- a/src/lib/converter.ts +++ b/src/lib/converter.ts @@ -1,5 +1,14 @@ import dayjs from 'dayjs'; -import type { MappingConfig, RowData, DataType, MappingTemplate } from './types.js'; +import type { + MappingConfig, + RowData, + DataType, + MappingTemplate, + ApiEnrichmentRule, + SubmissionConfig, + StaticRule, + JobBundle +} from './types.js'; /** * Check if a value is considered empty. @@ -195,3 +204,47 @@ export function exportTemplate(mappings: MappingConfig[]): MappingTemplate { return entry; }); } + +/** + * Convert enabled MappingConfigs to StaticRule format for Job Bundle. + */ +function toStaticRules(mappings: MappingConfig[]): StaticRule[] { + return mappings + .filter((m) => m.enabled) + .map((m) => { + const rule: StaticRule = { + type: 'static', + source: m.source, + target: m.target, + dataType: m.type + }; + if (m.type === 'date' && m.format) rule.format = m.format; + return rule; + }); +} + +/** + * Generate a complete Job Bundle for export. + */ +export function generateJobBundle( + rows: RowData[], + mappings: MappingConfig[], + enrichmentRules: ApiEnrichmentRule[], + submissionConfig: SubmissionConfig +): JobBundle { + const sourceData = convertData(rows, mappings); + const staticRules = toStaticRules(mappings); + + return { + meta: { + version: '1.0.0', + generated_at: new Date().toISOString() + }, + config: { + static_rules: staticRules, + enrichment_rules: enrichmentRules, + submission: submissionConfig + }, + source_data: sourceData + }; +} diff --git a/src/lib/types.ts b/src/lib/types.ts index a315b25..b404ead 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -33,3 +33,45 @@ export type MappingTemplate = Pick< MappingConfig, 'source' | 'target' | 'type' | 'format' | 'excludeIfEmpty' | 'defaultValue' >[]; + +/** Static mapping rule in Job Bundle output */ +export interface StaticRule { + type: 'static'; + source: string; + target: string; + dataType: DataType; + format?: string; +} + +/** Dynamic API enrichment rule */ +export interface ApiEnrichmentRule { + type: 'api_fetch'; + target_key: string; + url_template: string; + method: 'GET' | 'POST'; + headers?: Record; + body_template?: string; + response_path: string; + fallback_value?: unknown; +} + +/** Submission configuration for final data push */ +export interface SubmissionConfig { + target_url: string; + method: 'POST' | 'PUT'; + batch_size: number; +} + +/** Final exported Job Bundle structure */ +export interface JobBundle { + meta: { + version: string; + generated_at: string; + }; + config: { + static_rules: StaticRule[]; + enrichment_rules: ApiEnrichmentRule[]; + submission: SubmissionConfig; + }; + source_data: Record[]; +} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 83a84b9..4cd76cb 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,9 +1,11 @@
+
+ + + +
+ + + +
+
{/if} + + +{#if showApiConfig} + { showApiConfig = false; editingRuleIndex = null; }} + /> +{/if} + +{#if showSubmissionSettings} + (showSubmissionSettings = false)} + /> +{/if}