@onlineapps/conn-orch-validator 9.0.0 → 11.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 (58) hide show
  1. package/CHANGELOG.md +546 -0
  2. package/README.md +337 -19
  3. package/docs/DESIGN.md +32 -9
  4. package/manifests/biz-service.manifest.json +56 -6
  5. package/package.json +3 -2
  6. package/src/CookbookTestRunner.js +134 -22
  7. package/src/ValidationOrchestrator.js +312 -73
  8. package/src/cli/biz-ci-gate.js +191 -15
  9. package/src/cli/oa-sync-template.js +23 -8
  10. package/src/cli/oa-validate.js +70 -2
  11. package/src/index.js +21 -13
  12. package/src/lint/scripts/lintScripts.js +65 -18
  13. package/src/manifest/checks/composeRunnerBlock.js +37 -20
  14. package/src/manifest/checks/discoveryOrphan.js +2 -1
  15. package/src/manifest/checks/docsLintBridge.js +79 -21
  16. package/src/manifest/checks/gitTracked.js +14 -28
  17. package/src/manifest/checks/libraryPackage.js +3 -1
  18. package/src/manifest/checks/libraryWorkspace.js +18 -3
  19. package/src/manifest/checks/readmeRegion.js +9 -1
  20. package/src/manifest/checks/serviceConfig.js +29 -12
  21. package/src/manifest/checks/serviceDb.js +176 -7
  22. package/src/manifest/checks/serviceFiles.js +34 -7
  23. package/src/manifest/checks/serviceIdentityRows.js +3 -1
  24. package/src/manifest/checks/serviceRuntime.js +126 -1
  25. package/src/manifest/discovery.js +25 -7
  26. package/src/manifest/gitCheckout.js +84 -0
  27. package/src/manifest/runManifest.js +58 -7
  28. package/src/manifest/workspaceRoot.js +91 -5
  29. package/src/sync/serviceTemplate.js +76 -7
  30. package/src/sync/sharedEnv.js +11 -4
  31. package/src/sync/uniformFiles.js +91 -21
  32. package/src/utils/bizCiGateContract.js +25 -1
  33. package/src/utils/dbAccountGrants.js +126 -0
  34. package/src/utils/envContract.js +36 -6
  35. package/src/utils/envReads.js +102 -0
  36. package/src/utils/installContract.js +46 -5
  37. package/src/utils/libCompat.js +39 -19
  38. package/src/utils/preValidation.js +56 -11
  39. package/src/utils/stepFailure.js +106 -19
  40. package/src/utils/stepReferences.js +278 -0
  41. package/src/utils/testCoverageContract.js +60 -2
  42. package/src/utils/throwawaySchema.js +92 -7
  43. package/src/validatorIdentity.js +31 -0
  44. package/src/validators/ServiceStructureValidator.js +47 -15
  45. package/src/validators/ValidationProofGenerator.js +73 -34
  46. package/templates/business-service/.dockerignore +9 -1
  47. package/templates/business-service/.gitlab-ci.yml +199 -35
  48. package/templates/business-service/Dockerfile +49 -16
  49. package/templates/business-service/README.md +56 -9
  50. package/templates/business-service/config/env-templates/__SERVICE_NAME__.env +17 -5
  51. package/templates/business-service/config/env-templates/shared.env +8 -2
  52. package/templates/business-service/docker-compose.production.yml +9 -0
  53. package/templates/business-service/docker-compose.yml +17 -0
  54. package/templates/business-service/docs/80-setup/PLATFORM_MATRIX.md +1 -1
  55. package/templates/business-service/docs/80-setup/VALIDATION.md +1 -1
  56. package/templates/business-service/jest.config.js +9 -1
  57. package/templates/business-service/package.json.template +1 -1
  58. package/src/mocks/MockStorage.js +0 -188
@@ -23,7 +23,7 @@ Every command runs from the repository root (`api_biz/__SERVICE_NAME__/`).
23
23
  node node_modules/@onlineapps/conn-orch-validator/src/cli/biz-ci-gate.js verify-contract
24
24
 
25
25
  # 2 — unit suite, in the one-shot runner beside the service
26
- npm run test:container
26
+ npm run test:unit:container
27
27
 
28
28
  # 3 — cookbooks, in the same runner (it has the env files)
29
29
  npm run test:cookbooks:container
@@ -1,6 +1,14 @@
1
1
  module.exports = {
2
2
  testEnvironment: 'node',
3
3
  testMatch: ['**/tests/**/*.test.js'],
4
- testTimeout: 30000,
4
+ // 120 s, because the limit is there to catch a test that HANGS and not a
5
+ // queue for the processor: on the shared dev machine (load average 47-94,
6
+ // the runners of several services at once) five integration suites failed in
7
+ // beforeAll at the previous 30 s while each of them passed when run alone,
8
+ // and the whole run passed at 180 s (BIZ-converter, d.580). The number is the
9
+ // platform's, not a service's - row F-JEST holds this file byte for byte.
10
+ testTimeout: 120000,
11
+ // One suite at a time, which is what the runner's memory norm assumes
12
+ // (api/docs/governance/confirmations/biz-memory-limits.md 001).
5
13
  maxWorkers: 1
6
14
  };
@@ -13,7 +13,7 @@
13
13
  "test:ci": "jest",
14
14
  "test:unit": "jest tests/unit",
15
15
  "test:all": "npm run test:unit",
16
- "test:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:unit",
16
+ "test:unit:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:unit",
17
17
  "test:all:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:all",
18
18
  "test:coverage": "jest --coverage",
