# VV_ISSUE_003 — `any` type usage in src/db/pool.ts

**Status:** RESOLVED
**Severity:** MAJOR
**Category:** TYPE_VIOLATION
**Logged by:** LeadValidator
**Date:** 2026-04-07
**Audit phase:** Phase C — TypeScript Standards Audit

## Finding

The PRD (Sections 6.4 and 4.5) states: "No `any` types — ever." and "TypeScript strict mode:
zero `any` types." The `tsconfig.json` correctly enables `noImplicitAny: true` and all strict
flags.

Despite this, `src/db/pool.ts` contains explicit `any` type casts on two lines (lines 89 and
91), with ESLint suppression comments (`eslint-disable-next-line @typescript-eslint/no-explicit-any`)
added to bypass the linting rule. While the developer included a comment explaining the
technical reason (wrapping the pg query method in a shim that is difficult to type precisely),
the PRD standard is absolute: zero `any` types, with no exceptions granted.

The intent of the standard is to eliminate unsafe escape hatches that weaken TypeScript's
type safety guarantees. Using `any` in the database pool layer — a critical path component —
is particularly concerning since this wraps every database query in the application.

## Evidence

**File:** `src/db/pool.ts`, lines 88–91:

```typescript
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const originalQuery = pool.query.bind(pool) as (...args: any[]) => Promise<any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(pool as any).query = async (...args: any[]): Promise<any> => {
```

There are 5 `any` occurrences on these two lines:
- `(...args: any[]) => Promise<any>` — line 89
- `(pool as any)` — line 91
- `(...args: any[]): Promise<any>` — line 91

The surrounding comment (lines 84–87) acknowledges the issue and explains the rationale, but
does not resolve it per PRD standards.

## Required Action

Replace the `any` types in `src/db/pool.ts` with properly typed alternatives. Options:

1. Use the `pg` library's exported `QueryConfig`, `QueryResultRow`, and overload signatures
   to type the query wrapper correctly without resorting to `any`.
2. Use generic types: `<T extends QueryResultRow>(...args: Parameters<Pool['query']>) => Promise<QueryResult<T>>`
3. If the shim cannot be typed without `any` due to pg's type definitions, document the
   specific technical constraint and seek CEO approval for a formal exemption. An exemption
   does NOT mean leaving it as-is — it means a tracked, acknowledged deviation.

Remove the `eslint-disable-next-line` suppression comments once the `any` types are resolved.

## CTO Response

Agreed. The `any` types in pool.ts were a sanctioned workaround for pg's overloaded `Pool.query` signature. The correct solution is to use `unknown[]` rest parameters and `Object.defineProperty` to replace the method without widening the pool reference to `any`. The pool's typed interface is preserved at the type level for all callers; only the internal shim uses `unknown` as the safe alternative to `any`.

## Resolution

**Fixed in:** `src/db/pool.ts`

Replaced the two `any`-typed lines and two `eslint-disable-next-line` suppressions with a clean `Object.defineProperty` shim:
- `originalQuery` is typed via `pool.query.bind(pool)` — no cast needed
- The replacement function uses `unknown[]` rest params and `Promise<unknown>` — zero `any` types
- TypeScript compiles clean (`npx tsc --noEmit` — 0 errors)
- Pool's typed interface (`Pool['query']`) unchanged for all callers
