Implement Phase 2 asset storage pipeline

This commit is contained in:
Media
2026-08-16 19:59:10 -05:00
parent eb19675a5c
commit 722c6cf77d
29 changed files with 5059 additions and 16 deletions
+46
View File
@@ -156,6 +156,42 @@ function loadConfig(env = process.env) {
accessKeyId: storageCredential(env, "S3_ACCESS_KEY_ID", environment),
secretAccessKey: storageCredential(env, "S3_SECRET_ACCESS_KEY", environment),
forcePathStyle: boolean(env, "S3_FORCE_PATH_STYLE", true),
healthProbeIntervalMs: integer(
env,
"S3_HEALTH_PROBE_INTERVAL_MS",
30_000,
{ min: 1_000, max: 300_000 },
),
connectionTimeoutMs: integer(env, "S3_CONNECT_TIMEOUT_MS", 2_000, {
min: 250,
max: 60_000,
}),
requestTimeoutMs: integer(env, "S3_REQUEST_TIMEOUT_MS", 5_000, {
min: 1_000,
max: 120_000,
}),
maxAttempts: integer(env, "S3_MAX_ATTEMPTS", 2, { min: 1, max: 5 }),
}),
processing: Object.freeze({
tempDirectory: (() => {
const value = env.UPLOAD_TEMP_DIRECTORY?.trim() || "/tmp/announcements-uploads";
if (!path.isAbsolute(value)) {
throw new ConfigError(
"UPLOAD_TEMP_DIRECTORY must be an absolute path",
"UPLOAD_TEMP_DIRECTORY",
);
}
return value;
})(),
maxFileBytes: integer(env, "UPLOAD_MAX_FILE_BYTES", 25 * 1024 * 1024, {
min: 1,
max: 1024 * 1024 * 1024,
}),
maxFiles: integer(env, "UPLOAD_MAX_FILES", 20, { min: 1, max: 100 }),
maxInputPixels: integer(env, "IMAGE_MAX_INPUT_PIXELS", 40_000_000, {
min: 1,
max: 500_000_000,
}),
}),
mqtt: Object.freeze({
url: url(env, "MQTT_URL", {
@@ -193,6 +229,16 @@ function redactedConfig(config) {
region: config.storage.region,
bucket: config.storage.bucket,
forcePathStyle: config.storage.forcePathStyle,
healthProbeIntervalMs: config.storage.healthProbeIntervalMs,
connectionTimeoutMs: config.storage.connectionTimeoutMs,
requestTimeoutMs: config.storage.requestTimeoutMs,
maxAttempts: config.storage.maxAttempts,
},
processing: {
tempDirectoryConfigured: Boolean(config.processing.tempDirectory),
maxFileBytes: config.processing.maxFileBytes,
maxFiles: config.processing.maxFiles,
maxInputPixels: config.processing.maxInputPixels,
},
mqtt: {
configured: Boolean(config.mqtt.url),