All files / lib env-config.ts

100% Statements 9/9
100% Branches 2/2
100% Functions 4/4
100% Lines 9/9

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                                                            220x     220x   220x                 61x                     5x                                         53x 35x   18x                     13x    
/**
 * Non-Secret Environment Configuration
 *
 * Stores non-secret, environment-specific values in code rather than env vars.
 * Only true secrets (API keys, OAuth secrets, access tokens) belong in .dev.vars
 * or `wrangler secret put`.
 *
 * Follows the same pattern as domain-utils.ts: pure functions, env as parameter.
 */
 
import type { Environment } from "./domain-utils";
 
/**
 * WhatsApp Cloud API identifiers (non-secret โ€” these are Meta account IDs
 * visible in the Meta Developer Console, not credentials).
 *
 * Account model after the 2026-08 migration to the new Meta business account:
 * one WABA shared by every environment, with production on its own sender
 * number and all non-production environments sharing a second one. Template
 * approvals still apply account-wide (one provisioning run covers every env),
 * while send volume, quality rating and per-number rate limits are isolated โ€”
 * so dev/preview traffic can no longer drag down production's quality rating.
 *
 * Consequences to remember:
 * - `wa_templates` rows are WABA-scoped and therefore identical across envs.
 * - A message sent from dev cannot be replied to on the production number.
 * - Dev and preview share a number, so their conversation threads at Meta are
 *   the same thread. Only one env owns the webhook, so only that env records
 *   the inbound side (see docs/operations/whatsapp.md ยง14, limitation 2).
 */
const WHATSAPP_WABA_ID = "1671401930598703";
 
/** Non-production sender. Shared by local, development, dev and preview. */
const WHATSAPP_NON_PROD_PHONE_NUMBER_ID = "1202773472929711";
 
const WHATSAPP_PHONE_NUMBER_IDS: Record<Environment, string> = {
	local: WHATSAPP_NON_PROD_PHONE_NUMBER_ID,
	development: WHATSAPP_NON_PROD_PHONE_NUMBER_ID,
	dev: WHATSAPP_NON_PROD_PHONE_NUMBER_ID,
	preview: WHATSAPP_NON_PROD_PHONE_NUMBER_ID,
	production: "1328095217044683",
};
 
export function getWhatsAppIds(env: Environment) {
	return {
		phoneNumberId: WHATSAPP_PHONE_NUMBER_IDS[env],
		wabaId: WHATSAPP_WABA_ID,
	} as const;
}
 
/**
 * OAuth provider public client IDs.
 * These are public values visible in OAuth redirect URLs โ€” not secrets.
 */
export function getOAuthClientIds() {
	return {
		google:
			"330313688024-d12ad189cectr4d6mrbq7hb2hrrthj62.apps.googleusercontent.com",
		facebook: "953599880467479",
	} as const;
}
 
export type WhatsAppSafetyConfig = {
	overrideNumber: string | undefined;
	allowedNumbers: string[];
};
 
/**
 * WhatsApp safety guards for non-production environments.
 * In production, messages go to real recipients.
 * In non-prod, messages are redirected to the override number unless
 * the recipient is in the allowed list.
 */
export function getWhatsAppSafetyConfig(
	env: Environment,
): WhatsAppSafetyConfig {
	if (env === "production") {
		return { overrideNumber: undefined, allowedNumbers: [] };
	}
	return {
		overrideNumber: "919550794178",
		allowedNumbers: ["919550794178", "919885365664"],
	};
}
 
/**
 * SMS provider name for the given environment.
 * Currently only "console" is implemented.
 */
export function getSmsProviderName(_env: Environment): string {
	return "console";
}