fix(tests): create missing infrastructure stubs and fix AVM spec (GOO-131)
Several committed modules imported files that were never created, causing
every spec that imports SharedModule/NotificationsModule to fail with
"Cannot find module" errors. This commit provides the missing pieces:
API infrastructure stubs (RFC-001/GOO-170 in-flight feature deps):
- shared/infrastructure/versioning.ts: API_VERSION_REGISTRY, resolveMajorSpec
and related types for RFC-001 Phase 1 versioning
- shared/infrastructure/interceptors/index.ts: VersionInterceptor +
DeprecationInterceptor NestJS interceptors
- metrics/metrics.constants.ts: add READ_MODEL_PROJECTOR_LAG_SECONDS,
READ_MODEL_REFRESH_DURATION_SECONDS, READ_MODEL_RECONCILIATION_DRIFT_TOTAL
Phone-login OTP flow (GOO-182 in-flight deps):
- auth/domain/events/phone-login-otp-requested.event.ts: DomainEvent stub
- notifications/.../phone-login-otp-requested.listener.ts: event listener
AVM spec fix:
- analytics/.../prisma-avm.service.spec.ts: switch mock from $queryRawUnsafe
to $queryRaw (findComparables was parameterized in 6774914) and use
mockResolvedValueOnce for correct call-order semantics
After these changes all 333 API + 148 web + 59 mcp-servers tests pass.
Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* RFC-001 Phase 1 — API versioning interceptors.
|
||||
*
|
||||
* Placeholder implementations so the module compiles while the full
|
||||
* versioning feature (GOO-170) is being developed on its own branch.
|
||||
*/
|
||||
import { Injectable, type NestInterceptor, type ExecutionContext, type CallHandler } from '@nestjs/common';
|
||||
import type { Observable } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
export const API_MINOR_HEADER = 'X-Api-Minor-Version';
|
||||
export const API_MINOR_RESOLVED_HEADER = 'X-Api-Minor-Resolved';
|
||||
|
||||
export interface ResolvedApiVersion {
|
||||
major: number;
|
||||
minor: number;
|
||||
raw: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the Accept-Version request header and attaches a parsed
|
||||
* ResolvedApiVersion object to `req.apiVersion` for downstream use.
|
||||
*/
|
||||
@Injectable()
|
||||
export class VersionInterceptor implements NestInterceptor {
|
||||
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
||||
const req = context.switchToHttp().getRequest<{ apiVersion?: ResolvedApiVersion; headers: Record<string, string> }>();
|
||||
const raw = req.headers['accept-version'] ?? 'v1.0';
|
||||
const [majorStr, minorStr] = raw.replace(/^v/, '').split('.');
|
||||
req.apiVersion = {
|
||||
major: parseInt(majorStr ?? '1', 10),
|
||||
minor: parseInt(minorStr ?? '0', 10),
|
||||
raw,
|
||||
};
|
||||
return next.handle();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes deprecation headers when the resolved spec carries a sunset date.
|
||||
*/
|
||||
@Injectable()
|
||||
export class DeprecationInterceptor implements NestInterceptor {
|
||||
intercept(_context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
||||
return next.handle().pipe(
|
||||
tap(() => {
|
||||
// Deprecation warnings are a no-op in the stub.
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
44
apps/api/src/modules/shared/infrastructure/versioning.ts
Normal file
44
apps/api/src/modules/shared/infrastructure/versioning.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* RFC-001 Phase 1 — API versioning registry.
|
||||
*
|
||||
* Placeholder stubs so the module compiles while the full versioning
|
||||
* feature (GOO-170) is being developed on its own branch.
|
||||
*/
|
||||
|
||||
export interface ApiVersionDeprecation {
|
||||
sunset: string;
|
||||
replacement?: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export interface ApiMajorSpec {
|
||||
major: number;
|
||||
minMinor: number;
|
||||
maxMinor: number;
|
||||
deprecation?: ApiVersionDeprecation;
|
||||
}
|
||||
|
||||
export interface ApiVersionRegistry {
|
||||
current: string;
|
||||
specs: ApiMajorSpec[];
|
||||
}
|
||||
|
||||
export const API_VERSION_REGISTRY: ApiVersionRegistry = {
|
||||
current: 'v1.0',
|
||||
specs: [
|
||||
{
|
||||
major: 1,
|
||||
minMinor: 0,
|
||||
maxMinor: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolve the major-version spec for a given Accept-Version header value.
|
||||
* Returns undefined when no matching spec is found.
|
||||
*/
|
||||
export function resolveMajorSpec(version: string): ApiMajorSpec | undefined {
|
||||
const major = parseInt(version.replace(/^v/, '').split('.')[0] ?? '1', 10);
|
||||
return API_VERSION_REGISTRY.specs.find((s) => s.major === major);
|
||||
}
|
||||
Reference in New Issue
Block a user