@avi770/testteam 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/agents/01-analyst.ts +100 -0
- package/agents/02-seed-architect.ts +59 -0
- package/agents/03-test-generator.ts +191 -0
- package/agents/04-unit-runner.ts +160 -0
- package/agents/05-browser-crawler.ts +790 -0
- package/agents/06-api-exerciser.ts +311 -0
- package/agents/07-security-scout.ts +188 -0
- package/agents/08-a11y-guardian.ts +212 -0
- package/agents/09-healer.ts +228 -0
- package/agents/10-reporter.ts +266 -0
- package/agents/11-fixer.ts +253 -0
- package/agents/12-ux-inspector.ts +444 -0
- package/agents/13-performance-profiler.ts +271 -0
- package/agents/14-data-integrity-auditor.ts +417 -0
- package/agents/15-regression-sentinel.ts +307 -0
- package/agents/16-chaos-agent.ts +228 -0
- package/agents/17-documentation-validator.ts +266 -0
- package/agents/18-integration-watchdog.ts +178 -0
- package/agents/19-tenant-isolation-auditor.ts +199 -0
- package/agents/20-workflow-completion-tester.ts +203 -0
- package/agents/21-state-session-tester.ts +262 -0
- package/agents/22-email-notification-verifier.ts +244 -0
- package/agents/23-migration-tester.ts +80 -0
- package/agents/__tests__/01-analyst.test.ts +188 -0
- package/agents/__tests__/02-seed-architect.test.ts +152 -0
- package/agents/__tests__/03-test-generator-full.test.ts +321 -0
- package/agents/__tests__/03-test-generator.test.ts +318 -0
- package/agents/__tests__/04-unit-runner.test.ts +320 -0
- package/agents/__tests__/05-browser-crawler-beta.test.ts +492 -0
- package/agents/__tests__/05-browser-crawler-release.test.ts +412 -0
- package/agents/__tests__/05-browser-crawler-uat.test.ts +578 -0
- package/agents/__tests__/05-browser-crawler.test.ts +518 -0
- package/agents/__tests__/06-api-exerciser.test.ts +619 -0
- package/agents/__tests__/07-security-scout.test.ts +382 -0
- package/agents/__tests__/08-a11y-guardian.test.ts +530 -0
- package/agents/__tests__/09-healer.test.ts +384 -0
- package/agents/__tests__/10-reporter.test.ts +366 -0
- package/agents/__tests__/11-fixer.test.ts +406 -0
- package/agents/__tests__/12-ux-inspector-extended.test.ts +465 -0
- package/agents/__tests__/12-ux-inspector.test.ts +443 -0
- package/agents/__tests__/13-performance-profiler.test.ts +411 -0
- package/agents/__tests__/14-data-integrity-auditor-extended.test.ts +573 -0
- package/agents/__tests__/14-data-integrity-auditor.test.ts +407 -0
- package/agents/__tests__/15-regression-sentinel.test.ts +657 -0
- package/agents/__tests__/16-chaos-agent.test.ts +427 -0
- package/agents/__tests__/17-documentation-validator.test.ts +402 -0
- package/agents/__tests__/18-integration-watchdog.test.ts +263 -0
- package/agents/__tests__/19-tenant-isolation-auditor.test.ts +400 -0
- package/agents/__tests__/20-workflow-completion-tester.test.ts +586 -0
- package/agents/__tests__/21-state-session-tester.test.ts +374 -0
- package/agents/__tests__/22-email-notification-verifier.test.ts +441 -0
- package/agents/__tests__/23-migration-tester.test.ts +145 -0
- package/agents/__tests__/base-agent.test.ts +188 -0
- package/agents/__tests__/registry.test.ts +218 -0
- package/agents/base-agent.ts +77 -0
- package/agents/registry.ts +136 -0
- package/baselines/api-schemas/.gitkeep +0 -0
- package/baselines/performance/.gitkeep +0 -0
- package/baselines/screenshots/.gitkeep +0 -0
- package/bin/testteam.js +10 -0
- package/core/__tests__/ci-output.test.ts +430 -0
- package/core/__tests__/cli.test.ts +387 -0
- package/core/__tests__/config.test.ts +78 -0
- package/core/__tests__/cost-tracker.test.ts +158 -0
- package/core/__tests__/evidence.test.ts +265 -0
- package/core/__tests__/fix-loop.test.ts +210 -0
- package/core/__tests__/health-check.test.ts +44 -0
- package/core/__tests__/init.test.ts +609 -0
- package/core/__tests__/integration.test.ts +204 -0
- package/core/__tests__/license-gen.test.ts +227 -0
- package/core/__tests__/license.test.ts +326 -0
- package/core/__tests__/multi-browser.test.ts +278 -0
- package/core/__tests__/orchestrator.test.ts +519 -0
- package/core/__tests__/phase-gate.test.ts +43 -0
- package/core/__tests__/report-html.test.ts +398 -0
- package/core/__tests__/report-upload.test.ts +325 -0
- package/core/__tests__/run-counter.test.ts +234 -0
- package/core/ci-output.ts +240 -0
- package/core/cli.ts +232 -0
- package/core/config.ts +178 -0
- package/core/cost-tracker.ts +59 -0
- package/core/evidence.ts +132 -0
- package/core/fix-loop.ts +85 -0
- package/core/health-check.ts +54 -0
- package/core/init.ts +546 -0
- package/core/license-gen.ts +212 -0
- package/core/license.ts +211 -0
- package/core/messages.ts +67 -0
- package/core/multi-browser.ts +136 -0
- package/core/orchestrator.ts +354 -0
- package/core/phase-gate.ts +55 -0
- package/core/report-html.ts +657 -0
- package/core/report-upload.ts +188 -0
- package/core/run-counter.ts +175 -0
- package/core/types.ts +57 -0
- package/dist/agents/01-analyst.d.ts +11 -0
- package/dist/agents/01-analyst.d.ts.map +1 -0
- package/dist/agents/01-analyst.js +75 -0
- package/dist/agents/01-analyst.js.map +1 -0
- package/dist/agents/02-seed-architect.d.ts +11 -0
- package/dist/agents/02-seed-architect.d.ts.map +1 -0
- package/dist/agents/02-seed-architect.js +51 -0
- package/dist/agents/02-seed-architect.js.map +1 -0
- package/dist/agents/03-test-generator.d.ts +9 -0
- package/dist/agents/03-test-generator.d.ts.map +1 -0
- package/dist/agents/03-test-generator.js +167 -0
- package/dist/agents/03-test-generator.js.map +1 -0
- package/dist/agents/04-unit-runner.d.ts +9 -0
- package/dist/agents/04-unit-runner.d.ts.map +1 -0
- package/dist/agents/04-unit-runner.js +113 -0
- package/dist/agents/04-unit-runner.js.map +1 -0
- package/dist/agents/05-browser-crawler.d.ts +30 -0
- package/dist/agents/05-browser-crawler.d.ts.map +1 -0
- package/dist/agents/05-browser-crawler.js +685 -0
- package/dist/agents/05-browser-crawler.js.map +1 -0
- package/dist/agents/06-api-exerciser.d.ts +23 -0
- package/dist/agents/06-api-exerciser.d.ts.map +1 -0
- package/dist/agents/06-api-exerciser.js +253 -0
- package/dist/agents/06-api-exerciser.js.map +1 -0
- package/dist/agents/07-security-scout.d.ts +11 -0
- package/dist/agents/07-security-scout.d.ts.map +1 -0
- package/dist/agents/07-security-scout.js +142 -0
- package/dist/agents/07-security-scout.js.map +1 -0
- package/dist/agents/08-a11y-guardian.d.ts +13 -0
- package/dist/agents/08-a11y-guardian.d.ts.map +1 -0
- package/dist/agents/08-a11y-guardian.js +176 -0
- package/dist/agents/08-a11y-guardian.js.map +1 -0
- package/dist/agents/09-healer.d.ts +33 -0
- package/dist/agents/09-healer.d.ts.map +1 -0
- package/dist/agents/09-healer.js +167 -0
- package/dist/agents/09-healer.js.map +1 -0
- package/dist/agents/10-reporter.d.ts +26 -0
- package/dist/agents/10-reporter.d.ts.map +1 -0
- package/dist/agents/10-reporter.js +215 -0
- package/dist/agents/10-reporter.js.map +1 -0
- package/dist/agents/11-fixer.d.ts +26 -0
- package/dist/agents/11-fixer.d.ts.map +1 -0
- package/dist/agents/11-fixer.js +195 -0
- package/dist/agents/11-fixer.js.map +1 -0
- package/dist/agents/12-ux-inspector.d.ts +15 -0
- package/dist/agents/12-ux-inspector.d.ts.map +1 -0
- package/dist/agents/12-ux-inspector.js +364 -0
- package/dist/agents/12-ux-inspector.js.map +1 -0
- package/dist/agents/13-performance-profiler.d.ts +13 -0
- package/dist/agents/13-performance-profiler.d.ts.map +1 -0
- package/dist/agents/13-performance-profiler.js +216 -0
- package/dist/agents/13-performance-profiler.js.map +1 -0
- package/dist/agents/14-data-integrity-auditor.d.ts +12 -0
- package/dist/agents/14-data-integrity-auditor.d.ts.map +1 -0
- package/dist/agents/14-data-integrity-auditor.js +356 -0
- package/dist/agents/14-data-integrity-auditor.js.map +1 -0
- package/dist/agents/15-regression-sentinel.d.ts +25 -0
- package/dist/agents/15-regression-sentinel.d.ts.map +1 -0
- package/dist/agents/15-regression-sentinel.js +251 -0
- package/dist/agents/15-regression-sentinel.js.map +1 -0
- package/dist/agents/16-chaos-agent.d.ts +9 -0
- package/dist/agents/16-chaos-agent.d.ts.map +1 -0
- package/dist/agents/16-chaos-agent.js +207 -0
- package/dist/agents/16-chaos-agent.js.map +1 -0
- package/dist/agents/17-documentation-validator.d.ts +31 -0
- package/dist/agents/17-documentation-validator.d.ts.map +1 -0
- package/dist/agents/17-documentation-validator.js +246 -0
- package/dist/agents/17-documentation-validator.js.map +1 -0
- package/dist/agents/18-integration-watchdog.d.ts +10 -0
- package/dist/agents/18-integration-watchdog.d.ts.map +1 -0
- package/dist/agents/18-integration-watchdog.js +138 -0
- package/dist/agents/18-integration-watchdog.js.map +1 -0
- package/dist/agents/19-tenant-isolation-auditor.d.ts +9 -0
- package/dist/agents/19-tenant-isolation-auditor.d.ts.map +1 -0
- package/dist/agents/19-tenant-isolation-auditor.js +166 -0
- package/dist/agents/19-tenant-isolation-auditor.js.map +1 -0
- package/dist/agents/20-workflow-completion-tester.d.ts +12 -0
- package/dist/agents/20-workflow-completion-tester.d.ts.map +1 -0
- package/dist/agents/20-workflow-completion-tester.js +159 -0
- package/dist/agents/20-workflow-completion-tester.js.map +1 -0
- package/dist/agents/21-state-session-tester.d.ts +10 -0
- package/dist/agents/21-state-session-tester.d.ts.map +1 -0
- package/dist/agents/21-state-session-tester.js +233 -0
- package/dist/agents/21-state-session-tester.js.map +1 -0
- package/dist/agents/22-email-notification-verifier.d.ts +11 -0
- package/dist/agents/22-email-notification-verifier.d.ts.map +1 -0
- package/dist/agents/22-email-notification-verifier.js +199 -0
- package/dist/agents/22-email-notification-verifier.js.map +1 -0
- package/dist/agents/23-migration-tester.d.ts +10 -0
- package/dist/agents/23-migration-tester.d.ts.map +1 -0
- package/dist/agents/23-migration-tester.js +74 -0
- package/dist/agents/23-migration-tester.js.map +1 -0
- package/dist/agents/base-agent.d.ts +19 -0
- package/dist/agents/base-agent.d.ts.map +1 -0
- package/dist/agents/base-agent.js +67 -0
- package/dist/agents/base-agent.js.map +1 -0
- package/dist/agents/registry.d.ts +29 -0
- package/dist/agents/registry.d.ts.map +1 -0
- package/dist/agents/registry.js +117 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/core/ci-output.d.ts +35 -0
- package/dist/core/ci-output.d.ts.map +1 -0
- package/dist/core/ci-output.js +193 -0
- package/dist/core/ci-output.js.map +1 -0
- package/dist/core/cli.d.ts +11 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +197 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +111 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +42 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cost-tracker.d.ts +22 -0
- package/dist/core/cost-tracker.d.ts.map +1 -0
- package/dist/core/cost-tracker.js +41 -0
- package/dist/core/cost-tracker.js.map +1 -0
- package/dist/core/evidence.d.ts +28 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +95 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/fix-loop.d.ts +29 -0
- package/dist/core/fix-loop.d.ts.map +1 -0
- package/dist/core/fix-loop.js +70 -0
- package/dist/core/fix-loop.js.map +1 -0
- package/dist/core/health-check.d.ts +21 -0
- package/dist/core/health-check.d.ts.map +1 -0
- package/dist/core/health-check.js +26 -0
- package/dist/core/health-check.js.map +1 -0
- package/dist/core/init.d.ts +2 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +435 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/license-gen.d.ts +12 -0
- package/dist/core/license-gen.d.ts.map +1 -0
- package/dist/core/license-gen.js +169 -0
- package/dist/core/license-gen.js.map +1 -0
- package/dist/core/license.d.ts +33 -0
- package/dist/core/license.d.ts.map +1 -0
- package/dist/core/license.js +170 -0
- package/dist/core/license.js.map +1 -0
- package/dist/core/messages.d.ts +10 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +47 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/multi-browser.d.ts +36 -0
- package/dist/core/multi-browser.d.ts.map +1 -0
- package/dist/core/multi-browser.js +88 -0
- package/dist/core/multi-browser.js.map +1 -0
- package/dist/core/orchestrator.d.ts +48 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +291 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/phase-gate.d.ts +4 -0
- package/dist/core/phase-gate.d.ts.map +1 -0
- package/dist/core/phase-gate.js +39 -0
- package/dist/core/phase-gate.js.map +1 -0
- package/dist/core/report-html.d.ts +9 -0
- package/dist/core/report-html.d.ts.map +1 -0
- package/dist/core/report-html.js +617 -0
- package/dist/core/report-html.js.map +1 -0
- package/dist/core/report-upload.d.ts +16 -0
- package/dist/core/report-upload.d.ts.map +1 -0
- package/dist/core/report-upload.js +124 -0
- package/dist/core/report-upload.js.map +1 -0
- package/dist/core/run-counter.d.ts +40 -0
- package/dist/core/run-counter.d.ts.map +1 -0
- package/dist/core/run-counter.js +120 -0
- package/dist/core/run-counter.js.map +1 -0
- package/dist/core/types.d.ts +53 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/helpers/api-client.d.ts +30 -0
- package/dist/helpers/api-client.d.ts.map +1 -0
- package/dist/helpers/api-client.js +77 -0
- package/dist/helpers/api-client.js.map +1 -0
- package/dist/helpers/element-discovery.d.ts +18 -0
- package/dist/helpers/element-discovery.d.ts.map +1 -0
- package/dist/helpers/element-discovery.js +82 -0
- package/dist/helpers/element-discovery.js.map +1 -0
- package/dist/helpers/env-resolver.d.ts +29 -0
- package/dist/helpers/env-resolver.d.ts.map +1 -0
- package/dist/helpers/env-resolver.js +51 -0
- package/dist/helpers/env-resolver.js.map +1 -0
- package/dist/helpers/form-filler.d.ts +13 -0
- package/dist/helpers/form-filler.d.ts.map +1 -0
- package/dist/helpers/form-filler.js +98 -0
- package/dist/helpers/form-filler.js.map +1 -0
- package/dist/helpers/modal-handler.d.ts +16 -0
- package/dist/helpers/modal-handler.d.ts.map +1 -0
- package/dist/helpers/modal-handler.js +95 -0
- package/dist/helpers/modal-handler.js.map +1 -0
- package/dist/helpers/navigation.d.ts +37 -0
- package/dist/helpers/navigation.d.ts.map +1 -0
- package/dist/helpers/navigation.js +83 -0
- package/dist/helpers/navigation.js.map +1 -0
- package/dist/helpers/quality-gate.d.ts +17 -0
- package/dist/helpers/quality-gate.d.ts.map +1 -0
- package/dist/helpers/quality-gate.js +144 -0
- package/dist/helpers/quality-gate.js.map +1 -0
- package/dist/helpers/screenshot.d.ts +24 -0
- package/dist/helpers/screenshot.d.ts.map +1 -0
- package/dist/helpers/screenshot.js +76 -0
- package/dist/helpers/screenshot.js.map +1 -0
- package/dist/helpers/seed-validator.d.ts +15 -0
- package/dist/helpers/seed-validator.d.ts.map +1 -0
- package/dist/helpers/seed-validator.js +53 -0
- package/dist/helpers/seed-validator.js.map +1 -0
- package/helpers/__tests__/api-client.test.ts +199 -0
- package/helpers/__tests__/element-discovery.test.ts +202 -0
- package/helpers/__tests__/form-filler-extended.test.ts +212 -0
- package/helpers/__tests__/form-filler.test.ts +99 -0
- package/helpers/__tests__/modal-handler.test.ts +152 -0
- package/helpers/__tests__/navigation.test.ts +214 -0
- package/helpers/__tests__/quality-gate.test.ts +117 -0
- package/helpers/__tests__/screenshot.test.ts +139 -0
- package/helpers/__tests__/seed-validator.test.ts +114 -0
- package/helpers/api-client.ts +111 -0
- package/helpers/element-discovery.ts +105 -0
- package/helpers/env-resolver.ts +69 -0
- package/helpers/form-filler.ts +126 -0
- package/helpers/modal-handler.ts +108 -0
- package/helpers/navigation.ts +100 -0
- package/helpers/quality-gate.ts +180 -0
- package/helpers/screenshot.ts +111 -0
- package/helpers/seed-validator.ts +70 -0
- package/package.json +88 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"12-ux-inspector.js","sourceRoot":"","sources":["../../agents/12-ux-inspector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Finding } from '../core/types';
|
|
2
|
+
import { BaseAgent } from './base-agent';
|
|
3
|
+
export declare class PerformanceProfilerAgent extends BaseAgent {
|
|
4
|
+
readonly agentId = 13;
|
|
5
|
+
readonly agentName = "Performance Profiler";
|
|
6
|
+
private baseUrl;
|
|
7
|
+
protected preFlight(): Promise<void>;
|
|
8
|
+
protected execute(): Promise<Finding[]>;
|
|
9
|
+
private profileModule;
|
|
10
|
+
private checkMemoryUsage;
|
|
11
|
+
private runLighthouse;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=13-performance-profiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"13-performance-profiler.d.ts","sourceRoot":"","sources":["../../agents/13-performance-profiler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA+BzC,qBAAa,wBAAyB,SAAQ,SAAS;IACrD,QAAQ,CAAC,OAAO,MAAM;IACtB,QAAQ,CAAC,SAAS,0BAA0B;IAC5C,OAAO,CAAC,OAAO,CAAM;cAEL,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;cAK1B,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAoD/B,aAAa;YAmGb,gBAAgB;YAgChB,aAAa;CA4C5B"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { BaseAgent } from './base-agent';
|
|
2
|
+
import { login, navigateToSection } from '../helpers/navigation';
|
|
3
|
+
import { resolveEnvironment } from '../helpers/env-resolver';
|
|
4
|
+
/** LCP threshold in milliseconds (Core Web Vitals "Good" boundary). */
|
|
5
|
+
const LCP_THRESHOLD_MS = 2500;
|
|
6
|
+
/** FCP threshold in milliseconds (Core Web Vitals "Good" boundary). */
|
|
7
|
+
const FCP_THRESHOLD_MS = 1800;
|
|
8
|
+
/** JS heap size threshold: 100 MB in bytes. */
|
|
9
|
+
const HEAP_SIZE_THRESHOLD_BYTES = 100 * 1024 * 1024;
|
|
10
|
+
export class PerformanceProfilerAgent extends BaseAgent {
|
|
11
|
+
agentId = 13;
|
|
12
|
+
agentName = 'Performance Profiler';
|
|
13
|
+
baseUrl = '';
|
|
14
|
+
async preFlight() {
|
|
15
|
+
const { env } = await resolveEnvironment(this.config, this.phase);
|
|
16
|
+
this.baseUrl = env.baseUrl;
|
|
17
|
+
}
|
|
18
|
+
async execute() {
|
|
19
|
+
const findings = [];
|
|
20
|
+
const rawLoginUrl = this.config.auth.loginUrl ?? '/login';
|
|
21
|
+
const loginUrl = rawLoginUrl.startsWith('http') ? rawLoginUrl : `${this.baseUrl}${rawLoginUrl}`;
|
|
22
|
+
const credentials = this.config.auth.credentials?.['admin'] ??
|
|
23
|
+
Object.values(this.config.auth.credentials ?? {})[0];
|
|
24
|
+
if (!credentials) {
|
|
25
|
+
findings.push({
|
|
26
|
+
id: '13-no-credentials',
|
|
27
|
+
type: 'infra-issue',
|
|
28
|
+
severity: 'critical',
|
|
29
|
+
agentId: this.agentId,
|
|
30
|
+
module: 'performance-profiler',
|
|
31
|
+
description: 'No credentials configured in auth.credentials — cannot log in',
|
|
32
|
+
});
|
|
33
|
+
return findings;
|
|
34
|
+
}
|
|
35
|
+
const { chromium } = await import('playwright');
|
|
36
|
+
let browser = null;
|
|
37
|
+
let page = null;
|
|
38
|
+
try {
|
|
39
|
+
browser = await chromium.launch({ headless: true });
|
|
40
|
+
page = await browser.newPage();
|
|
41
|
+
await login(page, credentials, loginUrl);
|
|
42
|
+
for (const module of this.config.modules) {
|
|
43
|
+
const moduleFindings = await this.profileModule(page, module.id);
|
|
44
|
+
findings.push(...moduleFindings);
|
|
45
|
+
}
|
|
46
|
+
// Check memory after navigating all sections (Chromium only)
|
|
47
|
+
const memoryFindings = await this.checkMemoryUsage(page);
|
|
48
|
+
findings.push(...memoryFindings);
|
|
49
|
+
// Run Lighthouse if available
|
|
50
|
+
const lighthouseFindings = await this.runLighthouse(this.baseUrl);
|
|
51
|
+
findings.push(...lighthouseFindings);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
if (page)
|
|
55
|
+
await page.close().catch(() => undefined);
|
|
56
|
+
if (browser)
|
|
57
|
+
await browser.close().catch(() => undefined);
|
|
58
|
+
}
|
|
59
|
+
return findings;
|
|
60
|
+
}
|
|
61
|
+
async profileModule(page, moduleId) {
|
|
62
|
+
const findings = [];
|
|
63
|
+
try {
|
|
64
|
+
await navigateToSection(page, moduleId, this.config);
|
|
65
|
+
}
|
|
66
|
+
catch (navErr) {
|
|
67
|
+
findings.push({
|
|
68
|
+
id: `13-nav-${moduleId}`,
|
|
69
|
+
type: 'infra-issue',
|
|
70
|
+
severity: 'high',
|
|
71
|
+
agentId: this.agentId,
|
|
72
|
+
module: moduleId,
|
|
73
|
+
description: `Navigation to module "${moduleId}" failed: ${navErr instanceof Error ? navErr.message : String(navErr)}`,
|
|
74
|
+
});
|
|
75
|
+
return findings;
|
|
76
|
+
}
|
|
77
|
+
// Measure navigation load time
|
|
78
|
+
const loadTimeMs = await page
|
|
79
|
+
.evaluate(() => {
|
|
80
|
+
const entries = performance.getEntriesByType('navigation');
|
|
81
|
+
if (entries.length === 0)
|
|
82
|
+
return 0;
|
|
83
|
+
const nav = entries[0];
|
|
84
|
+
return nav.loadEventEnd - nav.startTime;
|
|
85
|
+
})
|
|
86
|
+
.catch(() => 0);
|
|
87
|
+
this.addEvidence({
|
|
88
|
+
type: 'log',
|
|
89
|
+
path: `${this.runDir}/perf-${moduleId}.json`,
|
|
90
|
+
description: `Performance metrics for module "${moduleId}" — loadTime: ${loadTimeMs}ms`,
|
|
91
|
+
});
|
|
92
|
+
// Measure paint timings (FCP / LCP)
|
|
93
|
+
const paintEntriesRaw = await page
|
|
94
|
+
.evaluate(() => {
|
|
95
|
+
return performance.getEntriesByType('paint').map((e) => ({
|
|
96
|
+
name: e.name,
|
|
97
|
+
startTime: e.startTime,
|
|
98
|
+
}));
|
|
99
|
+
})
|
|
100
|
+
.catch(() => []);
|
|
101
|
+
const paintEntries = Array.isArray(paintEntriesRaw) ? paintEntriesRaw : [];
|
|
102
|
+
const fcpEntry = paintEntries.find((e) => e.name === 'first-contentful-paint');
|
|
103
|
+
const fcpMs = fcpEntry?.startTime ?? 0;
|
|
104
|
+
// LCP is reported via PerformanceObserver; use largest-contentful-paint entries if present
|
|
105
|
+
const lcpMs = await page
|
|
106
|
+
.evaluate(() => {
|
|
107
|
+
const entries = performance.getEntriesByType('largest-contentful-paint');
|
|
108
|
+
if (entries.length === 0)
|
|
109
|
+
return 0;
|
|
110
|
+
return entries[entries.length - 1].startTime;
|
|
111
|
+
})
|
|
112
|
+
.catch(() => 0);
|
|
113
|
+
if (fcpMs > FCP_THRESHOLD_MS) {
|
|
114
|
+
findings.push({
|
|
115
|
+
id: `13-fcp-${moduleId}`,
|
|
116
|
+
type: 'code-bug-logic',
|
|
117
|
+
severity: 'medium',
|
|
118
|
+
agentId: this.agentId,
|
|
119
|
+
module: moduleId,
|
|
120
|
+
description: `First Contentful Paint for module "${moduleId}" is ${fcpMs.toFixed(0)}ms (threshold: ${FCP_THRESHOLD_MS}ms)`,
|
|
121
|
+
suggestedFix: 'Reduce server response time, eliminate render-blocking resources, or defer non-critical scripts',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (lcpMs > LCP_THRESHOLD_MS) {
|
|
125
|
+
findings.push({
|
|
126
|
+
id: `13-lcp-${moduleId}`,
|
|
127
|
+
type: 'code-bug-logic',
|
|
128
|
+
severity: 'high',
|
|
129
|
+
agentId: this.agentId,
|
|
130
|
+
module: moduleId,
|
|
131
|
+
description: `Largest Contentful Paint for module "${moduleId}" is ${lcpMs.toFixed(0)}ms (threshold: ${LCP_THRESHOLD_MS}ms)`,
|
|
132
|
+
suggestedFix: 'Optimise hero images, preload critical assets, or reduce Time To First Byte',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (loadTimeMs > 0 && loadTimeMs > this.config.thresholds.apiResponseTime * 2) {
|
|
136
|
+
findings.push({
|
|
137
|
+
id: `13-load-time-${moduleId}`,
|
|
138
|
+
type: 'code-bug-logic',
|
|
139
|
+
severity: 'medium',
|
|
140
|
+
agentId: this.agentId,
|
|
141
|
+
module: moduleId,
|
|
142
|
+
description: `Page load time for module "${moduleId}" is ${loadTimeMs.toFixed(0)}ms (threshold: ${this.config.thresholds.apiResponseTime * 2}ms)`,
|
|
143
|
+
suggestedFix: 'Review waterfall of network requests and defer non-critical loading',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return findings;
|
|
147
|
+
}
|
|
148
|
+
async checkMemoryUsage(page) {
|
|
149
|
+
const findings = [];
|
|
150
|
+
try {
|
|
151
|
+
const usedHeap = await page
|
|
152
|
+
.evaluate(() => {
|
|
153
|
+
const perf = performance;
|
|
154
|
+
return perf.memory?.usedJSHeapSize ?? 0;
|
|
155
|
+
})
|
|
156
|
+
.catch(() => 0);
|
|
157
|
+
if (usedHeap > HEAP_SIZE_THRESHOLD_BYTES) {
|
|
158
|
+
const usedMb = (usedHeap / 1024 / 1024).toFixed(1);
|
|
159
|
+
const thresholdMb = (HEAP_SIZE_THRESHOLD_BYTES / 1024 / 1024).toFixed(0);
|
|
160
|
+
findings.push({
|
|
161
|
+
id: '13-memory-heap',
|
|
162
|
+
type: 'code-bug-logic',
|
|
163
|
+
severity: 'high',
|
|
164
|
+
agentId: this.agentId,
|
|
165
|
+
module: 'memory',
|
|
166
|
+
description: `JS heap size after navigating all modules is ${usedMb}MB (threshold: ${thresholdMb}MB). Possible memory leak.`,
|
|
167
|
+
suggestedFix: 'Profile with Chrome DevTools Memory panel, check for event listener leaks and large retained objects',
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// memory API is Chromium-only; ignore on other browsers
|
|
173
|
+
}
|
|
174
|
+
return findings;
|
|
175
|
+
}
|
|
176
|
+
async runLighthouse(baseUrl) {
|
|
177
|
+
const findings = [];
|
|
178
|
+
try {
|
|
179
|
+
// Dynamically import lighthouse — it is an optional peer dependency.
|
|
180
|
+
// Use a variable to prevent TypeScript from statically resolving the module.
|
|
181
|
+
const lighthouseModuleName = 'lighthouse';
|
|
182
|
+
const lighthouse = await import(/* webpackIgnore: true */ lighthouseModuleName).catch(() => null);
|
|
183
|
+
if (!lighthouse?.default)
|
|
184
|
+
return findings;
|
|
185
|
+
const run = lighthouse.default;
|
|
186
|
+
const result = await run(baseUrl, {
|
|
187
|
+
onlyCategories: ['performance'],
|
|
188
|
+
output: 'json',
|
|
189
|
+
logLevel: 'silent',
|
|
190
|
+
});
|
|
191
|
+
if (!result)
|
|
192
|
+
return findings;
|
|
193
|
+
const perfScore = (result.lhr.categories['performance']?.score ?? null);
|
|
194
|
+
if (perfScore === null)
|
|
195
|
+
return findings;
|
|
196
|
+
const perfPercent = Math.round(perfScore * 100);
|
|
197
|
+
const threshold = this.config.thresholds.lighthouse.performance;
|
|
198
|
+
if (perfPercent < threshold) {
|
|
199
|
+
findings.push({
|
|
200
|
+
id: '13-lighthouse-performance',
|
|
201
|
+
type: 'code-bug-logic',
|
|
202
|
+
severity: 'medium',
|
|
203
|
+
agentId: this.agentId,
|
|
204
|
+
module: 'lighthouse',
|
|
205
|
+
description: `Lighthouse performance score is ${perfPercent} (threshold: ${threshold})`,
|
|
206
|
+
suggestedFix: 'Address Lighthouse performance opportunities: reduce unused JavaScript, serve next-gen images, avoid large layout shifts',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Lighthouse not installed or audit failed — skip without failing
|
|
212
|
+
}
|
|
213
|
+
return findings;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=13-performance-profiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"13-performance-profiler.js","sourceRoot":"","sources":["../../agents/13-performance-profiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Finding } from '../core/types';
|
|
2
|
+
import { BaseAgent } from './base-agent';
|
|
3
|
+
export declare class DataIntegrityAuditorAgent extends BaseAgent {
|
|
4
|
+
readonly agentId = 14;
|
|
5
|
+
readonly agentName = "Data Integrity Auditor";
|
|
6
|
+
protected preFlight(): Promise<void>;
|
|
7
|
+
protected execute(): Promise<Finding[]>;
|
|
8
|
+
private testCrudRoundTrip;
|
|
9
|
+
private testDecimalPrecision;
|
|
10
|
+
private testTimezone;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=14-data-integrity-auditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"14-data-integrity-auditor.d.ts","sourceRoot":"","sources":["../../agents/14-data-integrity-auditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAuBzC,qBAAa,yBAA0B,SAAQ,SAAS;IACtD,QAAQ,CAAC,OAAO,MAAM;IACtB,QAAQ,CAAC,SAAS,4BAA4B;cAE9B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;cAsB1B,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YAiE/B,iBAAiB;YAsLjB,oBAAoB;YAgEpB,YAAY;CAuD3B"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { BaseAgent } from './base-agent';
|
|
2
|
+
import { ApiClient } from '../helpers/api-client';
|
|
3
|
+
import { resolveEnvironment, isUrlReachable } from '../helpers/env-resolver';
|
|
4
|
+
export class DataIntegrityAuditorAgent extends BaseAgent {
|
|
5
|
+
agentId = 14;
|
|
6
|
+
agentName = 'Data Integrity Auditor';
|
|
7
|
+
async preFlight() {
|
|
8
|
+
if (!this.config.accuracy.enabled) {
|
|
9
|
+
throw new Error('config.accuracy.enabled is false — Data Integrity Auditor requires accuracy checks to be enabled');
|
|
10
|
+
}
|
|
11
|
+
const { env, fallback } = await resolveEnvironment(this.config, this.phase);
|
|
12
|
+
if (!env) {
|
|
13
|
+
throw new Error('No environment configured — cannot verify API reachability');
|
|
14
|
+
}
|
|
15
|
+
// If we fell back to alpha, don't throw on unreachable — execute() will handle it gracefully
|
|
16
|
+
if (!fallback) {
|
|
17
|
+
const reachable = await isUrlReachable(env.baseUrl);
|
|
18
|
+
if (!reachable) {
|
|
19
|
+
throw new Error(`API base URL is not reachable: ${env.baseUrl}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async execute() {
|
|
24
|
+
const findings = [];
|
|
25
|
+
const { env, fallback } = await resolveEnvironment(this.config, this.phase);
|
|
26
|
+
if (!env) {
|
|
27
|
+
findings.push({
|
|
28
|
+
id: '14-no-env',
|
|
29
|
+
type: 'infra-issue',
|
|
30
|
+
severity: 'critical',
|
|
31
|
+
agentId: this.agentId,
|
|
32
|
+
module: 'data-integrity',
|
|
33
|
+
description: 'No environment configured — cannot determine base URL',
|
|
34
|
+
});
|
|
35
|
+
return findings;
|
|
36
|
+
}
|
|
37
|
+
const credentials = this.config.auth.credentials?.['admin'] ??
|
|
38
|
+
Object.values(this.config.auth.credentials ?? {})[0];
|
|
39
|
+
if (!credentials) {
|
|
40
|
+
findings.push({
|
|
41
|
+
id: '14-no-credentials',
|
|
42
|
+
type: 'infra-issue',
|
|
43
|
+
severity: 'critical',
|
|
44
|
+
agentId: this.agentId,
|
|
45
|
+
module: 'data-integrity',
|
|
46
|
+
description: 'No credentials configured in auth.credentials — cannot authenticate',
|
|
47
|
+
});
|
|
48
|
+
return findings;
|
|
49
|
+
}
|
|
50
|
+
let client;
|
|
51
|
+
try {
|
|
52
|
+
client = await ApiClient.createAuthenticated(env.baseUrl, credentials);
|
|
53
|
+
}
|
|
54
|
+
catch (authErr) {
|
|
55
|
+
// Auth failure is always medium — indicates missing API or wrong credentials, not a data integrity bug
|
|
56
|
+
const authSeverity = 'medium';
|
|
57
|
+
findings.push({
|
|
58
|
+
id: '14-auth-failed',
|
|
59
|
+
type: 'infra-issue',
|
|
60
|
+
severity: authSeverity,
|
|
61
|
+
agentId: this.agentId,
|
|
62
|
+
module: 'data-integrity',
|
|
63
|
+
description: `Authentication failed: ${authErr instanceof Error ? authErr.message : String(authErr)}`,
|
|
64
|
+
});
|
|
65
|
+
return findings;
|
|
66
|
+
}
|
|
67
|
+
// CRUD round-trip tests
|
|
68
|
+
const crudFindings = await this.testCrudRoundTrip(client);
|
|
69
|
+
findings.push(...crudFindings);
|
|
70
|
+
// Decimal precision test
|
|
71
|
+
const decimalFindings = await this.testDecimalPrecision(client);
|
|
72
|
+
findings.push(...decimalFindings);
|
|
73
|
+
// Timezone test
|
|
74
|
+
const timezoneFindings = await this.testTimezone(client);
|
|
75
|
+
findings.push(...timezoneFindings);
|
|
76
|
+
return findings;
|
|
77
|
+
}
|
|
78
|
+
async testCrudRoundTrip(client) {
|
|
79
|
+
const findings = [];
|
|
80
|
+
let createdId = null;
|
|
81
|
+
const createPayload = {
|
|
82
|
+
name: 'TF-DataIntegrity-Test',
|
|
83
|
+
email: `tf-integrity-${Date.now()}@test.invalid`,
|
|
84
|
+
testRecord: true,
|
|
85
|
+
};
|
|
86
|
+
// CREATE
|
|
87
|
+
let createResp;
|
|
88
|
+
try {
|
|
89
|
+
createResp = await client.post('/api/clients', createPayload);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
findings.push({
|
|
93
|
+
id: '14-crud-create-error',
|
|
94
|
+
type: 'infra-issue',
|
|
95
|
+
severity: 'critical',
|
|
96
|
+
agentId: this.agentId,
|
|
97
|
+
module: 'data-integrity',
|
|
98
|
+
description: `POST /api/clients failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
99
|
+
});
|
|
100
|
+
return findings;
|
|
101
|
+
}
|
|
102
|
+
if (createResp.status !== 200 && createResp.status !== 201) {
|
|
103
|
+
findings.push({
|
|
104
|
+
id: '14-crud-create-status',
|
|
105
|
+
type: 'code-bug-logic',
|
|
106
|
+
severity: 'high',
|
|
107
|
+
agentId: this.agentId,
|
|
108
|
+
module: 'data-integrity',
|
|
109
|
+
description: `POST /api/clients returned ${createResp.status} — expected 200 or 201`,
|
|
110
|
+
});
|
|
111
|
+
return findings;
|
|
112
|
+
}
|
|
113
|
+
const created = createResp.body;
|
|
114
|
+
createdId = created?.id ?? null;
|
|
115
|
+
if (!createdId) {
|
|
116
|
+
findings.push({
|
|
117
|
+
id: '14-crud-create-no-id',
|
|
118
|
+
type: 'code-bug-logic',
|
|
119
|
+
severity: 'high',
|
|
120
|
+
agentId: this.agentId,
|
|
121
|
+
module: 'data-integrity',
|
|
122
|
+
description: 'POST /api/clients response did not include an `id` field',
|
|
123
|
+
});
|
|
124
|
+
return findings;
|
|
125
|
+
}
|
|
126
|
+
// READ — verify all fields match what was sent
|
|
127
|
+
let readResp;
|
|
128
|
+
try {
|
|
129
|
+
readResp = await client.get(`/api/clients/${createdId}`);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
findings.push({
|
|
133
|
+
id: `14-crud-read-error-${createdId}`,
|
|
134
|
+
type: 'infra-issue',
|
|
135
|
+
severity: 'critical',
|
|
136
|
+
agentId: this.agentId,
|
|
137
|
+
module: 'data-integrity',
|
|
138
|
+
description: `GET /api/clients/${createdId} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
139
|
+
});
|
|
140
|
+
return findings;
|
|
141
|
+
}
|
|
142
|
+
if (readResp.status !== 200) {
|
|
143
|
+
findings.push({
|
|
144
|
+
id: `14-crud-read-status-${createdId}`,
|
|
145
|
+
type: 'code-bug-logic',
|
|
146
|
+
severity: 'high',
|
|
147
|
+
agentId: this.agentId,
|
|
148
|
+
module: 'data-integrity',
|
|
149
|
+
description: `GET /api/clients/${createdId} returned ${readResp.status} — expected 200 after create`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
const read = readResp.body;
|
|
154
|
+
// Verify fields match
|
|
155
|
+
const mismatches = [];
|
|
156
|
+
if (read.name !== createPayload.name) {
|
|
157
|
+
mismatches.push(`name: sent "${createPayload.name}", got "${read.name}"`);
|
|
158
|
+
}
|
|
159
|
+
if (read.email !== createPayload.email) {
|
|
160
|
+
mismatches.push(`email: sent "${createPayload.email}", got "${read.email}"`);
|
|
161
|
+
}
|
|
162
|
+
if (mismatches.length > 0) {
|
|
163
|
+
findings.push({
|
|
164
|
+
id: `14-crud-field-mismatch-${createdId}`,
|
|
165
|
+
type: 'code-bug-logic',
|
|
166
|
+
severity: 'high',
|
|
167
|
+
agentId: this.agentId,
|
|
168
|
+
module: 'data-integrity',
|
|
169
|
+
description: `CREATE→READ field mismatch for client ${createdId}: ${mismatches.join('; ')}`,
|
|
170
|
+
suggestedFix: 'Verify the API serialises and persists all fields from the request body',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// UPDATE
|
|
175
|
+
const updatePayload = { name: 'TF-DataIntegrity-Updated' };
|
|
176
|
+
let updateResp;
|
|
177
|
+
try {
|
|
178
|
+
updateResp = await client.put(`/api/clients/${createdId}`, updatePayload);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
findings.push({
|
|
182
|
+
id: `14-crud-update-error-${createdId}`,
|
|
183
|
+
type: 'infra-issue',
|
|
184
|
+
severity: 'high',
|
|
185
|
+
agentId: this.agentId,
|
|
186
|
+
module: 'data-integrity',
|
|
187
|
+
description: `PUT /api/clients/${createdId} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (updateResp && (updateResp.status === 200 || updateResp.status === 204)) {
|
|
191
|
+
// Read back and verify update was applied
|
|
192
|
+
const afterUpdateResp = await client.get(`/api/clients/${createdId}`).catch(() => null);
|
|
193
|
+
if (afterUpdateResp && afterUpdateResp.status === 200) {
|
|
194
|
+
const updated = afterUpdateResp.body;
|
|
195
|
+
if (updated.name !== updatePayload.name) {
|
|
196
|
+
findings.push({
|
|
197
|
+
id: `14-crud-update-mismatch-${createdId}`,
|
|
198
|
+
type: 'code-bug-logic',
|
|
199
|
+
severity: 'high',
|
|
200
|
+
agentId: this.agentId,
|
|
201
|
+
module: 'data-integrity',
|
|
202
|
+
description: `UPDATE→READ mismatch for client ${createdId}: name should be "${updatePayload.name}" but got "${updated.name}"`,
|
|
203
|
+
suggestedFix: 'Verify the API persists PUT request body fields correctly',
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// DELETE
|
|
209
|
+
let deleteResp;
|
|
210
|
+
try {
|
|
211
|
+
deleteResp = await client.delete(`/api/clients/${createdId}`);
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
findings.push({
|
|
215
|
+
id: `14-crud-delete-error-${createdId}`,
|
|
216
|
+
type: 'infra-issue',
|
|
217
|
+
severity: 'high',
|
|
218
|
+
agentId: this.agentId,
|
|
219
|
+
module: 'data-integrity',
|
|
220
|
+
description: `DELETE /api/clients/${createdId} failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
221
|
+
});
|
|
222
|
+
return findings;
|
|
223
|
+
}
|
|
224
|
+
if (deleteResp.status !== 200 && deleteResp.status !== 204) {
|
|
225
|
+
findings.push({
|
|
226
|
+
id: `14-crud-delete-status-${createdId}`,
|
|
227
|
+
type: 'code-bug-logic',
|
|
228
|
+
severity: 'medium',
|
|
229
|
+
agentId: this.agentId,
|
|
230
|
+
module: 'data-integrity',
|
|
231
|
+
description: `DELETE /api/clients/${createdId} returned ${deleteResp.status} — expected 200 or 204`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// Verify 404 after delete
|
|
235
|
+
const afterDeleteResp = await client.get(`/api/clients/${createdId}`).catch(() => null);
|
|
236
|
+
if (afterDeleteResp && afterDeleteResp.status !== 404) {
|
|
237
|
+
findings.push({
|
|
238
|
+
id: `14-crud-delete-verify-${createdId}`,
|
|
239
|
+
type: 'code-bug-logic',
|
|
240
|
+
severity: 'high',
|
|
241
|
+
agentId: this.agentId,
|
|
242
|
+
module: 'data-integrity',
|
|
243
|
+
description: `GET /api/clients/${createdId} returned ${afterDeleteResp.status} after DELETE — expected 404`,
|
|
244
|
+
suggestedFix: 'Ensure DELETE removes the record and subsequent GET returns 404',
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return findings;
|
|
248
|
+
}
|
|
249
|
+
async testDecimalPrecision(client) {
|
|
250
|
+
const findings = [];
|
|
251
|
+
const precision = this.config.accuracy.decimalPrecision;
|
|
252
|
+
const testAmount = 1000.105;
|
|
253
|
+
let createdId = null;
|
|
254
|
+
try {
|
|
255
|
+
const createPayload = {
|
|
256
|
+
name: 'TF-Decimal-Test',
|
|
257
|
+
email: `tf-decimal-${Date.now()}@test.invalid`,
|
|
258
|
+
amount: testAmount,
|
|
259
|
+
testRecord: true,
|
|
260
|
+
};
|
|
261
|
+
const createResp = await client.post('/api/clients', createPayload);
|
|
262
|
+
if (createResp.status !== 200 && createResp.status !== 201) {
|
|
263
|
+
// API may not support amount field — skip precision check
|
|
264
|
+
return findings;
|
|
265
|
+
}
|
|
266
|
+
const created = createResp.body;
|
|
267
|
+
createdId = created?.id ?? null;
|
|
268
|
+
if (!createdId)
|
|
269
|
+
return findings;
|
|
270
|
+
const readResp = await client.get(`/api/clients/${createdId}`);
|
|
271
|
+
if (readResp.status !== 200)
|
|
272
|
+
return findings;
|
|
273
|
+
const record = readResp.body;
|
|
274
|
+
const storedAmount = record?.amount;
|
|
275
|
+
if (storedAmount !== undefined && storedAmount !== null) {
|
|
276
|
+
// Check drift: compare to expected precision
|
|
277
|
+
const factor = Math.pow(10, precision);
|
|
278
|
+
const expected = Math.round(testAmount * factor) / factor;
|
|
279
|
+
const stored = Math.round(Number(storedAmount) * factor) / factor;
|
|
280
|
+
if (expected !== stored) {
|
|
281
|
+
findings.push({
|
|
282
|
+
id: `14-decimal-drift-${createdId}`,
|
|
283
|
+
type: 'code-bug-logic',
|
|
284
|
+
severity: 'high',
|
|
285
|
+
agentId: this.agentId,
|
|
286
|
+
module: 'data-integrity',
|
|
287
|
+
description: `Decimal precision drift: sent amount ${testAmount}, stored as ${storedAmount}. ` +
|
|
288
|
+
`Expected ${expected} at ${precision} decimal places, got ${stored}`,
|
|
289
|
+
suggestedFix: 'Use NUMERIC/DECIMAL SQL types with explicit precision rather than FLOAT. ' +
|
|
290
|
+
'Validate and round amounts to configured decimal precision on input.',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// Endpoint may not support amount — skip
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
if (createdId) {
|
|
300
|
+
await client.delete(`/api/clients/${createdId}`).catch(() => undefined);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return findings;
|
|
304
|
+
}
|
|
305
|
+
async testTimezone(client) {
|
|
306
|
+
const findings = [];
|
|
307
|
+
const expectedTimezone = this.config.accuracy.timezone;
|
|
308
|
+
let createdId = null;
|
|
309
|
+
try {
|
|
310
|
+
const createPayload = {
|
|
311
|
+
name: 'TF-Timezone-Test',
|
|
312
|
+
email: `tf-tz-${Date.now()}@test.invalid`,
|
|
313
|
+
testRecord: true,
|
|
314
|
+
};
|
|
315
|
+
const createResp = await client.post('/api/clients', createPayload);
|
|
316
|
+
if (createResp.status !== 200 && createResp.status !== 201)
|
|
317
|
+
return findings;
|
|
318
|
+
const created = createResp.body;
|
|
319
|
+
createdId = created?.id ?? null;
|
|
320
|
+
if (!createdId)
|
|
321
|
+
return findings;
|
|
322
|
+
const readResp = await client.get(`/api/clients/${createdId}`);
|
|
323
|
+
if (readResp.status !== 200)
|
|
324
|
+
return findings;
|
|
325
|
+
const record = readResp.body;
|
|
326
|
+
const createdAt = record?.createdAt;
|
|
327
|
+
if (createdAt && typeof createdAt === 'string') {
|
|
328
|
+
// ISO 8601 dates should end with Z (UTC) or include timezone offset
|
|
329
|
+
const isUtc = createdAt.endsWith('Z') || createdAt.includes('+00:00');
|
|
330
|
+
const isConfiguredTz = expectedTimezone === 'UTC' ? isUtc : createdAt.includes(expectedTimezone);
|
|
331
|
+
if (!isConfiguredTz && !isUtc) {
|
|
332
|
+
findings.push({
|
|
333
|
+
id: `14-timezone-mismatch-${createdId}`,
|
|
334
|
+
type: 'code-bug-logic',
|
|
335
|
+
severity: 'medium',
|
|
336
|
+
agentId: this.agentId,
|
|
337
|
+
module: 'data-integrity',
|
|
338
|
+
description: `Timezone mismatch: createdAt "${createdAt}" does not reflect configured timezone "${expectedTimezone}"`,
|
|
339
|
+
suggestedFix: 'Ensure all datetime fields are stored and returned in the configured timezone. ' +
|
|
340
|
+
'Store as UTC and convert on display, or consistently use the configured timezone.',
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
// Endpoint may not return createdAt — skip
|
|
347
|
+
}
|
|
348
|
+
finally {
|
|
349
|
+
if (createdId) {
|
|
350
|
+
await client.delete(`/api/clients/${createdId}`).catch(() => undefined);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return findings;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=14-data-integrity-auditor.js.map
|