seahaven-ap/packages/api/src/env.ts
Adam Moussa 9d3646876e
feat(api): stand up Hono Drizzle foundation with auth and Redocly (AP-14) (#12)
* feat(api): stand up Hono Drizzle foundation with auth and Redocly

* fix(api): bump drizzle-orm and hono node-server past audit highs

* fix(api): harden auth upsert and Cognito token verification
2026-08-11 00:10:49 +00:00

81 lines
2.5 KiB
TypeScript

export const USER_ROLES = ["admin", "ap_processor", "approver", "viewer"] as const;
export type UserRole = (typeof USER_ROLES)[number];
export function isUserRole(value: string): value is UserRole {
return (USER_ROLES as readonly string[]).includes(value);
}
export type ApiEnv = {
nodeEnv: string;
port: number;
databaseDriver: "postgres" | "data-api";
databaseUrl: string;
awsRegion: string;
rdsClusterArn: string;
rdsSecretArn: string;
rdsDatabase: string;
cognitoIssuer: string;
cognitoAudience: string;
devAuthBypass: boolean;
devAuthSub: string;
devAuthEmail: string;
devAuthName: string;
devAuthRole: UserRole;
};
function required(name: string, value: string | undefined): string {
if (!value) {
throw new Error(`Missing required env var ${name}.`);
}
return value;
}
export function loadEnv(env: NodeJS.ProcessEnv = process.env): ApiEnv {
const nodeEnv = env.NODE_ENV ?? "development";
const databaseDriver = (env.DATABASE_DRIVER ?? "postgres") as ApiEnv["databaseDriver"];
if (databaseDriver !== "postgres" && databaseDriver !== "data-api") {
throw new Error(`Invalid DATABASE_DRIVER: ${databaseDriver}`);
}
const devAuthBypass = env.DEV_AUTH_BYPASS === "true";
const localNodeEnvs = new Set(["development", "test"]);
if (devAuthBypass && !localNodeEnvs.has(nodeEnv)) {
throw new Error("DEV_AUTH_BYPASS is only allowed when NODE_ENV is development or test.");
}
const rawRole = env.DEV_AUTH_ROLE ?? "admin";
if (!isUserRole(rawRole)) {
throw new Error(`Invalid DEV_AUTH_ROLE: ${rawRole}`);
}
const base: ApiEnv = {
nodeEnv,
port: Number(env.API_PORT ?? "8787"),
databaseDriver,
databaseUrl: env.DATABASE_URL ?? "postgresql://seahaven:seahaven@127.0.0.1:5432/seahaven_ap",
awsRegion: env.AWS_REGION ?? "us-east-1",
rdsClusterArn: env.RDS_CLUSTER_ARN ?? "",
rdsSecretArn: env.RDS_SECRET_ARN ?? "",
rdsDatabase: env.RDS_DATABASE ?? "seahaven_ap",
cognitoIssuer: env.COGNITO_ISSUER ?? "",
cognitoAudience: env.COGNITO_AUDIENCE ?? "",
devAuthBypass,
devAuthSub: env.DEV_AUTH_SUB ?? "seed-sub-admin",
devAuthEmail: env.DEV_AUTH_EMAIL ?? "admin@seahavenind.com",
devAuthName: env.DEV_AUTH_NAME ?? "Dev Admin",
devAuthRole: rawRole,
};
if (databaseDriver === "data-api") {
required("RDS_CLUSTER_ARN", base.rdsClusterArn);
required("RDS_SECRET_ARN", base.rdsSecretArn);
}
if (!devAuthBypass && nodeEnv !== "test") {
required("COGNITO_ISSUER", base.cognitoIssuer);
required("COGNITO_AUDIENCE", base.cognitoAudience);
}
return base;
}