forked from EduCraft/curriculum-project-hub
feat: add deployable alpha silo
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import type { PrismaClient } from "@prisma/client";
|
||||
|
||||
export interface SiloOrganization {
|
||||
readonly id: string;
|
||||
readonly slug: string;
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the deployment-pinned Organization identity. A Silo process must never
|
||||
* infer its tenant from request data or from whichever row happens to exist.
|
||||
*/
|
||||
export function readSiloOrganizationId(
|
||||
env: Readonly<Record<string, string | undefined>> = process.env,
|
||||
): string {
|
||||
const organizationId = env["HUB_SILO_ORGANIZATION_ID"]?.trim();
|
||||
if (organizationId === undefined || organizationId === "") {
|
||||
throw new Error("HUB_SILO_ORGANIZATION_ID is required");
|
||||
}
|
||||
return organizationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prove the database is a single-tenant Silo before accepting traffic.
|
||||
* Archived rows count too: pointing a Silo process at a pooled or reused
|
||||
* database is a deployment error, not a condition to paper over.
|
||||
*/
|
||||
export async function requireSiloOrganization(
|
||||
prisma: PrismaClient,
|
||||
organizationId: string,
|
||||
): Promise<SiloOrganization> {
|
||||
const [count, organization] = await Promise.all([
|
||||
prisma.organization.count(),
|
||||
prisma.organization.findUnique({
|
||||
where: { id: organizationId },
|
||||
select: { id: true, slug: true, name: true, status: true },
|
||||
}),
|
||||
]);
|
||||
if (count !== 1) {
|
||||
throw new Error(`Silo database must contain exactly one Organization; found ${count}`);
|
||||
}
|
||||
if (organization === null) {
|
||||
throw new Error(
|
||||
`Silo Organization mismatch: configured ${organizationId} is not the sole database Organization`,
|
||||
);
|
||||
}
|
||||
if (organization.status !== "ACTIVE") {
|
||||
throw new Error(`Silo Organization ${organizationId} is ${organization.status}`);
|
||||
}
|
||||
return { id: organization.id, slug: organization.slug, name: organization.name };
|
||||
}
|
||||
Reference in New Issue
Block a user