Skip to content

feat: test data factories, client bundle secret scan, advisory-lock job leader election, accessible chart tables - #940

Merged
Dydex merged 1 commit into
AstronLabs:mainfrom
Ojukwu-Chinedu:feat/testing-security-database-frontend-batch
Oct 17, 2026
Merged

Dydex merged 1 commit into
AstronLabs:mainfrom
Ojukwu-Chinedu:feat/testing-security-database-frontend-batch

Conversation

@Ojukwu-Chinedu

Copy link
Copy Markdown
Contributor

Summary

Resolves #932, #933, #935 and #928.

closes #932 Shared test data factories

  • backend/src/test-utils/factories/: immutable fluent builders (with, build, buildMany, deep-merge overrides, deterministic ids).
    • applicantFactory: verified(), ineligible(), pending(), deleted(), snapshot().
    • loanFactory (API shape) and loanRowFactory (Prisma row shape): overdue(), repaying(), approved(), manualReview(), ...
    • milestoneProposalFactory: open(), approved(), rejected().
  • testFactories.test.ts compares the Applicant/LoanApplication factories with schema.prisma, so a model change fails in one place.
  • Migrated autoRejectionRules, adminPortfolioDigest, optimisticLocking, loanAsOf.
  • Lint rule: noInlineFixtures.test.ts is a ratcheted guard. Legacy files are baselined and the list can only shrink; // fixture-ok: opts out. Also a PR template checklist item and a CONTRIBUTING note.
  • Docs: docs/TEST_DATA_FACTORIES.md

closes #933 Client bundle secret scan

  • scripts/client-bundle-secret-scan.mjs + .github/workflows/client-bundle-secret-scan.yml.
  • Scans .next/static and app sources in source maps for known key formats: checksum-validated Stellar seeds, AWS/GitHub/Slack/Stripe/etc., PEM, JWT, credentialed URLs, high-entropy secret assignments.
  • Fails if the value of a server-only secret env var appears in the bundle (CI uses a per-run canary).
  • Enforces the NEXT_PUBLIC_ prefix: next.config env:, client-component process.env reads, and secret-looking NEXT_PUBLIC_* names.
  • Reviewed allowlist devops/client-bundle-secret-allowlist.json (SHA-256 or value, reason required). Reports never print full secrets.
  • next.config.ts: productionBrowserSourceMaps only when CLIENT_BUNDLE_SOURCEMAPS=true (CI scan only).
  • 18 tests with planted fake secrets. The real frontend build scans clean.
  • Docs: docs/CLIENT_BUNDLE_SECRET_SCAN.md

closes #935 Advisory-lock leader election

  • services/jobLeaderElection.ts: pg_try_advisory_xact_lock held by an open transaction. A crashed holder's connection dies, so PostgreSQL releases the lock immediately (no TTL).
  • Under the lock: abandon the dead holder's running row, skip if the run already completed within minIntervalMs (recently_run), record ScheduledJobRun {jobName, instanceId, ...}.
  • scheduledJob() wrapper (never rejects, fails closed) applied to cluster-wide jobs in scheduler.ts, partitionManager, analyticsRefresh, webhookAutoDisable, ipfsOrphanCleanup, backupScheduler. Per-process jobs (JWT/secrets/webhook key rotation, mTLS) are intentionally not wrapped.
  • Metrics: remitmortgage_scheduled_job_skipped_total{job,reason}, remitmortgage_scheduled_job_runs_total{job,outcome}.
  • Migration 20261017030000_scheduled_job_runs (with down.sql) + Prisma model.
  • Tests: 12 simulated instances racing, straggler, next tick, crash takeover, failure, metrics, PG backend.
  • Docs: docs/JOB_LEADER_ELECTION.md

closes #928 Accessible chart data tables

  • AccessibleChart wrapper + lib/chart-summary.ts (trend/share summaries).
  • Toggle "View as table / chart" (aria-pressed); real <table> with caption, scope headers, focusable scroll region; live-region announcement. The table renders the same rows as the chart/CSV export, so it follows filters and time range.
  • Applied to Volume Trends, Loan Performance, TVL, Pool APY and ROI Projection.
  • Tests: values match plotted data row for row, headers, keyboard operation, summaries.
  • Docs: docs/ACCESSIBLE_CHART_TABLES.md

Testing

  • Frontend: chart/summary/ROI/export/next-config jest suites pass (24 tests); tsc --noEmit clean.
  • Backend: new jobLeaderElection, testFactories, noInlineFixtures suites plus migrated suites pass (53 tests). Compared with main, the suites I touched show the same pre-existing failures (see notes).
  • node --test scripts/client-bundle-secret-scan.test.mjs: 18/18; scanner run against a real next build with source maps: 0 findings.

Notes for reviewers

  • schema.prisma already fails validation on main (ApiKey.usage references an undefined ApiKeyUsage), so prisma generate fails there. I did not touch it. I verified using a patched copy of the schema.
  • check-migration-rollbacks and a number of backend suites already fail on main in this environment. The new migration has a down.sql.
  • Rollout: apply the migration before deploying, since wrapped jobs fail closed if ScheduledJobRun is missing.

…ection, accessible chart tables

- testing (AstronLabs#932): typed fluent factories for applicants, loans and milestones
  with named variants (verified, overdue, approved, ...). A schema-drift test
  ties them to prisma/schema.prisma. A ratcheted guard test discourages inline
  fixtures. First four test files migrated; pattern documented.
- security (AstronLabs#933): scripts/client-bundle-secret-scan.mjs scans the built client
  bundle and source maps for known key formats, leaked server env values and
  non-NEXT_PUBLIC_ exposure, against a reviewed allowlist. New CI workflow;
  tests plant fake secrets.
- database (AstronLabs#935): PostgreSQL advisory-lock leader election for scheduled jobs.
  One instance runs each tick, the lock is release are
  recorded in ScheduledJobRun, skips are exported as metrics. Scheduler jobs
  wrapped.
- frontend (AstronLabs#928): AccessibleChart wrapper adds a trend summary and a
  chart/table toggle (real table, keyboard operablrt.
@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@Ojukwu-Chinedu Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Dydex
Dydex merged commit 8a26983 into AstronLabs:main Oct 17, 2026
24 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants