From eaa8e8638fd3a6731214a4767c4b4bf1eaa01532 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 20 Jul 2026 22:29:24 +0200 Subject: [PATCH] feat: scaffold NestJS BullMQ worker skeleton --- .env.example | 2 ++ .gitignore | 4 ++++ Dockerfile | 14 ++++++++++++++ README.md | 11 +++++++++++ nest-cli.json | 5 +++++ package.json | 29 +++++++++++++++++++++++++++++ src/app.module.ts | 18 ++++++++++++++++++ src/main.ts | 12 ++++++++++++ src/queue/example.processor.ts | 10 ++++++++++ tsconfig.json | 20 ++++++++++++++++++++ 10 files changed, 125 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 nest-cli.json create mode 100644 package.json create mode 100644 src/app.module.ts create mode 100644 src/main.ts create mode 100644 src/queue/example.processor.ts create mode 100644 tsconfig.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f168e84 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# Redis (ceo-os-redis, Coolify) +REDIS_URL=redis://default:CHANGE_ME@ceo-os-redis:6379/0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa0926a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +.env +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d4a72b0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM node:22-alpine AS build +WORKDIR /app +COPY package.json ./ +RUN npm install +COPY . . +RUN npm run build + +FROM node:22-alpine +WORKDIR /app +ENV NODE_ENV=production +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/dist ./dist +COPY package.json ./ +CMD ["node", "dist/main"] diff --git a/README.md b/README.md index f00b578..1de6307 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,13 @@ # ceo-worker +Worker de background pentru CEO-OS, bazat pe BullMQ (NestJS). Consuma joburi din coada Redis (`ceo-os-redis`, Coolify). + +## Dezvoltare + +```bash +npm install +cp .env.example .env +npm run start:dev +``` + +Contine un procesor placeholder (`example` queue) — inlocuieste-l cu joburile reale (rapoarte, notificari, sincronizari). diff --git a/nest-cli.json b/nest-cli.json new file mode 100644 index 0000000..2566481 --- /dev/null +++ b/nest-cli.json @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..850624e --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "ceo-worker", + "version": "0.1.0", + "description": "CEO-OS background worker (BullMQ)", + "private": true, + "license": "UNLICENSED", + "scripts": { + "build": "nest build", + "start": "node dist/main", + "start:dev": "nest start --watch", + "lint": "eslint \"src/**/*.ts\"", + "test": "jest" + }, + "dependencies": { + "@nestjs/bullmq": "^11.0.0", + "@nestjs/common": "^11.0.0", + "@nestjs/config": "^4.0.0", + "@nestjs/core": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "bullmq": "^5.28.0", + "reflect-metadata": "^0.2.2", + "rxjs": "^7.8.1" + }, + "devDependencies": { + "@nestjs/cli": "^11.0.0", + "@types/node": "^22.0.0", + "typescript": "^5.6.0" + } +} diff --git a/src/app.module.ts b/src/app.module.ts new file mode 100644 index 0000000..8b1fc30 --- /dev/null +++ b/src/app.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { BullModule } from '@nestjs/bullmq'; +import { ExampleProcessor } from './queue/example.processor'; + +@Module({ + imports: [ + ConfigModule.forRoot({ isGlobal: true }), + BullModule.forRoot({ + connection: { + url: process.env.REDIS_URL, + }, + }), + BullModule.registerQueue({ name: 'example' }), + ], + providers: [ExampleProcessor], +}) +export class AppModule {} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..bb7dc51 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,12 @@ +import 'reflect-metadata'; +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app.module'; + +async function bootstrap() { + const app = await NestFactory.createApplicationContext(AppModule); + await app.init(); + // eslint-disable-next-line no-console + console.log('ceo-worker started, listening for BullMQ jobs'); +} + +bootstrap(); diff --git a/src/queue/example.processor.ts b/src/queue/example.processor.ts new file mode 100644 index 0000000..d8dedd7 --- /dev/null +++ b/src/queue/example.processor.ts @@ -0,0 +1,10 @@ +import { Processor, WorkerHost } from '@nestjs/bullmq'; +import { Job } from 'bullmq'; + +@Processor('example') +export class ExampleProcessor extends WorkerHost { + async process(job: Job): Promise { + // eslint-disable-next-line no-console + console.log(`processing job ${job.id}`, job.data); + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1a766ad --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "ES2022", + "moduleResolution": "node", + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "noImplicitAny": true, + "esModuleInterop": true + } +}