@openmdm/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/schema.js CHANGED
@@ -28,6 +28,8 @@ var mdmSchema = {
28
28
  nullable: true,
29
29
  references: { table: "mdm_policies", column: "id", onDelete: "set null" }
30
30
  },
31
+ agent_version: { type: "string", nullable: true },
32
+ // MDM agent version installed on device
31
33
  last_heartbeat: { type: "datetime", nullable: true },
32
34
  last_sync: { type: "datetime", nullable: true },
33
35
  // Telemetry (denormalized for quick access)
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema.ts"],"names":[],"mappings":"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","file":"schema.js","sourcesContent":["/**\n * OpenMDM Database Schema Definition\n *\n * This schema defines the structure for MDM data storage.\n * Database adapters implement this schema for their specific ORM/database.\n *\n * Tables:\n * - mdm_devices: Enrolled devices and their state\n * - mdm_policies: Device policies and configurations\n * - mdm_applications: Registered applications for deployment\n * - mdm_commands: Command queue for device operations\n * - mdm_events: Event log for device activities\n * - mdm_groups: Device grouping for bulk operations\n * - mdm_device_groups: Many-to-many device-group relationships\n * - mdm_push_tokens: FCM/MQTT push notification tokens\n * - mdm_app_deployments: App-to-policy/group deployment mappings\n * - mdm_app_versions: App version history for rollback support\n * - mdm_rollbacks: Rollback operation history and status\n * - mdm_webhook_endpoints: Outbound webhook configuration\n * - mdm_webhook_deliveries: Webhook delivery history\n * - mdm_tenants: Multi-tenant organization isolation\n * - mdm_roles: RBAC role definitions\n * - mdm_users: User accounts for authorization\n * - mdm_user_roles: User-role mapping\n * - mdm_audit_logs: Compliance and audit trail\n * - mdm_scheduled_tasks: Scheduled task definitions\n * - mdm_task_executions: Task execution history\n * - mdm_message_queue: Persistent push message queue\n * - mdm_plugin_storage: Plugin state persistence\n */\n\n// ============================================\n// Schema Column Types\n// ============================================\n\nexport type ColumnType =\n | 'string'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'boolean'\n | 'datetime'\n | 'json'\n | 'enum';\n\nexport interface ColumnDefinition {\n type: ColumnType;\n nullable?: boolean;\n primaryKey?: boolean;\n unique?: boolean;\n default?: unknown;\n enumValues?: string[];\n references?: {\n table: string;\n column: string;\n onDelete?: 'cascade' | 'set null' | 'restrict';\n };\n}\n\nexport interface IndexDefinition {\n columns: string[];\n unique?: boolean;\n name?: string;\n}\n\nexport interface TableDefinition {\n columns: Record<string, ColumnDefinition>;\n indexes?: IndexDefinition[];\n}\n\nexport interface SchemaDefinition {\n tables: Record<string, TableDefinition>;\n}\n\n// ============================================\n// OpenMDM Schema\n// ============================================\n\nexport const mdmSchema: SchemaDefinition = {\n tables: {\n // ----------------------------------------\n // Devices Table\n // ----------------------------------------\n mdm_devices: {\n columns: {\n id: { type: 'string', primaryKey: true },\n external_id: { type: 'string', nullable: true },\n enrollment_id: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'enrolled', 'unenrolled', 'blocked'],\n default: 'pending',\n },\n\n // Device Info\n model: { type: 'string', nullable: true },\n manufacturer: { type: 'string', nullable: true },\n os_version: { type: 'string', nullable: true },\n serial_number: { type: 'string', nullable: true },\n imei: { type: 'string', nullable: true },\n mac_address: { type: 'string', nullable: true },\n android_id: { type: 'string', nullable: true },\n\n // MDM State\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n last_heartbeat: { type: 'datetime', nullable: true },\n last_sync: { type: 'datetime', nullable: true },\n\n // Telemetry (denormalized for quick access)\n battery_level: { type: 'integer', nullable: true },\n storage_used: { type: 'bigint', nullable: true },\n storage_total: { type: 'bigint', nullable: true },\n latitude: { type: 'string', nullable: true }, // Stored as string for precision\n longitude: { type: 'string', nullable: true },\n location_timestamp: { type: 'datetime', nullable: true },\n\n // JSON fields\n installed_apps: { type: 'json', nullable: true },\n tags: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n\n // Timestamps\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enrollment_id'], unique: true },\n { columns: ['status'] },\n { columns: ['policy_id'] },\n { columns: ['last_heartbeat'] },\n { columns: ['mac_address'] },\n { columns: ['serial_number'] },\n ],\n },\n\n // ----------------------------------------\n // Policies Table\n // ----------------------------------------\n mdm_policies: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n is_default: { type: 'boolean', default: false },\n settings: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['is_default'] },\n ],\n },\n\n // ----------------------------------------\n // Applications Table\n // ----------------------------------------\n mdm_applications: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true }, // SHA-256\n size: { type: 'bigint', nullable: true },\n min_sdk_version: { type: 'integer', nullable: true },\n\n // Deployment settings\n show_icon: { type: 'boolean', default: true },\n run_after_install: { type: 'boolean', default: false },\n run_at_boot: { type: 'boolean', default: false },\n is_system: { type: 'boolean', default: false },\n\n // State\n is_active: { type: 'boolean', default: true },\n\n // Metadata\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['package_name'] },\n { columns: ['package_name', 'version'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Commands Table\n // ----------------------------------------\n mdm_commands: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'sent', 'acknowledged', 'completed', 'failed', 'cancelled'],\n default: 'pending',\n },\n result: { type: 'json', nullable: true },\n error: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n sent_at: { type: 'datetime', nullable: true },\n acknowledged_at: { type: 'datetime', nullable: true },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['device_id', 'status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Events Table\n // ----------------------------------------\n mdm_events: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['type'] },\n { columns: ['device_id', 'type'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Groups Table\n // ----------------------------------------\n mdm_groups: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n parent_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_groups', column: 'id', onDelete: 'set null' },\n },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['policy_id'] },\n { columns: ['parent_id'] },\n ],\n },\n\n // ----------------------------------------\n // Device Groups (Many-to-Many)\n // ----------------------------------------\n mdm_device_groups: {\n columns: {\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n group_id: {\n type: 'string',\n references: { table: 'mdm_groups', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id', 'group_id'], unique: true },\n { columns: ['group_id'] },\n ],\n },\n\n // ----------------------------------------\n // Push Tokens (for FCM/MQTT registration)\n // ----------------------------------------\n mdm_push_tokens: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n provider: {\n type: 'enum',\n enumValues: ['fcm', 'mqtt', 'websocket'],\n },\n token: { type: 'string' },\n is_active: { type: 'boolean', default: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['provider', 'token'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Application Deployments (Which apps go to which policies/groups)\n // ----------------------------------------\n mdm_app_deployments: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n // Target can be policy or group\n target_type: {\n type: 'enum',\n enumValues: ['policy', 'group'],\n },\n target_id: { type: 'string' },\n action: {\n type: 'enum',\n enumValues: ['install', 'update', 'uninstall'],\n default: 'install',\n },\n is_required: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['target_type', 'target_id'] },\n ],\n },\n\n // ----------------------------------------\n // App Versions (Version history for rollback support)\n // ----------------------------------------\n mdm_app_versions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true },\n size: { type: 'bigint', nullable: true },\n release_notes: { type: 'text', nullable: true },\n is_minimum_version: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['package_name'] },\n { columns: ['package_name', 'version_code'], unique: true },\n { columns: ['is_minimum_version'] },\n ],\n },\n\n // ----------------------------------------\n // App Rollbacks (Rollback history and status)\n // ----------------------------------------\n mdm_rollbacks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n from_version: { type: 'string' },\n from_version_code: { type: 'integer' },\n to_version: { type: 'string' },\n to_version_code: { type: 'integer' },\n reason: { type: 'text', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'in_progress', 'completed', 'failed'],\n default: 'pending',\n },\n error: { type: 'text', nullable: true },\n initiated_by: { type: 'string', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['package_name'] },\n { columns: ['device_id', 'package_name'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Endpoints (For outbound webhook configuration storage)\n // ----------------------------------------\n mdm_webhook_endpoints: {\n columns: {\n id: { type: 'string', primaryKey: true },\n url: { type: 'string' },\n events: { type: 'json' }, // Array of event types or ['*']\n headers: { type: 'json', nullable: true },\n enabled: { type: 'boolean', default: true },\n description: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enabled'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Deliveries (Delivery history and status)\n // ----------------------------------------\n mdm_webhook_deliveries: {\n columns: {\n id: { type: 'string', primaryKey: true },\n endpoint_id: {\n type: 'string',\n references: { table: 'mdm_webhook_endpoints', column: 'id', onDelete: 'cascade' },\n },\n event_id: { type: 'string' },\n event_type: { type: 'string' },\n payload: { type: 'json' },\n status: {\n type: 'enum',\n enumValues: ['pending', 'success', 'failed'],\n default: 'pending',\n },\n status_code: { type: 'integer', nullable: true },\n error: { type: 'text', nullable: true },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n delivered_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['endpoint_id'] },\n { columns: ['event_type'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Tenants Table (Multi-tenancy)\n // ----------------------------------------\n mdm_tenants: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n slug: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'suspended', 'pending'],\n default: 'pending',\n },\n settings: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['slug'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // Roles Table (RBAC)\n // ----------------------------------------\n mdm_roles: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n permissions: { type: 'json' },\n is_system: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['name'] },\n { columns: ['tenant_id', 'name'], unique: true },\n ],\n },\n\n // ----------------------------------------\n // Users Table (RBAC)\n // ----------------------------------------\n mdm_users: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n email: { type: 'string' },\n name: { type: 'string', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'inactive', 'pending'],\n default: 'pending',\n },\n metadata: { type: 'json', nullable: true },\n last_login_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['email'] },\n { columns: ['tenant_id', 'email'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // User Roles (Many-to-Many)\n // ----------------------------------------\n mdm_user_roles: {\n columns: {\n user_id: {\n type: 'string',\n references: { table: 'mdm_users', column: 'id', onDelete: 'cascade' },\n },\n role_id: {\n type: 'string',\n references: { table: 'mdm_roles', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['user_id', 'role_id'], unique: true },\n { columns: ['user_id'] },\n { columns: ['role_id'] },\n ],\n },\n\n // ----------------------------------------\n // Audit Logs Table\n // ----------------------------------------\n mdm_audit_logs: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n user_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_users', column: 'id', onDelete: 'set null' },\n },\n action: { type: 'string' },\n resource: { type: 'string' },\n resource_id: { type: 'string', nullable: true },\n details: { type: 'json', nullable: true },\n ip_address: { type: 'string', nullable: true },\n user_agent: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['user_id'] },\n { columns: ['action'] },\n { columns: ['resource'] },\n { columns: ['resource', 'resource_id'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Scheduled Tasks Table\n // ----------------------------------------\n mdm_scheduled_tasks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n task_type: {\n type: 'enum',\n enumValues: ['command', 'policy_update', 'app_install', 'maintenance', 'custom'],\n },\n schedule: { type: 'json' },\n target: { type: 'json', nullable: true },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'paused', 'completed', 'failed'],\n default: 'active',\n },\n next_run_at: { type: 'datetime', nullable: true },\n last_run_at: { type: 'datetime', nullable: true },\n max_retries: { type: 'integer', default: 3 },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['task_type'] },\n { columns: ['status'] },\n { columns: ['next_run_at'] },\n ],\n },\n\n // ----------------------------------------\n // Task Executions Table\n // ----------------------------------------\n mdm_task_executions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n task_id: {\n type: 'string',\n references: { table: 'mdm_scheduled_tasks', column: 'id', onDelete: 'cascade' },\n },\n status: {\n type: 'enum',\n enumValues: ['running', 'completed', 'failed'],\n default: 'running',\n },\n started_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n devices_processed: { type: 'integer', default: 0 },\n devices_succeeded: { type: 'integer', default: 0 },\n devices_failed: { type: 'integer', default: 0 },\n error: { type: 'text', nullable: true },\n details: { type: 'json', nullable: true },\n },\n indexes: [\n { columns: ['task_id'] },\n { columns: ['status'] },\n { columns: ['started_at'] },\n ],\n },\n\n // ----------------------------------------\n // Message Queue Table\n // ----------------------------------------\n mdm_message_queue: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n message_type: { type: 'string' },\n payload: { type: 'json' },\n priority: {\n type: 'enum',\n enumValues: ['high', 'normal', 'low'],\n default: 'normal',\n },\n status: {\n type: 'enum',\n enumValues: ['pending', 'processing', 'delivered', 'failed', 'expired'],\n default: 'pending',\n },\n attempts: { type: 'integer', default: 0 },\n max_attempts: { type: 'integer', default: 3 },\n last_attempt_at: { type: 'datetime', nullable: true },\n last_error: { type: 'text', nullable: true },\n expires_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['priority'] },\n { columns: ['expires_at'] },\n { columns: ['device_id', 'status', 'priority'] },\n ],\n },\n\n // ----------------------------------------\n // Plugin Storage Table\n // ----------------------------------------\n mdm_plugin_storage: {\n columns: {\n plugin_name: { type: 'string' },\n key: { type: 'string' },\n value: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['plugin_name', 'key'], unique: true },\n { columns: ['plugin_name'] },\n ],\n },\n },\n};\n\n// ============================================\n// Schema Helper Functions\n// ============================================\n\n/**\n * Get all table names from the schema\n */\nexport function getTableNames(): string[] {\n return Object.keys(mdmSchema.tables);\n}\n\n/**\n * Get column names for a table\n */\nexport function getColumnNames(tableName: string): string[] {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n return Object.keys(table.columns);\n}\n\n/**\n * Get the primary key column for a table\n */\nexport function getPrimaryKey(tableName: string): string | null {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n\n for (const [name, def] of Object.entries(table.columns)) {\n if (def.primaryKey) return name;\n }\n return null;\n}\n\n/**\n * Convert snake_case column name to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Convert camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Transform object keys from snake_case to camelCase\n */\nexport function transformToCamelCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[snakeToCamel(key)] = value;\n }\n return result;\n}\n\n/**\n * Transform object keys from camelCase to snake_case\n */\nexport function transformToSnakeCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[camelToSnake(key)] = value;\n }\n return result;\n}\n"]}
1
+ {"version":3,"sources":["../src/schema.ts"],"names":[],"mappings":"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","file":"schema.js","sourcesContent":["/**\n * OpenMDM Database Schema Definition\n *\n * This schema defines the structure for MDM data storage.\n * Database adapters implement this schema for their specific ORM/database.\n *\n * Tables:\n * - mdm_devices: Enrolled devices and their state\n * - mdm_policies: Device policies and configurations\n * - mdm_applications: Registered applications for deployment\n * - mdm_commands: Command queue for device operations\n * - mdm_events: Event log for device activities\n * - mdm_groups: Device grouping for bulk operations\n * - mdm_device_groups: Many-to-many device-group relationships\n * - mdm_push_tokens: FCM/MQTT push notification tokens\n * - mdm_app_deployments: App-to-policy/group deployment mappings\n * - mdm_app_versions: App version history for rollback support\n * - mdm_rollbacks: Rollback operation history and status\n * - mdm_webhook_endpoints: Outbound webhook configuration\n * - mdm_webhook_deliveries: Webhook delivery history\n * - mdm_tenants: Multi-tenant organization isolation\n * - mdm_roles: RBAC role definitions\n * - mdm_users: User accounts for authorization\n * - mdm_user_roles: User-role mapping\n * - mdm_audit_logs: Compliance and audit trail\n * - mdm_scheduled_tasks: Scheduled task definitions\n * - mdm_task_executions: Task execution history\n * - mdm_message_queue: Persistent push message queue\n * - mdm_plugin_storage: Plugin state persistence\n */\n\n// ============================================\n// Schema Column Types\n// ============================================\n\nexport type ColumnType =\n | 'string'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'boolean'\n | 'datetime'\n | 'json'\n | 'enum';\n\nexport interface ColumnDefinition {\n type: ColumnType;\n nullable?: boolean;\n primaryKey?: boolean;\n unique?: boolean;\n default?: unknown;\n enumValues?: string[];\n references?: {\n table: string;\n column: string;\n onDelete?: 'cascade' | 'set null' | 'restrict';\n };\n}\n\nexport interface IndexDefinition {\n columns: string[];\n unique?: boolean;\n name?: string;\n}\n\nexport interface TableDefinition {\n columns: Record<string, ColumnDefinition>;\n indexes?: IndexDefinition[];\n}\n\nexport interface SchemaDefinition {\n tables: Record<string, TableDefinition>;\n}\n\n// ============================================\n// OpenMDM Schema\n// ============================================\n\nexport const mdmSchema: SchemaDefinition = {\n tables: {\n // ----------------------------------------\n // Devices Table\n // ----------------------------------------\n mdm_devices: {\n columns: {\n id: { type: 'string', primaryKey: true },\n external_id: { type: 'string', nullable: true },\n enrollment_id: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'enrolled', 'unenrolled', 'blocked'],\n default: 'pending',\n },\n\n // Device Info\n model: { type: 'string', nullable: true },\n manufacturer: { type: 'string', nullable: true },\n os_version: { type: 'string', nullable: true },\n serial_number: { type: 'string', nullable: true },\n imei: { type: 'string', nullable: true },\n mac_address: { type: 'string', nullable: true },\n android_id: { type: 'string', nullable: true },\n\n // MDM State\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n agent_version: { type: 'string', nullable: true }, // MDM agent version installed on device\n last_heartbeat: { type: 'datetime', nullable: true },\n last_sync: { type: 'datetime', nullable: true },\n\n // Telemetry (denormalized for quick access)\n battery_level: { type: 'integer', nullable: true },\n storage_used: { type: 'bigint', nullable: true },\n storage_total: { type: 'bigint', nullable: true },\n latitude: { type: 'string', nullable: true }, // Stored as string for precision\n longitude: { type: 'string', nullable: true },\n location_timestamp: { type: 'datetime', nullable: true },\n\n // JSON fields\n installed_apps: { type: 'json', nullable: true },\n tags: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n\n // Timestamps\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enrollment_id'], unique: true },\n { columns: ['status'] },\n { columns: ['policy_id'] },\n { columns: ['last_heartbeat'] },\n { columns: ['mac_address'] },\n { columns: ['serial_number'] },\n ],\n },\n\n // ----------------------------------------\n // Policies Table\n // ----------------------------------------\n mdm_policies: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n is_default: { type: 'boolean', default: false },\n settings: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['is_default'] },\n ],\n },\n\n // ----------------------------------------\n // Applications Table\n // ----------------------------------------\n mdm_applications: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true }, // SHA-256\n size: { type: 'bigint', nullable: true },\n min_sdk_version: { type: 'integer', nullable: true },\n\n // Deployment settings\n show_icon: { type: 'boolean', default: true },\n run_after_install: { type: 'boolean', default: false },\n run_at_boot: { type: 'boolean', default: false },\n is_system: { type: 'boolean', default: false },\n\n // State\n is_active: { type: 'boolean', default: true },\n\n // Metadata\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['package_name'] },\n { columns: ['package_name', 'version'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Commands Table\n // ----------------------------------------\n mdm_commands: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'sent', 'acknowledged', 'completed', 'failed', 'cancelled'],\n default: 'pending',\n },\n result: { type: 'json', nullable: true },\n error: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n sent_at: { type: 'datetime', nullable: true },\n acknowledged_at: { type: 'datetime', nullable: true },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['device_id', 'status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Events Table\n // ----------------------------------------\n mdm_events: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n type: { type: 'string' },\n payload: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['type'] },\n { columns: ['device_id', 'type'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Groups Table\n // ----------------------------------------\n mdm_groups: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n policy_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_policies', column: 'id', onDelete: 'set null' },\n },\n parent_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_groups', column: 'id', onDelete: 'set null' },\n },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['name'] },\n { columns: ['policy_id'] },\n { columns: ['parent_id'] },\n ],\n },\n\n // ----------------------------------------\n // Device Groups (Many-to-Many)\n // ----------------------------------------\n mdm_device_groups: {\n columns: {\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n group_id: {\n type: 'string',\n references: { table: 'mdm_groups', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id', 'group_id'], unique: true },\n { columns: ['group_id'] },\n ],\n },\n\n // ----------------------------------------\n // Push Tokens (for FCM/MQTT registration)\n // ----------------------------------------\n mdm_push_tokens: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n provider: {\n type: 'enum',\n enumValues: ['fcm', 'mqtt', 'websocket'],\n },\n token: { type: 'string' },\n is_active: { type: 'boolean', default: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['provider', 'token'], unique: true },\n { columns: ['is_active'] },\n ],\n },\n\n // ----------------------------------------\n // Application Deployments (Which apps go to which policies/groups)\n // ----------------------------------------\n mdm_app_deployments: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n // Target can be policy or group\n target_type: {\n type: 'enum',\n enumValues: ['policy', 'group'],\n },\n target_id: { type: 'string' },\n action: {\n type: 'enum',\n enumValues: ['install', 'update', 'uninstall'],\n default: 'install',\n },\n is_required: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['target_type', 'target_id'] },\n ],\n },\n\n // ----------------------------------------\n // App Versions (Version history for rollback support)\n // ----------------------------------------\n mdm_app_versions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n application_id: {\n type: 'string',\n references: { table: 'mdm_applications', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n version: { type: 'string' },\n version_code: { type: 'integer' },\n url: { type: 'string' },\n hash: { type: 'string', nullable: true },\n size: { type: 'bigint', nullable: true },\n release_notes: { type: 'text', nullable: true },\n is_minimum_version: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['application_id'] },\n { columns: ['package_name'] },\n { columns: ['package_name', 'version_code'], unique: true },\n { columns: ['is_minimum_version'] },\n ],\n },\n\n // ----------------------------------------\n // App Rollbacks (Rollback history and status)\n // ----------------------------------------\n mdm_rollbacks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n package_name: { type: 'string' },\n from_version: { type: 'string' },\n from_version_code: { type: 'integer' },\n to_version: { type: 'string' },\n to_version_code: { type: 'integer' },\n reason: { type: 'text', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['pending', 'in_progress', 'completed', 'failed'],\n default: 'pending',\n },\n error: { type: 'text', nullable: true },\n initiated_by: { type: 'string', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['device_id'] },\n { columns: ['package_name'] },\n { columns: ['device_id', 'package_name'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Endpoints (For outbound webhook configuration storage)\n // ----------------------------------------\n mdm_webhook_endpoints: {\n columns: {\n id: { type: 'string', primaryKey: true },\n url: { type: 'string' },\n events: { type: 'json' }, // Array of event types or ['*']\n headers: { type: 'json', nullable: true },\n enabled: { type: 'boolean', default: true },\n description: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['enabled'] },\n ],\n },\n\n // ----------------------------------------\n // Webhook Deliveries (Delivery history and status)\n // ----------------------------------------\n mdm_webhook_deliveries: {\n columns: {\n id: { type: 'string', primaryKey: true },\n endpoint_id: {\n type: 'string',\n references: { table: 'mdm_webhook_endpoints', column: 'id', onDelete: 'cascade' },\n },\n event_id: { type: 'string' },\n event_type: { type: 'string' },\n payload: { type: 'json' },\n status: {\n type: 'enum',\n enumValues: ['pending', 'success', 'failed'],\n default: 'pending',\n },\n status_code: { type: 'integer', nullable: true },\n error: { type: 'text', nullable: true },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n delivered_at: { type: 'datetime', nullable: true },\n },\n indexes: [\n { columns: ['endpoint_id'] },\n { columns: ['event_type'] },\n { columns: ['status'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Tenants Table (Multi-tenancy)\n // ----------------------------------------\n mdm_tenants: {\n columns: {\n id: { type: 'string', primaryKey: true },\n name: { type: 'string' },\n slug: { type: 'string', unique: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'suspended', 'pending'],\n default: 'pending',\n },\n settings: { type: 'json', nullable: true },\n metadata: { type: 'json', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['slug'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // Roles Table (RBAC)\n // ----------------------------------------\n mdm_roles: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n permissions: { type: 'json' },\n is_system: { type: 'boolean', default: false },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['name'] },\n { columns: ['tenant_id', 'name'], unique: true },\n ],\n },\n\n // ----------------------------------------\n // Users Table (RBAC)\n // ----------------------------------------\n mdm_users: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n email: { type: 'string' },\n name: { type: 'string', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'inactive', 'pending'],\n default: 'pending',\n },\n metadata: { type: 'json', nullable: true },\n last_login_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['email'] },\n { columns: ['tenant_id', 'email'], unique: true },\n { columns: ['status'] },\n ],\n },\n\n // ----------------------------------------\n // User Roles (Many-to-Many)\n // ----------------------------------------\n mdm_user_roles: {\n columns: {\n user_id: {\n type: 'string',\n references: { table: 'mdm_users', column: 'id', onDelete: 'cascade' },\n },\n role_id: {\n type: 'string',\n references: { table: 'mdm_roles', column: 'id', onDelete: 'cascade' },\n },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['user_id', 'role_id'], unique: true },\n { columns: ['user_id'] },\n { columns: ['role_id'] },\n ],\n },\n\n // ----------------------------------------\n // Audit Logs Table\n // ----------------------------------------\n mdm_audit_logs: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n user_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_users', column: 'id', onDelete: 'set null' },\n },\n action: { type: 'string' },\n resource: { type: 'string' },\n resource_id: { type: 'string', nullable: true },\n details: { type: 'json', nullable: true },\n ip_address: { type: 'string', nullable: true },\n user_agent: { type: 'text', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['user_id'] },\n { columns: ['action'] },\n { columns: ['resource'] },\n { columns: ['resource', 'resource_id'] },\n { columns: ['created_at'] },\n ],\n },\n\n // ----------------------------------------\n // Scheduled Tasks Table\n // ----------------------------------------\n mdm_scheduled_tasks: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n name: { type: 'string' },\n description: { type: 'text', nullable: true },\n task_type: {\n type: 'enum',\n enumValues: ['command', 'policy_update', 'app_install', 'maintenance', 'custom'],\n },\n schedule: { type: 'json' },\n target: { type: 'json', nullable: true },\n payload: { type: 'json', nullable: true },\n status: {\n type: 'enum',\n enumValues: ['active', 'paused', 'completed', 'failed'],\n default: 'active',\n },\n next_run_at: { type: 'datetime', nullable: true },\n last_run_at: { type: 'datetime', nullable: true },\n max_retries: { type: 'integer', default: 3 },\n retry_count: { type: 'integer', default: 0 },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['task_type'] },\n { columns: ['status'] },\n { columns: ['next_run_at'] },\n ],\n },\n\n // ----------------------------------------\n // Task Executions Table\n // ----------------------------------------\n mdm_task_executions: {\n columns: {\n id: { type: 'string', primaryKey: true },\n task_id: {\n type: 'string',\n references: { table: 'mdm_scheduled_tasks', column: 'id', onDelete: 'cascade' },\n },\n status: {\n type: 'enum',\n enumValues: ['running', 'completed', 'failed'],\n default: 'running',\n },\n started_at: { type: 'datetime', default: 'now' },\n completed_at: { type: 'datetime', nullable: true },\n devices_processed: { type: 'integer', default: 0 },\n devices_succeeded: { type: 'integer', default: 0 },\n devices_failed: { type: 'integer', default: 0 },\n error: { type: 'text', nullable: true },\n details: { type: 'json', nullable: true },\n },\n indexes: [\n { columns: ['task_id'] },\n { columns: ['status'] },\n { columns: ['started_at'] },\n ],\n },\n\n // ----------------------------------------\n // Message Queue Table\n // ----------------------------------------\n mdm_message_queue: {\n columns: {\n id: { type: 'string', primaryKey: true },\n tenant_id: {\n type: 'string',\n nullable: true,\n references: { table: 'mdm_tenants', column: 'id', onDelete: 'cascade' },\n },\n device_id: {\n type: 'string',\n references: { table: 'mdm_devices', column: 'id', onDelete: 'cascade' },\n },\n message_type: { type: 'string' },\n payload: { type: 'json' },\n priority: {\n type: 'enum',\n enumValues: ['high', 'normal', 'low'],\n default: 'normal',\n },\n status: {\n type: 'enum',\n enumValues: ['pending', 'processing', 'delivered', 'failed', 'expired'],\n default: 'pending',\n },\n attempts: { type: 'integer', default: 0 },\n max_attempts: { type: 'integer', default: 3 },\n last_attempt_at: { type: 'datetime', nullable: true },\n last_error: { type: 'text', nullable: true },\n expires_at: { type: 'datetime', nullable: true },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['tenant_id'] },\n { columns: ['device_id'] },\n { columns: ['status'] },\n { columns: ['priority'] },\n { columns: ['expires_at'] },\n { columns: ['device_id', 'status', 'priority'] },\n ],\n },\n\n // ----------------------------------------\n // Plugin Storage Table\n // ----------------------------------------\n mdm_plugin_storage: {\n columns: {\n plugin_name: { type: 'string' },\n key: { type: 'string' },\n value: { type: 'json' },\n created_at: { type: 'datetime', default: 'now' },\n updated_at: { type: 'datetime', default: 'now' },\n },\n indexes: [\n { columns: ['plugin_name', 'key'], unique: true },\n { columns: ['plugin_name'] },\n ],\n },\n },\n};\n\n// ============================================\n// Schema Helper Functions\n// ============================================\n\n/**\n * Get all table names from the schema\n */\nexport function getTableNames(): string[] {\n return Object.keys(mdmSchema.tables);\n}\n\n/**\n * Get column names for a table\n */\nexport function getColumnNames(tableName: string): string[] {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n return Object.keys(table.columns);\n}\n\n/**\n * Get the primary key column for a table\n */\nexport function getPrimaryKey(tableName: string): string | null {\n const table = mdmSchema.tables[tableName];\n if (!table) throw new Error(`Table ${tableName} not found in schema`);\n\n for (const [name, def] of Object.entries(table.columns)) {\n if (def.primaryKey) return name;\n }\n return null;\n}\n\n/**\n * Convert snake_case column name to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\n/**\n * Convert camelCase to snake_case\n */\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n/**\n * Transform object keys from snake_case to camelCase\n */\nexport function transformToCamelCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[snakeToCamel(key)] = value;\n }\n return result;\n}\n\n/**\n * Transform object keys from camelCase to snake_case\n */\nexport function transformToSnakeCase<T extends Record<string, unknown>>(\n obj: T\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[camelToSnake(key)] = value;\n }\n return result;\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -18,6 +18,7 @@ interface Device {
18
18
  macAddress?: string | null;
19
19
  androidId?: string | null;
20
20
  policyId?: string | null;
21
+ agentVersion?: string | null;
21
22
  lastHeartbeat?: Date | null;
22
23
  lastSync?: Date | null;
23
24
  batteryLevel?: number | null;
@@ -60,6 +61,7 @@ interface UpdateDeviceInput {
60
61
  externalId?: string | null;
61
62
  status?: DeviceStatus;
62
63
  policyId?: string | null;
64
+ agentVersion?: string | null;
63
65
  model?: string;
64
66
  manufacturer?: string;
65
67
  osVersion?: string;
@@ -266,7 +268,7 @@ interface CreateAppRollbackInput {
266
268
  reason?: string;
267
269
  initiatedBy?: string;
268
270
  }
269
- type CommandType = 'reboot' | 'shutdown' | 'sync' | 'lock' | 'unlock' | 'wipe' | 'factoryReset' | 'installApp' | 'uninstallApp' | 'updateApp' | 'runApp' | 'clearAppData' | 'clearAppCache' | 'shell' | 'setPolicy' | 'grantPermissions' | 'exitKiosk' | 'enterKiosk' | 'setWifi' | 'screenshot' | 'getLocation' | 'setVolume' | 'sendNotification' | 'whitelistBattery' | 'enablePermissiveMode' | 'setTimeZone' | 'enableAdb' | 'rollbackApp' | 'custom';
271
+ type CommandType = 'reboot' | 'shutdown' | 'sync' | 'lock' | 'unlock' | 'wipe' | 'factoryReset' | 'installApp' | 'uninstallApp' | 'updateApp' | 'runApp' | 'clearAppData' | 'clearAppCache' | 'shell' | 'setPolicy' | 'grantPermissions' | 'exitKiosk' | 'enterKiosk' | 'setWifi' | 'screenshot' | 'getLocation' | 'setVolume' | 'sendNotification' | 'whitelistBattery' | 'enablePermissiveMode' | 'setTimeZone' | 'enableAdb' | 'rollbackApp' | 'updateAgent' | 'custom';
270
272
  type CommandStatus = 'pending' | 'sent' | 'acknowledged' | 'completed' | 'failed' | 'cancelled';
271
273
  interface Command {
272
274
  id: string;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAgwDO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClC,WAAA,CACE,OAAA,EACO,IAAA,EACA,UAAA,GAAqB,KACrB,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAAA,EACd;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,wBAAA,GAAN,cAAuC,QAAA,CAAS;AAAA,EACrD,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,uBAAA,EAA0B,UAAU,CAAA,CAAA,EAAI,uBAAA,EAAyB,GAAG,CAAA;AAAA,EAC5E;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,UAAU,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAClE;AACF;AAEO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC9C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,UAAU,CAAA,CAAA,EAAI,gBAAA,EAAkB,GAAG,CAAA;AAAA,EAC9D;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,UAAU,CAAA,CAAA,EAAI,iBAAA,EAAmB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC9C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,UAAU,CAAA,CAAA,EAAI,gBAAA,EAAkB,GAAG,CAAA;AAAA,EAC9D;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,WAAA,CAAY,UAAkB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,OAAA,EAAS,wBAAwB,GAAG,CAAA;AAAA,EAC5C;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,WAAA,CAAY,UAAkB,eAAA,EAAiB;AAC7C,IAAA,KAAA,CAAM,OAAA,EAAS,uBAAuB,GAAG,CAAA;AAAA,EAC3C;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF","file":"types.js","sourcesContent":["/**\n * OpenMDM Core Types\n *\n * These types define the core data structures for the MDM system.\n * Designed to be database-agnostic and framework-agnostic.\n */\n\n// ============================================\n// Device Types\n// ============================================\n\nexport type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';\n\nexport interface Device {\n id: string;\n externalId?: string | null;\n enrollmentId: string;\n status: DeviceStatus;\n\n // Device Info\n model?: string | null;\n manufacturer?: string | null;\n osVersion?: string | null;\n serialNumber?: string | null;\n imei?: string | null;\n macAddress?: string | null;\n androidId?: string | null;\n\n // MDM State\n policyId?: string | null;\n lastHeartbeat?: Date | null;\n lastSync?: Date | null;\n\n // Telemetry\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n location?: DeviceLocation | null;\n installedApps?: InstalledApp[] | null;\n\n // Metadata\n tags?: Record<string, string> | null;\n metadata?: Record<string, unknown> | null;\n\n // Timestamps\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeviceLocation {\n latitude: number;\n longitude: number;\n accuracy?: number;\n timestamp: Date;\n}\n\nexport interface InstalledApp {\n packageName: string;\n version: string;\n versionCode?: number;\n installedAt?: Date;\n}\n\nexport interface CreateDeviceInput {\n enrollmentId: string;\n externalId?: string;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n serialNumber?: string;\n imei?: string;\n macAddress?: string;\n androidId?: string;\n policyId?: string;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateDeviceInput {\n externalId?: string | null;\n status?: DeviceStatus;\n policyId?: string | null;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n lastHeartbeat?: Date;\n lastSync?: Date;\n installedApps?: InstalledApp[];\n location?: DeviceLocation;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeviceFilter {\n status?: DeviceStatus | DeviceStatus[];\n policyId?: string;\n groupId?: string;\n search?: string;\n tags?: Record<string, string>;\n limit?: number;\n offset?: number;\n}\n\nexport interface DeviceListResult {\n devices: Device[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Policy Types\n// ============================================\n\nexport interface Policy {\n id: string;\n name: string;\n description?: string | null;\n isDefault: boolean;\n settings: PolicySettings;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface PolicySettings {\n // Kiosk Mode\n kioskMode?: boolean;\n mainApp?: string;\n allowedApps?: string[];\n kioskExitPassword?: string;\n\n // Lock Features\n lockStatusBar?: boolean;\n lockNavigationBar?: boolean;\n lockSettings?: boolean;\n lockPowerButton?: boolean;\n blockInstall?: boolean;\n blockUninstall?: boolean;\n\n // Hardware Controls\n bluetooth?: HardwareControl;\n wifi?: HardwareControl;\n gps?: HardwareControl;\n mobileData?: HardwareControl;\n camera?: HardwareControl;\n microphone?: HardwareControl;\n usb?: HardwareControl;\n nfc?: HardwareControl;\n\n // Update Settings\n systemUpdatePolicy?: SystemUpdatePolicy;\n updateWindow?: TimeWindow;\n\n // Security\n passwordPolicy?: PasswordPolicy;\n encryptionRequired?: boolean;\n factoryResetProtection?: boolean;\n safeBootDisabled?: boolean;\n\n // Telemetry\n heartbeatInterval?: number;\n locationReportInterval?: number;\n locationEnabled?: boolean;\n\n // Network\n wifiConfigs?: WifiConfig[];\n vpnConfig?: VpnConfig;\n\n // Applications\n applications?: PolicyApplication[];\n\n // Custom settings (for plugins)\n custom?: Record<string, unknown>;\n}\n\nexport type HardwareControl = 'on' | 'off' | 'user';\nexport type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';\n\nexport interface TimeWindow {\n start: string; // \"HH:MM\"\n end: string; // \"HH:MM\"\n}\n\nexport interface PasswordPolicy {\n required: boolean;\n minLength?: number;\n complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';\n maxFailedAttempts?: number;\n expirationDays?: number;\n historyLength?: number;\n}\n\nexport interface WifiConfig {\n ssid: string;\n securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';\n password?: string;\n hidden?: boolean;\n autoConnect?: boolean;\n}\n\nexport interface VpnConfig {\n type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';\n server: string;\n username?: string;\n password?: string;\n certificate?: string;\n config?: Record<string, unknown>;\n}\n\nexport interface PolicyApplication {\n packageName: string;\n action: 'install' | 'update' | 'uninstall';\n version?: string;\n required?: boolean;\n autoUpdate?: boolean;\n}\n\nexport interface CreatePolicyInput {\n name: string;\n description?: string;\n isDefault?: boolean;\n settings: PolicySettings;\n}\n\nexport interface UpdatePolicyInput {\n name?: string;\n description?: string | null;\n isDefault?: boolean;\n settings?: PolicySettings;\n}\n\n// ============================================\n// Application Types\n// ============================================\n\nexport interface Application {\n id: string;\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n\n // Deployment settings\n showIcon: boolean;\n runAfterInstall: boolean;\n runAtBoot: boolean;\n isSystem: boolean;\n\n // State\n isActive: boolean;\n\n // Metadata\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateApplicationInput {\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string;\n size?: number;\n minSdkVersion?: number;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isSystem?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateApplicationInput {\n name?: string;\n version?: string;\n versionCode?: number;\n url?: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isActive?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface DeployTarget {\n devices?: string[];\n policies?: string[];\n groups?: string[];\n}\n\n// ============================================\n// App Version & Rollback Types\n// ============================================\n\nexport interface AppVersion {\n id: string;\n applicationId: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n releaseNotes?: string | null;\n isMinimumVersion: boolean;\n createdAt: Date;\n}\n\nexport interface AppRollback {\n id: string;\n deviceId: string;\n packageName: string;\n fromVersion: string;\n fromVersionCode: number;\n toVersion: string;\n toVersionCode: number;\n reason?: string | null;\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\n error?: string | null;\n initiatedBy?: string | null;\n createdAt: Date;\n completedAt?: Date | null;\n}\n\nexport interface CreateAppRollbackInput {\n deviceId: string;\n packageName: string;\n toVersionCode: number;\n reason?: string;\n initiatedBy?: string;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\nexport type CommandType =\n | 'reboot'\n | 'shutdown'\n | 'sync'\n | 'lock'\n | 'unlock'\n | 'wipe'\n | 'factoryReset'\n | 'installApp'\n | 'uninstallApp'\n | 'updateApp'\n | 'runApp'\n | 'clearAppData'\n | 'clearAppCache'\n | 'shell'\n | 'setPolicy'\n | 'grantPermissions'\n | 'exitKiosk'\n | 'enterKiosk'\n | 'setWifi'\n | 'screenshot'\n | 'getLocation'\n | 'setVolume'\n | 'sendNotification'\n | 'whitelistBattery' // Whitelist app from battery optimization (Doze)\n | 'enablePermissiveMode' // Enable permissive mode for debugging\n | 'setTimeZone' // Set device timezone\n | 'enableAdb' // Enable/disable ADB debugging\n | 'rollbackApp' // Rollback to previous app version\n | 'custom';\n\nexport type CommandStatus =\n | 'pending'\n | 'sent'\n | 'acknowledged'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\nexport interface Command {\n id: string;\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown> | null;\n status: CommandStatus;\n result?: CommandResult | null;\n error?: string | null;\n createdAt: Date;\n sentAt?: Date | null;\n acknowledgedAt?: Date | null;\n completedAt?: Date | null;\n}\n\nexport interface CommandResult {\n success: boolean;\n message?: string;\n data?: unknown;\n}\n\nexport interface SendCommandInput {\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandFilter {\n deviceId?: string;\n status?: CommandStatus | CommandStatus[];\n type?: CommandType | CommandType[];\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Event Types\n// ============================================\n\nexport type EventType =\n | 'device.enrolled'\n | 'device.unenrolled'\n | 'device.blocked'\n | 'device.heartbeat'\n | 'device.locationUpdated'\n | 'device.statusChanged'\n | 'device.policyChanged'\n | 'app.installed'\n | 'app.uninstalled'\n | 'app.updated'\n | 'app.crashed'\n | 'app.started'\n | 'app.stopped'\n | 'policy.applied'\n | 'policy.failed'\n | 'command.received'\n | 'command.acknowledged'\n | 'command.completed'\n | 'command.failed'\n | 'security.tamper'\n | 'security.rootDetected'\n | 'security.screenLocked'\n | 'security.screenUnlocked'\n | 'custom';\n\nexport interface MDMEvent<T = unknown> {\n id: string;\n deviceId: string;\n type: EventType;\n payload: T;\n createdAt: Date;\n}\n\nexport interface EventFilter {\n deviceId?: string;\n type?: EventType | EventType[];\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Group Types\n// ============================================\n\nexport interface Group {\n id: string;\n name: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateGroupInput {\n name: string;\n description?: string;\n policyId?: string;\n parentId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateGroupInput {\n name?: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Enrollment Types\n// ============================================\n\nexport type EnrollmentMethod =\n | 'qr'\n | 'nfc'\n | 'zero-touch'\n | 'knox'\n | 'manual'\n | 'app-only'\n | 'adb';\n\nexport interface EnrollmentRequest {\n // Device identifiers (at least one required)\n macAddress?: string;\n serialNumber?: string;\n imei?: string;\n androidId?: string;\n\n // Device info\n model: string;\n manufacturer: string;\n osVersion: string;\n sdkVersion?: number;\n\n // Agent info\n agentVersion?: string;\n agentPackage?: string;\n\n // Enrollment details\n method: EnrollmentMethod;\n timestamp: string;\n signature: string;\n\n // Optional pre-assigned policy/group\n policyId?: string;\n groupId?: string;\n}\n\nexport interface EnrollmentResponse {\n deviceId: string;\n enrollmentId: string;\n policyId?: string;\n policy?: Policy;\n serverUrl: string;\n pushConfig: PushConfig;\n token: string;\n refreshToken?: string;\n tokenExpiresAt?: Date;\n}\n\nexport interface PushConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n fcmSenderId?: string;\n mqttUrl?: string;\n mqttTopic?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n wsUrl?: string;\n pollingInterval?: number;\n}\n\n// ============================================\n// Telemetry Types\n// ============================================\n\nexport interface Heartbeat {\n deviceId: string;\n timestamp: Date;\n\n // Battery\n batteryLevel: number;\n isCharging: boolean;\n batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';\n\n // Storage\n storageUsed: number;\n storageTotal: number;\n\n // Memory\n memoryUsed: number;\n memoryTotal: number;\n\n // Network\n networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';\n networkName?: string; // SSID or carrier\n signalStrength?: number;\n ipAddress?: string;\n\n // Location\n location?: DeviceLocation;\n\n // Apps\n installedApps: InstalledApp[];\n runningApps?: string[];\n\n // Security\n isRooted?: boolean;\n isEncrypted?: boolean;\n screenLockEnabled?: boolean;\n\n // Agent status\n agentVersion?: string;\n policyVersion?: string;\n lastPolicySync?: Date;\n}\n\n// ============================================\n// Push Token Types\n// ============================================\n\nexport interface PushToken {\n id: string;\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface RegisterPushTokenInput {\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\nexport interface MDMConfig {\n /** Database adapter for persistence */\n database: DatabaseAdapter;\n\n /** Authentication/authorization configuration */\n auth?: AuthConfig;\n\n /** Push notification provider configuration */\n push?: PushProviderConfig;\n\n /** Device enrollment configuration */\n enrollment?: EnrollmentConfig;\n\n /** Server URL (used in enrollment responses) */\n serverUrl?: string;\n\n /** APK/file storage configuration */\n storage?: StorageConfig;\n\n /** Outbound webhook configuration */\n webhooks?: WebhookConfig;\n\n /** Plugins to extend functionality */\n plugins?: MDMPlugin[];\n\n /** Event handlers */\n onDeviceEnrolled?: (device: Device) => Promise<void>;\n onDeviceUnenrolled?: (device: Device) => Promise<void>;\n onDeviceBlocked?: (device: Device) => Promise<void>;\n onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;\n onCommand?: (command: Command) => Promise<void>;\n onEvent?: (event: MDMEvent) => Promise<void>;\n\n // Enterprise features\n /** Multi-tenancy configuration */\n multiTenancy?: {\n enabled: boolean;\n defaultTenantId?: string;\n tenantResolver?: (context: unknown) => Promise<string | null>;\n };\n\n /** Authorization (RBAC) configuration */\n authorization?: {\n enabled: boolean;\n defaultRole?: string;\n };\n\n /** Audit logging configuration */\n audit?: {\n enabled: boolean;\n retentionDays?: number;\n };\n\n /** Scheduling configuration */\n scheduling?: {\n enabled: boolean;\n timezone?: string;\n };\n\n /** Plugin storage configuration */\n pluginStorage?: {\n adapter: 'database' | 'memory';\n };\n}\n\nexport interface StorageConfig {\n /** Storage provider (s3, local, custom) */\n provider: 's3' | 'local' | 'custom';\n\n /** S3 configuration */\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For S3-compatible services\n presignedUrlExpiry?: number; // Seconds, default 3600\n };\n\n /** Local storage path */\n localPath?: string;\n\n /** Custom storage adapter */\n customAdapter?: {\n upload: (file: Buffer, key: string) => Promise<string>;\n getUrl: (key: string) => Promise<string>;\n delete: (key: string) => Promise<void>;\n };\n}\n\nexport interface WebhookConfig {\n /** Webhook endpoints to notify */\n endpoints?: WebhookEndpoint[];\n\n /** Retry configuration */\n retry?: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n };\n\n /** Sign webhooks with HMAC secret */\n signingSecret?: string;\n}\n\nexport interface WebhookEndpoint {\n /** Unique identifier */\n id: string;\n /** Webhook URL */\n url: string;\n /** Events to trigger this webhook */\n events: (EventType | '*')[];\n /** Custom headers */\n headers?: Record<string, string>;\n /** Whether endpoint is active */\n enabled: boolean;\n}\n\nexport interface AuthConfig {\n /** Get current user from request context */\n getUser: <T = unknown>(context: unknown) => Promise<T | null>;\n /** Check if user has admin privileges */\n isAdmin?: (user: unknown) => Promise<boolean>;\n /** Check if user can access specific device */\n canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;\n /** Device JWT secret (for device auth tokens) */\n deviceTokenSecret?: string;\n /** Device token expiration in seconds (default: 365 days) */\n deviceTokenExpiration?: number;\n}\n\nexport interface PushProviderConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n\n // FCM configuration\n fcmCredentials?: string | Record<string, unknown>;\n fcmProjectId?: string;\n\n // MQTT configuration\n mqttUrl?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n mqttTopicPrefix?: string;\n\n // WebSocket configuration\n wsPath?: string;\n wsPingInterval?: number;\n\n // Polling fallback\n pollingInterval?: number;\n}\n\nexport interface EnrollmentConfig {\n /** Auto-enroll devices with valid signature */\n autoEnroll?: boolean;\n /** HMAC secret for device signature verification */\n deviceSecret: string;\n /** Allowed enrollment methods */\n allowedMethods?: EnrollmentMethod[];\n /** Default policy for new devices */\n defaultPolicyId?: string;\n /** Default group for new devices */\n defaultGroupId?: string;\n /** Require manual approval for enrollment */\n requireApproval?: boolean;\n /** Custom enrollment validation */\n validate?: (request: EnrollmentRequest) => Promise<boolean>;\n}\n\n// ============================================\n// Adapter Interfaces\n// ============================================\n\nexport interface DatabaseAdapter {\n // Devices\n findDevice(id: string): Promise<Device | null>;\n findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;\n createDevice(data: CreateDeviceInput): Promise<Device>;\n updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;\n deleteDevice(id: string): Promise<void>;\n countDevices(filter?: DeviceFilter): Promise<number>;\n\n // Policies\n findPolicy(id: string): Promise<Policy | null>;\n findDefaultPolicy(): Promise<Policy | null>;\n listPolicies(): Promise<Policy[]>;\n createPolicy(data: CreatePolicyInput): Promise<Policy>;\n updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;\n deletePolicy(id: string): Promise<void>;\n\n // Applications\n findApplication(id: string): Promise<Application | null>;\n findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;\n listApplications(activeOnly?: boolean): Promise<Application[]>;\n createApplication(data: CreateApplicationInput): Promise<Application>;\n updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;\n deleteApplication(id: string): Promise<void>;\n\n // Commands\n findCommand(id: string): Promise<Command | null>;\n listCommands(filter?: CommandFilter): Promise<Command[]>;\n createCommand(data: SendCommandInput): Promise<Command>;\n updateCommand(id: string, data: Partial<Command>): Promise<Command>;\n getPendingCommands(deviceId: string): Promise<Command[]>;\n\n // Events\n createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;\n listEvents(filter?: EventFilter): Promise<MDMEvent[]>;\n\n // Groups\n findGroup(id: string): Promise<Group | null>;\n listGroups(): Promise<Group[]>;\n createGroup(data: CreateGroupInput): Promise<Group>;\n updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;\n deleteGroup(id: string): Promise<void>;\n listDevicesInGroup(groupId: string): Promise<Device[]>;\n addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;\n removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;\n getDeviceGroups(deviceId: string): Promise<Group[]>;\n\n // Push Tokens\n findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;\n upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;\n deletePushToken(deviceId: string, provider?: string): Promise<void>;\n\n // App Versions (optional - for version tracking)\n listAppVersions?(packageName: string): Promise<AppVersion[]>;\n createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;\n setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;\n getMinimumVersion?(packageName: string): Promise<AppVersion | null>;\n\n // Rollback History (optional)\n createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;\n updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;\n listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;\n\n // Group Hierarchy (optional)\n getGroupChildren?(parentId: string | null): Promise<Group[]>;\n getGroupAncestors?(groupId: string): Promise<Group[]>;\n getGroupDescendants?(groupId: string): Promise<Group[]>;\n getGroupTree?(rootId?: string): Promise<GroupTreeNode[]>;\n getGroupEffectivePolicy?(groupId: string): Promise<Policy | null>;\n moveGroup?(groupId: string, newParentId: string | null): Promise<Group>;\n getGroupHierarchyStats?(): Promise<GroupHierarchyStats>;\n\n // Tenants (optional - for multi-tenancy)\n findTenant?(id: string): Promise<Tenant | null>;\n findTenantBySlug?(slug: string): Promise<Tenant | null>;\n listTenants?(filter?: TenantFilter): Promise<TenantListResult>;\n createTenant?(data: CreateTenantInput): Promise<Tenant>;\n updateTenant?(id: string, data: UpdateTenantInput): Promise<Tenant>;\n deleteTenant?(id: string): Promise<void>;\n getTenantStats?(tenantId: string): Promise<TenantStats>;\n\n // Users (optional - for RBAC)\n findUser?(id: string): Promise<User | null>;\n findUserByEmail?(email: string, tenantId?: string): Promise<User | null>;\n listUsers?(filter?: UserFilter): Promise<UserListResult>;\n createUser?(data: CreateUserInput): Promise<User>;\n updateUser?(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser?(id: string): Promise<void>;\n\n // Roles (optional - for RBAC)\n findRole?(id: string): Promise<Role | null>;\n listRoles?(tenantId?: string): Promise<Role[]>;\n createRole?(data: CreateRoleInput): Promise<Role>;\n updateRole?(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole?(id: string): Promise<void>;\n assignRoleToUser?(userId: string, roleId: string): Promise<void>;\n removeRoleFromUser?(userId: string, roleId: string): Promise<void>;\n getUserRoles?(userId: string): Promise<Role[]>;\n\n // Audit Logs (optional - for compliance)\n createAuditLog?(data: CreateAuditLogInput): Promise<AuditLog>;\n listAuditLogs?(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n deleteAuditLogs?(filter: { olderThan?: Date; tenantId?: string }): Promise<number>;\n\n // Scheduled Tasks (optional - for scheduling)\n findScheduledTask?(id: string): Promise<ScheduledTask | null>;\n listScheduledTasks?(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n createScheduledTask?(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n updateScheduledTask?(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n deleteScheduledTask?(id: string): Promise<void>;\n getUpcomingTasks?(hours: number): Promise<ScheduledTask[]>;\n createTaskExecution?(data: { taskId: string }): Promise<TaskExecution>;\n updateTaskExecution?(id: string, data: Partial<TaskExecution>): Promise<TaskExecution>;\n listTaskExecutions?(taskId: string, limit?: number): Promise<TaskExecution[]>;\n\n // Message Queue (optional - for persistent messaging)\n enqueueMessage?(data: EnqueueMessageInput): Promise<QueuedMessage>;\n dequeueMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n peekMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledgeMessage?(messageId: string): Promise<void>;\n failMessage?(messageId: string, error: string): Promise<void>;\n retryFailedMessages?(maxAttempts?: number): Promise<number>;\n purgeExpiredMessages?(): Promise<number>;\n getQueueStats?(tenantId?: string): Promise<QueueStats>;\n\n // Plugin Storage (optional)\n getPluginValue?(pluginName: string, key: string): Promise<unknown | null>;\n setPluginValue?(pluginName: string, key: string, value: unknown): Promise<void>;\n deletePluginValue?(pluginName: string, key: string): Promise<void>;\n listPluginKeys?(pluginName: string, prefix?: string): Promise<string[]>;\n clearPluginData?(pluginName: string): Promise<void>;\n\n // Dashboard (optional - for analytics)\n getDashboardStats?(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown?(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend?(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates?(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary?(tenantId?: string): Promise<AppInstallationSummary>;\n\n // Transactions (optional)\n transaction?<T>(fn: () => Promise<T>): Promise<T>;\n}\n\nexport interface PushAdapter {\n /** Send push message to a device */\n send(deviceId: string, message: PushMessage): Promise<PushResult>;\n /** Send push message to multiple devices */\n sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;\n /** Register device push token */\n registerToken?(deviceId: string, token: string): Promise<void>;\n /** Unregister device push token */\n unregisterToken?(deviceId: string): Promise<void>;\n /** Subscribe device to topic */\n subscribe?(deviceId: string, topic: string): Promise<void>;\n /** Unsubscribe device from topic */\n unsubscribe?(deviceId: string, topic: string): Promise<void>;\n}\n\nexport interface PushMessage {\n type: string;\n payload?: Record<string, unknown>;\n priority?: 'high' | 'normal';\n ttl?: number;\n collapseKey?: string;\n}\n\nexport interface PushResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\nexport interface PushBatchResult {\n successCount: number;\n failureCount: number;\n results: Array<{ deviceId: string; result: PushResult }>;\n}\n\n// ============================================\n// Plugin Interface\n// ============================================\n\nexport interface MDMPlugin {\n /** Unique plugin name */\n name: string;\n /** Plugin version */\n version: string;\n\n /** Called when MDM is initialized */\n onInit?(mdm: MDMInstance): Promise<void>;\n\n /** Called when MDM is destroyed */\n onDestroy?(): Promise<void>;\n\n /** Additional routes to mount */\n routes?: PluginRoute[];\n\n /** Middleware to apply to all routes */\n middleware?: PluginMiddleware[];\n\n /** Extend enrollment process */\n onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;\n\n /** Extend device processing */\n onDeviceEnrolled?(device: Device): Promise<void>;\n onDeviceUnenrolled?(device: Device): Promise<void>;\n onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;\n\n /** Extend policy processing */\n policySchema?: Record<string, unknown>;\n validatePolicy?(settings: PolicySettings): Promise<{ valid: boolean; errors?: string[] }>;\n applyPolicy?(device: Device, policy: Policy): Promise<void>;\n\n /** Extend command processing */\n commandTypes?: CommandType[];\n executeCommand?(device: Device, command: Command): Promise<CommandResult>;\n}\n\nexport interface PluginRoute {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: (context: unknown) => Promise<unknown>;\n auth?: boolean;\n admin?: boolean;\n}\n\nexport type PluginMiddleware = (\n context: unknown,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n// ============================================\n// MDM Instance Interface\n// ============================================\n\nexport interface WebhookManager {\n /** Deliver an event to all matching webhook endpoints */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n /** Add a webhook endpoint at runtime */\n addEndpoint(endpoint: WebhookEndpoint): void;\n /** Remove a webhook endpoint */\n removeEndpoint(endpointId: string): void;\n /** Update a webhook endpoint */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n /** Get all configured endpoints */\n getEndpoints(): WebhookEndpoint[];\n /** Test a webhook endpoint with a test payload */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface MDMInstance {\n /** Device management */\n devices: DeviceManager;\n /** Policy management */\n policies: PolicyManager;\n /** Application management */\n apps: ApplicationManager;\n /** Command management */\n commands: CommandManager;\n /** Group management */\n groups: GroupManager;\n\n /** Tenant management (if multi-tenancy enabled) */\n tenants?: TenantManager;\n /** Authorization management (RBAC) */\n authorization?: AuthorizationManager;\n /** Audit logging */\n audit?: AuditManager;\n /** Scheduled task management */\n schedules?: ScheduleManager;\n /** Persistent message queue */\n messageQueue?: MessageQueueManager;\n /** Dashboard analytics */\n dashboard?: DashboardManager;\n /** Plugin storage */\n pluginStorage?: PluginStorageAdapter;\n\n /** Push notification service */\n push: PushAdapter;\n\n /** Webhook delivery (if configured) */\n webhooks?: WebhookManager;\n\n /** Database adapter */\n db: DatabaseAdapter;\n\n /** Configuration */\n config: MDMConfig;\n\n /** Subscribe to events */\n on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;\n /** Emit an event */\n emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;\n\n /** Process device enrollment */\n enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;\n /** Process device heartbeat */\n processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;\n /** Verify device token */\n verifyDeviceToken(token: string): Promise<{ deviceId: string } | null>;\n\n /** Get loaded plugins */\n getPlugins(): MDMPlugin[];\n /** Get plugin by name */\n getPlugin(name: string): MDMPlugin | undefined;\n}\n\n// ============================================\n// Manager Interfaces\n// ============================================\n\nexport interface DeviceManager {\n get(id: string): Promise<Device | null>;\n getByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n list(filter?: DeviceFilter): Promise<DeviceListResult>;\n create(data: CreateDeviceInput): Promise<Device>;\n update(id: string, data: UpdateDeviceInput): Promise<Device>;\n delete(id: string): Promise<void>;\n assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;\n addToGroup(deviceId: string, groupId: string): Promise<void>;\n removeFromGroup(deviceId: string, groupId: string): Promise<void>;\n getGroups(deviceId: string): Promise<Group[]>;\n sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;\n sync(deviceId: string): Promise<Command>;\n reboot(deviceId: string): Promise<Command>;\n lock(deviceId: string, message?: string): Promise<Command>;\n wipe(deviceId: string, preserveData?: boolean): Promise<Command>;\n}\n\nexport interface PolicyManager {\n get(id: string): Promise<Policy | null>;\n getDefault(): Promise<Policy | null>;\n list(): Promise<Policy[]>;\n create(data: CreatePolicyInput): Promise<Policy>;\n update(id: string, data: UpdatePolicyInput): Promise<Policy>;\n delete(id: string): Promise<void>;\n setDefault(id: string): Promise<Policy>;\n getDevices(policyId: string): Promise<Device[]>;\n applyToDevice(policyId: string, deviceId: string): Promise<void>;\n}\n\nexport interface ApplicationManager {\n get(id: string): Promise<Application | null>;\n getByPackage(packageName: string, version?: string): Promise<Application | null>;\n list(activeOnly?: boolean): Promise<Application[]>;\n register(data: CreateApplicationInput): Promise<Application>;\n update(id: string, data: UpdateApplicationInput): Promise<Application>;\n delete(id: string): Promise<void>;\n activate(id: string): Promise<Application>;\n deactivate(id: string): Promise<Application>;\n deploy(packageName: string, target: DeployTarget): Promise<void>;\n installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;\n uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;\n}\n\nexport interface CommandManager {\n get(id: string): Promise<Command | null>;\n list(filter?: CommandFilter): Promise<Command[]>;\n send(input: SendCommandInput): Promise<Command>;\n cancel(id: string): Promise<Command>;\n acknowledge(id: string): Promise<Command>;\n complete(id: string, result: CommandResult): Promise<Command>;\n fail(id: string, error: string): Promise<Command>;\n getPending(deviceId: string): Promise<Command[]>;\n}\n\nexport interface GroupManager {\n // Basic CRUD operations\n get(id: string): Promise<Group | null>;\n list(): Promise<Group[]>;\n create(data: CreateGroupInput): Promise<Group>;\n update(id: string, data: UpdateGroupInput): Promise<Group>;\n delete(id: string): Promise<void>;\n\n // Device management\n getDevices(groupId: string): Promise<Device[]>;\n addDevice(groupId: string, deviceId: string): Promise<void>;\n removeDevice(groupId: string, deviceId: string): Promise<void>;\n\n // Hierarchy operations\n getChildren(groupId: string): Promise<Group[]>;\n getTree(rootId?: string): Promise<GroupTreeNode[]>;\n getAncestors(groupId: string): Promise<Group[]>;\n getDescendants(groupId: string): Promise<Group[]>;\n move(groupId: string, newParentId: string | null): Promise<Group>;\n getEffectivePolicy(groupId: string): Promise<Policy | null>;\n getHierarchyStats(): Promise<GroupHierarchyStats>;\n}\n\n// ============================================\n// Group Hierarchy Types\n// ============================================\n\nexport interface GroupTreeNode extends Group {\n children: GroupTreeNode[];\n depth: number;\n path: string[];\n effectivePolicyId?: string | null;\n}\n\nexport interface GroupHierarchyStats {\n totalGroups: number;\n maxDepth: number;\n groupsWithDevices: number;\n groupsWithPolicies: number;\n}\n\n// ============================================\n// Tenant Types (Multi-tenancy)\n// ============================================\n\nexport type TenantStatus = 'active' | 'suspended' | 'pending';\n\nexport interface Tenant {\n id: string;\n name: string;\n slug: string;\n status: TenantStatus;\n settings?: TenantSettings | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface TenantSettings {\n maxDevices?: number;\n maxUsers?: number;\n features?: string[];\n branding?: {\n logo?: string;\n primaryColor?: string;\n };\n}\n\nexport interface CreateTenantInput {\n name: string;\n slug: string;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTenantInput {\n name?: string;\n slug?: string;\n status?: TenantStatus;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TenantFilter {\n status?: TenantStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface TenantListResult {\n tenants: Tenant[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TenantStats {\n deviceCount: number;\n userCount: number;\n policyCount: number;\n appCount: number;\n}\n\n// ============================================\n// RBAC Types (Role-Based Access Control)\n// ============================================\n\nexport type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'manage' | '*';\nexport type PermissionResource = 'devices' | 'policies' | 'apps' | 'groups' | 'commands' | 'users' | 'roles' | 'tenants' | 'audit' | '*';\n\nexport interface Permission {\n action: PermissionAction;\n resource: PermissionResource;\n resourceId?: string;\n}\n\nexport interface Role {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n permissions: Permission[];\n isSystem: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateRoleInput {\n tenantId?: string;\n name: string;\n description?: string;\n permissions: Permission[];\n}\n\nexport interface UpdateRoleInput {\n name?: string;\n description?: string;\n permissions?: Permission[];\n}\n\nexport interface User {\n id: string;\n tenantId?: string | null;\n email: string;\n name?: string | null;\n status: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown> | null;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UserWithRoles extends User {\n roles: Role[];\n}\n\nexport interface CreateUserInput {\n tenantId?: string;\n email: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateUserInput {\n email?: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UserFilter {\n tenantId?: string;\n status?: 'active' | 'inactive' | 'pending';\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface UserListResult {\n users: User[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Audit Types\n// ============================================\n\nexport type AuditAction = 'create' | 'read' | 'update' | 'delete' | 'login' | 'logout' | 'enroll' | 'unenroll' | 'command' | 'export' | 'import' | 'custom';\n\nexport interface AuditLog {\n id: string;\n tenantId?: string | null;\n userId?: string | null;\n action: AuditAction;\n resource: string;\n resourceId?: string | null;\n status: 'success' | 'failure';\n error?: string | null;\n details?: Record<string, unknown> | null;\n ipAddress?: string | null;\n userAgent?: string | null;\n createdAt: Date;\n}\n\nexport interface CreateAuditLogInput {\n tenantId?: string;\n userId?: string;\n action: AuditAction;\n resource: string;\n resourceId?: string;\n status?: 'success' | 'failure';\n error?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n}\n\nexport interface AuditConfig {\n enabled: boolean;\n retentionDays?: number;\n skipReadOperations?: boolean;\n logActions?: AuditAction[];\n logResources?: string[];\n}\n\nexport interface AuditSummary {\n totalLogs: number;\n byAction: Record<AuditAction, number>;\n byResource: Record<string, number>;\n byStatus: { success: number; failure: number };\n topUsers: Array<{ userId: string; count: number }>;\n recentFailures: AuditLog[];\n}\n\nexport interface AuditLogFilter {\n tenantId?: string;\n userId?: string;\n action?: string;\n resource?: string;\n resourceId?: string;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\nexport interface AuditLogListResult {\n logs: AuditLog[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Schedule Types\n// ============================================\n\nexport type TaskType = 'command' | 'policy_update' | 'app_install' | 'maintenance' | 'custom';\nexport type ScheduledTaskStatus = 'active' | 'paused' | 'completed' | 'failed';\n\nexport interface MaintenanceWindow {\n daysOfWeek: number[];\n startTime: string;\n endTime: string;\n timezone: string;\n}\n\nexport interface TaskSchedule {\n type: 'once' | 'recurring' | 'window';\n executeAt?: Date;\n cron?: string;\n window?: MaintenanceWindow;\n}\n\nexport interface ScheduledTask {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown> | null;\n status: ScheduledTaskStatus;\n nextRunAt?: Date | null;\n lastRunAt?: Date | null;\n maxRetries: number;\n retryCount: number;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateScheduledTaskInput {\n tenantId?: string;\n name: string;\n description?: string;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n maxRetries?: number;\n}\n\nexport interface UpdateScheduledTaskInput {\n name?: string;\n description?: string;\n schedule?: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n status?: ScheduledTaskStatus;\n maxRetries?: number;\n}\n\nexport interface ScheduledTaskFilter {\n tenantId?: string;\n taskType?: TaskType | TaskType[];\n status?: ScheduledTaskStatus | ScheduledTaskStatus[];\n limit?: number;\n offset?: number;\n}\n\nexport interface ScheduledTaskListResult {\n tasks: ScheduledTask[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TaskExecution {\n id: string;\n taskId: string;\n status: 'running' | 'completed' | 'failed';\n startedAt: Date;\n completedAt?: Date | null;\n devicesProcessed: number;\n devicesSucceeded: number;\n devicesFailed: number;\n error?: string | null;\n details?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Message Queue Types\n// ============================================\n\nexport type QueueMessageStatus = 'pending' | 'processing' | 'delivered' | 'failed' | 'expired';\n\nexport interface QueuedMessage {\n id: string;\n tenantId?: string | null;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority: 'high' | 'normal' | 'low';\n status: QueueMessageStatus;\n attempts: number;\n maxAttempts: number;\n lastAttemptAt?: Date | null;\n lastError?: string | null;\n expiresAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface EnqueueMessageInput {\n tenantId?: string;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority?: 'high' | 'normal' | 'low';\n maxAttempts?: number;\n ttlSeconds?: number;\n}\n\nexport interface QueueStats {\n pending: number;\n processing: number;\n delivered: number;\n failed: number;\n expired: number;\n byDevice: Record<string, number>;\n oldestPending?: Date;\n}\n\n// ============================================\n// Dashboard Types\n// ============================================\n\nexport interface DashboardStats {\n devices: {\n total: number;\n enrolled: number;\n active: number;\n blocked: number;\n pending: number;\n };\n policies: {\n total: number;\n deployed: number;\n };\n applications: {\n total: number;\n deployed: number;\n };\n commands: {\n pendingCount: number;\n last24hTotal: number;\n last24hSuccess: number;\n last24hFailed: number;\n };\n groups: {\n total: number;\n withDevices: number;\n };\n}\n\nexport interface DeviceStatusBreakdown {\n byStatus: Record<DeviceStatus, number>;\n byOs: Record<string, number>;\n byManufacturer: Record<string, number>;\n byModel: Record<string, number>;\n}\n\nexport interface EnrollmentTrendPoint {\n date: Date;\n enrolled: number;\n unenrolled: number;\n netChange: number;\n totalDevices: number;\n}\n\nexport interface CommandSuccessRates {\n overall: {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n };\n byType: Record<string, {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n avgExecutionTimeMs?: number;\n }>;\n last24h: {\n total: number;\n completed: number;\n failed: number;\n pending: number;\n };\n}\n\nexport interface AppInstallationSummary {\n total: number;\n byStatus: Record<string, number>;\n recentFailures: Array<{\n packageName: string;\n deviceId: string;\n error: string;\n timestamp: Date;\n }>;\n topInstalled: Array<{\n packageName: string;\n name: string;\n installedCount: number;\n }>;\n}\n\n// ============================================\n// Plugin Storage Types\n// ============================================\n\nexport interface PluginStorageAdapter {\n get<T>(pluginName: string, key: string): Promise<T | null>;\n set<T>(pluginName: string, key: string, value: T): Promise<void>;\n delete(pluginName: string, key: string): Promise<void>;\n list(pluginName: string, prefix?: string): Promise<string[]>;\n clear(pluginName: string): Promise<void>;\n}\n\nexport interface PluginStorageEntry {\n pluginName: string;\n key: string;\n value: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\n// ============================================\n// Enterprise Manager Interfaces\n// ============================================\n\nexport interface TenantManager {\n get(id: string): Promise<Tenant | null>;\n getBySlug(slug: string): Promise<Tenant | null>;\n list(filter?: TenantFilter): Promise<TenantListResult>;\n create(data: CreateTenantInput): Promise<Tenant>;\n update(id: string, data: UpdateTenantInput): Promise<Tenant>;\n delete(id: string, cascade?: boolean): Promise<void>;\n getStats(tenantId: string): Promise<TenantStats>;\n activate(id: string): Promise<Tenant>;\n deactivate(id: string): Promise<Tenant>;\n}\n\nexport interface AuthorizationManager {\n createRole(data: CreateRoleInput): Promise<Role>;\n getRole(id: string): Promise<Role | null>;\n listRoles(tenantId?: string): Promise<Role[]>;\n updateRole(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole(id: string): Promise<void>;\n createUser(data: CreateUserInput): Promise<User>;\n getUser(id: string): Promise<UserWithRoles | null>;\n getUserByEmail(email: string, tenantId?: string): Promise<UserWithRoles | null>;\n listUsers(filter?: UserFilter): Promise<UserListResult>;\n updateUser(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser(id: string): Promise<void>;\n assignRole(userId: string, roleId: string): Promise<void>;\n removeRole(userId: string, roleId: string): Promise<void>;\n getUserRoles(userId: string): Promise<Role[]>;\n can(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<boolean>;\n canAny(userId: string, permissions: Array<{ action: PermissionAction; resource: PermissionResource }>): Promise<boolean>;\n requirePermission(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<void>;\n isAdmin(userId: string): Promise<boolean>;\n}\n\nexport interface AuditManager {\n log(entry: CreateAuditLogInput): Promise<AuditLog>;\n list(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n getByResource(resource: string, resourceId: string): Promise<AuditLog[]>;\n getByUser(userId: string, filter?: AuditLogFilter): Promise<AuditLogListResult>;\n export(filter: AuditLogFilter, format: 'json' | 'csv'): Promise<string>;\n purge(olderThanDays?: number): Promise<number>;\n getSummary(tenantId?: string, days?: number): Promise<AuditSummary>;\n}\n\nexport interface ScheduleManager {\n get(id: string): Promise<ScheduledTask | null>;\n list(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n create(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n update(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n delete(id: string): Promise<void>;\n pause(id: string): Promise<ScheduledTask>;\n resume(id: string): Promise<ScheduledTask>;\n runNow(id: string): Promise<TaskExecution>;\n getUpcoming(hours: number): Promise<ScheduledTask[]>;\n getExecutions(taskId: string, limit?: number): Promise<TaskExecution[]>;\n calculateNextRun(schedule: TaskSchedule): Date | null;\n}\n\nexport interface MessageQueueManager {\n enqueue(message: EnqueueMessageInput): Promise<QueuedMessage>;\n enqueueBatch(messages: EnqueueMessageInput[]): Promise<QueuedMessage[]>;\n dequeue(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledge(messageId: string): Promise<void>;\n fail(messageId: string, error: string): Promise<void>;\n retryFailed(maxAttempts?: number): Promise<number>;\n purgeExpired(): Promise<number>;\n getStats(tenantId?: string): Promise<QueueStats>;\n peek(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n}\n\nexport interface DashboardManager {\n getStats(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary(tenantId?: string): Promise<AppInstallationSummary>;\n}\n\n// ============================================\n// Event Handler Types\n// ============================================\n\nexport type EventHandler<T extends EventType> = (\n event: MDMEvent<EventPayloadMap[T]>\n) => Promise<void> | void;\n\nexport interface EventPayloadMap {\n 'device.enrolled': { device: Device };\n 'device.unenrolled': { device: Device; reason?: string };\n 'device.blocked': { device: Device; reason: string };\n 'device.heartbeat': { device: Device; heartbeat: Heartbeat };\n 'device.locationUpdated': { device: Device; location: DeviceLocation };\n 'device.statusChanged': { device: Device; oldStatus: DeviceStatus; newStatus: DeviceStatus };\n 'device.policyChanged': { device: Device; oldPolicyId?: string; newPolicyId?: string };\n 'app.installed': { device: Device; app: InstalledApp };\n 'app.uninstalled': { device: Device; packageName: string };\n 'app.updated': { device: Device; app: InstalledApp; oldVersion: string };\n 'app.crashed': { device: Device; packageName: string; error?: string };\n 'app.started': { device: Device; packageName: string };\n 'app.stopped': { device: Device; packageName: string };\n 'policy.applied': { device: Device; policy: Policy };\n 'policy.failed': { device: Device; policy: Policy; error: string };\n 'command.received': { device: Device; command: Command };\n 'command.acknowledged': { device: Device; command: Command };\n 'command.completed': { device: Device; command: Command; result: CommandResult };\n 'command.failed': { device: Device; command: Command; error: string };\n 'security.tamper': { device: Device; type: string; details?: unknown };\n 'security.rootDetected': { device: Device };\n 'security.screenLocked': { device: Device };\n 'security.screenUnlocked': { device: Device };\n custom: Record<string, unknown>;\n}\n\n// ============================================\n// Error Types\n// ============================================\n\nexport class MDMError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: unknown\n ) {\n super(message);\n this.name = 'MDMError';\n }\n}\n\nexport class DeviceNotFoundError extends MDMError {\n constructor(deviceId: string) {\n super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND', 404);\n }\n}\n\nexport class PolicyNotFoundError extends MDMError {\n constructor(policyId: string) {\n super(`Policy not found: ${policyId}`, 'POLICY_NOT_FOUND', 404);\n }\n}\n\nexport class ApplicationNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Application not found: ${identifier}`, 'APPLICATION_NOT_FOUND', 404);\n }\n}\n\nexport class TenantNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Tenant not found: ${identifier}`, 'TENANT_NOT_FOUND', 404);\n }\n}\n\nexport class RoleNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Role not found: ${identifier}`, 'ROLE_NOT_FOUND', 404);\n }\n}\n\nexport class GroupNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Group not found: ${identifier}`, 'GROUP_NOT_FOUND', 404);\n }\n}\n\nexport class UserNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`User not found: ${identifier}`, 'USER_NOT_FOUND', 404);\n }\n}\n\nexport class EnrollmentError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'ENROLLMENT_ERROR', 400, details);\n }\n}\n\nexport class AuthenticationError extends MDMError {\n constructor(message: string = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n }\n}\n\nexport class AuthorizationError extends MDMError {\n constructor(message: string = 'Access denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n }\n}\n\nexport class ValidationError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', 400, details);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAmwDO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClC,WAAA,CACE,OAAA,EACO,IAAA,EACA,UAAA,GAAqB,KACrB,OAAA,EACP;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJN,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,UAAA,GAAA,UAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AAGP,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AAAA,EACd;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,QAAA,EAAkB;AAC5B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAQ,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,wBAAA,GAAN,cAAuC,QAAA,CAAS;AAAA,EACrD,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,uBAAA,EAA0B,UAAU,CAAA,CAAA,EAAI,uBAAA,EAAyB,GAAG,CAAA;AAAA,EAC5E;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,kBAAA,EAAqB,UAAU,CAAA,CAAA,EAAI,kBAAA,EAAoB,GAAG,CAAA;AAAA,EAClE;AACF;AAEO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC9C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,UAAU,CAAA,CAAA,EAAI,gBAAA,EAAkB,GAAG,CAAA;AAAA,EAC9D;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,iBAAA,EAAoB,UAAU,CAAA,CAAA,EAAI,iBAAA,EAAmB,GAAG,CAAA;AAAA,EAChE;AACF;AAEO,IAAM,iBAAA,GAAN,cAAgC,QAAA,CAAS;AAAA,EAC9C,YAAY,UAAA,EAAoB;AAC9B,IAAA,KAAA,CAAM,CAAA,gBAAA,EAAmB,UAAU,CAAA,CAAA,EAAI,gBAAA,EAAkB,GAAG,CAAA;AAAA,EAC9D;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF;AAEO,IAAM,mBAAA,GAAN,cAAkC,QAAA,CAAS;AAAA,EAChD,WAAA,CAAY,UAAkB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,OAAA,EAAS,wBAAwB,GAAG,CAAA;AAAA,EAC5C;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,QAAA,CAAS;AAAA,EAC/C,WAAA,CAAY,UAAkB,eAAA,EAAiB;AAC7C,IAAA,KAAA,CAAM,OAAA,EAAS,uBAAuB,GAAG,CAAA;AAAA,EAC3C;AACF;AAEO,IAAM,eAAA,GAAN,cAA8B,QAAA,CAAS;AAAA,EAC5C,WAAA,CAAY,SAAiB,OAAA,EAAmB;AAC9C,IAAA,KAAA,CAAM,OAAA,EAAS,kBAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAAA,EACjD;AACF","file":"types.js","sourcesContent":["/**\n * OpenMDM Core Types\n *\n * These types define the core data structures for the MDM system.\n * Designed to be database-agnostic and framework-agnostic.\n */\n\n// ============================================\n// Device Types\n// ============================================\n\nexport type DeviceStatus = 'pending' | 'enrolled' | 'unenrolled' | 'blocked';\n\nexport interface Device {\n id: string;\n externalId?: string | null;\n enrollmentId: string;\n status: DeviceStatus;\n\n // Device Info\n model?: string | null;\n manufacturer?: string | null;\n osVersion?: string | null;\n serialNumber?: string | null;\n imei?: string | null;\n macAddress?: string | null;\n androidId?: string | null;\n\n // MDM State\n policyId?: string | null;\n agentVersion?: string | null; // MDM agent version installed on device\n lastHeartbeat?: Date | null;\n lastSync?: Date | null;\n\n // Telemetry\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n location?: DeviceLocation | null;\n installedApps?: InstalledApp[] | null;\n\n // Metadata\n tags?: Record<string, string> | null;\n metadata?: Record<string, unknown> | null;\n\n // Timestamps\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface DeviceLocation {\n latitude: number;\n longitude: number;\n accuracy?: number;\n timestamp: Date;\n}\n\nexport interface InstalledApp {\n packageName: string;\n version: string;\n versionCode?: number;\n installedAt?: Date;\n}\n\nexport interface CreateDeviceInput {\n enrollmentId: string;\n externalId?: string;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n serialNumber?: string;\n imei?: string;\n macAddress?: string;\n androidId?: string;\n policyId?: string;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateDeviceInput {\n externalId?: string | null;\n status?: DeviceStatus;\n policyId?: string | null;\n agentVersion?: string | null;\n model?: string;\n manufacturer?: string;\n osVersion?: string;\n batteryLevel?: number | null;\n storageUsed?: number | null;\n storageTotal?: number | null;\n lastHeartbeat?: Date;\n lastSync?: Date;\n installedApps?: InstalledApp[];\n location?: DeviceLocation;\n tags?: Record<string, string>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeviceFilter {\n status?: DeviceStatus | DeviceStatus[];\n policyId?: string;\n groupId?: string;\n search?: string;\n tags?: Record<string, string>;\n limit?: number;\n offset?: number;\n}\n\nexport interface DeviceListResult {\n devices: Device[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Policy Types\n// ============================================\n\nexport interface Policy {\n id: string;\n name: string;\n description?: string | null;\n isDefault: boolean;\n settings: PolicySettings;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface PolicySettings {\n // Kiosk Mode\n kioskMode?: boolean;\n mainApp?: string;\n allowedApps?: string[];\n kioskExitPassword?: string;\n\n // Lock Features\n lockStatusBar?: boolean;\n lockNavigationBar?: boolean;\n lockSettings?: boolean;\n lockPowerButton?: boolean;\n blockInstall?: boolean;\n blockUninstall?: boolean;\n\n // Hardware Controls\n bluetooth?: HardwareControl;\n wifi?: HardwareControl;\n gps?: HardwareControl;\n mobileData?: HardwareControl;\n camera?: HardwareControl;\n microphone?: HardwareControl;\n usb?: HardwareControl;\n nfc?: HardwareControl;\n\n // Update Settings\n systemUpdatePolicy?: SystemUpdatePolicy;\n updateWindow?: TimeWindow;\n\n // Security\n passwordPolicy?: PasswordPolicy;\n encryptionRequired?: boolean;\n factoryResetProtection?: boolean;\n safeBootDisabled?: boolean;\n\n // Telemetry\n heartbeatInterval?: number;\n locationReportInterval?: number;\n locationEnabled?: boolean;\n\n // Network\n wifiConfigs?: WifiConfig[];\n vpnConfig?: VpnConfig;\n\n // Applications\n applications?: PolicyApplication[];\n\n // Custom settings (for plugins)\n custom?: Record<string, unknown>;\n}\n\nexport type HardwareControl = 'on' | 'off' | 'user';\nexport type SystemUpdatePolicy = 'auto' | 'windowed' | 'postpone' | 'manual';\n\nexport interface TimeWindow {\n start: string; // \"HH:MM\"\n end: string; // \"HH:MM\"\n}\n\nexport interface PasswordPolicy {\n required: boolean;\n minLength?: number;\n complexity?: 'none' | 'numeric' | 'alphanumeric' | 'complex';\n maxFailedAttempts?: number;\n expirationDays?: number;\n historyLength?: number;\n}\n\nexport interface WifiConfig {\n ssid: string;\n securityType: 'none' | 'wep' | 'wpa' | 'wpa2' | 'wpa3';\n password?: string;\n hidden?: boolean;\n autoConnect?: boolean;\n}\n\nexport interface VpnConfig {\n type: 'pptp' | 'l2tp' | 'ipsec' | 'openvpn' | 'wireguard';\n server: string;\n username?: string;\n password?: string;\n certificate?: string;\n config?: Record<string, unknown>;\n}\n\nexport interface PolicyApplication {\n packageName: string;\n action: 'install' | 'update' | 'uninstall';\n version?: string;\n required?: boolean;\n autoUpdate?: boolean;\n}\n\nexport interface CreatePolicyInput {\n name: string;\n description?: string;\n isDefault?: boolean;\n settings: PolicySettings;\n}\n\nexport interface UpdatePolicyInput {\n name?: string;\n description?: string | null;\n isDefault?: boolean;\n settings?: PolicySettings;\n}\n\n// ============================================\n// Application Types\n// ============================================\n\nexport interface Application {\n id: string;\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n\n // Deployment settings\n showIcon: boolean;\n runAfterInstall: boolean;\n runAtBoot: boolean;\n isSystem: boolean;\n\n // State\n isActive: boolean;\n\n // Metadata\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateApplicationInput {\n name: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string;\n size?: number;\n minSdkVersion?: number;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isSystem?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateApplicationInput {\n name?: string;\n version?: string;\n versionCode?: number;\n url?: string;\n hash?: string | null;\n size?: number | null;\n minSdkVersion?: number | null;\n showIcon?: boolean;\n runAfterInstall?: boolean;\n runAtBoot?: boolean;\n isActive?: boolean;\n metadata?: Record<string, unknown> | null;\n}\n\nexport interface DeployTarget {\n devices?: string[];\n policies?: string[];\n groups?: string[];\n}\n\n// ============================================\n// App Version & Rollback Types\n// ============================================\n\nexport interface AppVersion {\n id: string;\n applicationId: string;\n packageName: string;\n version: string;\n versionCode: number;\n url: string;\n hash?: string | null;\n size?: number | null;\n releaseNotes?: string | null;\n isMinimumVersion: boolean;\n createdAt: Date;\n}\n\nexport interface AppRollback {\n id: string;\n deviceId: string;\n packageName: string;\n fromVersion: string;\n fromVersionCode: number;\n toVersion: string;\n toVersionCode: number;\n reason?: string | null;\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\n error?: string | null;\n initiatedBy?: string | null;\n createdAt: Date;\n completedAt?: Date | null;\n}\n\nexport interface CreateAppRollbackInput {\n deviceId: string;\n packageName: string;\n toVersionCode: number;\n reason?: string;\n initiatedBy?: string;\n}\n\n// ============================================\n// Command Types\n// ============================================\n\nexport type CommandType =\n | 'reboot'\n | 'shutdown'\n | 'sync'\n | 'lock'\n | 'unlock'\n | 'wipe'\n | 'factoryReset'\n | 'installApp'\n | 'uninstallApp'\n | 'updateApp'\n | 'runApp'\n | 'clearAppData'\n | 'clearAppCache'\n | 'shell'\n | 'setPolicy'\n | 'grantPermissions'\n | 'exitKiosk'\n | 'enterKiosk'\n | 'setWifi'\n | 'screenshot'\n | 'getLocation'\n | 'setVolume'\n | 'sendNotification'\n | 'whitelistBattery' // Whitelist app from battery optimization (Doze)\n | 'enablePermissiveMode' // Enable permissive mode for debugging\n | 'setTimeZone' // Set device timezone\n | 'enableAdb' // Enable/disable ADB debugging\n | 'rollbackApp' // Rollback to previous app version\n | 'updateAgent' // Update MDM agent to a new version\n | 'custom';\n\nexport type CommandStatus =\n | 'pending'\n | 'sent'\n | 'acknowledged'\n | 'completed'\n | 'failed'\n | 'cancelled';\n\nexport interface Command {\n id: string;\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown> | null;\n status: CommandStatus;\n result?: CommandResult | null;\n error?: string | null;\n createdAt: Date;\n sentAt?: Date | null;\n acknowledgedAt?: Date | null;\n completedAt?: Date | null;\n}\n\nexport interface CommandResult {\n success: boolean;\n message?: string;\n data?: unknown;\n}\n\nexport interface SendCommandInput {\n deviceId: string;\n type: CommandType;\n payload?: Record<string, unknown>;\n}\n\nexport interface CommandFilter {\n deviceId?: string;\n status?: CommandStatus | CommandStatus[];\n type?: CommandType | CommandType[];\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Event Types\n// ============================================\n\nexport type EventType =\n | 'device.enrolled'\n | 'device.unenrolled'\n | 'device.blocked'\n | 'device.heartbeat'\n | 'device.locationUpdated'\n | 'device.statusChanged'\n | 'device.policyChanged'\n | 'app.installed'\n | 'app.uninstalled'\n | 'app.updated'\n | 'app.crashed'\n | 'app.started'\n | 'app.stopped'\n | 'policy.applied'\n | 'policy.failed'\n | 'command.received'\n | 'command.acknowledged'\n | 'command.completed'\n | 'command.failed'\n | 'security.tamper'\n | 'security.rootDetected'\n | 'security.screenLocked'\n | 'security.screenUnlocked'\n | 'custom';\n\nexport interface MDMEvent<T = unknown> {\n id: string;\n deviceId: string;\n type: EventType;\n payload: T;\n createdAt: Date;\n}\n\nexport interface EventFilter {\n deviceId?: string;\n type?: EventType | EventType[];\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\n// ============================================\n// Group Types\n// ============================================\n\nexport interface Group {\n id: string;\n name: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateGroupInput {\n name: string;\n description?: string;\n policyId?: string;\n parentId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateGroupInput {\n name?: string;\n description?: string | null;\n policyId?: string | null;\n parentId?: string | null;\n metadata?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Enrollment Types\n// ============================================\n\nexport type EnrollmentMethod =\n | 'qr'\n | 'nfc'\n | 'zero-touch'\n | 'knox'\n | 'manual'\n | 'app-only'\n | 'adb';\n\nexport interface EnrollmentRequest {\n // Device identifiers (at least one required)\n macAddress?: string;\n serialNumber?: string;\n imei?: string;\n androidId?: string;\n\n // Device info\n model: string;\n manufacturer: string;\n osVersion: string;\n sdkVersion?: number;\n\n // Agent info\n agentVersion?: string;\n agentPackage?: string;\n\n // Enrollment details\n method: EnrollmentMethod;\n timestamp: string;\n signature: string;\n\n // Optional pre-assigned policy/group\n policyId?: string;\n groupId?: string;\n}\n\nexport interface EnrollmentResponse {\n deviceId: string;\n enrollmentId: string;\n policyId?: string;\n policy?: Policy;\n serverUrl: string;\n pushConfig: PushConfig;\n token: string;\n refreshToken?: string;\n tokenExpiresAt?: Date;\n}\n\nexport interface PushConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n fcmSenderId?: string;\n mqttUrl?: string;\n mqttTopic?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n wsUrl?: string;\n pollingInterval?: number;\n}\n\n// ============================================\n// Telemetry Types\n// ============================================\n\nexport interface Heartbeat {\n deviceId: string;\n timestamp: Date;\n\n // Battery\n batteryLevel: number;\n isCharging: boolean;\n batteryHealth?: 'good' | 'overheat' | 'dead' | 'cold' | 'unknown';\n\n // Storage\n storageUsed: number;\n storageTotal: number;\n\n // Memory\n memoryUsed: number;\n memoryTotal: number;\n\n // Network\n networkType?: 'wifi' | 'cellular' | 'ethernet' | 'none';\n networkName?: string; // SSID or carrier\n signalStrength?: number;\n ipAddress?: string;\n\n // Location\n location?: DeviceLocation;\n\n // Apps\n installedApps: InstalledApp[];\n runningApps?: string[];\n\n // Security\n isRooted?: boolean;\n isEncrypted?: boolean;\n screenLockEnabled?: boolean;\n\n // Agent status\n agentVersion?: string;\n policyVersion?: string;\n lastPolicySync?: Date;\n}\n\n// ============================================\n// Push Token Types\n// ============================================\n\nexport interface PushToken {\n id: string;\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n isActive: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface RegisterPushTokenInput {\n deviceId: string;\n provider: 'fcm' | 'mqtt' | 'websocket';\n token: string;\n}\n\n// ============================================\n// Configuration Types\n// ============================================\n\nexport interface MDMConfig {\n /** Database adapter for persistence */\n database: DatabaseAdapter;\n\n /** Authentication/authorization configuration */\n auth?: AuthConfig;\n\n /** Push notification provider configuration */\n push?: PushProviderConfig;\n\n /** Device enrollment configuration */\n enrollment?: EnrollmentConfig;\n\n /** Server URL (used in enrollment responses) */\n serverUrl?: string;\n\n /** APK/file storage configuration */\n storage?: StorageConfig;\n\n /** Outbound webhook configuration */\n webhooks?: WebhookConfig;\n\n /** Plugins to extend functionality */\n plugins?: MDMPlugin[];\n\n /** Event handlers */\n onDeviceEnrolled?: (device: Device) => Promise<void>;\n onDeviceUnenrolled?: (device: Device) => Promise<void>;\n onDeviceBlocked?: (device: Device) => Promise<void>;\n onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;\n onCommand?: (command: Command) => Promise<void>;\n onEvent?: (event: MDMEvent) => Promise<void>;\n\n // Enterprise features\n /** Multi-tenancy configuration */\n multiTenancy?: {\n enabled: boolean;\n defaultTenantId?: string;\n tenantResolver?: (context: unknown) => Promise<string | null>;\n };\n\n /** Authorization (RBAC) configuration */\n authorization?: {\n enabled: boolean;\n defaultRole?: string;\n };\n\n /** Audit logging configuration */\n audit?: {\n enabled: boolean;\n retentionDays?: number;\n };\n\n /** Scheduling configuration */\n scheduling?: {\n enabled: boolean;\n timezone?: string;\n };\n\n /** Plugin storage configuration */\n pluginStorage?: {\n adapter: 'database' | 'memory';\n };\n}\n\nexport interface StorageConfig {\n /** Storage provider (s3, local, custom) */\n provider: 's3' | 'local' | 'custom';\n\n /** S3 configuration */\n s3?: {\n bucket: string;\n region: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string; // For S3-compatible services\n presignedUrlExpiry?: number; // Seconds, default 3600\n };\n\n /** Local storage path */\n localPath?: string;\n\n /** Custom storage adapter */\n customAdapter?: {\n upload: (file: Buffer, key: string) => Promise<string>;\n getUrl: (key: string) => Promise<string>;\n delete: (key: string) => Promise<void>;\n };\n}\n\nexport interface WebhookConfig {\n /** Webhook endpoints to notify */\n endpoints?: WebhookEndpoint[];\n\n /** Retry configuration */\n retry?: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n };\n\n /** Sign webhooks with HMAC secret */\n signingSecret?: string;\n}\n\nexport interface WebhookEndpoint {\n /** Unique identifier */\n id: string;\n /** Webhook URL */\n url: string;\n /** Events to trigger this webhook */\n events: (EventType | '*')[];\n /** Custom headers */\n headers?: Record<string, string>;\n /** Whether endpoint is active */\n enabled: boolean;\n}\n\nexport interface AuthConfig {\n /** Get current user from request context */\n getUser: <T = unknown>(context: unknown) => Promise<T | null>;\n /** Check if user has admin privileges */\n isAdmin?: (user: unknown) => Promise<boolean>;\n /** Check if user can access specific device */\n canAccessDevice?: (user: unknown, deviceId: string) => Promise<boolean>;\n /** Device JWT secret (for device auth tokens) */\n deviceTokenSecret?: string;\n /** Device token expiration in seconds (default: 365 days) */\n deviceTokenExpiration?: number;\n}\n\nexport interface PushProviderConfig {\n provider: 'fcm' | 'mqtt' | 'websocket' | 'polling';\n\n // FCM configuration\n fcmCredentials?: string | Record<string, unknown>;\n fcmProjectId?: string;\n\n // MQTT configuration\n mqttUrl?: string;\n mqttUsername?: string;\n mqttPassword?: string;\n mqttTopicPrefix?: string;\n\n // WebSocket configuration\n wsPath?: string;\n wsPingInterval?: number;\n\n // Polling fallback\n pollingInterval?: number;\n}\n\nexport interface EnrollmentConfig {\n /** Auto-enroll devices with valid signature */\n autoEnroll?: boolean;\n /** HMAC secret for device signature verification */\n deviceSecret: string;\n /** Allowed enrollment methods */\n allowedMethods?: EnrollmentMethod[];\n /** Default policy for new devices */\n defaultPolicyId?: string;\n /** Default group for new devices */\n defaultGroupId?: string;\n /** Require manual approval for enrollment */\n requireApproval?: boolean;\n /** Custom enrollment validation */\n validate?: (request: EnrollmentRequest) => Promise<boolean>;\n}\n\n// ============================================\n// Adapter Interfaces\n// ============================================\n\nexport interface DatabaseAdapter {\n // Devices\n findDevice(id: string): Promise<Device | null>;\n findDeviceByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n listDevices(filter?: DeviceFilter): Promise<DeviceListResult>;\n createDevice(data: CreateDeviceInput): Promise<Device>;\n updateDevice(id: string, data: UpdateDeviceInput): Promise<Device>;\n deleteDevice(id: string): Promise<void>;\n countDevices(filter?: DeviceFilter): Promise<number>;\n\n // Policies\n findPolicy(id: string): Promise<Policy | null>;\n findDefaultPolicy(): Promise<Policy | null>;\n listPolicies(): Promise<Policy[]>;\n createPolicy(data: CreatePolicyInput): Promise<Policy>;\n updatePolicy(id: string, data: UpdatePolicyInput): Promise<Policy>;\n deletePolicy(id: string): Promise<void>;\n\n // Applications\n findApplication(id: string): Promise<Application | null>;\n findApplicationByPackage(packageName: string, version?: string): Promise<Application | null>;\n listApplications(activeOnly?: boolean): Promise<Application[]>;\n createApplication(data: CreateApplicationInput): Promise<Application>;\n updateApplication(id: string, data: UpdateApplicationInput): Promise<Application>;\n deleteApplication(id: string): Promise<void>;\n\n // Commands\n findCommand(id: string): Promise<Command | null>;\n listCommands(filter?: CommandFilter): Promise<Command[]>;\n createCommand(data: SendCommandInput): Promise<Command>;\n updateCommand(id: string, data: Partial<Command>): Promise<Command>;\n getPendingCommands(deviceId: string): Promise<Command[]>;\n\n // Events\n createEvent(event: Omit<MDMEvent, 'id' | 'createdAt'>): Promise<MDMEvent>;\n listEvents(filter?: EventFilter): Promise<MDMEvent[]>;\n\n // Groups\n findGroup(id: string): Promise<Group | null>;\n listGroups(): Promise<Group[]>;\n createGroup(data: CreateGroupInput): Promise<Group>;\n updateGroup(id: string, data: UpdateGroupInput): Promise<Group>;\n deleteGroup(id: string): Promise<void>;\n listDevicesInGroup(groupId: string): Promise<Device[]>;\n addDeviceToGroup(deviceId: string, groupId: string): Promise<void>;\n removeDeviceFromGroup(deviceId: string, groupId: string): Promise<void>;\n getDeviceGroups(deviceId: string): Promise<Group[]>;\n\n // Push Tokens\n findPushToken(deviceId: string, provider: string): Promise<PushToken | null>;\n upsertPushToken(data: RegisterPushTokenInput): Promise<PushToken>;\n deletePushToken(deviceId: string, provider?: string): Promise<void>;\n\n // App Versions (optional - for version tracking)\n listAppVersions?(packageName: string): Promise<AppVersion[]>;\n createAppVersion?(data: Omit<AppVersion, 'id' | 'createdAt'>): Promise<AppVersion>;\n setMinimumVersion?(packageName: string, versionCode: number): Promise<void>;\n getMinimumVersion?(packageName: string): Promise<AppVersion | null>;\n\n // Rollback History (optional)\n createRollback?(data: CreateAppRollbackInput): Promise<AppRollback>;\n updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;\n listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;\n\n // Group Hierarchy (optional)\n getGroupChildren?(parentId: string | null): Promise<Group[]>;\n getGroupAncestors?(groupId: string): Promise<Group[]>;\n getGroupDescendants?(groupId: string): Promise<Group[]>;\n getGroupTree?(rootId?: string): Promise<GroupTreeNode[]>;\n getGroupEffectivePolicy?(groupId: string): Promise<Policy | null>;\n moveGroup?(groupId: string, newParentId: string | null): Promise<Group>;\n getGroupHierarchyStats?(): Promise<GroupHierarchyStats>;\n\n // Tenants (optional - for multi-tenancy)\n findTenant?(id: string): Promise<Tenant | null>;\n findTenantBySlug?(slug: string): Promise<Tenant | null>;\n listTenants?(filter?: TenantFilter): Promise<TenantListResult>;\n createTenant?(data: CreateTenantInput): Promise<Tenant>;\n updateTenant?(id: string, data: UpdateTenantInput): Promise<Tenant>;\n deleteTenant?(id: string): Promise<void>;\n getTenantStats?(tenantId: string): Promise<TenantStats>;\n\n // Users (optional - for RBAC)\n findUser?(id: string): Promise<User | null>;\n findUserByEmail?(email: string, tenantId?: string): Promise<User | null>;\n listUsers?(filter?: UserFilter): Promise<UserListResult>;\n createUser?(data: CreateUserInput): Promise<User>;\n updateUser?(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser?(id: string): Promise<void>;\n\n // Roles (optional - for RBAC)\n findRole?(id: string): Promise<Role | null>;\n listRoles?(tenantId?: string): Promise<Role[]>;\n createRole?(data: CreateRoleInput): Promise<Role>;\n updateRole?(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole?(id: string): Promise<void>;\n assignRoleToUser?(userId: string, roleId: string): Promise<void>;\n removeRoleFromUser?(userId: string, roleId: string): Promise<void>;\n getUserRoles?(userId: string): Promise<Role[]>;\n\n // Audit Logs (optional - for compliance)\n createAuditLog?(data: CreateAuditLogInput): Promise<AuditLog>;\n listAuditLogs?(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n deleteAuditLogs?(filter: { olderThan?: Date; tenantId?: string }): Promise<number>;\n\n // Scheduled Tasks (optional - for scheduling)\n findScheduledTask?(id: string): Promise<ScheduledTask | null>;\n listScheduledTasks?(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n createScheduledTask?(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n updateScheduledTask?(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n deleteScheduledTask?(id: string): Promise<void>;\n getUpcomingTasks?(hours: number): Promise<ScheduledTask[]>;\n createTaskExecution?(data: { taskId: string }): Promise<TaskExecution>;\n updateTaskExecution?(id: string, data: Partial<TaskExecution>): Promise<TaskExecution>;\n listTaskExecutions?(taskId: string, limit?: number): Promise<TaskExecution[]>;\n\n // Message Queue (optional - for persistent messaging)\n enqueueMessage?(data: EnqueueMessageInput): Promise<QueuedMessage>;\n dequeueMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n peekMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledgeMessage?(messageId: string): Promise<void>;\n failMessage?(messageId: string, error: string): Promise<void>;\n retryFailedMessages?(maxAttempts?: number): Promise<number>;\n purgeExpiredMessages?(): Promise<number>;\n getQueueStats?(tenantId?: string): Promise<QueueStats>;\n\n // Plugin Storage (optional)\n getPluginValue?(pluginName: string, key: string): Promise<unknown | null>;\n setPluginValue?(pluginName: string, key: string, value: unknown): Promise<void>;\n deletePluginValue?(pluginName: string, key: string): Promise<void>;\n listPluginKeys?(pluginName: string, prefix?: string): Promise<string[]>;\n clearPluginData?(pluginName: string): Promise<void>;\n\n // Dashboard (optional - for analytics)\n getDashboardStats?(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown?(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend?(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates?(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary?(tenantId?: string): Promise<AppInstallationSummary>;\n\n // Transactions (optional)\n transaction?<T>(fn: () => Promise<T>): Promise<T>;\n}\n\nexport interface PushAdapter {\n /** Send push message to a device */\n send(deviceId: string, message: PushMessage): Promise<PushResult>;\n /** Send push message to multiple devices */\n sendBatch(deviceIds: string[], message: PushMessage): Promise<PushBatchResult>;\n /** Register device push token */\n registerToken?(deviceId: string, token: string): Promise<void>;\n /** Unregister device push token */\n unregisterToken?(deviceId: string): Promise<void>;\n /** Subscribe device to topic */\n subscribe?(deviceId: string, topic: string): Promise<void>;\n /** Unsubscribe device from topic */\n unsubscribe?(deviceId: string, topic: string): Promise<void>;\n}\n\nexport interface PushMessage {\n type: string;\n payload?: Record<string, unknown>;\n priority?: 'high' | 'normal';\n ttl?: number;\n collapseKey?: string;\n}\n\nexport interface PushResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\nexport interface PushBatchResult {\n successCount: number;\n failureCount: number;\n results: Array<{ deviceId: string; result: PushResult }>;\n}\n\n// ============================================\n// Plugin Interface\n// ============================================\n\nexport interface MDMPlugin {\n /** Unique plugin name */\n name: string;\n /** Plugin version */\n version: string;\n\n /** Called when MDM is initialized */\n onInit?(mdm: MDMInstance): Promise<void>;\n\n /** Called when MDM is destroyed */\n onDestroy?(): Promise<void>;\n\n /** Additional routes to mount */\n routes?: PluginRoute[];\n\n /** Middleware to apply to all routes */\n middleware?: PluginMiddleware[];\n\n /** Extend enrollment process */\n onEnroll?(device: Device, request: EnrollmentRequest): Promise<void>;\n\n /** Extend device processing */\n onDeviceEnrolled?(device: Device): Promise<void>;\n onDeviceUnenrolled?(device: Device): Promise<void>;\n onHeartbeat?(device: Device, heartbeat: Heartbeat): Promise<void>;\n\n /** Extend policy processing */\n policySchema?: Record<string, unknown>;\n validatePolicy?(settings: PolicySettings): Promise<{ valid: boolean; errors?: string[] }>;\n applyPolicy?(device: Device, policy: Policy): Promise<void>;\n\n /** Extend command processing */\n commandTypes?: CommandType[];\n executeCommand?(device: Device, command: Command): Promise<CommandResult>;\n}\n\nexport interface PluginRoute {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n path: string;\n handler: (context: unknown) => Promise<unknown>;\n auth?: boolean;\n admin?: boolean;\n}\n\nexport type PluginMiddleware = (\n context: unknown,\n next: () => Promise<unknown>\n) => Promise<unknown>;\n\n// ============================================\n// MDM Instance Interface\n// ============================================\n\nexport interface WebhookManager {\n /** Deliver an event to all matching webhook endpoints */\n deliver<T>(event: MDMEvent<T>): Promise<WebhookDeliveryResult[]>;\n /** Add a webhook endpoint at runtime */\n addEndpoint(endpoint: WebhookEndpoint): void;\n /** Remove a webhook endpoint */\n removeEndpoint(endpointId: string): void;\n /** Update a webhook endpoint */\n updateEndpoint(endpointId: string, updates: Partial<WebhookEndpoint>): void;\n /** Get all configured endpoints */\n getEndpoints(): WebhookEndpoint[];\n /** Test a webhook endpoint with a test payload */\n testEndpoint(endpointId: string): Promise<WebhookDeliveryResult>;\n}\n\nexport interface WebhookDeliveryResult {\n endpointId: string;\n success: boolean;\n statusCode?: number;\n error?: string;\n retryCount: number;\n deliveredAt?: Date;\n}\n\nexport interface MDMInstance {\n /** Device management */\n devices: DeviceManager;\n /** Policy management */\n policies: PolicyManager;\n /** Application management */\n apps: ApplicationManager;\n /** Command management */\n commands: CommandManager;\n /** Group management */\n groups: GroupManager;\n\n /** Tenant management (if multi-tenancy enabled) */\n tenants?: TenantManager;\n /** Authorization management (RBAC) */\n authorization?: AuthorizationManager;\n /** Audit logging */\n audit?: AuditManager;\n /** Scheduled task management */\n schedules?: ScheduleManager;\n /** Persistent message queue */\n messageQueue?: MessageQueueManager;\n /** Dashboard analytics */\n dashboard?: DashboardManager;\n /** Plugin storage */\n pluginStorage?: PluginStorageAdapter;\n\n /** Push notification service */\n push: PushAdapter;\n\n /** Webhook delivery (if configured) */\n webhooks?: WebhookManager;\n\n /** Database adapter */\n db: DatabaseAdapter;\n\n /** Configuration */\n config: MDMConfig;\n\n /** Subscribe to events */\n on<T extends EventType>(event: T, handler: EventHandler<T>): () => void;\n /** Emit an event */\n emit<T extends EventType>(event: T, data: EventPayloadMap[T]): Promise<void>;\n\n /** Process device enrollment */\n enroll(request: EnrollmentRequest): Promise<EnrollmentResponse>;\n /** Process device heartbeat */\n processHeartbeat(deviceId: string, heartbeat: Heartbeat): Promise<void>;\n /** Verify device token */\n verifyDeviceToken(token: string): Promise<{ deviceId: string } | null>;\n\n /** Get loaded plugins */\n getPlugins(): MDMPlugin[];\n /** Get plugin by name */\n getPlugin(name: string): MDMPlugin | undefined;\n}\n\n// ============================================\n// Manager Interfaces\n// ============================================\n\nexport interface DeviceManager {\n get(id: string): Promise<Device | null>;\n getByEnrollmentId(enrollmentId: string): Promise<Device | null>;\n list(filter?: DeviceFilter): Promise<DeviceListResult>;\n create(data: CreateDeviceInput): Promise<Device>;\n update(id: string, data: UpdateDeviceInput): Promise<Device>;\n delete(id: string): Promise<void>;\n assignPolicy(deviceId: string, policyId: string | null): Promise<Device>;\n addToGroup(deviceId: string, groupId: string): Promise<void>;\n removeFromGroup(deviceId: string, groupId: string): Promise<void>;\n getGroups(deviceId: string): Promise<Group[]>;\n sendCommand(deviceId: string, input: Omit<SendCommandInput, 'deviceId'>): Promise<Command>;\n sync(deviceId: string): Promise<Command>;\n reboot(deviceId: string): Promise<Command>;\n lock(deviceId: string, message?: string): Promise<Command>;\n wipe(deviceId: string, preserveData?: boolean): Promise<Command>;\n}\n\nexport interface PolicyManager {\n get(id: string): Promise<Policy | null>;\n getDefault(): Promise<Policy | null>;\n list(): Promise<Policy[]>;\n create(data: CreatePolicyInput): Promise<Policy>;\n update(id: string, data: UpdatePolicyInput): Promise<Policy>;\n delete(id: string): Promise<void>;\n setDefault(id: string): Promise<Policy>;\n getDevices(policyId: string): Promise<Device[]>;\n applyToDevice(policyId: string, deviceId: string): Promise<void>;\n}\n\nexport interface ApplicationManager {\n get(id: string): Promise<Application | null>;\n getByPackage(packageName: string, version?: string): Promise<Application | null>;\n list(activeOnly?: boolean): Promise<Application[]>;\n register(data: CreateApplicationInput): Promise<Application>;\n update(id: string, data: UpdateApplicationInput): Promise<Application>;\n delete(id: string): Promise<void>;\n activate(id: string): Promise<Application>;\n deactivate(id: string): Promise<Application>;\n deploy(packageName: string, target: DeployTarget): Promise<void>;\n installOnDevice(packageName: string, deviceId: string, version?: string): Promise<Command>;\n uninstallFromDevice(packageName: string, deviceId: string): Promise<Command>;\n}\n\nexport interface CommandManager {\n get(id: string): Promise<Command | null>;\n list(filter?: CommandFilter): Promise<Command[]>;\n send(input: SendCommandInput): Promise<Command>;\n cancel(id: string): Promise<Command>;\n acknowledge(id: string): Promise<Command>;\n complete(id: string, result: CommandResult): Promise<Command>;\n fail(id: string, error: string): Promise<Command>;\n getPending(deviceId: string): Promise<Command[]>;\n}\n\nexport interface GroupManager {\n // Basic CRUD operations\n get(id: string): Promise<Group | null>;\n list(): Promise<Group[]>;\n create(data: CreateGroupInput): Promise<Group>;\n update(id: string, data: UpdateGroupInput): Promise<Group>;\n delete(id: string): Promise<void>;\n\n // Device management\n getDevices(groupId: string): Promise<Device[]>;\n addDevice(groupId: string, deviceId: string): Promise<void>;\n removeDevice(groupId: string, deviceId: string): Promise<void>;\n\n // Hierarchy operations\n getChildren(groupId: string): Promise<Group[]>;\n getTree(rootId?: string): Promise<GroupTreeNode[]>;\n getAncestors(groupId: string): Promise<Group[]>;\n getDescendants(groupId: string): Promise<Group[]>;\n move(groupId: string, newParentId: string | null): Promise<Group>;\n getEffectivePolicy(groupId: string): Promise<Policy | null>;\n getHierarchyStats(): Promise<GroupHierarchyStats>;\n}\n\n// ============================================\n// Group Hierarchy Types\n// ============================================\n\nexport interface GroupTreeNode extends Group {\n children: GroupTreeNode[];\n depth: number;\n path: string[];\n effectivePolicyId?: string | null;\n}\n\nexport interface GroupHierarchyStats {\n totalGroups: number;\n maxDepth: number;\n groupsWithDevices: number;\n groupsWithPolicies: number;\n}\n\n// ============================================\n// Tenant Types (Multi-tenancy)\n// ============================================\n\nexport type TenantStatus = 'active' | 'suspended' | 'pending';\n\nexport interface Tenant {\n id: string;\n name: string;\n slug: string;\n status: TenantStatus;\n settings?: TenantSettings | null;\n metadata?: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface TenantSettings {\n maxDevices?: number;\n maxUsers?: number;\n features?: string[];\n branding?: {\n logo?: string;\n primaryColor?: string;\n };\n}\n\nexport interface CreateTenantInput {\n name: string;\n slug: string;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateTenantInput {\n name?: string;\n slug?: string;\n status?: TenantStatus;\n settings?: TenantSettings;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TenantFilter {\n status?: TenantStatus;\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface TenantListResult {\n tenants: Tenant[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TenantStats {\n deviceCount: number;\n userCount: number;\n policyCount: number;\n appCount: number;\n}\n\n// ============================================\n// RBAC Types (Role-Based Access Control)\n// ============================================\n\nexport type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'manage' | '*';\nexport type PermissionResource = 'devices' | 'policies' | 'apps' | 'groups' | 'commands' | 'users' | 'roles' | 'tenants' | 'audit' | '*';\n\nexport interface Permission {\n action: PermissionAction;\n resource: PermissionResource;\n resourceId?: string;\n}\n\nexport interface Role {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n permissions: Permission[];\n isSystem: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateRoleInput {\n tenantId?: string;\n name: string;\n description?: string;\n permissions: Permission[];\n}\n\nexport interface UpdateRoleInput {\n name?: string;\n description?: string;\n permissions?: Permission[];\n}\n\nexport interface User {\n id: string;\n tenantId?: string | null;\n email: string;\n name?: string | null;\n status: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown> | null;\n lastLoginAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UserWithRoles extends User {\n roles: Role[];\n}\n\nexport interface CreateUserInput {\n tenantId?: string;\n email: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateUserInput {\n email?: string;\n name?: string;\n status?: 'active' | 'inactive' | 'pending';\n metadata?: Record<string, unknown>;\n}\n\nexport interface UserFilter {\n tenantId?: string;\n status?: 'active' | 'inactive' | 'pending';\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface UserListResult {\n users: User[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Audit Types\n// ============================================\n\nexport type AuditAction = 'create' | 'read' | 'update' | 'delete' | 'login' | 'logout' | 'enroll' | 'unenroll' | 'command' | 'export' | 'import' | 'custom';\n\nexport interface AuditLog {\n id: string;\n tenantId?: string | null;\n userId?: string | null;\n action: AuditAction;\n resource: string;\n resourceId?: string | null;\n status: 'success' | 'failure';\n error?: string | null;\n details?: Record<string, unknown> | null;\n ipAddress?: string | null;\n userAgent?: string | null;\n createdAt: Date;\n}\n\nexport interface CreateAuditLogInput {\n tenantId?: string;\n userId?: string;\n action: AuditAction;\n resource: string;\n resourceId?: string;\n status?: 'success' | 'failure';\n error?: string;\n details?: Record<string, unknown>;\n ipAddress?: string;\n userAgent?: string;\n}\n\nexport interface AuditConfig {\n enabled: boolean;\n retentionDays?: number;\n skipReadOperations?: boolean;\n logActions?: AuditAction[];\n logResources?: string[];\n}\n\nexport interface AuditSummary {\n totalLogs: number;\n byAction: Record<AuditAction, number>;\n byResource: Record<string, number>;\n byStatus: { success: number; failure: number };\n topUsers: Array<{ userId: string; count: number }>;\n recentFailures: AuditLog[];\n}\n\nexport interface AuditLogFilter {\n tenantId?: string;\n userId?: string;\n action?: string;\n resource?: string;\n resourceId?: string;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n offset?: number;\n}\n\nexport interface AuditLogListResult {\n logs: AuditLog[];\n total: number;\n limit: number;\n offset: number;\n}\n\n// ============================================\n// Schedule Types\n// ============================================\n\nexport type TaskType = 'command' | 'policy_update' | 'app_install' | 'maintenance' | 'custom';\nexport type ScheduledTaskStatus = 'active' | 'paused' | 'completed' | 'failed';\n\nexport interface MaintenanceWindow {\n daysOfWeek: number[];\n startTime: string;\n endTime: string;\n timezone: string;\n}\n\nexport interface TaskSchedule {\n type: 'once' | 'recurring' | 'window';\n executeAt?: Date;\n cron?: string;\n window?: MaintenanceWindow;\n}\n\nexport interface ScheduledTask {\n id: string;\n tenantId?: string | null;\n name: string;\n description?: string | null;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown> | null;\n status: ScheduledTaskStatus;\n nextRunAt?: Date | null;\n lastRunAt?: Date | null;\n maxRetries: number;\n retryCount: number;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateScheduledTaskInput {\n tenantId?: string;\n name: string;\n description?: string;\n taskType: TaskType;\n schedule: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n maxRetries?: number;\n}\n\nexport interface UpdateScheduledTaskInput {\n name?: string;\n description?: string;\n schedule?: TaskSchedule;\n target?: DeployTarget;\n payload?: Record<string, unknown>;\n status?: ScheduledTaskStatus;\n maxRetries?: number;\n}\n\nexport interface ScheduledTaskFilter {\n tenantId?: string;\n taskType?: TaskType | TaskType[];\n status?: ScheduledTaskStatus | ScheduledTaskStatus[];\n limit?: number;\n offset?: number;\n}\n\nexport interface ScheduledTaskListResult {\n tasks: ScheduledTask[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport interface TaskExecution {\n id: string;\n taskId: string;\n status: 'running' | 'completed' | 'failed';\n startedAt: Date;\n completedAt?: Date | null;\n devicesProcessed: number;\n devicesSucceeded: number;\n devicesFailed: number;\n error?: string | null;\n details?: Record<string, unknown> | null;\n}\n\n// ============================================\n// Message Queue Types\n// ============================================\n\nexport type QueueMessageStatus = 'pending' | 'processing' | 'delivered' | 'failed' | 'expired';\n\nexport interface QueuedMessage {\n id: string;\n tenantId?: string | null;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority: 'high' | 'normal' | 'low';\n status: QueueMessageStatus;\n attempts: number;\n maxAttempts: number;\n lastAttemptAt?: Date | null;\n lastError?: string | null;\n expiresAt?: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface EnqueueMessageInput {\n tenantId?: string;\n deviceId: string;\n messageType: string;\n payload: Record<string, unknown>;\n priority?: 'high' | 'normal' | 'low';\n maxAttempts?: number;\n ttlSeconds?: number;\n}\n\nexport interface QueueStats {\n pending: number;\n processing: number;\n delivered: number;\n failed: number;\n expired: number;\n byDevice: Record<string, number>;\n oldestPending?: Date;\n}\n\n// ============================================\n// Dashboard Types\n// ============================================\n\nexport interface DashboardStats {\n devices: {\n total: number;\n enrolled: number;\n active: number;\n blocked: number;\n pending: number;\n };\n policies: {\n total: number;\n deployed: number;\n };\n applications: {\n total: number;\n deployed: number;\n };\n commands: {\n pendingCount: number;\n last24hTotal: number;\n last24hSuccess: number;\n last24hFailed: number;\n };\n groups: {\n total: number;\n withDevices: number;\n };\n}\n\nexport interface DeviceStatusBreakdown {\n byStatus: Record<DeviceStatus, number>;\n byOs: Record<string, number>;\n byManufacturer: Record<string, number>;\n byModel: Record<string, number>;\n}\n\nexport interface EnrollmentTrendPoint {\n date: Date;\n enrolled: number;\n unenrolled: number;\n netChange: number;\n totalDevices: number;\n}\n\nexport interface CommandSuccessRates {\n overall: {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n };\n byType: Record<string, {\n total: number;\n completed: number;\n failed: number;\n successRate: number;\n avgExecutionTimeMs?: number;\n }>;\n last24h: {\n total: number;\n completed: number;\n failed: number;\n pending: number;\n };\n}\n\nexport interface AppInstallationSummary {\n total: number;\n byStatus: Record<string, number>;\n recentFailures: Array<{\n packageName: string;\n deviceId: string;\n error: string;\n timestamp: Date;\n }>;\n topInstalled: Array<{\n packageName: string;\n name: string;\n installedCount: number;\n }>;\n}\n\n// ============================================\n// Plugin Storage Types\n// ============================================\n\nexport interface PluginStorageAdapter {\n get<T>(pluginName: string, key: string): Promise<T | null>;\n set<T>(pluginName: string, key: string, value: T): Promise<void>;\n delete(pluginName: string, key: string): Promise<void>;\n list(pluginName: string, prefix?: string): Promise<string[]>;\n clear(pluginName: string): Promise<void>;\n}\n\nexport interface PluginStorageEntry {\n pluginName: string;\n key: string;\n value: unknown;\n createdAt: Date;\n updatedAt: Date;\n}\n\n// ============================================\n// Enterprise Manager Interfaces\n// ============================================\n\nexport interface TenantManager {\n get(id: string): Promise<Tenant | null>;\n getBySlug(slug: string): Promise<Tenant | null>;\n list(filter?: TenantFilter): Promise<TenantListResult>;\n create(data: CreateTenantInput): Promise<Tenant>;\n update(id: string, data: UpdateTenantInput): Promise<Tenant>;\n delete(id: string, cascade?: boolean): Promise<void>;\n getStats(tenantId: string): Promise<TenantStats>;\n activate(id: string): Promise<Tenant>;\n deactivate(id: string): Promise<Tenant>;\n}\n\nexport interface AuthorizationManager {\n createRole(data: CreateRoleInput): Promise<Role>;\n getRole(id: string): Promise<Role | null>;\n listRoles(tenantId?: string): Promise<Role[]>;\n updateRole(id: string, data: UpdateRoleInput): Promise<Role>;\n deleteRole(id: string): Promise<void>;\n createUser(data: CreateUserInput): Promise<User>;\n getUser(id: string): Promise<UserWithRoles | null>;\n getUserByEmail(email: string, tenantId?: string): Promise<UserWithRoles | null>;\n listUsers(filter?: UserFilter): Promise<UserListResult>;\n updateUser(id: string, data: UpdateUserInput): Promise<User>;\n deleteUser(id: string): Promise<void>;\n assignRole(userId: string, roleId: string): Promise<void>;\n removeRole(userId: string, roleId: string): Promise<void>;\n getUserRoles(userId: string): Promise<Role[]>;\n can(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<boolean>;\n canAny(userId: string, permissions: Array<{ action: PermissionAction; resource: PermissionResource }>): Promise<boolean>;\n requirePermission(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<void>;\n isAdmin(userId: string): Promise<boolean>;\n}\n\nexport interface AuditManager {\n log(entry: CreateAuditLogInput): Promise<AuditLog>;\n list(filter?: AuditLogFilter): Promise<AuditLogListResult>;\n getByResource(resource: string, resourceId: string): Promise<AuditLog[]>;\n getByUser(userId: string, filter?: AuditLogFilter): Promise<AuditLogListResult>;\n export(filter: AuditLogFilter, format: 'json' | 'csv'): Promise<string>;\n purge(olderThanDays?: number): Promise<number>;\n getSummary(tenantId?: string, days?: number): Promise<AuditSummary>;\n}\n\nexport interface ScheduleManager {\n get(id: string): Promise<ScheduledTask | null>;\n list(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;\n create(data: CreateScheduledTaskInput): Promise<ScheduledTask>;\n update(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;\n delete(id: string): Promise<void>;\n pause(id: string): Promise<ScheduledTask>;\n resume(id: string): Promise<ScheduledTask>;\n runNow(id: string): Promise<TaskExecution>;\n getUpcoming(hours: number): Promise<ScheduledTask[]>;\n getExecutions(taskId: string, limit?: number): Promise<TaskExecution[]>;\n calculateNextRun(schedule: TaskSchedule): Date | null;\n}\n\nexport interface MessageQueueManager {\n enqueue(message: EnqueueMessageInput): Promise<QueuedMessage>;\n enqueueBatch(messages: EnqueueMessageInput[]): Promise<QueuedMessage[]>;\n dequeue(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n acknowledge(messageId: string): Promise<void>;\n fail(messageId: string, error: string): Promise<void>;\n retryFailed(maxAttempts?: number): Promise<number>;\n purgeExpired(): Promise<number>;\n getStats(tenantId?: string): Promise<QueueStats>;\n peek(deviceId: string, limit?: number): Promise<QueuedMessage[]>;\n}\n\nexport interface DashboardManager {\n getStats(tenantId?: string): Promise<DashboardStats>;\n getDeviceStatusBreakdown(tenantId?: string): Promise<DeviceStatusBreakdown>;\n getEnrollmentTrend(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;\n getCommandSuccessRates(tenantId?: string): Promise<CommandSuccessRates>;\n getAppInstallationSummary(tenantId?: string): Promise<AppInstallationSummary>;\n}\n\n// ============================================\n// Event Handler Types\n// ============================================\n\nexport type EventHandler<T extends EventType> = (\n event: MDMEvent<EventPayloadMap[T]>\n) => Promise<void> | void;\n\nexport interface EventPayloadMap {\n 'device.enrolled': { device: Device };\n 'device.unenrolled': { device: Device; reason?: string };\n 'device.blocked': { device: Device; reason: string };\n 'device.heartbeat': { device: Device; heartbeat: Heartbeat };\n 'device.locationUpdated': { device: Device; location: DeviceLocation };\n 'device.statusChanged': { device: Device; oldStatus: DeviceStatus; newStatus: DeviceStatus };\n 'device.policyChanged': { device: Device; oldPolicyId?: string; newPolicyId?: string };\n 'app.installed': { device: Device; app: InstalledApp };\n 'app.uninstalled': { device: Device; packageName: string };\n 'app.updated': { device: Device; app: InstalledApp; oldVersion: string };\n 'app.crashed': { device: Device; packageName: string; error?: string };\n 'app.started': { device: Device; packageName: string };\n 'app.stopped': { device: Device; packageName: string };\n 'policy.applied': { device: Device; policy: Policy };\n 'policy.failed': { device: Device; policy: Policy; error: string };\n 'command.received': { device: Device; command: Command };\n 'command.acknowledged': { device: Device; command: Command };\n 'command.completed': { device: Device; command: Command; result: CommandResult };\n 'command.failed': { device: Device; command: Command; error: string };\n 'security.tamper': { device: Device; type: string; details?: unknown };\n 'security.rootDetected': { device: Device };\n 'security.screenLocked': { device: Device };\n 'security.screenUnlocked': { device: Device };\n custom: Record<string, unknown>;\n}\n\n// ============================================\n// Error Types\n// ============================================\n\nexport class MDMError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: unknown\n ) {\n super(message);\n this.name = 'MDMError';\n }\n}\n\nexport class DeviceNotFoundError extends MDMError {\n constructor(deviceId: string) {\n super(`Device not found: ${deviceId}`, 'DEVICE_NOT_FOUND', 404);\n }\n}\n\nexport class PolicyNotFoundError extends MDMError {\n constructor(policyId: string) {\n super(`Policy not found: ${policyId}`, 'POLICY_NOT_FOUND', 404);\n }\n}\n\nexport class ApplicationNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Application not found: ${identifier}`, 'APPLICATION_NOT_FOUND', 404);\n }\n}\n\nexport class TenantNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Tenant not found: ${identifier}`, 'TENANT_NOT_FOUND', 404);\n }\n}\n\nexport class RoleNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Role not found: ${identifier}`, 'ROLE_NOT_FOUND', 404);\n }\n}\n\nexport class GroupNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`Group not found: ${identifier}`, 'GROUP_NOT_FOUND', 404);\n }\n}\n\nexport class UserNotFoundError extends MDMError {\n constructor(identifier: string) {\n super(`User not found: ${identifier}`, 'USER_NOT_FOUND', 404);\n }\n}\n\nexport class EnrollmentError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'ENROLLMENT_ERROR', 400, details);\n }\n}\n\nexport class AuthenticationError extends MDMError {\n constructor(message: string = 'Authentication required') {\n super(message, 'AUTHENTICATION_ERROR', 401);\n }\n}\n\nexport class AuthorizationError extends MDMError {\n constructor(message: string = 'Access denied') {\n super(message, 'AUTHORIZATION_ERROR', 403);\n }\n}\n\nexport class ValidationError extends MDMError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', 400, details);\n }\n}\n"]}