@openmdm/core 0.2.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 ADDED
@@ -0,0 +1,415 @@
1
+ // src/schema.ts
2
+ var mdmSchema = {
3
+ tables: {
4
+ // ----------------------------------------
5
+ // Devices Table
6
+ // ----------------------------------------
7
+ mdm_devices: {
8
+ columns: {
9
+ id: { type: "string", primaryKey: true },
10
+ external_id: { type: "string", nullable: true },
11
+ enrollment_id: { type: "string", unique: true },
12
+ status: {
13
+ type: "enum",
14
+ enumValues: ["pending", "enrolled", "unenrolled", "blocked"],
15
+ default: "pending"
16
+ },
17
+ // Device Info
18
+ model: { type: "string", nullable: true },
19
+ manufacturer: { type: "string", nullable: true },
20
+ os_version: { type: "string", nullable: true },
21
+ serial_number: { type: "string", nullable: true },
22
+ imei: { type: "string", nullable: true },
23
+ mac_address: { type: "string", nullable: true },
24
+ android_id: { type: "string", nullable: true },
25
+ // MDM State
26
+ policy_id: {
27
+ type: "string",
28
+ nullable: true,
29
+ references: { table: "mdm_policies", column: "id", onDelete: "set null" }
30
+ },
31
+ last_heartbeat: { type: "datetime", nullable: true },
32
+ last_sync: { type: "datetime", nullable: true },
33
+ // Telemetry (denormalized for quick access)
34
+ battery_level: { type: "integer", nullable: true },
35
+ storage_used: { type: "bigint", nullable: true },
36
+ storage_total: { type: "bigint", nullable: true },
37
+ latitude: { type: "string", nullable: true },
38
+ // Stored as string for precision
39
+ longitude: { type: "string", nullable: true },
40
+ location_timestamp: { type: "datetime", nullable: true },
41
+ // JSON fields
42
+ installed_apps: { type: "json", nullable: true },
43
+ tags: { type: "json", nullable: true },
44
+ metadata: { type: "json", nullable: true },
45
+ // Timestamps
46
+ created_at: { type: "datetime", default: "now" },
47
+ updated_at: { type: "datetime", default: "now" }
48
+ },
49
+ indexes: [
50
+ { columns: ["enrollment_id"], unique: true },
51
+ { columns: ["status"] },
52
+ { columns: ["policy_id"] },
53
+ { columns: ["last_heartbeat"] },
54
+ { columns: ["mac_address"] },
55
+ { columns: ["serial_number"] }
56
+ ]
57
+ },
58
+ // ----------------------------------------
59
+ // Policies Table
60
+ // ----------------------------------------
61
+ mdm_policies: {
62
+ columns: {
63
+ id: { type: "string", primaryKey: true },
64
+ name: { type: "string" },
65
+ description: { type: "text", nullable: true },
66
+ is_default: { type: "boolean", default: false },
67
+ settings: { type: "json" },
68
+ created_at: { type: "datetime", default: "now" },
69
+ updated_at: { type: "datetime", default: "now" }
70
+ },
71
+ indexes: [
72
+ { columns: ["name"] },
73
+ { columns: ["is_default"] }
74
+ ]
75
+ },
76
+ // ----------------------------------------
77
+ // Applications Table
78
+ // ----------------------------------------
79
+ mdm_applications: {
80
+ columns: {
81
+ id: { type: "string", primaryKey: true },
82
+ name: { type: "string" },
83
+ package_name: { type: "string" },
84
+ version: { type: "string" },
85
+ version_code: { type: "integer" },
86
+ url: { type: "string" },
87
+ hash: { type: "string", nullable: true },
88
+ // SHA-256
89
+ size: { type: "bigint", nullable: true },
90
+ min_sdk_version: { type: "integer", nullable: true },
91
+ // Deployment settings
92
+ show_icon: { type: "boolean", default: true },
93
+ run_after_install: { type: "boolean", default: false },
94
+ run_at_boot: { type: "boolean", default: false },
95
+ is_system: { type: "boolean", default: false },
96
+ // State
97
+ is_active: { type: "boolean", default: true },
98
+ // Metadata
99
+ metadata: { type: "json", nullable: true },
100
+ created_at: { type: "datetime", default: "now" },
101
+ updated_at: { type: "datetime", default: "now" }
102
+ },
103
+ indexes: [
104
+ { columns: ["package_name"] },
105
+ { columns: ["package_name", "version"], unique: true },
106
+ { columns: ["is_active"] }
107
+ ]
108
+ },
109
+ // ----------------------------------------
110
+ // Commands Table
111
+ // ----------------------------------------
112
+ mdm_commands: {
113
+ columns: {
114
+ id: { type: "string", primaryKey: true },
115
+ device_id: {
116
+ type: "string",
117
+ references: { table: "mdm_devices", column: "id", onDelete: "cascade" }
118
+ },
119
+ type: { type: "string" },
120
+ payload: { type: "json", nullable: true },
121
+ status: {
122
+ type: "enum",
123
+ enumValues: ["pending", "sent", "acknowledged", "completed", "failed", "cancelled"],
124
+ default: "pending"
125
+ },
126
+ result: { type: "json", nullable: true },
127
+ error: { type: "text", nullable: true },
128
+ created_at: { type: "datetime", default: "now" },
129
+ sent_at: { type: "datetime", nullable: true },
130
+ acknowledged_at: { type: "datetime", nullable: true },
131
+ completed_at: { type: "datetime", nullable: true }
132
+ },
133
+ indexes: [
134
+ { columns: ["device_id"] },
135
+ { columns: ["status"] },
136
+ { columns: ["device_id", "status"] },
137
+ { columns: ["created_at"] }
138
+ ]
139
+ },
140
+ // ----------------------------------------
141
+ // Events Table
142
+ // ----------------------------------------
143
+ mdm_events: {
144
+ columns: {
145
+ id: { type: "string", primaryKey: true },
146
+ device_id: {
147
+ type: "string",
148
+ references: { table: "mdm_devices", column: "id", onDelete: "cascade" }
149
+ },
150
+ type: { type: "string" },
151
+ payload: { type: "json" },
152
+ created_at: { type: "datetime", default: "now" }
153
+ },
154
+ indexes: [
155
+ { columns: ["device_id"] },
156
+ { columns: ["type"] },
157
+ { columns: ["device_id", "type"] },
158
+ { columns: ["created_at"] }
159
+ ]
160
+ },
161
+ // ----------------------------------------
162
+ // Groups Table
163
+ // ----------------------------------------
164
+ mdm_groups: {
165
+ columns: {
166
+ id: { type: "string", primaryKey: true },
167
+ name: { type: "string" },
168
+ description: { type: "text", nullable: true },
169
+ policy_id: {
170
+ type: "string",
171
+ nullable: true,
172
+ references: { table: "mdm_policies", column: "id", onDelete: "set null" }
173
+ },
174
+ parent_id: {
175
+ type: "string",
176
+ nullable: true,
177
+ references: { table: "mdm_groups", column: "id", onDelete: "set null" }
178
+ },
179
+ metadata: { type: "json", nullable: true },
180
+ created_at: { type: "datetime", default: "now" },
181
+ updated_at: { type: "datetime", default: "now" }
182
+ },
183
+ indexes: [
184
+ { columns: ["name"] },
185
+ { columns: ["policy_id"] },
186
+ { columns: ["parent_id"] }
187
+ ]
188
+ },
189
+ // ----------------------------------------
190
+ // Device Groups (Many-to-Many)
191
+ // ----------------------------------------
192
+ mdm_device_groups: {
193
+ columns: {
194
+ device_id: {
195
+ type: "string",
196
+ references: { table: "mdm_devices", column: "id", onDelete: "cascade" }
197
+ },
198
+ group_id: {
199
+ type: "string",
200
+ references: { table: "mdm_groups", column: "id", onDelete: "cascade" }
201
+ },
202
+ created_at: { type: "datetime", default: "now" }
203
+ },
204
+ indexes: [
205
+ { columns: ["device_id", "group_id"], unique: true },
206
+ { columns: ["group_id"] }
207
+ ]
208
+ },
209
+ // ----------------------------------------
210
+ // Push Tokens (for FCM/MQTT registration)
211
+ // ----------------------------------------
212
+ mdm_push_tokens: {
213
+ columns: {
214
+ id: { type: "string", primaryKey: true },
215
+ device_id: {
216
+ type: "string",
217
+ references: { table: "mdm_devices", column: "id", onDelete: "cascade" }
218
+ },
219
+ provider: {
220
+ type: "enum",
221
+ enumValues: ["fcm", "mqtt", "websocket"]
222
+ },
223
+ token: { type: "string" },
224
+ is_active: { type: "boolean", default: true },
225
+ created_at: { type: "datetime", default: "now" },
226
+ updated_at: { type: "datetime", default: "now" }
227
+ },
228
+ indexes: [
229
+ { columns: ["device_id"] },
230
+ { columns: ["provider", "token"], unique: true },
231
+ { columns: ["is_active"] }
232
+ ]
233
+ },
234
+ // ----------------------------------------
235
+ // Application Deployments (Which apps go to which policies/groups)
236
+ // ----------------------------------------
237
+ mdm_app_deployments: {
238
+ columns: {
239
+ id: { type: "string", primaryKey: true },
240
+ application_id: {
241
+ type: "string",
242
+ references: { table: "mdm_applications", column: "id", onDelete: "cascade" }
243
+ },
244
+ // Target can be policy or group
245
+ target_type: {
246
+ type: "enum",
247
+ enumValues: ["policy", "group"]
248
+ },
249
+ target_id: { type: "string" },
250
+ action: {
251
+ type: "enum",
252
+ enumValues: ["install", "update", "uninstall"],
253
+ default: "install"
254
+ },
255
+ is_required: { type: "boolean", default: false },
256
+ created_at: { type: "datetime", default: "now" }
257
+ },
258
+ indexes: [
259
+ { columns: ["application_id"] },
260
+ { columns: ["target_type", "target_id"] }
261
+ ]
262
+ },
263
+ // ----------------------------------------
264
+ // App Versions (Version history for rollback support)
265
+ // ----------------------------------------
266
+ mdm_app_versions: {
267
+ columns: {
268
+ id: { type: "string", primaryKey: true },
269
+ application_id: {
270
+ type: "string",
271
+ references: { table: "mdm_applications", column: "id", onDelete: "cascade" }
272
+ },
273
+ package_name: { type: "string" },
274
+ version: { type: "string" },
275
+ version_code: { type: "integer" },
276
+ url: { type: "string" },
277
+ hash: { type: "string", nullable: true },
278
+ size: { type: "bigint", nullable: true },
279
+ release_notes: { type: "text", nullable: true },
280
+ is_minimum_version: { type: "boolean", default: false },
281
+ created_at: { type: "datetime", default: "now" }
282
+ },
283
+ indexes: [
284
+ { columns: ["application_id"] },
285
+ { columns: ["package_name"] },
286
+ { columns: ["package_name", "version_code"], unique: true },
287
+ { columns: ["is_minimum_version"] }
288
+ ]
289
+ },
290
+ // ----------------------------------------
291
+ // App Rollbacks (Rollback history and status)
292
+ // ----------------------------------------
293
+ mdm_rollbacks: {
294
+ columns: {
295
+ id: { type: "string", primaryKey: true },
296
+ device_id: {
297
+ type: "string",
298
+ references: { table: "mdm_devices", column: "id", onDelete: "cascade" }
299
+ },
300
+ package_name: { type: "string" },
301
+ from_version: { type: "string" },
302
+ from_version_code: { type: "integer" },
303
+ to_version: { type: "string" },
304
+ to_version_code: { type: "integer" },
305
+ reason: { type: "text", nullable: true },
306
+ status: {
307
+ type: "enum",
308
+ enumValues: ["pending", "in_progress", "completed", "failed"],
309
+ default: "pending"
310
+ },
311
+ error: { type: "text", nullable: true },
312
+ initiated_by: { type: "string", nullable: true },
313
+ created_at: { type: "datetime", default: "now" },
314
+ completed_at: { type: "datetime", nullable: true }
315
+ },
316
+ indexes: [
317
+ { columns: ["device_id"] },
318
+ { columns: ["package_name"] },
319
+ { columns: ["device_id", "package_name"] },
320
+ { columns: ["status"] },
321
+ { columns: ["created_at"] }
322
+ ]
323
+ },
324
+ // ----------------------------------------
325
+ // Webhook Endpoints (For outbound webhook configuration storage)
326
+ // ----------------------------------------
327
+ mdm_webhook_endpoints: {
328
+ columns: {
329
+ id: { type: "string", primaryKey: true },
330
+ url: { type: "string" },
331
+ events: { type: "json" },
332
+ // Array of event types or ['*']
333
+ headers: { type: "json", nullable: true },
334
+ enabled: { type: "boolean", default: true },
335
+ description: { type: "text", nullable: true },
336
+ created_at: { type: "datetime", default: "now" },
337
+ updated_at: { type: "datetime", default: "now" }
338
+ },
339
+ indexes: [
340
+ { columns: ["enabled"] }
341
+ ]
342
+ },
343
+ // ----------------------------------------
344
+ // Webhook Deliveries (Delivery history and status)
345
+ // ----------------------------------------
346
+ mdm_webhook_deliveries: {
347
+ columns: {
348
+ id: { type: "string", primaryKey: true },
349
+ endpoint_id: {
350
+ type: "string",
351
+ references: { table: "mdm_webhook_endpoints", column: "id", onDelete: "cascade" }
352
+ },
353
+ event_id: { type: "string" },
354
+ event_type: { type: "string" },
355
+ payload: { type: "json" },
356
+ status: {
357
+ type: "enum",
358
+ enumValues: ["pending", "success", "failed"],
359
+ default: "pending"
360
+ },
361
+ status_code: { type: "integer", nullable: true },
362
+ error: { type: "text", nullable: true },
363
+ retry_count: { type: "integer", default: 0 },
364
+ created_at: { type: "datetime", default: "now" },
365
+ delivered_at: { type: "datetime", nullable: true }
366
+ },
367
+ indexes: [
368
+ { columns: ["endpoint_id"] },
369
+ { columns: ["event_type"] },
370
+ { columns: ["status"] },
371
+ { columns: ["created_at"] }
372
+ ]
373
+ }
374
+ }
375
+ };
376
+ function getTableNames() {
377
+ return Object.keys(mdmSchema.tables);
378
+ }
379
+ function getColumnNames(tableName) {
380
+ const table = mdmSchema.tables[tableName];
381
+ if (!table) throw new Error(`Table ${tableName} not found in schema`);
382
+ return Object.keys(table.columns);
383
+ }
384
+ function getPrimaryKey(tableName) {
385
+ const table = mdmSchema.tables[tableName];
386
+ if (!table) throw new Error(`Table ${tableName} not found in schema`);
387
+ for (const [name, def] of Object.entries(table.columns)) {
388
+ if (def.primaryKey) return name;
389
+ }
390
+ return null;
391
+ }
392
+ function snakeToCamel(str) {
393
+ return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
394
+ }
395
+ function camelToSnake(str) {
396
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
397
+ }
398
+ function transformToCamelCase(obj) {
399
+ const result = {};
400
+ for (const [key, value] of Object.entries(obj)) {
401
+ result[snakeToCamel(key)] = value;
402
+ }
403
+ return result;
404
+ }
405
+ function transformToSnakeCase(obj) {
406
+ const result = {};
407
+ for (const [key, value] of Object.entries(obj)) {
408
+ result[camelToSnake(key)] = value;
409
+ }
410
+ return result;
411
+ }
412
+
413
+ export { camelToSnake, getColumnNames, getPrimaryKey, getTableNames, mdmSchema, snakeToCamel, transformToCamelCase, transformToSnakeCase };
414
+ //# sourceMappingURL=schema.js.map
415
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +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 */\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\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"]}