@avi770/testteam 1.2.0 → 2.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 (300) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/README.md +53 -6
  3. package/agents/24-signup-onboarding-tester.ts +429 -0
  4. package/agents/25-crud-flow-tester.ts +302 -0
  5. package/agents/26-form-validator.ts +297 -0
  6. package/agents/27-search-filter-tester.ts +326 -0
  7. package/agents/28-navigation-routing-tester.ts +425 -0
  8. package/agents/29-responsive-interaction-tester.ts +350 -0
  9. package/agents/30-multi-user-scenario-tester.ts +319 -0
  10. package/agents/31-load-tester.ts +134 -0
  11. package/agents/32-memory-leak-detector.ts +194 -0
  12. package/agents/33-bundle-analyzer.ts +132 -0
  13. package/agents/34-xss-scanner.ts +191 -0
  14. package/agents/35-csrf-tester.ts +82 -0
  15. package/agents/36-auth-fuzzer.ts +194 -0
  16. package/agents/37-dependency-scanner.ts +176 -0
  17. package/agents/38-secrets-scanner.ts +137 -0
  18. package/agents/39-api-contract-tester.ts +199 -0
  19. package/agents/40-rate-limit-tester.ts +94 -0
  20. package/agents/41-api-pagination-tester.ts +97 -0
  21. package/agents/42-graphql-tester.ts +222 -0
  22. package/agents/43-data-consistency-checker.ts +205 -0
  23. package/agents/44-backup-recovery-tester.ts +152 -0
  24. package/agents/45-data-privacy-scanner.ts +125 -0
  25. package/agents/46-seo-auditor.ts +294 -0
  26. package/agents/47-social-preview-tester.ts +232 -0
  27. package/agents/48-lighthouse-auditor.ts +213 -0
  28. package/agents/49-i18n-tester.ts +198 -0
  29. package/agents/50-timezone-tester.ts +173 -0
  30. package/agents/51-error-recovery-tester.ts +155 -0
  31. package/agents/52-offline-mode-tester.ts +180 -0
  32. package/agents/53-graceful-degradation-tester.ts +156 -0
  33. package/agents/54-websocket-tester.ts +151 -0
  34. package/agents/55-realtime-sync-tester.ts +194 -0
  35. package/agents/56-file-upload-tester.ts +194 -0
  36. package/agents/57-export-tester.ts +174 -0
  37. package/agents/58-payment-flow-tester.ts +183 -0
  38. package/agents/59-ssl-tls-auditor.ts +141 -0
  39. package/agents/60-dns-cdn-tester.ts +117 -0
  40. package/agents/61-docker-health-checker.ts +111 -0
  41. package/agents/62-env-config-validator.ts +152 -0
  42. package/agents/63-log-quality-auditor.ts +136 -0
  43. package/agents/64-analytics-tracker-tester.ts +165 -0
  44. package/agents/65-gdpr-compliance-tester.ts +215 -0
  45. package/agents/66-soc2-control-validator.ts +210 -0
  46. package/agents/67-wcag-aaa-tester.ts +241 -0
  47. package/agents/68-dead-code-detector.ts +135 -0
  48. package/agents/69-type-safety-auditor.ts +164 -0
  49. package/agents/70-complexity-analyzer.ts +179 -0
  50. package/agents/__tests__/24-signup-onboarding-tester.test.ts +274 -0
  51. package/agents/__tests__/25-crud-flow-tester.test.ts +322 -0
  52. package/agents/__tests__/26-form-validator.test.ts +345 -0
  53. package/agents/__tests__/27-search-filter-tester.test.ts +311 -0
  54. package/agents/__tests__/28-navigation-routing-tester.test.ts +328 -0
  55. package/agents/__tests__/29-responsive-interaction-tester.test.ts +297 -0
  56. package/agents/__tests__/30-multi-user-scenario-tester.test.ts +328 -0
  57. package/agents/__tests__/31-load-tester.test.ts +189 -0
  58. package/agents/__tests__/32-memory-leak-detector.test.ts +251 -0
  59. package/agents/__tests__/33-bundle-analyzer.test.ts +237 -0
  60. package/agents/__tests__/34-xss-scanner.test.ts +258 -0
  61. package/agents/__tests__/35-csrf-tester.test.ts +200 -0
  62. package/agents/__tests__/36-auth-fuzzer.test.ts +214 -0
  63. package/agents/__tests__/37-dependency-scanner.test.ts +266 -0
  64. package/agents/__tests__/38-secrets-scanner.test.ts +224 -0
  65. package/agents/__tests__/39-api-contract-tester.test.ts +312 -0
  66. package/agents/__tests__/40-rate-limit-tester.test.ts +192 -0
  67. package/agents/__tests__/41-api-pagination-tester.test.ts +198 -0
  68. package/agents/__tests__/42-graphql-tester.test.ts +252 -0
  69. package/agents/__tests__/43-data-consistency-checker.test.ts +232 -0
  70. package/agents/__tests__/44-backup-recovery-tester.test.ts +222 -0
  71. package/agents/__tests__/45-data-privacy-scanner.test.ts +223 -0
  72. package/agents/__tests__/46-seo-auditor.test.ts +261 -0
  73. package/agents/__tests__/47-social-preview-tester.test.ts +245 -0
  74. package/agents/__tests__/48-lighthouse-auditor.test.ts +276 -0
  75. package/agents/__tests__/49-i18n-tester.test.ts +201 -0
  76. package/agents/__tests__/50-timezone-tester.test.ts +172 -0
  77. package/agents/__tests__/51-error-recovery-tester.test.ts +162 -0
  78. package/agents/__tests__/52-offline-mode-tester.test.ts +164 -0
  79. package/agents/__tests__/53-graceful-degradation-tester.test.ts +168 -0
  80. package/agents/__tests__/54-websocket-tester.test.ts +157 -0
  81. package/agents/__tests__/55-realtime-sync-tester.test.ts +181 -0
  82. package/agents/__tests__/56-file-upload-tester.test.ts +172 -0
  83. package/agents/__tests__/57-export-tester.test.ts +169 -0
  84. package/agents/__tests__/58-payment-flow-tester.test.ts +182 -0
  85. package/agents/__tests__/59-ssl-tls-auditor.test.ts +179 -0
  86. package/agents/__tests__/60-dns-cdn-tester.test.ts +176 -0
  87. package/agents/__tests__/61-docker-health-checker.test.ts +150 -0
  88. package/agents/__tests__/62-env-config-validator.test.ts +166 -0
  89. package/agents/__tests__/63-log-quality-auditor.test.ts +175 -0
  90. package/agents/__tests__/64-analytics-tracker-tester.test.ts +158 -0
  91. package/agents/__tests__/65-gdpr-compliance-tester.test.ts +174 -0
  92. package/agents/__tests__/66-soc2-control-validator.test.ts +183 -0
  93. package/agents/__tests__/67-wcag-aaa-tester.test.ts +190 -0
  94. package/agents/__tests__/68-dead-code-detector.test.ts +174 -0
  95. package/agents/__tests__/69-type-safety-auditor.test.ts +173 -0
  96. package/agents/__tests__/70-complexity-analyzer.test.ts +177 -0
  97. package/agents/__tests__/registry.test.ts +13 -13
  98. package/agents/registry.ts +146 -5
  99. package/core/__tests__/integration.test.ts +4 -4
  100. package/core/__tests__/orchestrator.test.ts +17 -16
  101. package/core/license.ts +208 -211
  102. package/core/orchestrator.ts +6 -4
  103. package/dist/agents/24-signup-onboarding-tester.d.ts +35 -0
  104. package/dist/agents/24-signup-onboarding-tester.d.ts.map +1 -0
  105. package/dist/agents/24-signup-onboarding-tester.js +357 -0
  106. package/dist/agents/24-signup-onboarding-tester.js.map +1 -0
  107. package/dist/agents/25-crud-flow-tester.d.ts +11 -0
  108. package/dist/agents/25-crud-flow-tester.d.ts.map +1 -0
  109. package/dist/agents/25-crud-flow-tester.js +253 -0
  110. package/dist/agents/25-crud-flow-tester.js.map +1 -0
  111. package/dist/agents/26-form-validator.d.ts +12 -0
  112. package/dist/agents/26-form-validator.d.ts.map +1 -0
  113. package/dist/agents/26-form-validator.js +257 -0
  114. package/dist/agents/26-form-validator.js.map +1 -0
  115. package/dist/agents/27-search-filter-tester.d.ts +20 -0
  116. package/dist/agents/27-search-filter-tester.d.ts.map +1 -0
  117. package/dist/agents/27-search-filter-tester.js +267 -0
  118. package/dist/agents/27-search-filter-tester.js.map +1 -0
  119. package/dist/agents/28-navigation-routing-tester.d.ts +32 -0
  120. package/dist/agents/28-navigation-routing-tester.d.ts.map +1 -0
  121. package/dist/agents/28-navigation-routing-tester.js +363 -0
  122. package/dist/agents/28-navigation-routing-tester.js.map +1 -0
  123. package/dist/agents/29-responsive-interaction-tester.d.ts +26 -0
  124. package/dist/agents/29-responsive-interaction-tester.d.ts.map +1 -0
  125. package/dist/agents/29-responsive-interaction-tester.js +272 -0
  126. package/dist/agents/29-responsive-interaction-tester.js.map +1 -0
  127. package/dist/agents/30-multi-user-scenario-tester.d.ts +24 -0
  128. package/dist/agents/30-multi-user-scenario-tester.d.ts.map +1 -0
  129. package/dist/agents/30-multi-user-scenario-tester.js +254 -0
  130. package/dist/agents/30-multi-user-scenario-tester.js.map +1 -0
  131. package/dist/agents/31-load-tester.d.ts +12 -0
  132. package/dist/agents/31-load-tester.d.ts.map +1 -0
  133. package/dist/agents/31-load-tester.js +110 -0
  134. package/dist/agents/31-load-tester.js.map +1 -0
  135. package/dist/agents/32-memory-leak-detector.d.ts +12 -0
  136. package/dist/agents/32-memory-leak-detector.d.ts.map +1 -0
  137. package/dist/agents/32-memory-leak-detector.js +167 -0
  138. package/dist/agents/32-memory-leak-detector.js.map +1 -0
  139. package/dist/agents/33-bundle-analyzer.d.ts +10 -0
  140. package/dist/agents/33-bundle-analyzer.d.ts.map +1 -0
  141. package/dist/agents/33-bundle-analyzer.js +111 -0
  142. package/dist/agents/33-bundle-analyzer.js.map +1 -0
  143. package/dist/agents/34-xss-scanner.d.ts +11 -0
  144. package/dist/agents/34-xss-scanner.d.ts.map +1 -0
  145. package/dist/agents/34-xss-scanner.js +164 -0
  146. package/dist/agents/34-xss-scanner.js.map +1 -0
  147. package/dist/agents/35-csrf-tester.d.ts +11 -0
  148. package/dist/agents/35-csrf-tester.d.ts.map +1 -0
  149. package/dist/agents/35-csrf-tester.js +70 -0
  150. package/dist/agents/35-csrf-tester.js.map +1 -0
  151. package/dist/agents/36-auth-fuzzer.d.ts +13 -0
  152. package/dist/agents/36-auth-fuzzer.d.ts.map +1 -0
  153. package/dist/agents/36-auth-fuzzer.js +163 -0
  154. package/dist/agents/36-auth-fuzzer.js.map +1 -0
  155. package/dist/agents/37-dependency-scanner.d.ts +11 -0
  156. package/dist/agents/37-dependency-scanner.d.ts.map +1 -0
  157. package/dist/agents/37-dependency-scanner.js +139 -0
  158. package/dist/agents/37-dependency-scanner.js.map +1 -0
  159. package/dist/agents/38-secrets-scanner.d.ts +11 -0
  160. package/dist/agents/38-secrets-scanner.d.ts.map +1 -0
  161. package/dist/agents/38-secrets-scanner.js +116 -0
  162. package/dist/agents/38-secrets-scanner.js.map +1 -0
  163. package/dist/agents/39-api-contract-tester.d.ts +12 -0
  164. package/dist/agents/39-api-contract-tester.d.ts.map +1 -0
  165. package/dist/agents/39-api-contract-tester.js +142 -0
  166. package/dist/agents/39-api-contract-tester.js.map +1 -0
  167. package/dist/agents/40-rate-limit-tester.d.ts +12 -0
  168. package/dist/agents/40-rate-limit-tester.d.ts.map +1 -0
  169. package/dist/agents/40-rate-limit-tester.js +79 -0
  170. package/dist/agents/40-rate-limit-tester.js.map +1 -0
  171. package/dist/agents/41-api-pagination-tester.d.ts +12 -0
  172. package/dist/agents/41-api-pagination-tester.d.ts.map +1 -0
  173. package/dist/agents/41-api-pagination-tester.js +79 -0
  174. package/dist/agents/41-api-pagination-tester.js.map +1 -0
  175. package/dist/agents/42-graphql-tester.d.ts +13 -0
  176. package/dist/agents/42-graphql-tester.d.ts.map +1 -0
  177. package/dist/agents/42-graphql-tester.js +187 -0
  178. package/dist/agents/42-graphql-tester.js.map +1 -0
  179. package/dist/agents/43-data-consistency-checker.d.ts +11 -0
  180. package/dist/agents/43-data-consistency-checker.d.ts.map +1 -0
  181. package/dist/agents/43-data-consistency-checker.js +176 -0
  182. package/dist/agents/43-data-consistency-checker.js.map +1 -0
  183. package/dist/agents/44-backup-recovery-tester.d.ts +11 -0
  184. package/dist/agents/44-backup-recovery-tester.d.ts.map +1 -0
  185. package/dist/agents/44-backup-recovery-tester.js +128 -0
  186. package/dist/agents/44-backup-recovery-tester.js.map +1 -0
  187. package/dist/agents/45-data-privacy-scanner.d.ts +11 -0
  188. package/dist/agents/45-data-privacy-scanner.d.ts.map +1 -0
  189. package/dist/agents/45-data-privacy-scanner.js +100 -0
  190. package/dist/agents/45-data-privacy-scanner.js.map +1 -0
  191. package/dist/agents/46-seo-auditor.d.ts +12 -0
  192. package/dist/agents/46-seo-auditor.d.ts.map +1 -0
  193. package/dist/agents/46-seo-auditor.js +275 -0
  194. package/dist/agents/46-seo-auditor.js.map +1 -0
  195. package/dist/agents/47-social-preview-tester.d.ts +11 -0
  196. package/dist/agents/47-social-preview-tester.d.ts.map +1 -0
  197. package/dist/agents/47-social-preview-tester.js +219 -0
  198. package/dist/agents/47-social-preview-tester.js.map +1 -0
  199. package/dist/agents/48-lighthouse-auditor.d.ts +11 -0
  200. package/dist/agents/48-lighthouse-auditor.d.ts.map +1 -0
  201. package/dist/agents/48-lighthouse-auditor.js +192 -0
  202. package/dist/agents/48-lighthouse-auditor.js.map +1 -0
  203. package/dist/agents/49-i18n-tester.d.ts +13 -0
  204. package/dist/agents/49-i18n-tester.d.ts.map +1 -0
  205. package/dist/agents/49-i18n-tester.js +172 -0
  206. package/dist/agents/49-i18n-tester.js.map +1 -0
  207. package/dist/agents/50-timezone-tester.d.ts +11 -0
  208. package/dist/agents/50-timezone-tester.d.ts.map +1 -0
  209. package/dist/agents/50-timezone-tester.js +152 -0
  210. package/dist/agents/50-timezone-tester.js.map +1 -0
  211. package/dist/agents/51-error-recovery-tester.d.ts +11 -0
  212. package/dist/agents/51-error-recovery-tester.d.ts.map +1 -0
  213. package/dist/agents/51-error-recovery-tester.js +134 -0
  214. package/dist/agents/51-error-recovery-tester.js.map +1 -0
  215. package/dist/agents/52-offline-mode-tester.d.ts +12 -0
  216. package/dist/agents/52-offline-mode-tester.d.ts.map +1 -0
  217. package/dist/agents/52-offline-mode-tester.js +161 -0
  218. package/dist/agents/52-offline-mode-tester.js.map +1 -0
  219. package/dist/agents/53-graceful-degradation-tester.d.ts +12 -0
  220. package/dist/agents/53-graceful-degradation-tester.d.ts.map +1 -0
  221. package/dist/agents/53-graceful-degradation-tester.js +130 -0
  222. package/dist/agents/53-graceful-degradation-tester.js.map +1 -0
  223. package/dist/agents/54-websocket-tester.d.ts +10 -0
  224. package/dist/agents/54-websocket-tester.d.ts.map +1 -0
  225. package/dist/agents/54-websocket-tester.js +132 -0
  226. package/dist/agents/54-websocket-tester.js.map +1 -0
  227. package/dist/agents/55-realtime-sync-tester.d.ts +11 -0
  228. package/dist/agents/55-realtime-sync-tester.d.ts.map +1 -0
  229. package/dist/agents/55-realtime-sync-tester.js +175 -0
  230. package/dist/agents/55-realtime-sync-tester.js.map +1 -0
  231. package/dist/agents/56-file-upload-tester.d.ts +12 -0
  232. package/dist/agents/56-file-upload-tester.d.ts.map +1 -0
  233. package/dist/agents/56-file-upload-tester.js +166 -0
  234. package/dist/agents/56-file-upload-tester.js.map +1 -0
  235. package/dist/agents/57-export-tester.d.ts +11 -0
  236. package/dist/agents/57-export-tester.d.ts.map +1 -0
  237. package/dist/agents/57-export-tester.js +155 -0
  238. package/dist/agents/57-export-tester.js.map +1 -0
  239. package/dist/agents/58-payment-flow-tester.d.ts +11 -0
  240. package/dist/agents/58-payment-flow-tester.d.ts.map +1 -0
  241. package/dist/agents/58-payment-flow-tester.js +159 -0
  242. package/dist/agents/58-payment-flow-tester.js.map +1 -0
  243. package/dist/agents/59-ssl-tls-auditor.d.ts +10 -0
  244. package/dist/agents/59-ssl-tls-auditor.d.ts.map +1 -0
  245. package/dist/agents/59-ssl-tls-auditor.js +132 -0
  246. package/dist/agents/59-ssl-tls-auditor.js.map +1 -0
  247. package/dist/agents/60-dns-cdn-tester.d.ts +10 -0
  248. package/dist/agents/60-dns-cdn-tester.d.ts.map +1 -0
  249. package/dist/agents/60-dns-cdn-tester.js +105 -0
  250. package/dist/agents/60-dns-cdn-tester.js.map +1 -0
  251. package/dist/agents/61-docker-health-checker.d.ts +10 -0
  252. package/dist/agents/61-docker-health-checker.d.ts.map +1 -0
  253. package/dist/agents/61-docker-health-checker.js +95 -0
  254. package/dist/agents/61-docker-health-checker.js.map +1 -0
  255. package/dist/agents/62-env-config-validator.d.ts +10 -0
  256. package/dist/agents/62-env-config-validator.d.ts.map +1 -0
  257. package/dist/agents/62-env-config-validator.js +132 -0
  258. package/dist/agents/62-env-config-validator.js.map +1 -0
  259. package/dist/agents/63-log-quality-auditor.d.ts +9 -0
  260. package/dist/agents/63-log-quality-auditor.d.ts.map +1 -0
  261. package/dist/agents/63-log-quality-auditor.js +121 -0
  262. package/dist/agents/63-log-quality-auditor.js.map +1 -0
  263. package/dist/agents/64-analytics-tracker-tester.d.ts +10 -0
  264. package/dist/agents/64-analytics-tracker-tester.d.ts.map +1 -0
  265. package/dist/agents/64-analytics-tracker-tester.js +146 -0
  266. package/dist/agents/64-analytics-tracker-tester.js.map +1 -0
  267. package/dist/agents/65-gdpr-compliance-tester.d.ts +13 -0
  268. package/dist/agents/65-gdpr-compliance-tester.d.ts.map +1 -0
  269. package/dist/agents/65-gdpr-compliance-tester.js +186 -0
  270. package/dist/agents/65-gdpr-compliance-tester.js.map +1 -0
  271. package/dist/agents/66-soc2-control-validator.d.ts +14 -0
  272. package/dist/agents/66-soc2-control-validator.d.ts.map +1 -0
  273. package/dist/agents/66-soc2-control-validator.js +178 -0
  274. package/dist/agents/66-soc2-control-validator.js.map +1 -0
  275. package/dist/agents/67-wcag-aaa-tester.d.ts +13 -0
  276. package/dist/agents/67-wcag-aaa-tester.d.ts.map +1 -0
  277. package/dist/agents/67-wcag-aaa-tester.js +207 -0
  278. package/dist/agents/67-wcag-aaa-tester.js.map +1 -0
  279. package/dist/agents/68-dead-code-detector.d.ts +9 -0
  280. package/dist/agents/68-dead-code-detector.d.ts.map +1 -0
  281. package/dist/agents/68-dead-code-detector.js +116 -0
  282. package/dist/agents/68-dead-code-detector.js.map +1 -0
  283. package/dist/agents/69-type-safety-auditor.d.ts +9 -0
  284. package/dist/agents/69-type-safety-auditor.d.ts.map +1 -0
  285. package/dist/agents/69-type-safety-auditor.js +148 -0
  286. package/dist/agents/69-type-safety-auditor.js.map +1 -0
  287. package/dist/agents/70-complexity-analyzer.d.ts +10 -0
  288. package/dist/agents/70-complexity-analyzer.d.ts.map +1 -0
  289. package/dist/agents/70-complexity-analyzer.js +154 -0
  290. package/dist/agents/70-complexity-analyzer.js.map +1 -0
  291. package/dist/agents/registry.d.ts +3 -3
  292. package/dist/agents/registry.d.ts.map +1 -1
  293. package/dist/agents/registry.js +146 -5
  294. package/dist/agents/registry.js.map +1 -1
  295. package/dist/core/license.js +2 -5
  296. package/dist/core/license.js.map +1 -1
  297. package/dist/core/orchestrator.d.ts.map +1 -1
  298. package/dist/core/orchestrator.js +6 -4
  299. package/dist/core/orchestrator.js.map +1 -1
  300. package/package.json +2 -2
