/** * crew#371: a PROJECT's requirements, domain and coverage, as FOLDS over the per-repo reads that * already exist (design: program-2026-09 design/DES-W4-CR5-PRODUCT-AGGREGATES.md, posted on the * issue). No new source: * * - requirements: `listRequirements` over each repo's `requirements_graph.json` artifact (the one * source, crew#548); * - domain: the same artifact, summarised per domain (full graphs stay on * `GET /repos/:id/domain-graph`; N 15k-requirement graphs in one body is not a view); * - coverage: `adapter.getCoverageReportForRepo` per repo, never the vacuous store-wide report. * * Every `crew.repo` member is a ROW, never dropped: `ok`, `absent` (nothing generated or indexed * yet), `error` (with its status and message), or `dangling` (the member's registry record is * gone). The studio Product view (wicked-studio#157 / #158) reads these. */ import type { FastifyInstance } from 'fastify'; import { z } from 'zod'; import type { CoreAdapter } from '../core/adapter.js'; import type { ProjectCoverageResponse, ProjectDomainResponse, ProjectRequirementsResponse, RepoEntry } from '../core/types.js'; /** At most this many repos are read at once. */ export declare const AGGREGATE_CONCURRENCY = 4; /** A repo's coverage read that takes longer than this is that row's `error`. */ export declare const COVERAGE_TIMEOUT_MS = 15000; /** The project's repos, in membership order: registered ones, and the refs whose record is gone. */ export type Member = { ref: string; repo: RepoEntry | null; }; export declare class AggregateHttpError extends Error { readonly status: number; constructor(status: number, message: string); } export declare function membersOf(adapter: CoreAdapter, projectId: string): Promise; export declare const ProjectRequirementsQuerySchema: z.ZodObject<{ q: z.ZodOptional; risk: z.ZodOptional>; category: z.ZodOptional>; domain: z.ZodOptional; offset: z.ZodDefault; limit: z.ZodDefault; }, "strict", z.ZodTypeAny, { limit: number; offset: number; domain?: string | undefined; q?: string | undefined; risk?: "risk" | "no-risk" | undefined; category?: "functional" | "config-data" | undefined; }, { domain?: string | undefined; limit?: number | undefined; q?: string | undefined; risk?: "risk" | "no-risk" | undefined; offset?: number | undefined; category?: "functional" | "config-data" | undefined; }>; export declare function projectRequirements(adapter: CoreAdapter, projectId: string, query: z.output): Promise; export declare function projectDomain(adapter: CoreAdapter, projectId: string): Promise; export declare function projectCoverage(adapter: CoreAdapter, projectId: string, timeoutMs?: number): Promise; /** `GET /projects/:id/{requirements,domain,coverage}`. */ export declare function registerProjectAggregateRoutes(app: FastifyInstance, adapter: CoreAdapter): void; //# sourceMappingURL=project-aggregates.d.ts.map