diff --git a/backend/src/jobs/processors/log-cleanup.processor.ts b/backend/src/jobs/processors/log-cleanup.processor.ts deleted file mode 100644 index d0d81a8..0000000 --- a/backend/src/jobs/processors/log-cleanup.processor.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Processor, WorkerHost } from '@nestjs/bullmq'; -import { Logger } from '@nestjs/common'; -import { Job } from 'bullmq'; -import { PrismaService } from '../../prisma/prisma.service'; - -@Processor('log-cleanup') -export class LogCleanupProcessor extends WorkerHost { - private readonly logger = new Logger(LogCleanupProcessor.name); - - constructor(private prisma: PrismaService) { - super(); - } - - async process(job: Job) { - const cutoff = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000); // 30 days ago - - this.logger.log(`Cleaning up device logs older than ${cutoff.toISOString()}`); - - const result = await this.prisma.deviceLog.deleteMany({ - where: { - createdAt: { lt: cutoff }, - }, - }); - - this.logger.log(`Deleted ${result.count} old device log entries`); - - return { deleted: result.count }; - } -} diff --git a/backend/src/jobs/processors/model-poller.processor.ts b/backend/src/jobs/processors/model-poller.processor.ts deleted file mode 100644 index 80e5891..0000000 --- a/backend/src/jobs/processors/model-poller.processor.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { Processor, WorkerHost } from '@nestjs/bullmq'; -import { Logger } from '@nestjs/common'; -import { Job } from 'bullmq'; -import { PrismaService } from '../../prisma/prisma.service'; -import { ConfigService } from '@nestjs/config'; -import axios from 'axios'; - -/** - * Model Poller Processor - * Polls Core Models API for new or updated device models - * Syncs device model definitions (screen dimensions, capabilities, etc.) - */ -@Processor('model-poller') -export class ModelPollerProcessor extends WorkerHost { - private readonly logger = new Logger(ModelPollerProcessor.name); - - constructor( - private prisma: PrismaService, - private configService: ConfigService, - ) { - super(); - } - - async process(job: Job) { - this.logger.log('Processing model poll job...'); - - try { - const modelsApiUrl = this.configService.get('models.apiUrl'); - - if (!modelsApiUrl) { - this.logger.debug( - 'Models API URL not configured, skipping external poll', - ); - return await this.checkLocalModels(); - } - - // Fetch models from external API - const response = await axios.get(modelsApiUrl, { - timeout: 10000, - }); - - const externalModels = response.data; - - if (!Array.isArray(externalModels)) { - throw new Error('Invalid response from models API'); - } - - // Sync models to database - let created = 0; - let updated = 0; - - for (const modelData of externalModels) { - const existingModel = await this.prisma.model.findUnique({ - where: { name: modelData.name }, - }); - - if (existingModel) { - // Update existing model if data changed - await this.prisma.model.update({ - where: { id: existingModel.id }, - data: { - label: modelData.label, - width: modelData.width, - height: modelData.height, - description: modelData.description, - colors: modelData.colors || 2, - bitDepth: modelData.bitDepth || 1, - }, - }); - updated++; - } else { - // Create new model - await this.prisma.model.create({ - data: { - name: modelData.name, - label: modelData.label, - width: modelData.width, - height: modelData.height, - description: modelData.description, - colors: modelData.colors || 2, - bitDepth: modelData.bitDepth || 1, - }, - }); - created++; - } - } - - this.logger.log( - `Model sync complete. Created: ${created}, Updated: ${updated}`, - ); - - return { - success: true, - created, - updated, - total: externalModels.length, - }; - } catch (error) { - if (axios.isAxiosError(error)) { - this.logger.warn(`Models API unreachable: ${error.message}`); - return await this.checkLocalModels(); - } - - this.logger.error('Model poll failed:', error); - throw error; - } - } - - private async checkLocalModels() { - const modelCount = await this.prisma.model.count(); - this.logger.log(`Local model check complete. Total models: ${modelCount}`); - - return { - success: true, - modelCount, - source: 'local', - }; - } -} diff --git a/backend/src/jobs/services/model-poller.service.ts b/backend/src/jobs/services/model-poller.service.ts deleted file mode 100644 index 8323c51..0000000 --- a/backend/src/jobs/services/model-poller.service.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; -import { InjectQueue } from '@nestjs/bullmq'; -import { Queue } from 'bullmq'; -import { ConfigService } from '@nestjs/config'; - -/** - * Model Poller Service - * Polls the Core Models API for new or updated device models - * Similar to Ruby's Models::Poller aspect - */ -@Injectable() -export class ModelPollerService implements OnModuleInit { - private readonly logger = new Logger(ModelPollerService.name); - - constructor( - @InjectQueue('model-poller') private modelQueue: Queue, - private configService: ConfigService, - ) {} - - async onModuleInit() { - const enabled = this.configService.get( - 'jobs.modelPoller.enabled', - true, - ); - - if (!enabled) { - this.logger.log('Model poller is disabled'); - return; - } - - await this.startPoller(); - } - - private async startPoller() { - // Poll every 24 hours by default - const interval = this.configService.get( - 'jobs.modelPoller.interval', - 86400000, // 24 hours in milliseconds - ); - - this.logger.log(`Starting model poller with interval: ${interval / 1000}s`); - - // Add repeatable job - await this.modelQueue.add( - 'poll-models', - {}, - { - repeat: { - every: interval, - }, - removeOnComplete: true, - removeOnFail: { count: 10 }, - }, - ); - - // Run immediately on startup - await this.modelQueue.add('poll-models', {}, { delay: 5000, removeOnComplete: true, removeOnFail: true }); - - this.logger.log('Model poller started'); - } - - async stopPoller() { - // Clean completed and failed jobs (grace period 0ms) - await this.modelQueue.clean(0, 0, 'completed'); - await this.modelQueue.clean(0, 0, 'failed'); - await this.modelQueue.drain(); - - const repeatableJobs = await this.modelQueue.getRepeatableJobs(); - for (const job of repeatableJobs) { - await this.modelQueue.removeRepeatableByKey(job.key); - } - - this.logger.log('Model poller stopped'); - } -} diff --git a/docker/services.d/redis/run b/docker/services.d/redis/run deleted file mode 100644 index 6134562..0000000 --- a/docker/services.d/redis/run +++ /dev/null @@ -1,2 +0,0 @@ -#!/command/with-contenv sh -exec redis-server --appendonly yes --dir /data --requirepass "${REDIS_PASSWORD:-inker_redis}"