19
19
  "test:cookbooks": "node node_modules/@onlineapps/conn-orch-validator/src/cli/biz-ci-gate.js run-prevalidation",
@@ -1,188 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * MockStorage - Simulates MinIO/S3 storage for testing
5
- */
6
- class MockStorage {
7
- constructor() {
8
- this.buckets = {};
9
- this.metadata = {};
10
- }
11
-
12
- /**
13
- * Create bucket
14
- */
15
- async createBucket(bucketName) {
16
- if (!this.buckets[bucketName]) {
17
- this.buckets[bucketName] = {};
18
- }
19
- return { success: true };
20
- }
21
-
22
- /**
23
- * Put object
24
- */
25
- async put(bucket, key, content, options = {}) {
26
- if (!this.buckets[bucket]) {
27
- await this.createBucket(bucket);
28
- }
29
-
30
- const data = typeof content === 'object' ? JSON.stringify(content) : content;
31
-
32
- this.buckets[bucket][key] = {
33
- content: data,
34
- contentType: options.contentType || 'application/json',
35
- metadata: options.metadata || {},
36
- timestamp: Date.now(),
37
- size: data.length
38
- };
39
-
40
- // Store metadata separately for querying
41
- if (!this.metadata[bucket]) {
42
- this.metadata[bucket] = {};
43
- }
44
- this.metadata[bucket][key] = {
45
- size: data.length,
46
- lastModified: Date.now(),
47
- contentType: options.contentType || 'application/json'
48
- };
49
-
50
- return {
51
- success: true,
52
- etag: `mock-etag-${Date.now()}`,
53
- location: `${bucket}/${key}`
54
- };
55
- }
56
-
57
- /**
58
- * Get object
59
- */
60
- async get(bucket, key) {
61
- if (!this.buckets[bucket] || !this.buckets[bucket][key]) {
62
- throw new Error(`[MockStorage] Object not found: ${bucket}/${key} - Expected the object to have `
63
- + 'been stored first. Fix: put(bucket, key, content) in the test setup before reading it.');
64
- }
65
-
66
- const obj = this.buckets[bucket][key];
67
- let content = obj.content;
68
-
69
- // Try to parse JSON if content type suggests it
70
- if (obj.contentType === 'application/json' && typeof content === 'string') {
71
- try {
72
- content = JSON.parse(content);
73
- } catch (e) {
74
- // Keep as string if parsing fails
75
- }
76
- }
77
-
78
- return {
79
- content,
80
- metadata: obj.metadata,
81
- contentType: obj.contentType,
82
- size: obj.size,
83
- lastModified: obj.timestamp
84
- };
85
- }
86
-
87
- /**
88
- * Delete object
89
- */
90
- async delete(bucket, key) {
91
- if (this.buckets[bucket]) {
92
- delete this.buckets[bucket][key];
93
- if (this.metadata[bucket]) {
94
- delete this.metadata[bucket][key];
95
- }
96
- }
97
- return { success: true };
98
- }
99
-
100
- /**
101
- * List objects in bucket
102
- */
103
- async list(bucket, prefix = '', limit = 1000) {
104
- if (!this.buckets[bucket]) {
105
- return { objects: [] };
106
- }
107
-
108
- const objects = Object.keys(this.buckets[bucket])
109
- .filter(key => key.startsWith(prefix))
110
- .slice(0, limit)
111
- .map(key => ({
112
- key,
113
- size: this.buckets[bucket][key].size,
114
- lastModified: this.buckets[bucket][key].timestamp
115
- }));
116
-
117
- return { objects };
118
- }
119
-
120
- /**
121
- * Check if object exists
122
- */
123
- async exists(bucket, key) {
124
- return !!(this.buckets[bucket] && this.buckets[bucket][key]);
125
- }
126
-
127
- /**
128
- * Get object metadata
129
- */
130
- async getMetadata(bucket, key) {
131
- if (!this.metadata[bucket] || !this.metadata[bucket][key]) {
132
- throw new Error(`[MockStorage] Metadata not found: ${bucket}/${key} - Expected metadata written `
133
- + 'by put(). Fix: store the object with put(bucket, key, content) before reading its metadata.');
134
- }
135
- return this.metadata[bucket][key];
136
- }
137
-
138
- /**
139
- * Generate presigned URL (mock)
140
- */
141
- async getPresignedUrl(bucket, key, expiresIn = 3600) {
142
- return {
143
- url: `http://mock-storage/${bucket}/${key}?token=mock-token-${Date.now()}`,
144
- expiresAt: Date.now() + (expiresIn * 1000)
145
- };
146
- }
147
-
148
- /**
149
- * Clear all data
150
- */
151
- clear() {
152
- this.buckets = {};
153
- this.metadata = {};
154
- }
155
-
156
- /**
157
- * Get storage stats
158
- */
159
- getStats() {
160
- const stats = {
161
- bucketCount: Object.keys(this.buckets).length,
162
- totalObjects: 0,
163
- totalSize: 0
164
- };
165
-
166
- Object.values(this.buckets).forEach(bucket => {
167
- Object.values(bucket).forEach(obj => {
168
- stats.totalObjects++;
169
- stats.totalSize += obj.size;
170
- });
171
- });
172
-
173
- return stats;
174
- }
175
-
176
- /**
177
- * Copy object
178
- */
179
- async copy(sourceBucket, sourceKey, destBucket, destKey) {
180
- const source = await this.get(sourceBucket, sourceKey);
181
- return await this.put(destBucket, destKey, source.content, {
182
- contentType: source.contentType,
183
- metadata: source.metadata
184
- });
185
- }
186
- }
187
-
188
- module.exports = MockStorage;