@@ -0,0 +1,205 @@
1
+ import type { Finding } from '../core/types';
2
+ import { BaseAgent } from './base-agent';
3
+ import { resolveEnvironment } from '../helpers/env-resolver';
4
+ import { ApiClient } from '../helpers/api-client';
5
+
6
+ const REQUEST_TIMEOUT_MS = 10_000;
7
+
8
+ export class DataConsistencyCheckerAgent extends BaseAgent {
9
+ readonly agentId = 43;
10
+ readonly agentName = 'Data Consistency Checker';
11
+ private baseUrl = '';
12
+
13
+ protected async preFlight(): Promise<void> {
14
+ const { env } = await resolveEnvironment(this.config, this.phase);
15
+ this.baseUrl = env.baseUrl;
16
+ }
17
+
18
+ protected async execute(): Promise<Finding[]> {
19
+ const findings: Finding[] = [];
20
+ const credentials =
21
+ this.config.auth.credentials?.['admin'] ??
22
+ Object.values(this.config.auth.credentials ?? {})[0];
23
+
24
+ let client: ApiClient;
25
+
26
+ if (credentials) {
27
+ try {
28
+ client = await Promise.race([
29
+ ApiClient.createAuthenticated(this.baseUrl, credentials),
30
+ new Promise<never>((_, reject) =>
31
+ setTimeout(() => reject(new Error('Auth timeout')), REQUEST_TIMEOUT_MS),
32
+ ),
33
+ ]);
34
+ } catch (authError) {
35
+ findings.push({
36
+ id: `${this.agentId}-auth-failed`,
37
+ type: 'infra-issue',
38
+ severity: 'medium',
39
+ agentId: this.agentId,
40
+ module: 'data-consistency',
41
+ description: `Authentication failed: ${authError instanceof Error ? authError.message.split('\n')[0] : String(authError)}`,
42
+ });
43
+ return findings;
44
+ }
45
+ } else {
46
+ client = new ApiClient(this.baseUrl);
47
+ }
48
+
49
+ // Test CRUD consistency for each module
50
+ const endpoints = this.config.modules.map(m => `/api${m.route}`);
51
+
52
+ for (const endpoint of endpoints) {
53
+ const endpointFindings = await this.testCrudConsistency(client, endpoint);
54
+ findings.push(...endpointFindings);
55
+ }
56
+
57
+ return findings;
58
+ }
59
+
60
+ private async testCrudConsistency(client: ApiClient, endpoint: string): Promise<Finding[]> {
61
+ const findings: Finding[] = [];
62
+ const testData = { name: `consistency-test-${Date.now()}`, test: true };
63
+
64
+ // Step 1: Create
65
+ let createdId: string | null = null;
66
+ try {
67
+ const createResponse = await Promise.race([
68
+ client.post(endpoint, testData),
69
+ new Promise<never>((_, reject) =>
70
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
71
+ ),
72
+ ]);
73
+
74
+ if (createResponse.status >= 200 && createResponse.status < 300) {
75
+ const body = createResponse.body as Record<string, unknown>;
76
+ createdId = String(body?.id ?? body?.['_id'] ?? '');
77
+ } else {
78
+ findings.push({
79
+ id: `${this.agentId}-create-failed-${endpoint.replace(/\//g, '_')}`,
80
+ type: 'infra-issue',
81
+ severity: 'low',
82
+ agentId: this.agentId,
83
+ module: 'data-consistency',
84
+ description: `Cannot test consistency — create returned ${createResponse.status} for ${endpoint}`,
85
+ });
86
+ return findings;
87
+ }
88
+ } catch (error) {
89
+ findings.push({
90
+ id: `${this.agentId}-create-error-${endpoint.replace(/\//g, '_')}`,
91
+ type: 'infra-issue',
92
+ severity: 'low',
93
+ agentId: this.agentId,
94
+ module: 'data-consistency',
95
+ description: `Cannot test consistency — create failed for ${endpoint}: ${error instanceof Error ? error.message : String(error)}`,
96
+ });
97
+ return findings;
98
+ }
99
+
100
+ if (!createdId) {
101
+ return findings;
102
+ }
103
+
104
+ // Step 2: Read back and compare
105
+ try {
106
+ const readResponse = await Promise.race([
107
+ client.get(`${endpoint}/${createdId}`),
108
+ new Promise<never>((_, reject) =>
109
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
110
+ ),
111
+ ]);
112
+
113
+ if (readResponse.status === 200) {
114
+ const body = readResponse.body as Record<string, unknown>;
115
+ if (body.name !== testData.name) {
116
+ findings.push({
117
+ id: `${this.agentId}-read-mismatch-${endpoint.replace(/\//g, '_')}`,
118
+ type: 'code-bug-logic',
119
+ severity: 'high',
120
+ agentId: this.agentId,
121
+ module: 'data-consistency',
122
+ description: `Data mismatch after create+read for ${endpoint}: expected name="${testData.name}", got name="${body.name}"`,
123
+ });
124
+ }
125
+ } else {
126
+ findings.push({
127
+ id: `${this.agentId}-read-failed-${endpoint.replace(/\//g, '_')}`,
128
+ type: 'code-bug-logic',
129
+ severity: 'high',
130
+ agentId: this.agentId,
131
+ module: 'data-consistency',
132
+ description: `Read after create returned ${readResponse.status} for ${endpoint}/${createdId}`,
133
+ });
134
+ }
135
+ } catch {
136
+ // Read failed
137
+ }
138
+
139
+ // Step 3: Update and verify
140
+ const updatedName = `updated-${Date.now()}`;
141
+ try {
142
+ await Promise.race([
143
+ client.put(`${endpoint}/${createdId}`, { name: updatedName }),
144
+ new Promise<never>((_, reject) =>
145
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
146
+ ),
147
+ ]);
148
+
149
+ const verifyResponse = await Promise.race([
150
+ client.get(`${endpoint}/${createdId}`),
151
+ new Promise<never>((_, reject) =>
152
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
153
+ ),
154
+ ]);
155
+
156
+ if (verifyResponse.status === 200) {
157
+ const body = verifyResponse.body as Record<string, unknown>;
158
+ if (body.name !== updatedName) {
159
+ findings.push({
160
+ id: `${this.agentId}-update-mismatch-${endpoint.replace(/\//g, '_')}`,
161
+ type: 'code-bug-logic',
162
+ severity: 'high',
163
+ agentId: this.agentId,
164
+ module: 'data-consistency',
165
+ description: `Data mismatch after update for ${endpoint}: expected name="${updatedName}", got name="${body.name}"`,
166
+ });
167
+ }
168
+ }
169
+ } catch {
170
+ // Update flow failed
171
+ }
172
+
173
+ // Step 4: Delete and verify 404
174
+ try {
175
+ await Promise.race([
176
+ client.delete(`${endpoint}/${createdId}`),
177
+ new Promise<never>((_, reject) =>
178
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
179
+ ),
180
+ ]);
181
+
182
+ const deleteVerify = await Promise.race([
183
+ client.get(`${endpoint}/${createdId}`),
184
+ new Promise<never>((_, reject) =>
185
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
186
+ ),
187
+ ]);
188
+
189
+ if (deleteVerify.status !== 404) {
190
+ findings.push({
191
+ id: `${this.agentId}-delete-not-404-${endpoint.replace(/\//g, '_')}`,
192
+ type: 'code-bug-logic',
193
+ severity: 'high',
194
+ agentId: this.agentId,
195
+ module: 'data-consistency',
196
+ description: `After delete, GET ${endpoint}/${createdId} returned ${deleteVerify.status} instead of 404`,
197
+ });
198
+ }
199
+ } catch {
200
+ // Delete flow failed
201
+ }
202
+
203
+ return findings;
204
+ }
205
+ }
@@ -0,0 +1,152 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { stat } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import type { Finding } from '../core/types';
6
+ import { BaseAgent } from './base-agent';
7
+
8
+ const execFileAsync = promisify(execFile);
9
+ const EXEC_TIMEOUT_MS = 30_000;
10
+
11
+ export class BackupRecoveryTesterAgent extends BaseAgent {
12
+ readonly agentId = 44;
13
+ readonly agentName = 'Backup Recovery Tester';
14
+
15
+ protected async preFlight(): Promise<void> {
16
+ // No special pre-conditions
17
+ }
18
+
19
+ protected async execute(): Promise<Finding[]> {
20
+ const findings: Finding[] = [];
21
+ const projectRoot = this.config.projectRoot ?? process.cwd();
22
+ const schemaPath = join(projectRoot, 'prisma', 'schema.prisma');
23
+
24
+ // Check if prisma schema exists
25
+ try {
26
+ await stat(schemaPath);
27
+ } catch {
28
+ findings.push({
29
+ id: `${this.agentId}-no-prisma-schema`,
30
+ type: 'infra-issue',
31
+ severity: 'low',
32
+ agentId: this.agentId,
33
+ module: 'backup-recovery',
34
+ description: `No prisma/schema.prisma found in ${projectRoot} — skipping database recovery tests`,
35
+ });
36
+ return findings;
37
+ }
38
+
39
+ // Test 1: Schema pull verification
40
+ const schemaFindings = await this.testSchemaPull(projectRoot);
41
+ findings.push(...schemaFindings);
42
+
43
+ // Test 2: Migration status
44
+ const migrationFindings = await this.testMigrationStatus(projectRoot);
45
+ findings.push(...migrationFindings);
46
+
47
+ return findings;
48
+ }
49
+
50
+ private async testSchemaPull(projectRoot: string): Promise<Finding[]> {
51
+ const findings: Finding[] = [];
52
+
53
+ try {
54
+ const { stdout, stderr } = await execFileAsync(
55
+ 'npx',
56
+ ['prisma', 'db', 'pull', '--print'],
57
+ { cwd: projectRoot, timeout: EXEC_TIMEOUT_MS },
58
+ );
59
+
60
+ if (stderr && stderr.includes('Error')) {
61
+ findings.push({
62
+ id: `${this.agentId}-schema-pull-error`,
63
+ type: 'infra-issue',
64
+ severity: 'medium',
65
+ agentId: this.agentId,
66
+ module: 'backup-recovery',
67
+ description: `prisma db pull reported errors: ${stderr.split('\n')[0]}`,
68
+ });
69
+ }
70
+
71
+ this.addEvidence({
72
+ type: 'report',
73
+ path: 'prisma-schema-pull',
74
+ description: `prisma db pull --print completed (${stdout.length} chars of schema output)`,
75
+ });
76
+ } catch (error) {
77
+ findings.push({
78
+ id: `${this.agentId}-schema-pull-failed`,
79
+ type: 'infra-issue',
80
+ severity: 'medium',
81
+ agentId: this.agentId,
82
+ module: 'backup-recovery',
83
+ description: `prisma db pull failed: ${error instanceof Error ? error.message : String(error)}`,
84
+ });
85
+ }
86
+
87
+ return findings;
88
+ }
89
+
90
+ private async testMigrationStatus(projectRoot: string): Promise<Finding[]> {
91
+ const findings: Finding[] = [];
92
+
93
+ try {
94
+ let stdout = '';
95
+ let stderr = '';
96
+ try {
97
+ const result = await execFileAsync(
98
+ 'npx',
99
+ ['prisma', 'migrate', 'status'],
100
+ { cwd: projectRoot, timeout: EXEC_TIMEOUT_MS },
101
+ );
102
+ stdout = result.stdout;
103
+ stderr = result.stderr;
104
+ } catch (execError) {
105
+ const err = execError as { stdout?: string; stderr?: string };
106
+ stdout = err.stdout ?? '';
107
+ stderr = err.stderr ?? '';
108
+ }
109
+
110
+ const output = `${stdout}\n${stderr}`;
111
+
112
+ if (output.includes('pending') || output.includes('not yet applied')) {
113
+ findings.push({
114
+ id: `${this.agentId}-pending-migrations`,
115
+ type: 'infra-issue',
116
+ severity: 'high',
117
+ agentId: this.agentId,
118
+ module: 'backup-recovery',
119
+ description: 'Pending database migrations detected — schema may be out of sync with production',
120
+ });
121
+ }
122
+
123
+ if (output.includes('drift') || output.includes('modified')) {
124
+ findings.push({
125
+ id: `${this.agentId}-schema-drift`,
126
+ type: 'infra-issue',
127
+ severity: 'high',
128
+ agentId: this.agentId,
129
+ module: 'backup-recovery',
130
+ description: 'Database schema drift detected — production database differs from migration history',
131
+ });
132
+ }
133
+
134
+ this.addEvidence({
135
+ type: 'report',
136
+ path: 'prisma-migrate-status',
137
+ description: `prisma migrate status output: ${output.substring(0, 200)}`,
138
+ });
139
+ } catch (error) {
140
+ findings.push({
141
+ id: `${this.agentId}-migration-status-error`,
142
+ type: 'infra-issue',
143
+ severity: 'medium',
144
+ agentId: this.agentId,
145
+ module: 'backup-recovery',
146
+ description: `prisma migrate status failed: ${error instanceof Error ? error.message : String(error)}`,
147
+ });
148
+ }
149
+
150
+ return findings;
151
+ }
152
+ }
@@ -0,0 +1,125 @@
1
+ import type { Finding } from '../core/types';
2
+ import { BaseAgent } from './base-agent';
3
+ import { resolveEnvironment } from '../helpers/env-resolver';
4
+ import { ApiClient } from '../helpers/api-client';
5
+
6
+ const REQUEST_TIMEOUT_MS = 10_000;
7
+
8
+ interface PiiPattern {
9
+ name: string;
10
+ regex: RegExp;
11
+ }
12
+
13
+ const PII_PATTERNS: PiiPattern[] = [
14
+ { name: 'Email', regex: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g },
15
+ { name: 'Phone', regex: /(?:\+?1[-.\s]?)?\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}/g },
16
+ { name: 'SSN', regex: /\d{3}-\d{2}-\d{4}/g },
17
+ { name: 'Credit Card', regex: /\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}/g },
18
+ ];
19
+
20
+ export class DataPrivacyScannerAgent extends BaseAgent {
21
+ readonly agentId = 45;
22
+ readonly agentName = 'Data Privacy Scanner';
23
+ private baseUrl = '';
24
+
25
+ protected async preFlight(): Promise<void> {
26
+ if (!this.config.modules || this.config.modules.length === 0) {
27
+ throw new Error('DataPrivacyScannerAgent requires at least one module in config.modules');
28
+ }
29
+ const { env } = await resolveEnvironment(this.config, this.phase);
30
+ this.baseUrl = env.baseUrl;
31
+ }
32
+
33
+ protected async execute(): Promise<Finding[]> {
34
+ const findings: Finding[] = [];
35
+ const credentials =
36
+ this.config.auth.credentials?.['admin'] ??
37
+ Object.values(this.config.auth.credentials ?? {})[0];
38
+
39
+ let client: ApiClient;
40
+
41
+ if (credentials) {
42
+ try {
43
+ client = await Promise.race([
44
+ ApiClient.createAuthenticated(this.baseUrl, credentials),
45
+ new Promise<never>((_, reject) =>
46
+ setTimeout(() => reject(new Error('Auth timeout')), REQUEST_TIMEOUT_MS),
47
+ ),
48
+ ]);
49
+ } catch (authError) {
50
+ findings.push({
51
+ id: `${this.agentId}-auth-failed`,
52
+ type: 'infra-issue',
53
+ severity: 'medium',
54
+ agentId: this.agentId,
55
+ module: 'data-privacy',
56
+ description: `Authentication failed: ${authError instanceof Error ? authError.message.split('\n')[0] : String(authError)}`,
57
+ });
58
+ return findings;
59
+ }
60
+ } else {
61
+ client = new ApiClient(this.baseUrl);
62
+ }
63
+
64
+ const endpoints = this.config.modules.map(m => `/api${m.route}`);
65
+
66
+ for (const endpoint of endpoints) {
67
+ const endpointFindings = await this.scanEndpointForPii(client, endpoint);
68
+ findings.push(...endpointFindings);
69
+ }
70
+
71
+ return findings;
72
+ }
73
+
74
+ private async scanEndpointForPii(client: ApiClient, endpoint: string): Promise<Finding[]> {
75
+ const findings: Finding[] = [];
76
+
77
+ try {
78
+ const response = await Promise.race([
79
+ client.get(endpoint),
80
+ new Promise<never>((_, reject) =>
81
+ setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT_MS),
82
+ ),
83
+ ]);
84
+
85
+ if (response.status !== 200) {
86
+ return findings;
87
+ }
88
+
89
+ const responseText = JSON.stringify(response.body);
90
+
91
+ for (const pattern of PII_PATTERNS) {
92
+ pattern.regex.lastIndex = 0;
93
+ const matches = responseText.match(pattern.regex);
94
+
95
+ if (matches && matches.length > 0) {
96
+ findings.push({
97
+ id: `${this.agentId}-unmasked-${pattern.name.toLowerCase()}-${endpoint.replace(/\//g, '_')}`,
98
+ type: 'code-bug-security',
99
+ severity: 'high',
100
+ agentId: this.agentId,
101
+ module: 'data-privacy',
102
+ description: `Unmasked ${pattern.name} found in response from ${endpoint} (${matches.length} occurrence(s))`,
103
+ });
104
+ }
105
+ }
106
+
107
+ this.addEvidence({
108
+ type: 'log',
109
+ path: `pii-scan-${endpoint.replace(/\//g, '_')}`,
110
+ description: `PII scan for ${endpoint}: response size=${responseText.length} chars`,
111
+ });
112
+ } catch (error) {
113
+ findings.push({
114
+ id: `${this.agentId}-scan-error-${endpoint.replace(/\//g, '_')}`,
115
+ type: 'infra-issue',
116
+ severity: 'low',
117
+ agentId: this.agentId,
118
+ module: 'data-privacy',
119
+ description: `Failed to scan ${endpoint}: ${error instanceof Error ? error.message : String(error)}`,
120
+ });
121
+ }
122
+
123
+ return findings;
124
+ }
125
+ }