feat: добавить базовые сервисы image-platform
- добавлены backend, admin, gateway и worker skeleton - добавлены Drizzle schema, database package и initial migration - добавлены shared packages для RabbitMQ topology и S3 helpers - обновлены dev-инфраструктура, env example, scripts и dependencies - обновлена документация под versioned image URLs и read-through flow
This commit is contained in:
21
packages/queue/package.json
Normal file
21
packages/queue/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@image-platform/queue",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"types": "./src/index.ts",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.build.json",
|
||||
"typecheck": "tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^25.6.0",
|
||||
"typescript": "^6.0.3"
|
||||
}
|
||||
}
|
||||
2
packages/queue/src/index.ts
Normal file
2
packages/queue/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./jobs.js"
|
||||
export * from "./topology.js"
|
||||
37
packages/queue/src/jobs.ts
Normal file
37
packages/queue/src/jobs.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
export type GenerateVariantJob = {
|
||||
jobId: string
|
||||
variantId: string
|
||||
}
|
||||
|
||||
export function parseGenerateVariantJobBuffer(buffer: Buffer): GenerateVariantJob {
|
||||
const value = JSON.parse(buffer.toString("utf8")) as unknown
|
||||
|
||||
return parseGenerateVariantJob(value)
|
||||
}
|
||||
|
||||
export function parseGenerateVariantJob(value: unknown): GenerateVariantJob {
|
||||
if (!isRecord(value)) {
|
||||
throw new Error("generate variant job must be a JSON object")
|
||||
}
|
||||
|
||||
if (!isNonEmptyString(value.jobId)) {
|
||||
throw new Error("generate variant job must include jobId")
|
||||
}
|
||||
|
||||
if (!isNonEmptyString(value.variantId)) {
|
||||
throw new Error("generate variant job must include variantId")
|
||||
}
|
||||
|
||||
return {
|
||||
jobId: value.jobId,
|
||||
variantId: value.variantId,
|
||||
}
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
}
|
||||
|
||||
function isNonEmptyString(value: unknown): value is string {
|
||||
return typeof value === "string" && value.trim().length > 0
|
||||
}
|
||||
33
packages/queue/src/topology.ts
Normal file
33
packages/queue/src/topology.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export type QueueTopology = {
|
||||
generateVariantDeadLetterQueue: string
|
||||
generateVariantDeadLetterRoutingKey: string
|
||||
generateVariantQueue: string
|
||||
generateVariantRoutingKey: string
|
||||
jobsDeadLetterExchange: string
|
||||
jobsExchange: string
|
||||
}
|
||||
|
||||
export const DEFAULT_QUEUE_TOPOLOGY: QueueTopology = {
|
||||
generateVariantDeadLetterQueue: "image.generate-variant.dlq",
|
||||
generateVariantDeadLetterRoutingKey: "image.generate-variant.dlq",
|
||||
generateVariantQueue: "image.generate-variant",
|
||||
generateVariantRoutingKey: "image.generate-variant",
|
||||
jobsDeadLetterExchange: "image-platform.jobs.dlx",
|
||||
jobsExchange: "image-platform.jobs",
|
||||
}
|
||||
|
||||
export function loadQueueTopologyFromEnv(env: NodeJS.ProcessEnv = process.env): QueueTopology {
|
||||
const generateVariantQueue = env.RABBITMQ_GENERATE_VARIANT_QUEUE ?? DEFAULT_QUEUE_TOPOLOGY.generateVariantQueue
|
||||
const generateVariantDeadLetterQueue =
|
||||
env.RABBITMQ_GENERATE_VARIANT_DLQ ?? DEFAULT_QUEUE_TOPOLOGY.generateVariantDeadLetterQueue
|
||||
|
||||
return {
|
||||
generateVariantDeadLetterQueue,
|
||||
generateVariantDeadLetterRoutingKey:
|
||||
env.RABBITMQ_GENERATE_VARIANT_DLQ_ROUTING_KEY ?? generateVariantDeadLetterQueue,
|
||||
generateVariantQueue,
|
||||
generateVariantRoutingKey: env.RABBITMQ_GENERATE_VARIANT_ROUTING_KEY ?? generateVariantQueue,
|
||||
jobsDeadLetterExchange: env.RABBITMQ_GENERATE_VARIANT_DLX ?? DEFAULT_QUEUE_TOPOLOGY.jobsDeadLetterExchange,
|
||||
jobsExchange: env.RABBITMQ_JOBS_EXCHANGE ?? DEFAULT_QUEUE_TOPOLOGY.jobsExchange,
|
||||
}
|
||||
}
|
||||
7
packages/queue/tsconfig.build.json
Normal file
7
packages/queue/tsconfig.build.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false
|
||||
},
|
||||
"exclude": ["dist", "node_modules", "**/*.spec.ts"]
|
||||
}
|
||||
21
packages/queue/tsconfig.json
Normal file
21
packages/queue/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["ES2023"],
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"target": "ES2023",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user