Add optional `analyticsEvents?: readonly string[]` to `UseCaseManifest` in `define-feature.ts` so manifests can declare which analytics events a use case emits. Field defaults to absent (treated as []) — all existing manifests remain valid without changes. Update the feature generator template to emit `analyticsEvents: []` so newly scaffolded features are analytics-declaration-ready from day one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import type { CoverageManifest } from "./coverage";
|
|
|
|
/**
|
|
* Per-use-case manifest entry. Declares what the use case does at the contract
|
|
* level: whether it mutates state, what audit events it emits, what cross-feature
|
|
* events it publishes or consumes. The conformance system reads these to
|
|
* derive binding-slot types and to verify code against manifest declarations.
|
|
*/
|
|
export type UseCaseManifest = {
|
|
readonly mutates: boolean;
|
|
readonly audits: readonly string[];
|
|
readonly publishes: readonly string[];
|
|
readonly consumes: readonly string[];
|
|
readonly analyticsEvents?: readonly string[];
|
|
};
|
|
|
|
/**
|
|
* The feature-level manifest. One per feature package, conventionally exported
|
|
* as `<featureName>Manifest` from `src/feature.manifest.ts`.
|
|
*
|
|
* `coverage` is optional for backward compatibility — features without a
|
|
* declared coverage section fall back to `DEFAULT_COVERAGE_BANDS` via
|
|
* `getCoverageBands(manifest)` (see `./coverage.ts`).
|
|
*/
|
|
export type FeatureManifest = {
|
|
readonly name: string;
|
|
readonly requiredCores: readonly string[];
|
|
readonly useCases: { readonly [k: string]: UseCaseManifest };
|
|
readonly realtimeChannels: readonly string[];
|
|
readonly jobs: readonly string[];
|
|
readonly coverage?: CoverageManifest;
|
|
};
|
|
|
|
/**
|
|
* Identity helper that exists purely to widen the input type to satisfy
|
|
* `FeatureManifest` while preserving the literal types of the `as const`
|
|
* input. Downstream types (`ProductionUseCase<I, O, M>`) consume the
|
|
* preserved literals to derive binding-slot brand requirements.
|
|
*
|
|
* Usage:
|
|
*
|
|
* export const authManifest = defineFeature({ name: "auth", ... } as const);
|
|
*/
|
|
export function defineFeature<const M extends FeatureManifest>(manifest: M): M {
|
|
return manifest;
|
|
}
|