/** * User Field Schema — discovery, persistence, and lifecycle. * * ## Architecture * * Three sources merge into one persisted schema: * 1. Discovery (Moodle sampling) — "what fields exist?" * 2. Defaults file — "how should they behave by default?" * 3. Operator overrides — "what did the operator change?" * * The persisted JSON is the single source of truth at runtime. * Tools read it; operators refresh/update it. */ import { MoodleClient } from "../moodle/client.js"; import { type FieldDefaults } from "./user-field-defaults.js"; export interface UserFieldDef extends FieldDefaults { /** Human-readable display name (e.g. "Last Access") */ name: string; /** Value type: "string" | "number" | "boolean" | "timestamp" | "text" | "menu" | "checkbox" */ type: string; /** Where this field came from: "standard" (Moodle core) or "custom" (profile field) */ source: "standard" | "custom"; } export interface UserFieldSchema { schemaVersion: number; generatedAt: string; siteUrl: string; moodleVersion: string; userFields: Record; } export interface SchemaDiff { added: string[]; removed: string[]; typeChanged: Array<{ key: string; from: string; to: string; }>; unchanged: string[]; } export interface SchemaUpdateResult { schema: UserFieldSchema; changed: string[]; } export interface DisplayFieldDef { key: string; label: string; source: "standard" | "custom"; type: string; displayOrder?: number; } export interface SchemaReorderResult { schema: UserFieldSchema; changed: string[]; order: DisplayFieldDef[]; } interface DiscoveredFields { standard: Record; custom: Record; } export declare function loadSchema(): UserFieldSchema | null; export declare function saveSchema(schema: UserFieldSchema): void; /** * Sample Moodle users to discover all user fields (standard + custom). * * Standard fields: inferred from a single user lookup + typeof on values. * Custom fields: sampled from enrolled users across courses. * * Bounded to avoid excessive API calls. Stops early when custom field * discovery stabilizes. */ export declare function discoverFields(client: MoodleClient): Promise; /** * Merge discovered fields + defaults + existing operator overrides into a schema. * * @param discovered - Raw field discovery result * @param siteUrl - Moodle site URL * @param moodleVersion - Moodle version string * @param existingSchema - Optional existing schema (preserves operator overrides) * @param schemaVersion - Version number for the new schema */ export declare function mergeSchema(discovered: DiscoveredFields, siteUrl: string, moodleVersion: string, existingSchema?: UserFieldSchema | null, schemaVersion?: number): UserFieldSchema; /** * Compare two schemas and report what changed. */ export declare function diffSchemas(oldSchema: UserFieldSchema, newSchema: UserFieldSchema): SchemaDiff; /** * Apply operator updates to a schema. Only mutates the fields provided. * Rejects unknown field keys. */ export declare function applyUpdates(schema: UserFieldSchema, updates: Record): SchemaUpdateResult; export declare function getFieldSortOrderValue(key: string, schema: UserFieldSchema): number; export declare function normalizeDisplayOrder(schema: UserFieldSchema, orderedKeys?: string[]): void; export declare function reorderDisplayField(schema: UserFieldSchema, input: { field: string; position?: "start" | "end"; before?: string; after?: string; }): SchemaReorderResult; /** * Return field definitions for fields marked display:true, in display order. */ export declare function getDisplayFieldDefs(schema: UserFieldSchema): DisplayFieldDef[]; export declare function getDisplayFields(schema: UserFieldSchema): Array<{ key: string; label: string; }>; /** * Format a user's custom fields into a simple key→value map. */ export declare function normalizeCustomFields(customfields?: Array<{ shortname: string; value: string; type: string; }>): Record; export {}; //# sourceMappingURL=user-fields.d.ts.map