@serve.zone/dcrouter 11.23.4 → 12.0.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.
Files changed (119) hide show
  1. package/dist_serve/bundle.js +1 -1
  2. package/dist_ts/00_commitinfo_data.js +2 -2
  3. package/dist_ts/classes.cert-provision-scheduler.d.ts +6 -8
  4. package/dist_ts/classes.cert-provision-scheduler.js +37 -17
  5. package/dist_ts/classes.dcrouter.d.ts +15 -29
  6. package/dist_ts/classes.dcrouter.js +96 -91
  7. package/dist_ts/classes.storage-cert-manager.d.ts +3 -6
  8. package/dist_ts/classes.storage-cert-manager.js +35 -25
  9. package/dist_ts/config/classes.api-token-manager.d.ts +1 -3
  10. package/dist_ts/config/classes.api-token-manager.js +45 -15
  11. package/dist_ts/config/classes.route-config-manager.d.ts +1 -3
  12. package/dist_ts/config/classes.route-config-manager.js +63 -25
  13. package/dist_ts/{cache → db}/classes.cache.cleaner.d.ts +3 -3
  14. package/dist_ts/db/classes.cache.cleaner.js +130 -0
  15. package/dist_ts/{cache → db}/classes.cached.document.js +1 -1
  16. package/dist_ts/db/classes.dcrouter-db.d.ts +70 -0
  17. package/dist_ts/db/classes.dcrouter-db.js +146 -0
  18. package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +32 -0
  19. package/dist_ts/db/documents/classes.accounting-session.doc.js +214 -0
  20. package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +13 -0
  21. package/dist_ts/db/documents/classes.acme-cert.doc.js +109 -0
  22. package/dist_ts/db/documents/classes.api-token.doc.d.ts +18 -0
  23. package/dist_ts/db/documents/classes.api-token.doc.js +127 -0
  24. package/dist_ts/{cache → db}/documents/classes.cached.email.js +3 -3
  25. package/dist_ts/{cache → db}/documents/classes.cached.ip.reputation.js +3 -3
  26. package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +11 -0
  27. package/dist_ts/db/documents/classes.cert-backoff.doc.js +97 -0
  28. package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +12 -0
  29. package/dist_ts/db/documents/classes.proxy-cert.doc.js +103 -0
  30. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +17 -0
  31. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +130 -0
  32. package/dist_ts/db/documents/classes.route-override.doc.d.ts +10 -0
  33. package/dist_ts/db/documents/classes.route-override.doc.js +91 -0
  34. package/dist_ts/db/documents/classes.stored-route.doc.d.ts +12 -0
  35. package/dist_ts/db/documents/classes.stored-route.doc.js +103 -0
  36. package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +15 -0
  37. package/dist_ts/db/documents/classes.vlan-mappings.doc.js +77 -0
  38. package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +18 -0
  39. package/dist_ts/db/documents/classes.vpn-client.doc.js +136 -0
  40. package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +10 -0
  41. package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +94 -0
  42. package/dist_ts/db/documents/index.d.ts +13 -0
  43. package/dist_ts/db/documents/index.js +20 -0
  44. package/dist_ts/{cache → db}/index.d.ts +1 -1
  45. package/dist_ts/db/index.js +9 -0
  46. package/dist_ts/opsserver/handlers/certificate.handler.js +66 -66
  47. package/dist_ts/opsserver/handlers/config.handler.js +14 -15
  48. package/dist_ts/paths.d.ts +0 -1
  49. package/dist_ts/paths.js +1 -2
  50. package/dist_ts/radius/classes.accounting.manager.d.ts +4 -12
  51. package/dist_ts/radius/classes.accounting.manager.js +80 -93
  52. package/dist_ts/radius/classes.radius.server.d.ts +1 -3
  53. package/dist_ts/radius/classes.radius.server.js +4 -6
  54. package/dist_ts/radius/classes.vlan.manager.d.ts +3 -7
  55. package/dist_ts/radius/classes.vlan.manager.js +21 -28
  56. package/dist_ts/radius/index.d.ts +1 -1
  57. package/dist_ts/radius/index.js +1 -1
  58. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +3 -5
  59. package/dist_ts/remoteingress/classes.remoteingress-manager.js +41 -21
  60. package/dist_ts/security/classes.ipreputationchecker.d.ts +6 -21
  61. package/dist_ts/security/classes.ipreputationchecker.js +59 -138
  62. package/dist_ts/vpn/classes.vpn-manager.d.ts +4 -22
  63. package/dist_ts/vpn/classes.vpn-manager.js +40 -45
  64. package/dist_ts_oci_container/index.js +4 -4
  65. package/dist_ts_web/00_commitinfo_data.js +2 -2
  66. package/package.json +1 -1
  67. package/readme.storage.md +55 -91
  68. package/ts/00_commitinfo_data.ts +1 -1
  69. package/ts/classes.cert-provision-scheduler.ts +35 -17
  70. package/ts/classes.dcrouter.ts +113 -125
  71. package/ts/classes.storage-cert-manager.ts +34 -22
  72. package/ts/config/classes.api-token-manager.ts +42 -11
  73. package/ts/config/classes.route-config-manager.ts +57 -22
  74. package/ts/{cache → db}/classes.cache.cleaner.ts +6 -6
  75. package/ts/db/classes.dcrouter-db.ts +179 -0
  76. package/ts/db/documents/classes.accounting-session.doc.ts +106 -0
  77. package/ts/db/documents/classes.acme-cert.doc.ts +41 -0
  78. package/ts/db/documents/classes.api-token.doc.ts +56 -0
  79. package/ts/{cache → db}/documents/classes.cached.email.ts +2 -2
  80. package/ts/{cache → db}/documents/classes.cached.ip.reputation.ts +2 -2
  81. package/ts/db/documents/classes.cert-backoff.doc.ts +35 -0
  82. package/ts/db/documents/classes.proxy-cert.doc.ts +38 -0
  83. package/ts/db/documents/classes.remote-ingress-edge.doc.ts +54 -0
  84. package/ts/db/documents/classes.route-override.doc.ts +32 -0
  85. package/ts/db/documents/classes.stored-route.doc.ts +38 -0
  86. package/ts/db/documents/classes.vlan-mappings.doc.ts +32 -0
  87. package/ts/db/documents/classes.vpn-client.doc.ts +57 -0
  88. package/ts/db/documents/classes.vpn-server-keys.doc.ts +31 -0
  89. package/ts/db/documents/index.ts +24 -0
  90. package/ts/{cache → db}/index.ts +6 -2
  91. package/ts/opsserver/handlers/certificate.handler.ts +67 -65
  92. package/ts/opsserver/handlers/config.handler.ts +13 -14
  93. package/ts/paths.ts +0 -1
  94. package/ts/radius/classes.accounting.manager.ts +81 -103
  95. package/ts/radius/classes.radius.server.ts +3 -6
  96. package/ts/radius/classes.vlan.manager.ts +20 -32
  97. package/ts/radius/index.ts +1 -1
  98. package/ts/remoteingress/classes.remoteingress-manager.ts +40 -22
  99. package/ts/security/classes.ipreputationchecker.ts +103 -196
  100. package/ts/vpn/classes.vpn-manager.ts +44 -75
  101. package/ts_web/00_commitinfo_data.ts +1 -1
  102. package/dist_ts/cache/classes.cache.cleaner.js +0 -130
  103. package/dist_ts/cache/classes.cachedb.d.ts +0 -60
  104. package/dist_ts/cache/classes.cachedb.js +0 -126
  105. package/dist_ts/cache/documents/index.d.ts +0 -2
  106. package/dist_ts/cache/documents/index.js +0 -3
  107. package/dist_ts/cache/index.js +0 -7
  108. package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
  109. package/dist_ts/storage/classes.storagemanager.js +0 -348
  110. package/dist_ts/storage/index.d.ts +0 -1
  111. package/dist_ts/storage/index.js +0 -3
  112. package/ts/cache/classes.cachedb.ts +0 -155
  113. package/ts/cache/documents/index.ts +0 -2
  114. package/ts/storage/classes.storagemanager.ts +0 -404
  115. package/ts/storage/index.ts +0 -2
  116. /package/dist_ts/{cache → db}/classes.cached.document.d.ts +0 -0
  117. /package/dist_ts/{cache → db}/documents/classes.cached.email.d.ts +0 -0
  118. /package/dist_ts/{cache → db}/documents/classes.cached.ip.reputation.d.ts +0 -0
  119. /package/ts/{cache → db}/classes.cached.document.ts +0 -0
