@openmdm/core 0.2.0 → 0.3.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/src/types.ts CHANGED
@@ -660,6 +660,37 @@ export interface MDMConfig {
660
660
  onHeartbeat?: (device: Device, heartbeat: Heartbeat) => Promise<void>;
661
661
  onCommand?: (command: Command) => Promise<void>;
662
662
  onEvent?: (event: MDMEvent) => Promise<void>;
663
+
664
+ // Enterprise features
665
+ /** Multi-tenancy configuration */
666
+ multiTenancy?: {
667
+ enabled: boolean;
668
+ defaultTenantId?: string;
669
+ tenantResolver?: (context: unknown) => Promise<string | null>;
670
+ };
671
+
672
+ /** Authorization (RBAC) configuration */
673
+ authorization?: {
674
+ enabled: boolean;
675
+ defaultRole?: string;
676
+ };
677
+
678
+ /** Audit logging configuration */
679
+ audit?: {
680
+ enabled: boolean;
681
+ retentionDays?: number;
682
+ };
683
+
684
+ /** Scheduling configuration */
685
+ scheduling?: {
686
+ enabled: boolean;
687
+ timezone?: string;
688
+ };
689
+
690
+ /** Plugin storage configuration */
691
+ pluginStorage?: {
692
+ adapter: 'database' | 'memory';
693
+ };
663
694
  }
664
695
 
