feat(core-shared): add withRateLimit wrapper and conformance enforcement

- Add withRateLimit(rateLimit, fn) in rate-limit/with-rate-limit.ts,
  attaching the RateLimited brand at DI bind time
- Extend wireUseCase to accept optional rateLimit?: IRateLimit and
  compose withRateLimit innermost (before analytics/audit); propagate
  __rateLimited through analytics + audit inline wrappers
- Extend withSpan and withCapture PROPAGATED_BRANDS to include
  __rateLimited so the outermost binding carries the brand
- Extend assertFeatureConformance to require __rateLimited brand when
  manifest.useCases[name].rateLimit.length > 0; refactored into
  helper functions to stay within complexity thresholds
- Add rateLimit?: IRateLimit to BindContext; default to NoopRateLimit
  in web-next bindAllProduction and bindAllDevSeed aggregators
- Unit tests for withRateLimit brand attachment, factory passthrough,
  and composition; synthetic fixture tests for conformance errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 09:00:31 +00:00
parent 24b2490d86
commit cb61f51ee1
12 changed files with 477 additions and 61 deletions

View File

@@ -2,8 +2,10 @@ import type { Container } from "inversify";
import type { ITracer } from "../instrumentation/tracer.interface";
import type { ILogger } from "../instrumentation/logger.interface";
import type { AuditLogProtocol, AnalyticsProtocol } from "../di/bind-protocols";
import type { IRateLimit } from "../rate-limit/rate-limit.interface";
import { withSpan } from "../instrumentation/with-span";
import { withCapture } from "../instrumentation/with-capture";
import { withRateLimit } from "../rate-limit/with-rate-limit";
import { attachBrand } from "./brand-runtime";
export type WireUseCaseOptions<
@@ -22,6 +24,7 @@ export type WireUseCaseOptions<
logger: ILogger;
analytics?: AnalyticsProtocol;
auditLog?: AuditLogProtocol;
rateLimit?: IRateLimit;
};
/**
@@ -53,6 +56,7 @@ export function wireUseCase<
logger,
analytics,
auditLog,
rateLimit,
} = opts;
const spanName = `${feature}.${name}`;
@@ -60,17 +64,27 @@ export function wireUseCase<
const raw = factory(...deps);
let toWrap: (...args: FnArgs) => Promise<R>;
// analytics is innermost — wraps raw before audit. withAnalytics lives in
// rateLimit is innermost — wraps raw before analytics/audit. Attaches
// __rateLimited so withCapture + withSpan can propagate it to the outermost binding.
let toWrap: (...args: FnArgs) => Promise<R> =
rateLimit !== undefined ? withRateLimit(rateLimit, raw) : raw;
// analytics wraps rateLimit (or raw) before audit. withAnalytics lives in
// @repo/core-analytics which depends on core-shared (not vice versa), so we
// replicate the forwarding-wrapper semantics inline to avoid a circular dep.
if (analytics !== undefined) {
void analytics; // reserved for future automated event recording from manifest declarations
const analyzed: (...args: FnArgs) => Promise<R> = (...args) => raw(...args);
const prev = toWrap;
const analyzed: (...args: FnArgs) => Promise<R> = (...args) =>
prev(...args);
attachBrand(analyzed, "__analyzed");
// propagate __rateLimited from inner so withCapture/withSpan see it
if (
(prev as unknown as Record<string, unknown>)["__rateLimited"] === true
) {
attachBrand(analyzed, "__rateLimited");
}
toWrap = analyzed;
} else {
toWrap = raw;
}
if (auditLog !== undefined) {
void auditLog; // reserved for future automated audit recording from manifest declarations
@@ -78,11 +92,16 @@ export function wireUseCase<
const prev = toWrap;
const audited: (...args: FnArgs) => Promise<R> = (...args) => prev(...args);
attachBrand(audited, "__audited");
// propagate __analyzed from the analytics layer below so withCapture/withSpan
// can see it on the outermost binding
// propagate __analyzed and __rateLimited from inner so withCapture/withSpan
// can see them on the outermost binding
if ((prev as unknown as Record<string, unknown>)["__analyzed"] === true) {
attachBrand(audited, "__analyzed");
}
if (
(prev as unknown as Record<string, unknown>)["__rateLimited"] === true
) {
attachBrand(audited, "__rateLimited");
}
toWrap = audited;
}