FIX: Type Safety, Environment Validation, Redis Integration Tests, an… - #413
Merged
meshackyaro merged 1 commit intoAug 31, 2026
Merged
Conversation
…d Dependency Scanning
|
@Biokes 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! 🚀 |
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR addresses four related infrastructure and code quality improvements that strengthen the backend's type safety, configuration management, testing coverage, and security posture.
Closes #224
Closes #231
Closes #223
Closes #226
Summary of Changes
#224 — Enable TypeScript
noImplicitAnyand ESLintno-explicit-anyProblem: The codebase had
noImplicitAny: falseintsconfig.jsonandno-explicit-any: "off"in.eslintrc.js, allowing implicitanytypes to slip through in request parsing, RPC response handling, and other critical paths where static typing provides the most value.Solution:
Fixed all implicit/explicit
anyusages in production code:health.controller.ts: ChangedPromise<any>toPromise<HealthStatus>event-processor.service.ts: Changedvalue: anytovalue: Record<string, unknown>auth.guard.ts: TypedhandleRequestsignature to match Passport's base classrate-limit.guard.ts: CreatedRateLimitRequestinterface for type-safe request handlingevent-ingestion.service.ts: Usedxdr.ScValandSorobanRpc.Server.GetEventsRequesttypessoroban.helper.ts: Added proper type guard forSimulateTransactionResponsestellar.service.ts: UsedHorizon.HorizonApi.BalanceLinetypediscord.service.ts: Added proper error type guardmetrics-http.interceptor.ts: ChangedObservable<any>toObservable<unknown>admin.guard.ts: Explicitly typed.map()callback parameterEnabled strict compiler and lint checks:
noImplicitAny: trueintsconfig.json@typescript-eslint/no-explicit-any: "warn"in.eslintrc.jsAdded
// eslint-disable-next-linecomments to spec files where mocks legitimately useany(test-only suppressions)Acceptance Criteria: ✅
npx tsc --noEmitandnpm run lint:checkboth pass with strict settings enabled#231 — Add Redis Integration Tests for Lua Scripts
Problem: Rate-limit and nonce-store specs mocked the Redis client rather than exercising the real Lua scripts (
TOKEN_BUCKET_SCRIPT,ABUSE_LOCKOUT_SCRIPT,GETDEL_LUA) against an actual Redis server. Lua script bugs (syntax errors, incorrectKEYS/ARGVindexing) would only surface at runtime in production.Solution:
redis:7-alpineservice container configured ✅gig.service.redis-integration.spec.tspattern:backend/src/auth/nonce-store.redis-integration.spec.ts:GETDEL_LUAatomic get-and-delete scriptdescribeIfRedispattern (skips whenREDIS_URLunset for local dev)backend/src/common/rate-limit/rate-limit.redis-integration.spec.ts:TOKEN_BUCKET_SCRIPTfor token bucket refill and capacity managementABUSE_LOCKOUT_SCRIPTfor sorted-set abuse tracking and lockout triggeringZREMRANGEBYSCOREcleanup, IP vs wallet bucket independence, and state persistence across guard instancesAcceptance Criteria: ✅
npm testruns are unaffected whenREDIS_URLisn't set (tests skip gracefully)#223 — Add Startup Environment Variable Validation with Zod
Problem: Configuration was read ad hoc with inline
process.env.X || fallbackscattered across many files. A typo'd variable name, empty string, or malformed value would silently fall through to a default or unusable value rather than failing at startup with a clear error.Solution:
Created
backend/src/config/env.config.tswith a centralized Zod schema for every environment variable the app reads:z.coerce.number(),z.string().url(),z.enum([...]),z.string().regex(...)Added
validateEnv()function called once at startup inmain.ts:Replaced scattered inline reads with typed
configobject imports across 13 files:main.ts,auth.module.ts,jwt.strategy.ts,discord.service.ts,redis.module.tsstellar.config.ts,rate-limit.guard.ts,event-ingestion.service.ts,soroban.helper.tshealth.service.ts,admin.guard.tsCreated comprehensive test suite (
env.config.spec.ts) covering:Acceptance Criteria: ✅
#226 — Add
npm auditDependency Vulnerability Scanning to CIProblem: CI had no automated signal when a known CVE landed in the dependency tree. With
@stellar/stellar-sdk,ioredis,@sentry/node, and other dependencies pulling in a large transitive tree, vulnerabilities could go unnoticed until discovered manually.Solution:
npm audit --audit-level=highstep to.github/workflows/backend-ci.ymlafter the build stepbackend/package-lock.jsondependency treeAcceptance Criteria: ✅
Testing
All changes are backward-compatible and have been verified to:
noImplicitAny: trueno-explicit-any: "warn"The Redis integration tests will run in CI against the existing
redis:7-alpineservice container and skip gracefully in local environments withoutREDIS_URL.Migration Notes
Environment Variables:
After merging, the app will fail to start if
JWT_SECRETis not set or is shorter than 16 characters. Ensure your.envfile or deployment environment includes:All other environment variables have sensible defaults and are optional. If any required variable is missing or malformed, the startup error message will list exactly which variables need to be fixed.
Files Changed
Configuration & Core:
.github/workflows/backend-ci.yml— Added npm audit stepbackend/tsconfig.json— EnablednoImplicitAnybackend/.eslintrc.js— Enabledno-explicit-any: "warn"backend/src/config/env.config.ts— New centralized env validation (NEW)backend/src/config/env.config.spec.ts— Env validation tests (NEW)backend/src/main.ts— Added env validation at startup, replaced inline readsType Safety Fixes:
backend/src/monitoring/health.controller.tsbackend/src/event-ingestion/event-processor.service.tsbackend/src/auth/auth.guard.tsbackend/src/common/rate-limit/rate-limit.guard.tsbackend/src/event-ingestion/event-ingestion.service.tsbackend/src/stellar/soroban.helper.tsbackend/src/stellar/stellar.service.tsbackend/src/webhook/discord.service.tsbackend/src/monitoring/metrics-http.interceptor.tsbackend/src/admin/admin.guard.tsConfig Migration:
backend/src/auth/auth.module.tsbackend/src/auth/jwt.strategy.tsbackend/src/common/redis/redis.module.tsbackend/src/stellar/stellar.config.tsbackend/src/monitoring/health.service.tsRedis Integration Tests (NEW):
backend/src/auth/nonce-store.redis-integration.spec.tsbackend/src/common/rate-limit/rate-limit.redis-integration.spec.tsTest Updates:
backend/src/auth/nonce-store.service.spec.tsbackend/src/common/rate-limit/rate-limit.guard.spec.tsbackend/src/auth/auth.service.spec.tsbackend/src/auth/auth.controller.spec.tsbackend/src/ipfs-pinning/ipfs-pinning.e2e-spec.tsChecklist