@@ -76,11 +76,11 @@ export function getOciContainerConfig() {
76
76
  routes: options.emailConfig?.routes || [],
77
77
  };
78
78
  }
79
- // Cache config
79
+ // DB config
80
80
  const cacheEnabled = process.env.DCROUTER_CACHE_ENABLED;
81
81
  if (cacheEnabled !== undefined) {
82
- options.cacheConfig = {
83
- ...options.cacheConfig,
82
+ options.dbConfig = {
83
+ ...options.dbConfig,
84
84
  enabled: cacheEnabled === 'true',
85
85
  };
86
86
  }
@@ -107,4 +107,4 @@ export function getOciContainerConfig() {
107
107
  }
108
108
  return options;
109
109
  }
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19vY2lfY29udGFpbmVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBMEI7SUFDckQsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUywwQkFBMEIsQ0FBQyxNQUEwQjtJQUM1RCxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLElBQUksT0FBTyxHQUFxQixFQUFFLENBQUM7SUFFbkMscUNBQXFDO0lBQ3JDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFDcEQsSUFBSSxVQUFVLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFV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
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19vY2lfY29udGFpbmVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBMEI7SUFDckQsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUywwQkFBMEIsQ0FBQyxNQUEwQjtJQUM1RCxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLElBQUksT0FBTyxHQUFxQixFQUFFLENBQUM7SUFFbkMscUNBQXFDO0lBQ3JDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFDcEQsSUFBSSxVQUFVLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFV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
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '11.23.4',
6
+ version: '12.0.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@serve.zone/dcrouter",
3
3
  "private": false,