665
696
  export interface StorageConfig {
@@ -834,6 +865,82 @@ export interface DatabaseAdapter {
834
865
  updateRollback?(id: string, data: Partial<AppRollback>): Promise<AppRollback>;
835
866
  listRollbacks?(filter?: { deviceId?: string; packageName?: string }): Promise<AppRollback[]>;
836
867
 
868
+ // Group Hierarchy (optional)
869
+ getGroupChildren?(parentId: string | null): Promise<Group[]>;
870
+ getGroupAncestors?(groupId: string): Promise<Group[]>;
871
+ getGroupDescendants?(groupId: string): Promise<Group[]>;
872
+ getGroupTree?(rootId?: string): Promise<GroupTreeNode[]>;
873
+ getGroupEffectivePolicy?(groupId: string): Promise<Policy | null>;
874
+ moveGroup?(groupId: string, newParentId: string | null): Promise<Group>;
875
+ getGroupHierarchyStats?(): Promise<GroupHierarchyStats>;
876
+
877
+ // Tenants (optional - for multi-tenancy)
878
+ findTenant?(id: string): Promise<Tenant | null>;
879
+ findTenantBySlug?(slug: string): Promise<Tenant | null>;
880
+ listTenants?(filter?: TenantFilter): Promise<TenantListResult>;
881
+ createTenant?(data: CreateTenantInput): Promise<Tenant>;
882
+ updateTenant?(id: string, data: UpdateTenantInput): Promise<Tenant>;
883
+ deleteTenant?(id: string): Promise<void>;
884
+ getTenantStats?(tenantId: string): Promise<TenantStats>;
885
+
886
+ // Users (optional - for RBAC)
887
+ findUser?(id: string): Promise<User | null>;
888
+ findUserByEmail?(email: string, tenantId?: string): Promise<User | null>;
889
+ listUsers?(filter?: UserFilter): Promise<UserListResult>;
890
+ createUser?(data: CreateUserInput): Promise<User>;
891
+ updateUser?(id: string, data: UpdateUserInput): Promise<User>;
892
+ deleteUser?(id: string): Promise<void>;
893
+
894
+ // Roles (optional - for RBAC)
895
+ findRole?(id: string): Promise<Role | null>;
896
+ listRoles?(tenantId?: string): Promise<Role[]>;
897
+ createRole?(data: CreateRoleInput): Promise<Role>;
898
+ updateRole?(id: string, data: UpdateRoleInput): Promise<Role>;
899
+ deleteRole?(id: string): Promise<void>;
900
+ assignRoleToUser?(userId: string, roleId: string): Promise<void>;
901
+ removeRoleFromUser?(userId: string, roleId: string): Promise<void>;
902
+ getUserRoles?(userId: string): Promise<Role[]>;
903
+
904
+ // Audit Logs (optional - for compliance)
905
+ createAuditLog?(data: CreateAuditLogInput): Promise<AuditLog>;
906
+ listAuditLogs?(filter?: AuditLogFilter): Promise<AuditLogListResult>;
907
+ deleteAuditLogs?(filter: { olderThan?: Date; tenantId?: string }): Promise<number>;
908
+
909
+ // Scheduled Tasks (optional - for scheduling)
910
+ findScheduledTask?(id: string): Promise<ScheduledTask | null>;
911
+ listScheduledTasks?(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;
912
+ createScheduledTask?(data: CreateScheduledTaskInput): Promise<ScheduledTask>;
913
+ updateScheduledTask?(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;
914
+ deleteScheduledTask?(id: string): Promise<void>;
915
+ getUpcomingTasks?(hours: number): Promise<ScheduledTask[]>;
916
+ createTaskExecution?(data: { taskId: string }): Promise<TaskExecution>;
917
+ updateTaskExecution?(id: string, data: Partial<TaskExecution>): Promise<TaskExecution>;
918
+ listTaskExecutions?(taskId: string, limit?: number): Promise<TaskExecution[]>;
919
+
920
+ // Message Queue (optional - for persistent messaging)
921
+ enqueueMessage?(data: EnqueueMessageInput): Promise<QueuedMessage>;
922
+ dequeueMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;
923
+ peekMessages?(deviceId: string, limit?: number): Promise<QueuedMessage[]>;
924
+ acknowledgeMessage?(messageId: string): Promise<void>;
925
+ failMessage?(messageId: string, error: string): Promise<void>;
926
+ retryFailedMessages?(maxAttempts?: number): Promise<number>;
927
+ purgeExpiredMessages?(): Promise<number>;
928
+ getQueueStats?(tenantId?: string): Promise<QueueStats>;
929
+
930
+ // Plugin Storage (optional)
931
+ getPluginValue?(pluginName: string, key: string): Promise<unknown | null>;
932
+ setPluginValue?(pluginName: string, key: string, value: unknown): Promise<void>;
933
+ deletePluginValue?(pluginName: string, key: string): Promise<void>;
934
+ listPluginKeys?(pluginName: string, prefix?: string): Promise<string[]>;
935
+ clearPluginData?(pluginName: string): Promise<void>;
936
+
937
+ // Dashboard (optional - for analytics)
938
+ getDashboardStats?(tenantId?: string): Promise<DashboardStats>;
939
+ getDeviceStatusBreakdown?(tenantId?: string): Promise<DeviceStatusBreakdown>;
940
+ getEnrollmentTrend?(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;
941
+ getCommandSuccessRates?(tenantId?: string): Promise<CommandSuccessRates>;
942
+ getAppInstallationSummary?(tenantId?: string): Promise<AppInstallationSummary>;
943
+
837
944
  // Transactions (optional)
838
945
  transaction?<T>(fn: () => Promise<T>): Promise<T>;
839
946
  }
@@ -966,6 +1073,21 @@ export interface MDMInstance {
966
1073
  /** Group management */
967
1074
  groups: GroupManager;
968
1075
 
1076
+ /** Tenant management (if multi-tenancy enabled) */
1077
+ tenants?: TenantManager;
1078
+ /** Authorization management (RBAC) */
1079
+ authorization?: AuthorizationManager;
1080
+ /** Audit logging */
1081
+ audit?: AuditManager;
1082
+ /** Scheduled task management */
1083
+ schedules?: ScheduleManager;
1084
+ /** Persistent message queue */
1085
+ messageQueue?: MessageQueueManager;
1086
+ /** Dashboard analytics */
1087
+ dashboard?: DashboardManager;
1088
+ /** Plugin storage */
1089
+ pluginStorage?: PluginStorageAdapter;
1090
+
969
1091
  /** Push notification service */
970
1092
  push: PushAdapter;
971
1093
 
@@ -1056,15 +1178,577 @@ export interface CommandManager {
1056
1178
  }
1057
1179
 
1058
1180
  export interface GroupManager {
1181
+ // Basic CRUD operations
1059
1182
  get(id: string): Promise<Group | null>;
1060
1183
  list(): Promise<Group[]>;
1061
1184
  create(data: CreateGroupInput): Promise<Group>;
1062
1185
  update(id: string, data: UpdateGroupInput): Promise<Group>;
1063
1186
  delete(id: string): Promise<void>;
1187
+
1188
+ // Device management
1064
1189
  getDevices(groupId: string): Promise<Device[]>;
1065
1190
  addDevice(groupId: string, deviceId: string): Promise<void>;
1066
1191
  removeDevice(groupId: string, deviceId: string): Promise<void>;
1192
+
1193
+ // Hierarchy operations
1067
1194
  getChildren(groupId: string): Promise<Group[]>;
1195
+ getTree(rootId?: string): Promise<GroupTreeNode[]>;
1196
+ getAncestors(groupId: string): Promise<Group[]>;
1197
+ getDescendants(groupId: string): Promise<Group[]>;
1198
+ move(groupId: string, newParentId: string | null): Promise<Group>;
1199
+ getEffectivePolicy(groupId: string): Promise<Policy | null>;
1200
+ getHierarchyStats(): Promise<GroupHierarchyStats>;
1201
+ }
1202
+
1203
+ // ============================================
1204
+ // Group Hierarchy Types
1205
+ // ============================================
1206
+
1207
+ export interface GroupTreeNode extends Group {
1208
+ children: GroupTreeNode[];
1209
+ depth: number;
1210
+ path: string[];
1211
+ effectivePolicyId?: string | null;
1212
+ }
1213
+
1214
+ export interface GroupHierarchyStats {
1215
+ totalGroups: number;
1216
+ maxDepth: number;
1217
+ groupsWithDevices: number;
1218
+ groupsWithPolicies: number;
1219
+ }
1220
+
1221
+ // ============================================
1222
+ // Tenant Types (Multi-tenancy)
1223
+ // ============================================
1224
+
1225
+ export type TenantStatus = 'active' | 'suspended' | 'pending';
1226
+
1227
+ export interface Tenant {
1228
+ id: string;
1229
+ name: string;
1230
+ slug: string;
1231
+ status: TenantStatus;
1232
+ settings?: TenantSettings | null;
1233
+ metadata?: Record<string, unknown> | null;
1234
+ createdAt: Date;
1235
+ updatedAt: Date;
1236
+ }
1237
+
1238
+ export interface TenantSettings {
1239
+ maxDevices?: number;
1240
+ maxUsers?: number;
1241
+ features?: string[];
1242
+ branding?: {
1243
+ logo?: string;
1244
+ primaryColor?: string;
1245
+ };
1246
+ }
1247
+
1248
+ export interface CreateTenantInput {
1249
+ name: string;
1250
+ slug: string;
1251
+ settings?: TenantSettings;
1252
+ metadata?: Record<string, unknown>;
1253
+ }
1254
+
1255
+ export interface UpdateTenantInput {
1256
+ name?: string;
1257
+ slug?: string;
1258
+ status?: TenantStatus;
1259
+ settings?: TenantSettings;
1260
+ metadata?: Record<string, unknown>;
1261
+ }
1262
+
1263
+ export interface TenantFilter {
1264
+ status?: TenantStatus;
1265
+ search?: string;
1266
+ limit?: number;
1267
+ offset?: number;
1268
+ }
1269
+
1270
+ export interface TenantListResult {
1271
+ tenants: Tenant[];
1272
+ total: number;
1273
+ limit: number;
1274
+ offset: number;
1275
+ }
1276
+
1277
+ export interface TenantStats {
1278
+ deviceCount: number;
1279
+ userCount: number;
1280
+ policyCount: number;
1281
+ appCount: number;
1282
+ }
1283
+
1284
+ // ============================================
1285
+ // RBAC Types (Role-Based Access Control)
1286
+ // ============================================
1287
+
1288
+ export type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'manage' | '*';
1289
+ export type PermissionResource = 'devices' | 'policies' | 'apps' | 'groups' | 'commands' | 'users' | 'roles' | 'tenants' | 'audit' | '*';
1290
+
1291
+ export interface Permission {
1292
+ action: PermissionAction;
1293
+ resource: PermissionResource;
1294
+ resourceId?: string;
1295
+ }
1296
+
1297
+ export interface Role {
1298
+ id: string;
1299
+ tenantId?: string | null;
1300
+ name: string;
1301
+ description?: string | null;
1302
+ permissions: Permission[];
1303
+ isSystem: boolean;
1304
+ createdAt: Date;
1305
+ updatedAt: Date;
1306
+ }
1307
+
1308
+ export interface CreateRoleInput {
1309
+ tenantId?: string;
1310
+ name: string;
1311
+ description?: string;
1312
+ permissions: Permission[];
1313
+ }
1314
+
1315
+ export interface UpdateRoleInput {
1316
+ name?: string;
1317
+ description?: string;
1318
+ permissions?: Permission[];
1319
+ }
1320
+
1321
+ export interface User {
1322
+ id: string;
1323
+ tenantId?: string | null;
1324
+ email: string;
1325
+ name?: string | null;
1326
+ status: 'active' | 'inactive' | 'pending';
1327
+ metadata?: Record<string, unknown> | null;
1328
+ lastLoginAt?: Date | null;
1329
+ createdAt: Date;
1330
+ updatedAt: Date;
1331
+ }
1332
+
1333
+ export interface UserWithRoles extends User {
1334
+ roles: Role[];
1335
+ }
1336
+
1337
+ export interface CreateUserInput {
1338
+ tenantId?: string;
1339
+ email: string;
1340
+ name?: string;
1341
+ status?: 'active' | 'inactive' | 'pending';
1342
+ metadata?: Record<string, unknown>;
1343
+ }
1344
+
1345
+ export interface UpdateUserInput {
1346
+ email?: string;
1347
+ name?: string;
1348
+ status?: 'active' | 'inactive' | 'pending';
1349
+ metadata?: Record<string, unknown>;
1350
+ }
1351
+
1352
+ export interface UserFilter {
1353
+ tenantId?: string;
1354
+ status?: 'active' | 'inactive' | 'pending';
1355
+ search?: string;
1356
+ limit?: number;
1357
+ offset?: number;
1358
+ }
1359
+
1360
+ export interface UserListResult {
1361
+ users: User[];
1362
+ total: number;
1363
+ limit: number;
1364
+ offset: number;
1365
+ }
1366
+
1367
+ // ============================================
1368
+ // Audit Types
1369
+ // ============================================
1370
+
1371
+ export type AuditAction = 'create' | 'read' | 'update' | 'delete' | 'login' | 'logout' | 'enroll' | 'unenroll' | 'command' | 'export' | 'import' | 'custom';
1372
+
1373
+ export interface AuditLog {
1374
+ id: string;
1375
+ tenantId?: string | null;
1376
+ userId?: string | null;
1377
+ action: AuditAction;
1378
+ resource: string;
1379
+ resourceId?: string | null;
1380
+ status: 'success' | 'failure';
1381
+ error?: string | null;
1382
+ details?: Record<string, unknown> | null;
1383
+ ipAddress?: string | null;
1384
+ userAgent?: string | null;
1385
+ createdAt: Date;
1386
+ }
1387
+
1388
+ export interface CreateAuditLogInput {
1389
+ tenantId?: string;
1390
+ userId?: string;
1391
+ action: AuditAction;
1392
+ resource: string;
1393
+ resourceId?: string;
1394
+ status?: 'success' | 'failure';
1395
+ error?: string;
1396
+ details?: Record<string, unknown>;
1397
+ ipAddress?: string;
1398
+ userAgent?: string;
1399
+ }
1400
+
1401
+ export interface AuditConfig {
1402
+ enabled: boolean;
1403
+ retentionDays?: number;
1404
+ skipReadOperations?: boolean;
1405
+ logActions?: AuditAction[];
1406
+ logResources?: string[];
1407
+ }
1408
+
1409
+ export interface AuditSummary {
1410
+ totalLogs: number;
1411
+ byAction: Record<AuditAction, number>;
1412
+ byResource: Record<string, number>;
1413
+ byStatus: { success: number; failure: number };
1414
+ topUsers: Array<{ userId: string; count: number }>;
1415
+ recentFailures: AuditLog[];
1416
+ }
1417
+
1418
+ export interface AuditLogFilter {
1419
+ tenantId?: string;
1420
+ userId?: string;
1421
+ action?: string;
1422
+ resource?: string;
1423
+ resourceId?: string;
1424
+ startDate?: Date;
1425
+ endDate?: Date;
1426
+ limit?: number;
1427
+ offset?: number;
1428
+ }
1429
+
1430
+ export interface AuditLogListResult {
1431
+ logs: AuditLog[];
1432
+ total: number;
1433
+ limit: number;
1434
+ offset: number;
1435
+ }
1436
+
1437
+ // ============================================
1438
+ // Schedule Types
1439
+ // ============================================
1440
+
1441
+ export type TaskType = 'command' | 'policy_update' | 'app_install' | 'maintenance' | 'custom';
1442
+ export type ScheduledTaskStatus = 'active' | 'paused' | 'completed' | 'failed';
1443
+
1444
+ export interface MaintenanceWindow {
1445
+ daysOfWeek: number[];
1446
+ startTime: string;
1447
+ endTime: string;
1448
+ timezone: string;
1449
+ }
1450
+
1451
+ export interface TaskSchedule {
1452
+ type: 'once' | 'recurring' | 'window';
1453
+ executeAt?: Date;
1454
+ cron?: string;
1455
+ window?: MaintenanceWindow;
1456
+ }
1457
+
1458
+ export interface ScheduledTask {
1459
+ id: string;
1460
+ tenantId?: string | null;
1461
+ name: string;
1462
+ description?: string | null;
1463
+ taskType: TaskType;
1464
+ schedule: TaskSchedule;
1465
+ target?: DeployTarget;
1466
+ payload?: Record<string, unknown> | null;
1467
+ status: ScheduledTaskStatus;
1468
+ nextRunAt?: Date | null;
1469
+ lastRunAt?: Date | null;
1470
+ maxRetries: number;
1471
+ retryCount: number;
1472
+ createdAt: Date;
1473
+ updatedAt: Date;
1474
+ }
1475
+
1476
+ export interface CreateScheduledTaskInput {
1477
+ tenantId?: string;
1478
+ name: string;
1479
+ description?: string;
1480
+ taskType: TaskType;
1481
+ schedule: TaskSchedule;
1482
+ target?: DeployTarget;
1483
+ payload?: Record<string, unknown>;
1484
+ maxRetries?: number;
1485
+ }
1486
+
1487
+ export interface UpdateScheduledTaskInput {
1488
+ name?: string;
1489
+ description?: string;
1490
+ schedule?: TaskSchedule;
1491
+ target?: DeployTarget;
1492
+ payload?: Record<string, unknown>;
1493
+ status?: ScheduledTaskStatus;
1494
+ maxRetries?: number;
1495
+ }
1496
+
1497
+ export interface ScheduledTaskFilter {
1498
+ tenantId?: string;
1499
+ taskType?: TaskType | TaskType[];
1500
+ status?: ScheduledTaskStatus | ScheduledTaskStatus[];
1501
+ limit?: number;
1502
+ offset?: number;
1503
+ }
1504
+
1505
+ export interface ScheduledTaskListResult {
1506
+ tasks: ScheduledTask[];
1507
+ total: number;
1508
+ limit: number;
1509
+ offset: number;
1510
+ }
1511
+
1512
+ export interface TaskExecution {
1513
+ id: string;
1514
+ taskId: string;
1515
+ status: 'running' | 'completed' | 'failed';
1516
+ startedAt: Date;
1517
+ completedAt?: Date | null;
1518
+ devicesProcessed: number;
1519
+ devicesSucceeded: number;
1520
+ devicesFailed: number;
1521
+ error?: string | null;
1522
+ details?: Record<string, unknown> | null;
1523
+ }
1524
+
1525
+ // ============================================
1526
+ // Message Queue Types
1527
+ // ============================================
1528
+
1529
+ export type QueueMessageStatus = 'pending' | 'processing' | 'delivered' | 'failed' | 'expired';
1530
+
1531
+ export interface QueuedMessage {
1532
+ id: string;
1533
+ tenantId?: string | null;
1534
+ deviceId: string;
1535
+ messageType: string;
1536
+ payload: Record<string, unknown>;
1537
+ priority: 'high' | 'normal' | 'low';
1538
+ status: QueueMessageStatus;
1539
+ attempts: number;
1540
+ maxAttempts: number;
1541
+ lastAttemptAt?: Date | null;
1542
+ lastError?: string | null;
1543
+ expiresAt?: Date | null;
1544
+ createdAt: Date;
1545
+ updatedAt: Date;
1546
+ }
1547
+
1548
+ export interface EnqueueMessageInput {
1549
+ tenantId?: string;
1550
+ deviceId: string;
1551
+ messageType: string;
1552
+ payload: Record<string, unknown>;
1553
+ priority?: 'high' | 'normal' | 'low';
1554
+ maxAttempts?: number;
1555
+ ttlSeconds?: number;
1556
+ }
1557
+
1558
+ export interface QueueStats {
1559
+ pending: number;
1560
+ processing: number;
1561
+ delivered: number;
1562
+ failed: number;
1563
+ expired: number;
1564
+ byDevice: Record<string, number>;
1565
+ oldestPending?: Date;
1566
+ }
1567
+
1568
+ // ============================================
1569
+ // Dashboard Types
1570
+ // ============================================
1571
+
1572
+ export interface DashboardStats {
1573
+ devices: {
1574
+ total: number;
1575
+ enrolled: number;
1576
+ active: number;
1577
+ blocked: number;
1578
+ pending: number;
1579
+ };
1580
+ policies: {
1581
+ total: number;
1582
+ deployed: number;
1583
+ };
1584
+ applications: {
1585
+ total: number;
1586
+ deployed: number;
1587
+ };
1588
+ commands: {
1589
+ pendingCount: number;
1590
+ last24hTotal: number;
1591
+ last24hSuccess: number;
1592
+ last24hFailed: number;
1593
+ };
1594
+ groups: {
1595
+ total: number;
1596
+ withDevices: number;
1597
+ };
1598
+ }
1599
+
1600
+ export interface DeviceStatusBreakdown {
1601
+ byStatus: Record<DeviceStatus, number>;
1602
+ byOs: Record<string, number>;
1603
+ byManufacturer: Record<string, number>;
1604
+ byModel: Record<string, number>;
1605
+ }
1606
+
1607
+ export interface EnrollmentTrendPoint {
1608
+ date: Date;
1609
+ enrolled: number;
1610
+ unenrolled: number;
1611
+ netChange: number;
1612
+ totalDevices: number;
1613
+ }
1614
+
1615
+ export interface CommandSuccessRates {
1616
+ overall: {
1617
+ total: number;
1618
+ completed: number;
1619
+ failed: number;
1620
+ successRate: number;
1621
+ };
1622
+ byType: Record<string, {
1623
+ total: number;
1624
+ completed: number;
1625
+ failed: number;
1626
+ successRate: number;
1627
+ avgExecutionTimeMs?: number;
1628
+ }>;
1629
+ last24h: {
1630
+ total: number;
1631
+ completed: number;
1632
+ failed: number;
1633
+ pending: number;
1634
+ };
1635
+ }
1636
+
1637
+ export interface AppInstallationSummary {
1638
+ total: number;
1639
+ byStatus: Record<string, number>;
1640
+ recentFailures: Array<{
1641
+ packageName: string;
1642
+ deviceId: string;
1643
+ error: string;
1644
+ timestamp: Date;
1645
+ }>;
1646
+ topInstalled: Array<{
1647
+ packageName: string;
1648
+ name: string;
1649
+ installedCount: number;
1650
+ }>;
1651
+ }
1652
+
1653
+ // ============================================
1654
+ // Plugin Storage Types
1655
+ // ============================================
1656
+
1657
+ export interface PluginStorageAdapter {
1658
+ get<T>(pluginName: string, key: string): Promise<T | null>;
1659
+ set<T>(pluginName: string, key: string, value: T): Promise<void>;
1660
+ delete(pluginName: string, key: string): Promise<void>;
1661
+ list(pluginName: string, prefix?: string): Promise<string[]>;
1662
+ clear(pluginName: string): Promise<void>;
1663
+ }
1664
+
1665
+ export interface PluginStorageEntry {
1666
+ pluginName: string;
1667
+ key: string;
1668
+ value: unknown;
1669
+ createdAt: Date;
1670
+ updatedAt: Date;
1671
+ }
1672
+
1673
+ // ============================================
1674
+ // Enterprise Manager Interfaces
1675
+ // ============================================
1676
+
1677
+ export interface TenantManager {
1678
+ get(id: string): Promise<Tenant | null>;
1679
+ getBySlug(slug: string): Promise<Tenant | null>;
1680
+ list(filter?: TenantFilter): Promise<TenantListResult>;
1681
+ create(data: CreateTenantInput): Promise<Tenant>;
1682
+ update(id: string, data: UpdateTenantInput): Promise<Tenant>;
1683
+ delete(id: string, cascade?: boolean): Promise<void>;
1684
+ getStats(tenantId: string): Promise<TenantStats>;
1685
+ activate(id: string): Promise<Tenant>;
1686
+ deactivate(id: string): Promise<Tenant>;
1687
+ }
1688
+
1689
+ export interface AuthorizationManager {
1690
+ createRole(data: CreateRoleInput): Promise<Role>;
1691
+ getRole(id: string): Promise<Role | null>;
1692
+ listRoles(tenantId?: string): Promise<Role[]>;
1693
+ updateRole(id: string, data: UpdateRoleInput): Promise<Role>;
1694
+ deleteRole(id: string): Promise<void>;
1695
+ createUser(data: CreateUserInput): Promise<User>;
1696
+ getUser(id: string): Promise<UserWithRoles | null>;
1697
+ getUserByEmail(email: string, tenantId?: string): Promise<UserWithRoles | null>;
1698
+ listUsers(filter?: UserFilter): Promise<UserListResult>;
1699
+ updateUser(id: string, data: UpdateUserInput): Promise<User>;
1700
+ deleteUser(id: string): Promise<void>;
1701
+ assignRole(userId: string, roleId: string): Promise<void>;
1702
+ removeRole(userId: string, roleId: string): Promise<void>;
1703
+ getUserRoles(userId: string): Promise<Role[]>;
1704
+ can(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<boolean>;
1705
+ canAny(userId: string, permissions: Array<{ action: PermissionAction; resource: PermissionResource }>): Promise<boolean>;
1706
+ requirePermission(userId: string, action: PermissionAction, resource: PermissionResource, resourceId?: string): Promise<void>;
1707
+ isAdmin(userId: string): Promise<boolean>;
1708
+ }
1709
+
1710
+ export interface AuditManager {
1711
+ log(entry: CreateAuditLogInput): Promise<AuditLog>;
1712
+ list(filter?: AuditLogFilter): Promise<AuditLogListResult>;
1713
+ getByResource(resource: string, resourceId: string): Promise<AuditLog[]>;
1714
+ getByUser(userId: string, filter?: AuditLogFilter): Promise<AuditLogListResult>;
1715
+ export(filter: AuditLogFilter, format: 'json' | 'csv'): Promise<string>;
1716
+ purge(olderThanDays?: number): Promise<number>;
1717
+ getSummary(tenantId?: string, days?: number): Promise<AuditSummary>;
1718
+ }
1719
+
1720
+ export interface ScheduleManager {
1721
+ get(id: string): Promise<ScheduledTask | null>;
1722
+ list(filter?: ScheduledTaskFilter): Promise<ScheduledTaskListResult>;
1723
+ create(data: CreateScheduledTaskInput): Promise<ScheduledTask>;
1724
+ update(id: string, data: UpdateScheduledTaskInput): Promise<ScheduledTask>;
1725
+ delete(id: string): Promise<void>;
1726
+ pause(id: string): Promise<ScheduledTask>;
1727
+ resume(id: string): Promise<ScheduledTask>;
1728
+ runNow(id: string): Promise<TaskExecution>;
1729
+ getUpcoming(hours: number): Promise<ScheduledTask[]>;
1730
+ getExecutions(taskId: string, limit?: number): Promise<TaskExecution[]>;
1731
+ calculateNextRun(schedule: TaskSchedule): Date | null;
1732
+ }
1733
+
1734
+ export interface MessageQueueManager {
1735
+ enqueue(message: EnqueueMessageInput): Promise<QueuedMessage>;
1736
+ enqueueBatch(messages: EnqueueMessageInput[]): Promise<QueuedMessage[]>;
1737
+ dequeue(deviceId: string, limit?: number): Promise<QueuedMessage[]>;
1738
+ acknowledge(messageId: string): Promise<void>;
1739
+ fail(messageId: string, error: string): Promise<void>;
1740
+ retryFailed(maxAttempts?: number): Promise<number>;
1741
+ purgeExpired(): Promise<number>;
1742
+ getStats(tenantId?: string): Promise<QueueStats>;
1743
+ peek(deviceId: string, limit?: number): Promise<QueuedMessage[]>;
1744
+ }
1745
+
1746
+ export interface DashboardManager {
1747
+ getStats(tenantId?: string): Promise<DashboardStats>;
1748
+ getDeviceStatusBreakdown(tenantId?: string): Promise<DeviceStatusBreakdown>;
1749
+ getEnrollmentTrend(days: number, tenantId?: string): Promise<EnrollmentTrendPoint[]>;
1750
+ getCommandSuccessRates(tenantId?: string): Promise<CommandSuccessRates>;
1751
+ getAppInstallationSummary(tenantId?: string): Promise<AppInstallationSummary>;
1068
1752
  }
1069
1753
 
1070
1754
  // ============================================
@@ -1136,6 +1820,30 @@ export class ApplicationNotFoundError extends MDMError {
1136
1820
  }
1137
1821
  }
1138
1822
 
1823
+ export class TenantNotFoundError extends MDMError {
1824
+ constructor(identifier: string) {
1825
+ super(`Tenant not found: ${identifier}`, 'TENANT_NOT_FOUND', 404);
1826
+ }
1827
+ }
1828
+
1829
+ export class RoleNotFoundError extends MDMError {
1830
+ constructor(identifier: string) {
1831
+ super(`Role not found: ${identifier}`, 'ROLE_NOT_FOUND', 404);
1832
+ }
1833
+ }
1834
+
1835
+ export class GroupNotFoundError extends MDMError {
1836
+ constructor(identifier: string) {
1837
+ super(`Group not found: ${identifier}`, 'GROUP_NOT_FOUND', 404);
1838
+ }
1839
+ }
1840
+
1841
+ export class UserNotFoundError extends MDMError {
1842
+ constructor(identifier: string) {
1843
+ super(`User not found: ${identifier}`, 'USER_NOT_FOUND', 404);
1844
+ }
1845
+ }
1846
+
1139
1847
  export class EnrollmentError extends MDMError {
1140
1848
  constructor(message: string, details?: unknown) {
1141
1849
  super(message, 'ENROLLMENT_ERROR', 400, details);