Files
curriculum-project-hub/hub/src/org/capacityPolicy.ts
T
hongjr03 3f9b60f692 chore: remove Lean spec; ADRs are the single source of truth
The spec/ Lean semantic master had no conformance gate, no codegen, and
no CI tie to implementations — alignment was carried entirely by human
review, the same mechanism that carries the ADRs. In practice the ADRs
plus greppable code comments were already the load-bearing artifacts,
so spec/ was the most expensive kind of stale documentation.

- delete spec/ and the spec-check CI workflow
- README: constitution rewritten around ADRs as decision truth
- AGENTS.md/CLAUDE.md: discipline re-anchored (new decisions -> new ADR,
  never rewrite ADR history; supersede instead)
- code comments: re-anchor 'Mirrors Spec.X' invariants to ADR numbers
  (cph-diag, cph-check, cph-model, hub runner/capacity/org, prisma)
- leave ADR bodies and .scratch audit snapshots untouched (history);
  fix live references in open readiness tickets
2026-07-20 09:07:26 +00:00

103 lines
4.0 KiB
TypeScript

/**
* Org capacity policy service (ADR-0022).
*
* Stores per-Organization lower `organizationLimit` overrides per
* `CapacityDimension`. Enforces the layered-limit invariant: a set limit must be ≤ the
* platform ceiling for that dimension. The effective limit (min of the two)
* is the value capacity admission should use; dimensions with no org override
* fall back to the platform ceiling.
*/
import type { PrismaClient } from "@prisma/client";
import { CAPACITY_DIMENSIONS, isCapacityDimension, type CapacityDimension } from "../capacity/dimensions.js";
import { readPlatformCeilings } from "../capacity/ceilings.js";
import { lockActiveOrganization } from "./status.js";
export interface CapacityPolicyView {
/** Per-dimension: platform ceiling (absent if not configured) + org limit. */
readonly dimensions: ReadonlyArray<{
readonly dimension: CapacityDimension;
readonly platformCeiling: number | null;
readonly organizationLimit: number | null;
readonly effective: number | null;
}>;
}
export async function getCapacityPolicy(
prisma: PrismaClient,
organizationId: string,
): Promise<CapacityPolicyView> {
const row = await prisma.organizationCapacityPolicy.findUnique({
where: { organizationId },
select: { limits: true },
});
const orgLimits = parseLimits(row?.limits);
const ceilings = readPlatformCeilings();
const dimensions = CAPACITY_DIMENSIONS.map((dimension) => {
const platformCeiling = ceilings[dimension] ?? null;
const organizationLimit = orgLimits[dimension] ?? null;
const effective = effectiveLimit(platformCeiling, organizationLimit);
return { dimension, platformCeiling, organizationLimit, effective };
});
return { dimensions };
}
export async function setCapacityPolicy(
prisma: PrismaClient,
input: {
readonly organizationId: string;
/** Partial map of dimension → limit. null/absent clears a dimension. */
readonly limits: Partial<Record<CapacityDimension, number | null>>;
},
): Promise<CapacityPolicyView> {
const ceilings = readPlatformCeilings();
const cleaned: Record<string, number> = {};
for (const [dimension, value] of Object.entries(input.limits)) {
if (!isCapacityDimension(dimension)) {
throw new Error(`unknown capacity dimension: ${dimension}`);
}
if (value === null || value === undefined) continue;
if (!Number.isFinite(value) || value <= 0 || !Number.isInteger(value)) {
throw new Error(`limit for ${dimension} must be a positive integer`);
}
const ceiling = ceilings[dimension];
if (ceiling === undefined) {
throw new Error(
`platform ceiling for ${dimension} is not configured; cannot set an organization limit (spec LayeredLimit.Valid)`,
);
}
if (value > ceiling) {
throw new Error(
`organization limit ${value} for ${dimension} exceeds platform ceiling ${ceiling} (spec LayeredLimit.Valid)`,
);
}
cleaned[dimension] = value;
}
await prisma.$transaction(async (tx) => {
await lockActiveOrganization(tx, input.organizationId);
await tx.organizationCapacityPolicy.upsert({
where: { organizationId: input.organizationId },
create: { organizationId: input.organizationId, limits: cleaned },
update: { limits: cleaned },
});
});
return getCapacityPolicy(prisma, input.organizationId);
}
function effectiveLimit(platformCeiling: number | null, organizationLimit: number | null): number | null {
if (platformCeiling === null) return null;
if (organizationLimit === null) return platformCeiling;
return Math.min(platformCeiling, organizationLimit);
}
function parseLimits(raw: unknown): Partial<Record<CapacityDimension, number>> {
if (raw === null || typeof raw !== "object") return {};
const result: Partial<Record<CapacityDimension, number>> = {};
for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {
if (isCapacityDimension(key) && typeof value === "number" && Number.isFinite(value)) {
result[key] = value;
}
}
return result;
}