feat: добавить генерацию image variants

- добавлен shared config presets, custom transforms и allowlist hosts
- реализованы Backend endpoints для assets, presets и variants
- добавлена orchestration через PostgreSQL, RabbitMQ, S3 и worker
- обновлён Gateway read-through flow с L1 cache и корректным Vary: Accept
- добавлена миграция resize_mode для variants lookup
- обновлены dev scripts, env template, lockfile и документация
This commit is contained in:
2026-05-05 13:25:28 +03:00
parent bcadb85a83
commit 1c0e8277a3
59 changed files with 3526 additions and 143 deletions

View File

@@ -0,0 +1,29 @@
import type { Channel } from "amqplib"
import type { GenerateVariantJob } from "./jobs.js"
import type { QueueTopology } from "./topology.js"
export async function assertQueueTopology(channel: Channel, topology: QueueTopology) {
await channel.assertExchange(topology.jobsExchange, "direct", { durable: true })
await channel.assertExchange(topology.jobsDeadLetterExchange, "direct", { durable: true })
await channel.assertQueue(topology.generateVariantQueue, {
deadLetterExchange: topology.jobsDeadLetterExchange,
deadLetterRoutingKey: topology.generateVariantDeadLetterRoutingKey,
durable: true,
})
await channel.assertQueue(topology.generateVariantDeadLetterQueue, { durable: true })
await channel.bindQueue(topology.generateVariantQueue, topology.jobsExchange, topology.generateVariantRoutingKey)
await channel.bindQueue(
topology.generateVariantDeadLetterQueue,
topology.jobsDeadLetterExchange,
topology.generateVariantDeadLetterRoutingKey,
)
}
export function publishGenerateVariantJob(channel: Channel, topology: QueueTopology, job: GenerateVariantJob) {
return channel.publish(topology.jobsExchange, topology.generateVariantRoutingKey, Buffer.from(JSON.stringify(job)), {
contentType: "application/json",
deliveryMode: 2,
persistent: true,
})
}

View File

@@ -1,2 +1,3 @@
export * from "./amqp.js"
export * from "./jobs.js"
export * from "./topology.js"