4
- "version": "11.23.4",
4
+ "version": "12.0.0",
5
5
  "description": "A multifaceted routing service handling mail and SMS delivery functions.",
6
6
  "type": "module",
7
7
  "exports": {
package/readme.storage.md CHANGED
@@ -1,120 +1,84 @@
1
1
  # DCRouter Storage Overview
2
2
 
3
- DCRouter uses two complementary storage systems: **StorageManager** for configuration and state, and **CacheDb** for time-limited cached data.
3
+ DCRouter uses a **unified database layer** backed by `@push.rocks/smartdata` for all persistent data. All data is stored as typed document classes in a single database.
4
4
 
5
- ## StorageManager (Key-Value Store)
5
+ ## Database Modes
6
6
 
7
- A lightweight, pluggable key-value store for configuration, credentials, and runtime state. Data is persisted as flat JSON files on disk by default.
8
-
9
- ### Default Path
7
+ ### Embedded Mode (default)
8
+ When no external MongoDB URL is provided, DCRouter starts an embedded `LocalSmartDb` (Rust-based MongoDB-compatible engine) via `@push.rocks/smartdb`.
10
9
 
11
10
  ```
12
- ~/.serve.zone/dcrouter/storage/
11
+ ~/.serve.zone/dcrouter/tsmdb/
13
12
  ```
14
13
 
15
- Configurable via `options.storage.fsPath` or `options.baseDir`.
16
-
17
- ### Backends
14
+ ### External Mode
15
+ Connect to any MongoDB-compatible database by providing a connection URL.
18
16
 
19
17
  ```typescript
20
- // Filesystem (default)
21
- storage: { fsPath: '/var/lib/dcrouter/data' }
22
-
23
- // Custom (Redis, S3, etc.)
24
- storage: {
25
- readFunction: async (key) => await redis.get(key),
26
- writeFunction: async (key, value) => await redis.set(key, value),
18
+ dbConfig: {
19
+ mongoDbUrl: 'mongodb://host:27017',
20
+ dbName: 'dcrouter',
27
21
  }
28
-
29
- // In-memory (omit storage config — data lost on restart)
30
22
  ```
31
23
 
32
- ### What's Stored
33
-
34
- | Prefix | Contents | Managed By |
35
- |--------|----------|------------|
36
- | `/vpn/server-keys` | VPN server Noise + WireGuard keypairs | `VpnManager` |
37
- | `/vpn/clients/{clientId}` | VPN client registrations (keys, tags, description, assigned IP) | `VpnManager` |
38
- | `/config-api/routes/{uuid}.json` | Programmatic routes (created via OpsServer API) | `RouteConfigManager` |
39
- | `/config-api/tokens/{uuid}.json` | API tokens (hashed secrets, scopes, expiry) | `ApiTokenManager` |
40
- | `/config-api/overrides/{routeName}.json` | Hardcoded route overrides (enable/disable) | `RouteConfigManager` |
41
- | `/email/bounces/suppression-list.json` | Email bounce suppression list | `smartmta` |
42
- | `/certs/*` | TLS certificates and ACME state | `SmartAcme` (via `StorageBackedCertManager`) |
43
-
44
- ### API
24
+ ## Configuration
45
25
 
46
26
  ```typescript
47
- // Read/write JSON
48
- await storageManager.getJSON<T>(key);
49
- await storageManager.setJSON(key, value);
50
-
51
- // Raw string read/write
52
- await storageManager.get(key);
53
- await storageManager.set(key, value);
54
-
55
- // List keys by prefix
56
- await storageManager.list('/vpn/clients/');
57
-
58
- // Delete
59
- await storageManager.delete(key);
60
- ```
61
-
62
- ## CacheDb (Embedded MongoDB)
63
-
64
- An embedded MongoDB-compatible database (via `@push.rocks/smartdb` + `@push.rocks/smartdata`) for cached data with automatic TTL-based cleanup.
65
-
66
- ### Default Path
67
-
68
- ```
69
- ~/.serve.zone/dcrouter/tsmdb/
27
+ dbConfig: {
28
+ enabled: true, // default: true
29
+ mongoDbUrl: undefined, // default: embedded LocalSmartDb
30
+ storagePath: '~/.serve.zone/dcrouter/tsmdb', // default (embedded mode only)
31
+ dbName: 'dcrouter', // default
32
+ cleanupIntervalHours: 1, // TTL cleanup interval
33
+ }
70
34
  ```
71
35
 
72
- Configurable via `options.cacheConfig.storagePath`.
36
+ ## Document Classes
73
37
 
74
- ### What's Cached
38
+ All data is stored as smartdata document classes in `ts/db/documents/`.
75
39
 
76
- | Document Type | Default TTL | Purpose |
77
- |--------------|-------------|---------|
78
- | `CachedEmail` | 30 days | Email metadata cache for dashboard display |
79
- | `CachedIPReputation` | 1 day | IP reputation lookup results (DNSBL checks) |
40
+ | Document Class | Collection | Unique Key | Purpose |
41
+ |---|---|---|---|
42
+ | `StoredRouteDoc` | storedRoutes | `id` | Programmatic routes (created via API) |
43
+ | `RouteOverrideDoc` | routeOverrides | `routeName` | Hardcoded route enable/disable overrides |
44
+ | `ApiTokenDoc` | apiTokens | `id` | API tokens (hashed secrets, scopes, expiry) |
45
+ | `VpnServerKeysDoc` | vpnServerKeys | `configId` (singleton) | VPN server Noise + WireGuard keypairs |
46
+ | `VpnClientDoc` | vpnClients | `clientId` | VPN client registrations |
47
+ | `AcmeCertDoc` | acmeCerts | `domainName` | ACME certificates and keys |
48
+ | `ProxyCertDoc` | proxyCerts | `domain` | SmartProxy TLS certificates |
49
+ | `CertBackoffDoc` | certBackoff | `domain` | Per-domain cert provision backoff state |
50
+ | `RemoteIngressEdgeDoc` | remoteIngressEdges | `id` | Edge node registrations |
51
+ | `VlanMappingsDoc` | vlanMappings | `configId` (singleton) | MAC-to-VLAN mapping table |
52
+ | `AccountingSessionDoc` | accountingSessions | `sessionId` | RADIUS accounting sessions |
53
+ | `CachedEmail` | cachedEmails | `id` | Email metadata (TTL: 30 days) |
54
+ | `CachedIPReputation` | cachedIPReputation | `ipAddress` | IP reputation results (TTL: 24 hours) |
80
55
 
81
- ### Configuration
56
+ ## Architecture
82
57
 
83
- ```typescript
84
- cacheConfig: {
85
- enabled: true, // default: true
86
- storagePath: '~/.serve.zone/dcrouter/tsmdb', // default
87
- dbName: 'dcrouter', // default
88
- cleanupIntervalHours: 1, // how often to purge expired records
89
- ttlConfig: {
90
- emails: 30, // days
91
- ipReputation: 1, // days
92
- bounces: 30, // days (reserved)
93
- dkimKeys: 90, // days (reserved)
94
- suppression: 30, // days (reserved)
95
- },
96
- }
58
+ ```
59
+ DcRouterDb (singleton)
60
+ ├── LocalSmartDb (embedded, Rust) ─── or ─── External MongoDB
61
+ └── SmartdataDb (ORM)
62
+ └── @Collection(() => getDb())
63
+ ├── StoredRouteDoc
64
+ ├── RouteOverrideDoc
65
+ ├── ApiTokenDoc
66
+ ├── VpnServerKeysDoc / VpnClientDoc
67
+ ├── AcmeCertDoc / ProxyCertDoc / CertBackoffDoc
68
+ ├── RemoteIngressEdgeDoc
69
+ ├── VlanMappingsDoc / AccountingSessionDoc
70
+ ├── CachedEmail (TTL)
71
+ └── CachedIPReputation (TTL)
97
72
  ```
98
73
 
99
- ### How It Works
74
+ ### TTL Cleanup
100
75
 
101
- 1. `CacheDb` starts a `LocalSmartDb` instance (embedded MongoDB process)
102
- 2. `smartdata` connects to it via Unix socket
103
- 3. Document classes (`CachedEmail`, `CachedIPReputation`) are decorated with `@Collection` and use `smartdata` ORM
104
- 4. `CacheCleaner` runs on a timer, purging records older than their configured TTL
76
+ `CacheCleaner` runs on a configurable interval (default: 1 hour) and removes expired documents where `expiresAt < now()`.
105
77
 
106
- ### Disabling
78
+ ## Disabling
107
79
 
108
- For development or lightweight deployments, disable the cache to avoid starting a MongoDB process:
80
+ For tests or lightweight deployments without persistence:
109
81
 
110
82
  ```typescript
111
- cacheConfig: { enabled: false }
83
+ dbConfig: { enabled: false }
112
84
  ```
113
-
114
- ## When to Use Which
115
-
116
- | Use Case | System | Why |
117
- |----------|--------|-----|
118
- | VPN keys, API tokens, routes, certs | **StorageManager** | Small JSON blobs, key-value access, no queries needed |
119
- | Email metadata, IP reputation | **CacheDb** | Time-series data, TTL expiry, potential for queries/aggregation |
120
- | Runtime state (connected clients, metrics) | **Neither** | In-memory only, rebuilt on startup |
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '11.23.4',
6
+ version: '12.0.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import { logger } from './logger.js';
2
- import type { StorageManager } from './storage/index.js';
2
+ import { CertBackoffDoc } from './db/index.js';
3
3
 
4
4
  interface IBackoffEntry {
5
5
  failures: number;
@@ -10,54 +10,68 @@ interface IBackoffEntry {
10
10
 
11
11
  /**
12
12
  * Manages certificate provisioning scheduling with:
13
- * - Per-domain exponential backoff persisted in StorageManager
13
+ * - Per-domain exponential backoff persisted via CertBackoffDoc
14
14
  *
15
15
  * Note: Serial stagger queue was removed — smartacme v9 handles
16
16
  * concurrency, per-domain dedup, and rate limiting internally.
17
17
  */
18
18
  export class CertProvisionScheduler {
19
- private storageManager: StorageManager;
20
19
  private maxBackoffHours: number;
21
20
 
22
21
  // In-memory backoff cache (mirrors storage for fast lookups)
23
22
  private backoffCache = new Map<string, IBackoffEntry>();
24
23
 
25
24
  constructor(
26
- storageManager: StorageManager,
27
25
  options?: { maxBackoffHours?: number }
28
26
  ) {
29
- this.storageManager = storageManager;
30
27
  this.maxBackoffHours = options?.maxBackoffHours ?? 24;
31
28
  }
32
29
 
33
30
  /**
34
- * Storage key for a domain's backoff entry
31
+ * Sanitized domain key for storage lookups
35
32
  */
36
- private backoffKey(domain: string): string {
37
- const clean = domain.replace(/\*/g, '_wildcard_').replace(/[^a-zA-Z0-9._-]/g, '_');
38
- return `/cert-backoff/${clean}`;
33
+ private sanitizeDomain(domain: string): string {
34
+ return domain.replace(/\*/g, '_wildcard_').replace(/[^a-zA-Z0-9._-]/g, '_');
39
35
  }
40
36
 
41
37
  /**
42
- * Load backoff entry from storage (with in-memory cache)
38
+ * Load backoff entry from database (with in-memory cache)
43
39
  */
44
40
  private async loadBackoff(domain: string): Promise<IBackoffEntry | null> {
45
41
  const cached = this.backoffCache.get(domain);
46
42
  if (cached) return cached;
47
43
 
48
- const entry = await this.storageManager.getJSON<IBackoffEntry>(this.backoffKey(domain));
49
- if (entry) {
44
+ const sanitized = this.sanitizeDomain(domain);
45
+ const doc = await CertBackoffDoc.findByDomain(sanitized);
46
+ if (doc) {
47
+ const entry: IBackoffEntry = {
48
+ failures: doc.failures,
49
+ lastFailure: doc.lastFailure,
50
+ retryAfter: doc.retryAfter,
51
+ lastError: doc.lastError,
52
+ };
50
53
  this.backoffCache.set(domain, entry);
54
+ return entry;
51
55
  }
52
- return entry;
56
+ return null;
53
57
  }
54
58
 
55
59
  /**
56
- * Save backoff entry to both cache and storage
60
+ * Save backoff entry to both cache and database
57
61
  */
58
62
  private async saveBackoff(domain: string, entry: IBackoffEntry): Promise<void> {
59
63
  this.backoffCache.set(domain, entry);
60
- await this.storageManager.setJSON(this.backoffKey(domain), entry);
64
+ const sanitized = this.sanitizeDomain(domain);
65
+ let doc = await CertBackoffDoc.findByDomain(sanitized);
66
+ if (!doc) {
67
+ doc = new CertBackoffDoc();
68
+ doc.domain = sanitized;
69
+ }
70
+ doc.failures = entry.failures;
71
+ doc.lastFailure = entry.lastFailure;
72
+ doc.retryAfter = entry.retryAfter;
73
+ doc.lastError = entry.lastError || '';
74
+ await doc.save();
61
75
  }
62
76
 
63
77
  /**
@@ -107,9 +121,13 @@ export class CertProvisionScheduler {
107
121
  async clearBackoff(domain: string): Promise<void> {
108
122
  this.backoffCache.delete(domain);
109
123
  try {
110
- await this.storageManager.delete(this.backoffKey(domain));
124
+ const sanitized = this.sanitizeDomain(domain);
125
+ const doc = await CertBackoffDoc.findByDomain(sanitized);
126
+ if (doc) {
127
+ await doc.delete();
128
+ }
111
129
  } catch {
112
- // Ignore delete errors (key may not exist)
130
+ // Ignore delete errors (doc may not exist)
113
131
  }
114
132
  }
115
133