Spaces:
Running
Running
Download apps/api/dist/admin/admin-operations.service.js from Benaah/MicProtocol: direct link, hf CLI and curl.
- Browser
- Download file 11.7 kB
-
https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/api/dist/admin/admin-operations.service.js
- Command line
-
hf download hf://spaces/Benaah/MicProtocol/apps/api/dist/admin/admin-operations.service.js
-
curl -L -o admin-operations.service.js https://huggingface.co/spaces/Benaah/MicProtocol/resolve/main/apps/api/dist/admin/admin-operations.service.js
11.7 kB
| ; | |
| var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | |
| var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; | |
| if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); | |
| else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; | |
| return c > 3 && r && Object.defineProperty(target, key, r), r; | |
| }; | |
| var __metadata = (this && this.__metadata) || function (k, v) { | |
| if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); | |
| }; | |
| var __param = (this && this.__param) || function (paramIndex, decorator) { | |
| return function (target, key) { decorator(target, key, paramIndex); } | |
| }; | |
| var AdminOperationsService_1; | |
| Object.defineProperty(exports, "__esModule", { value: true }); | |
| exports.AdminOperationsService = exports.OPERATIONS_QUEUES = void 0; | |
| const common_1 = require("@nestjs/common"); | |
| const bullmq_1 = require("@nestjs/bullmq"); | |
| const common_2 = require("@nestjs/common"); | |
| const prisma_service_1 = require("../prisma/prisma.service"); | |
| const audit_service_1 = require("../audit/audit.service"); | |
| const cache_service_1 = require("../common/cache/cache.service"); | |
| const redis_constants_1 = require("../common/redis.constants"); | |
| const shared_types_1 = require("@micprotocol/shared-types"); | |
| const admin_permission_decorator_1 = require("../common/decorators/admin-permission.decorator"); | |
| exports.OPERATIONS_QUEUES = [ | |
| "outreach", | |
| "content", | |
| "notifications", | |
| "analytics", | |
| "network", | |
| "post-interview", | |
| "clip-scoring", | |
| "email", | |
| "reminder", | |
| "asset-processing", | |
| "outreach-automation", | |
| "verification", | |
| ]; | |
| let AdminOperationsService = AdminOperationsService_1 = class AdminOperationsService { | |
| prisma; | |
| audit; | |
| cache; | |
| redis; | |
| outreachQueue; | |
| contentQueue; | |
| notificationsQueue; | |
| analyticsQueue; | |
| networkQueue; | |
| postInterviewQueue; | |
| clipScoringQueue; | |
| emailQueue; | |
| reminderQueue; | |
| assetProcessingQueue; | |
| outreachAutomationQueue; | |
| verificationQueue; | |
| logger = new common_1.Logger(AdminOperationsService_1.name); | |
| constructor(prisma, audit, cache, redis, outreachQueue, contentQueue, notificationsQueue, analyticsQueue, networkQueue, postInterviewQueue, clipScoringQueue, emailQueue, reminderQueue, assetProcessingQueue, outreachAutomationQueue, verificationQueue) { | |
| this.prisma = prisma; | |
| this.audit = audit; | |
| this.cache = cache; | |
| this.redis = redis; | |
| this.outreachQueue = outreachQueue; | |
| this.contentQueue = contentQueue; | |
| this.notificationsQueue = notificationsQueue; | |
| this.analyticsQueue = analyticsQueue; | |
| this.networkQueue = networkQueue; | |
| this.postInterviewQueue = postInterviewQueue; | |
| this.clipScoringQueue = clipScoringQueue; | |
| this.emailQueue = emailQueue; | |
| this.reminderQueue = reminderQueue; | |
| this.assetProcessingQueue = assetProcessingQueue; | |
| this.outreachAutomationQueue = outreachAutomationQueue; | |
| this.verificationQueue = verificationQueue; | |
| } | |
| queueByName(name) { | |
| const queues = { | |
| outreach: this.outreachQueue, | |
| content: this.contentQueue, | |
| notifications: this.notificationsQueue, | |
| analytics: this.analyticsQueue, | |
| network: this.networkQueue, | |
| "post-interview": this.postInterviewQueue, | |
| "clip-scoring": this.clipScoringQueue, | |
| email: this.emailQueue, | |
| reminder: this.reminderQueue, | |
| "asset-processing": this.assetProcessingQueue, | |
| "outreach-automation": this.outreachAutomationQueue, | |
| verification: this.verificationQueue, | |
| }; | |
| const queue = queues[name]; | |
| if (!queue) | |
| throw new common_1.NotFoundException(`Unknown queue ${name}`); | |
| return queue; | |
| } | |
| async getQueueHealth() { | |
| const results = []; | |
| for (const name of exports.OPERATIONS_QUEUES) { | |
| const queue = this.queueByName(name); | |
| const [waiting, active, completed, failed, delayed] = await Promise.all([ | |
| queue.getWaitingCount(), | |
| queue.getActiveCount(), | |
| queue.getCompletedCount(), | |
| queue.getFailedCount(), | |
| queue.getDelayedCount(), | |
| ]); | |
| results.push({ name, waiting, active, completed, failed, delayed }); | |
| } | |
| return results.sort((a, b) => b.failed - a.failed || b.waiting - a.waiting); | |
| } | |
| async getQueueJobs(queueName, type, limit = 50) { | |
| const queue = this.queueByName(queueName); | |
| const getJobs = queue[`get${type.charAt(0).toUpperCase() + type.slice(1)}`]; | |
| const jobs = await getJobs.call(queue, 0, Math.min(limit, 200)); | |
| return jobs.map((job) => ({ | |
| id: job.id, | |
| type: job.name, | |
| progress: job.progress, | |
| failedReason: job.failedReason, | |
| createdAt: job.timestamp ? new Date(job.timestamp) : null, | |
| })); | |
| } | |
| async retryJob(queueName, jobId, actorUserId) { | |
| const queue = this.queueByName(queueName); | |
| const job = await queue.getJob(jobId); | |
| if (!job) | |
| throw new common_1.NotFoundException(`Job ${jobId} not found in queue ${queueName}`); | |
| await job.retry(); | |
| await this.audit.log({ | |
| userId: actorUserId, | |
| action: "admin.ops.retry_jobs", | |
| entityType: "Job", | |
| entityId: jobId, | |
| metadata: { queue: queueName, jobType: job.name }, | |
| }); | |
| return { retried: jobId, queue: queueName }; | |
| } | |
| async purgeFailedJobs(queueName, actorUserId) { | |
| const queue = this.queueByName(queueName); | |
| const failed = await queue.getFailed(); | |
| let removed = 0; | |
| for (const job of failed) { | |
| await job.remove(); | |
| removed++; | |
| } | |
| await this.audit.log({ | |
| userId: actorUserId, | |
| action: "admin.ops.purge_jobs", | |
| entityType: "Queue", | |
| entityId: queueName, | |
| metadata: { removed, type: "failed" }, | |
| }); | |
| return { purged: removed, queue: queueName }; | |
| } | |
| async getLocks(pattern = "lock:clip:*", limit = 100) { | |
| const keys = await this.redis.keys(pattern); | |
| const sample = keys.slice(0, limit); | |
| return { pattern, total: keys.length, keys: sample }; | |
| } | |
| async releaseLock(key, actorUserId) { | |
| const deleted = await this.redis.del(key); | |
| await this.audit.log({ | |
| userId: actorUserId, | |
| action: "admin.ops.locks", | |
| entityType: "Lock", | |
| entityId: key, | |
| metadata: { deleted }, | |
| }); | |
| return { key, deleted }; | |
| } | |
| async getSystemHealth() { | |
| let database = "down"; | |
| let redis = "down"; | |
| try { | |
| await this.prisma.$queryRawUnsafe("SELECT 1"); | |
| database = "up"; | |
| } | |
| catch { | |
| database = "down"; | |
| } | |
| try { | |
| await this.redis.ping(); | |
| redis = "up"; | |
| } | |
| catch { | |
| redis = "down"; | |
| } | |
| const overall = database === "up" && redis === "up" ? "up" : database === "down" && redis === "down" ? "down" : "degraded"; | |
| return { database, redis, overall }; | |
| } | |
| async setMaintenanceMode(enabled, actorUserId) { | |
| const setting = await this.prisma.platformSetting.upsert({ | |
| where: { key: "maintenance.mode" }, | |
| update: { | |
| value: enabled, | |
| updatedById: actorUserId, | |
| }, | |
| create: { | |
| key: "maintenance.mode", | |
| value: enabled, | |
| description: "Platform maintenance mode — signups and writes are rejected when enabled", | |
| category: "operations", | |
| updatedById: actorUserId, | |
| }, | |
| }); | |
| await this.audit.log({ | |
| userId: actorUserId, | |
| action: "admin.ops.maintenance", | |
| entityType: "PlatformSetting", | |
| entityId: "maintenance.mode", | |
| metadata: { before: null, after: enabled }, | |
| }); | |
| return setting; | |
| } | |
| async flushCache(pattern, actorUserId) { | |
| await this.cache.delPattern(pattern); | |
| await this.audit.log({ | |
| userId: actorUserId, | |
| action: "admin.ops.cache", | |
| entityType: "Cache", | |
| entityId: pattern, | |
| metadata: { pattern }, | |
| }); | |
| return { flushed: pattern }; | |
| } | |
| }; | |
| exports.AdminOperationsService = AdminOperationsService; | |
| __decorate([ | |
| (0, admin_permission_decorator_1.requireAdminPermission)(shared_types_1.AdminPermission.OPS_RETRY_JOBS), | |
| __metadata("design:type", Function), | |
| __metadata("design:paramtypes", [String, String, String]), | |
| __metadata("design:returntype", Promise) | |
| ], AdminOperationsService.prototype, "retryJob", null); | |
| __decorate([ | |
| (0, admin_permission_decorator_1.requireAdminPermission)(shared_types_1.AdminPermission.OPS_PURGE_JOBS), | |
| __metadata("design:type", Function), | |
| __metadata("design:paramtypes", [String, String]), | |
| __metadata("design:returntype", Promise) | |
| ], AdminOperationsService.prototype, "purgeFailedJobs", null); | |
| __decorate([ | |
| (0, admin_permission_decorator_1.requireAdminPermission)(shared_types_1.AdminPermission.OPS_LOCKS), | |
| __metadata("design:type", Function), | |
| __metadata("design:paramtypes", [String, String]), | |
| __metadata("design:returntype", Promise) | |
| ], AdminOperationsService.prototype, "releaseLock", null); | |
| __decorate([ | |
| (0, admin_permission_decorator_1.requireAdminPermission)(shared_types_1.AdminPermission.OPS_MAINTENANCE), | |
| __metadata("design:type", Function), | |
| __metadata("design:paramtypes", [Boolean, String]), | |
| __metadata("design:returntype", Promise) | |
| ], AdminOperationsService.prototype, "setMaintenanceMode", null); | |
| __decorate([ | |
| (0, admin_permission_decorator_1.requireAdminPermission)(shared_types_1.AdminPermission.OPS_CACHE), | |
| __metadata("design:type", Function), | |
| __metadata("design:paramtypes", [String, String]), | |
| __metadata("design:returntype", Promise) | |
| ], AdminOperationsService.prototype, "flushCache", null); | |
| exports.AdminOperationsService = AdminOperationsService = AdminOperationsService_1 = __decorate([ | |
| (0, common_1.Injectable)(), | |
| __param(3, (0, common_2.Inject)(redis_constants_1.REDIS_CLIENT)), | |
| __param(4, (0, bullmq_1.InjectQueue)("outreach")), | |
| __param(5, (0, bullmq_1.InjectQueue)("content")), | |
| __param(6, (0, bullmq_1.InjectQueue)("notifications")), | |
| __param(7, (0, bullmq_1.InjectQueue)("analytics")), | |
| __param(8, (0, bullmq_1.InjectQueue)("network")), | |
| __param(9, (0, bullmq_1.InjectQueue)("post-interview")), | |
| __param(10, (0, bullmq_1.InjectQueue)("clip-scoring")), | |
| __param(11, (0, bullmq_1.InjectQueue)("email")), | |
| __param(12, (0, bullmq_1.InjectQueue)("reminder")), | |
| __param(13, (0, bullmq_1.InjectQueue)("asset-processing")), | |
| __param(14, (0, bullmq_1.InjectQueue)("outreach-automation")), | |
| __param(15, (0, bullmq_1.InjectQueue)("verification")), | |
| __metadata("design:paramtypes", [prisma_service_1.PrismaService, | |
| audit_service_1.AuditService, | |
| cache_service_1.CacheService, Object, Function, Function, Function, Function, Function, Function, Function, Function, Function, Function, Function, Function]) | |
| ], AdminOperationsService); | |
| //# sourceMappingURL=admin-operations.service.js.map |