Integrate external parts catalogs API with auth service, add BullMQ-based catalog prefetch worker for background data caching, expand vehicles service with shared vehicle support, and add vehicle select modal to frontend. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const envSchema = z.object({
|
|
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
|
|
PORT: z.coerce.number().default(4000),
|
|
|
|
DATABASE_URL: z.string().url(),
|
|
|
|
REDIS_HOST: z.string().default("127.0.0.1"),
|
|
REDIS_PORT: z.coerce.number().default(6379),
|
|
REDIS_PASSWORD: z.string(),
|
|
|
|
BETTER_AUTH_SECRET: z.string().min(32),
|
|
BETTER_AUTH_URL: z.string().url(),
|
|
|
|
GOOGLE_CLIENT_ID: z.string().optional(),
|
|
GOOGLE_CLIENT_SECRET: z.string().optional(),
|
|
|
|
MINIO_ENDPOINT: z.string(),
|
|
MINIO_ACCESS_KEY: z.string(),
|
|
MINIO_SECRET_KEY: z.string(),
|
|
MINIO_BUCKET_NAME: z.string().default("sase-schemas"),
|
|
MINIO_PUBLIC_URL: z.string(),
|
|
MINIO_USE_SSL: z
|
|
.string()
|
|
.transform((v) => v === "true")
|
|
.default("false"),
|
|
|
|
CORS_ORIGIN: z.string().default("http://localhost:3000"),
|
|
|
|
IYZICO_API_KEY: z.string().optional(),
|
|
IYZICO_SECRET_KEY: z.string().optional(),
|
|
IYZICO_BASE_URL: z.string().optional(),
|
|
|
|
PL24_BASE_URL: z.string().optional(),
|
|
PL24_COMPANY_CODE: z.string().optional(),
|
|
PL24_USERNAME: z.string().optional(),
|
|
PL24_PASSWORD: z.string().optional(),
|
|
|
|
EMEX_USERNAME: z.string().optional(),
|
|
EMEX_PASSWORD: z.string().optional(),
|
|
|
|
// Parts-Catalogs (Playwright JWT capture + DataImpulse proxy)
|
|
PCAT_USE_PROXY: z.string().default("true"),
|
|
PCAT_PROXY_HOST: z.string().default("gw.dataimpulse.com"),
|
|
PCAT_PROXY_USER: z.string().optional(),
|
|
PCAT_PROXY_PASS: z.string().optional(),
|
|
|
|
ML_PREDICTION_ENABLED: z
|
|
.string()
|
|
.transform((v) => v === "true")
|
|
.default("false"),
|
|
|
|
// Postal Email
|
|
POSTAL_API_URL: z.string().url().optional(),
|
|
POSTAL_API_KEY: z.string().optional(),
|
|
POSTAL_FROM_ADDRESS: z.string().email().default("noreply@sase.tr"),
|
|
POSTAL_FROM_NAME: z.string().default("Sase.tr"),
|
|
|
|
// OpenTelemetry
|
|
OTEL_ENABLED: z
|
|
.string()
|
|
.transform((v) => v === "true")
|
|
.default("false"),
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: z.string().optional(),
|
|
OTEL_EXPORTER_OTLP_HEADERS: z.string().optional(),
|
|
OTEL_SERVICE_NAME: z.string().default("sase-api"),
|
|
OTEL_TRACE_SAMPLE_RATE: z.coerce.number().min(0).max(1).default(1.0),
|
|
});
|
|
|
|
export type Env = z.infer<typeof envSchema>;
|
|
|
|
export function validateEnv(env: Record<string, unknown> = process.env as Record<string, unknown>): Env {
|
|
const result = envSchema.safeParse(env);
|
|
if (!result.success) {
|
|
const formatted = result.error.format();
|
|
console.error("Environment validation failed:");
|
|
console.error(JSON.stringify(formatted, null, 2));
|
|
throw new Error("Invalid environment variables");
|
|
}
|
|
return result.data;
|
|
}
|