@bloomneo/appkit 1.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +902 -0
- package/bin/appkit.js +71 -0
- package/bin/commands/generate.js +1050 -0
- package/bin/templates/backend/README.md.template +39 -0
- package/bin/templates/backend/api.http.template +0 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
- package/bin/templates/backend/package.json.template +34 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
- package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
- package/bin/templates/backend/src/api/server.ts.template +188 -0
- package/bin/templates/backend/tsconfig.api.json.template +24 -0
- package/bin/templates/backend/tsconfig.json.template +40 -0
- package/bin/templates/feature/feature.http.template +63 -0
- package/bin/templates/feature/feature.route.ts.template +36 -0
- package/bin/templates/feature/feature.service.ts.template +81 -0
- package/bin/templates/feature/feature.types.ts.template +23 -0
- package/bin/templates/feature-db/feature.http.template +63 -0
- package/bin/templates/feature-db/feature.model.ts.template +74 -0
- package/bin/templates/feature-db/feature.route.ts.template +58 -0
- package/bin/templates/feature-db/feature.service.ts.template +231 -0
- package/bin/templates/feature-db/feature.types.ts.template +25 -0
- package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
- package/bin/templates/feature-db/seeding/README.md.template +57 -0
- package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
- package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
- package/bin/templates/feature-user/user.http.template +157 -0
- package/bin/templates/feature-user/user.model.ts.template +244 -0
- package/bin/templates/feature-user/user.route.ts.template +379 -0
- package/bin/templates/feature-user/user.seed.js.template +182 -0
- package/bin/templates/feature-user/user.service.ts.template +426 -0
- package/bin/templates/feature-user/user.types.ts.template +127 -0
- package/dist/auth/auth.d.ts +182 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +477 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/defaults.d.ts +104 -0
- package/dist/auth/defaults.d.ts.map +1 -0
- package/dist/auth/defaults.js +374 -0
- package/dist/auth/defaults.js.map +1 -0
- package/dist/auth/index.d.ts +70 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +94 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/cache/cache.d.ts +118 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +249 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/defaults.d.ts +63 -0
- package/dist/cache/defaults.d.ts.map +1 -0
- package/dist/cache/defaults.js +193 -0
- package/dist/cache/defaults.js.map +1 -0
- package/dist/cache/index.d.ts +101 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +203 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/strategies/memory.d.ts +138 -0
- package/dist/cache/strategies/memory.d.ts.map +1 -0
- package/dist/cache/strategies/memory.js +348 -0
- package/dist/cache/strategies/memory.js.map +1 -0
- package/dist/cache/strategies/redis.d.ts +105 -0
- package/dist/cache/strategies/redis.d.ts.map +1 -0
- package/dist/cache/strategies/redis.js +318 -0
- package/dist/cache/strategies/redis.js.map +1 -0
- package/dist/config/config.d.ts +62 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +107 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/defaults.d.ts +44 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +217 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +163 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/adapters/mongoose.d.ts +106 -0
- package/dist/database/adapters/mongoose.d.ts.map +1 -0
- package/dist/database/adapters/mongoose.js +480 -0
- package/dist/database/adapters/mongoose.js.map +1 -0
- package/dist/database/adapters/prisma.d.ts +106 -0
- package/dist/database/adapters/prisma.d.ts.map +1 -0
- package/dist/database/adapters/prisma.js +494 -0
- package/dist/database/adapters/prisma.js.map +1 -0
- package/dist/database/defaults.d.ts +87 -0
- package/dist/database/defaults.d.ts.map +1 -0
- package/dist/database/defaults.js +271 -0
- package/dist/database/defaults.js.map +1 -0
- package/dist/database/index.d.ts +137 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +490 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/defaults.d.ts +100 -0
- package/dist/email/defaults.d.ts.map +1 -0
- package/dist/email/defaults.js +400 -0
- package/dist/email/defaults.js.map +1 -0
- package/dist/email/email.d.ts +139 -0
- package/dist/email/email.d.ts.map +1 -0
- package/dist/email/email.js +316 -0
- package/dist/email/email.js.map +1 -0
- package/dist/email/index.d.ts +176 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +251 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/strategies/console.d.ts +90 -0
- package/dist/email/strategies/console.d.ts.map +1 -0
- package/dist/email/strategies/console.js +268 -0
- package/dist/email/strategies/console.js.map +1 -0
- package/dist/email/strategies/resend.d.ts +84 -0
- package/dist/email/strategies/resend.d.ts.map +1 -0
- package/dist/email/strategies/resend.js +266 -0
- package/dist/email/strategies/resend.js.map +1 -0
- package/dist/email/strategies/smtp.d.ts +77 -0
- package/dist/email/strategies/smtp.d.ts.map +1 -0
- package/dist/email/strategies/smtp.js +286 -0
- package/dist/email/strategies/smtp.js.map +1 -0
- package/dist/error/defaults.d.ts +40 -0
- package/dist/error/defaults.d.ts.map +1 -0
- package/dist/error/defaults.js +75 -0
- package/dist/error/defaults.js.map +1 -0
- package/dist/error/error.d.ts +140 -0
- package/dist/error/error.d.ts.map +1 -0
- package/dist/error/error.js +200 -0
- package/dist/error/error.js.map +1 -0
- package/dist/error/index.d.ts +145 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +145 -0
- package/dist/error/index.js.map +1 -0
- package/dist/event/defaults.d.ts +111 -0
- package/dist/event/defaults.d.ts.map +1 -0
- package/dist/event/defaults.js +378 -0
- package/dist/event/defaults.js.map +1 -0
- package/dist/event/event.d.ts +171 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +391 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/index.d.ts +173 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +302 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/strategies/memory.d.ts +122 -0
- package/dist/event/strategies/memory.d.ts.map +1 -0
- package/dist/event/strategies/memory.js +331 -0
- package/dist/event/strategies/memory.js.map +1 -0
- package/dist/event/strategies/redis.d.ts +115 -0
- package/dist/event/strategies/redis.d.ts.map +1 -0
- package/dist/event/strategies/redis.js +434 -0
- package/dist/event/strategies/redis.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/defaults.d.ts +67 -0
- package/dist/logger/defaults.d.ts.map +1 -0
- package/dist/logger/defaults.js +213 -0
- package/dist/logger/defaults.js.map +1 -0
- package/dist/logger/index.d.ts +84 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +101 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.d.ts +165 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +843 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/logger/transports/console.d.ts +102 -0
- package/dist/logger/transports/console.d.ts.map +1 -0
- package/dist/logger/transports/console.js +276 -0
- package/dist/logger/transports/console.js.map +1 -0
- package/dist/logger/transports/database.d.ts +153 -0
- package/dist/logger/transports/database.d.ts.map +1 -0
- package/dist/logger/transports/database.js +539 -0
- package/dist/logger/transports/database.js.map +1 -0
- package/dist/logger/transports/file.d.ts +146 -0
- package/dist/logger/transports/file.d.ts.map +1 -0
- package/dist/logger/transports/file.js +464 -0
- package/dist/logger/transports/file.js.map +1 -0
- package/dist/logger/transports/http.d.ts +128 -0
- package/dist/logger/transports/http.d.ts.map +1 -0
- package/dist/logger/transports/http.js +401 -0
- package/dist/logger/transports/http.js.map +1 -0
- package/dist/logger/transports/webhook.d.ts +152 -0
- package/dist/logger/transports/webhook.d.ts.map +1 -0
- package/dist/logger/transports/webhook.js +485 -0
- package/dist/logger/transports/webhook.js.map +1 -0
- package/dist/queue/defaults.d.ts +66 -0
- package/dist/queue/defaults.d.ts.map +1 -0
- package/dist/queue/defaults.js +205 -0
- package/dist/queue/defaults.js.map +1 -0
- package/dist/queue/index.d.ts +124 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +116 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +156 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +387 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/queue/transports/database.d.ts +165 -0
- package/dist/queue/transports/database.d.ts.map +1 -0
- package/dist/queue/transports/database.js +595 -0
- package/dist/queue/transports/database.js.map +1 -0
- package/dist/queue/transports/memory.d.ts +143 -0
- package/dist/queue/transports/memory.d.ts.map +1 -0
- package/dist/queue/transports/memory.js +415 -0
- package/dist/queue/transports/memory.js.map +1 -0
- package/dist/queue/transports/redis.d.ts +203 -0
- package/dist/queue/transports/redis.d.ts.map +1 -0
- package/dist/queue/transports/redis.js +744 -0
- package/dist/queue/transports/redis.js.map +1 -0
- package/dist/security/defaults.d.ts +64 -0
- package/dist/security/defaults.d.ts.map +1 -0
- package/dist/security/defaults.js +159 -0
- package/dist/security/defaults.js.map +1 -0
- package/dist/security/index.d.ts +110 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +160 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security.d.ts +138 -0
- package/dist/security/security.d.ts.map +1 -0
- package/dist/security/security.js +419 -0
- package/dist/security/security.js.map +1 -0
- package/dist/storage/defaults.d.ts +79 -0
- package/dist/storage/defaults.d.ts.map +1 -0
- package/dist/storage/defaults.js +358 -0
- package/dist/storage/defaults.js.map +1 -0
- package/dist/storage/index.d.ts +153 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +242 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +151 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +439 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/strategies/local.d.ts +117 -0
- package/dist/storage/strategies/local.d.ts.map +1 -0
- package/dist/storage/strategies/local.js +368 -0
- package/dist/storage/strategies/local.js.map +1 -0
- package/dist/storage/strategies/r2.d.ts +130 -0
- package/dist/storage/strategies/r2.d.ts.map +1 -0
- package/dist/storage/strategies/r2.js +470 -0
- package/dist/storage/strategies/r2.js.map +1 -0
- package/dist/storage/strategies/s3.d.ts +121 -0
- package/dist/storage/strategies/s3.d.ts.map +1 -0
- package/dist/storage/strategies/s3.js +461 -0
- package/dist/storage/strategies/s3.js.map +1 -0
- package/dist/util/defaults.d.ts +77 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +193 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/index.d.ts +97 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +165 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/util.d.ts +145 -0
- package/dist/util/util.d.ts.map +1 -0
- package/dist/util/util.js +481 -0
- package/dist/util/util.js.map +1 -0
- package/package.json +234 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database queue transport using AppKit Prisma for persistent job storage
|
|
3
|
+
* @module @bloomneo/appkit/queue
|
|
4
|
+
* @file src/queue/transports/database.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Need persistent queuing with existing database - leverages AppKit database
|
|
7
|
+
* @llm-rule AVOID: When high-throughput needed - database polling has overhead
|
|
8
|
+
* @llm-rule NOTE: Uses existing Prisma client from AppKit, perfect for simple persistent queuing
|
|
9
|
+
*/
|
|
10
|
+
import database from '../../database/index.js'; // Leverage existing Prisma client
|
|
11
|
+
/**
|
|
12
|
+
* Database transport using AppKit Prisma for persistent storage
|
|
13
|
+
*/
|
|
14
|
+
export class DatabaseTransport {
|
|
15
|
+
config;
|
|
16
|
+
db;
|
|
17
|
+
handlers = new Map();
|
|
18
|
+
paused = new Set();
|
|
19
|
+
processing = new Set();
|
|
20
|
+
// Timers for background processing
|
|
21
|
+
processingLoop = null;
|
|
22
|
+
cleanupTimer = null;
|
|
23
|
+
healthCheckTimer = null;
|
|
24
|
+
/**
|
|
25
|
+
* Creates database transport using existing AppKit Prisma client
|
|
26
|
+
* @llm-rule WHEN: Auto-detected from DATABASE_URL with existing AppKit database
|
|
27
|
+
* @llm-rule AVOID: Manual database setup - leverages existing infrastructure
|
|
28
|
+
*/
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.initialize();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize database transport
|
|
35
|
+
* @llm-rule WHEN: Transport creation - ensures table exists and starts processing
|
|
36
|
+
* @llm-rule AVOID: Calling manually - constructor handles initialization
|
|
37
|
+
*/
|
|
38
|
+
async initialize() {
|
|
39
|
+
try {
|
|
40
|
+
// Get the database client
|
|
41
|
+
this.db = await database.get();
|
|
42
|
+
await this.ensureTableExists();
|
|
43
|
+
if (this.config.worker.enabled) {
|
|
44
|
+
this.startProcessing();
|
|
45
|
+
this.setupCleanup();
|
|
46
|
+
this.setupHealthCheck();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error('Database transport initialization failed:', error.message);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add job to database queue
|
|
55
|
+
* @llm-rule WHEN: Adding jobs for persistent background processing
|
|
56
|
+
* @llm-rule AVOID: Very high frequency - database has transaction overhead
|
|
57
|
+
*/
|
|
58
|
+
async add(id, jobType, data, options) {
|
|
59
|
+
try {
|
|
60
|
+
await this.db.queueJob.create({
|
|
61
|
+
data: {
|
|
62
|
+
id,
|
|
63
|
+
queue: jobType,
|
|
64
|
+
type: jobType,
|
|
65
|
+
payload: data,
|
|
66
|
+
status: 'pending',
|
|
67
|
+
attempts: 0,
|
|
68
|
+
maxAttempts: options.attempts || this.config.maxAttempts,
|
|
69
|
+
priority: options.priority || this.config.defaultPriority,
|
|
70
|
+
runAt: new Date(),
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw new Error(`Failed to add job to database: ${error.message}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Register job processor
|
|
80
|
+
* @llm-rule WHEN: Setting up job handlers for database-persisted jobs
|
|
81
|
+
* @llm-rule AVOID: Multiple handlers for same type - causes processing conflicts
|
|
82
|
+
*/
|
|
83
|
+
process(jobType, handler) {
|
|
84
|
+
this.handlers.set(jobType, handler);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Schedule job for future execution
|
|
88
|
+
* @llm-rule WHEN: Need persistent delayed job execution with database reliability
|
|
89
|
+
* @llm-rule AVOID: Very frequent scheduling - database writes have overhead
|
|
90
|
+
*/
|
|
91
|
+
async schedule(id, jobType, data, delay) {
|
|
92
|
+
try {
|
|
93
|
+
const runAt = new Date(Date.now() + delay);
|
|
94
|
+
await this.db.queueJob.create({
|
|
95
|
+
data: {
|
|
96
|
+
id,
|
|
97
|
+
queue: jobType,
|
|
98
|
+
type: jobType,
|
|
99
|
+
payload: data,
|
|
100
|
+
status: 'pending',
|
|
101
|
+
attempts: 0,
|
|
102
|
+
maxAttempts: this.config.maxAttempts,
|
|
103
|
+
priority: this.config.defaultPriority,
|
|
104
|
+
runAt,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw new Error(`Failed to schedule job in database: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Pause queue processing
|
|
114
|
+
* @llm-rule WHEN: Maintenance mode or controlled processing stop
|
|
115
|
+
* @llm-rule AVOID: Database-wide pausing - affects other application parts
|
|
116
|
+
*/
|
|
117
|
+
async pause(jobType) {
|
|
118
|
+
if (jobType) {
|
|
119
|
+
this.paused.add(jobType);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Pause all job types
|
|
123
|
+
for (const type of this.handlers.keys()) {
|
|
124
|
+
this.paused.add(type);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Resume queue processing
|
|
130
|
+
* @llm-rule WHEN: Resuming after maintenance pause
|
|
131
|
+
* @llm-rule AVOID: Resuming without checking database health
|
|
132
|
+
*/
|
|
133
|
+
async resume(jobType) {
|
|
134
|
+
if (jobType) {
|
|
135
|
+
this.paused.delete(jobType);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// Resume all
|
|
139
|
+
this.paused.clear();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get queue statistics from database
|
|
144
|
+
* @llm-rule WHEN: Monitoring queue health and job status distribution
|
|
145
|
+
* @llm-rule AVOID: Frequent polling - database aggregation queries are expensive
|
|
146
|
+
*/
|
|
147
|
+
async getStats(jobType) {
|
|
148
|
+
try {
|
|
149
|
+
const where = jobType ? { queue: jobType } : {};
|
|
150
|
+
const [pending, processing, completed, failed,] = await Promise.all([
|
|
151
|
+
this.db.queueJob.count({ where: { ...where, status: 'pending' } }),
|
|
152
|
+
this.db.queueJob.count({ where: { ...where, status: 'processing' } }),
|
|
153
|
+
this.db.queueJob.count({ where: { ...where, status: 'completed' } }),
|
|
154
|
+
this.db.queueJob.count({ where: { ...where, status: 'failed' } }),
|
|
155
|
+
]);
|
|
156
|
+
return {
|
|
157
|
+
waiting: pending,
|
|
158
|
+
active: processing,
|
|
159
|
+
completed,
|
|
160
|
+
failed,
|
|
161
|
+
delayed: 0, // Database doesn't distinguish delayed vs pending
|
|
162
|
+
paused: this.paused.size,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
throw new Error(`Failed to get database stats: ${error.message}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get jobs by status from database
|
|
171
|
+
* @llm-rule WHEN: Debugging failed jobs or monitoring job history
|
|
172
|
+
* @llm-rule AVOID: Large result sets without pagination - database performance impact
|
|
173
|
+
*/
|
|
174
|
+
async getJobs(status, jobType, limit = 100) {
|
|
175
|
+
try {
|
|
176
|
+
// Map JobStatus to database status
|
|
177
|
+
const dbStatus = this.mapStatusToDb(status);
|
|
178
|
+
const where = { status: dbStatus };
|
|
179
|
+
if (jobType) {
|
|
180
|
+
where.queue = jobType;
|
|
181
|
+
}
|
|
182
|
+
const jobs = await this.db.queueJob.findMany({
|
|
183
|
+
where,
|
|
184
|
+
orderBy: { createdAt: 'desc' },
|
|
185
|
+
take: limit,
|
|
186
|
+
});
|
|
187
|
+
return jobs.map((job) => this.dbJobToInfo(job));
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
throw new Error(`Failed to get database jobs: ${error.message}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Retry failed job in database
|
|
195
|
+
* @llm-rule WHEN: Manual retry of failed jobs from admin interface
|
|
196
|
+
* @llm-rule AVOID: Retrying without fixing underlying code issues
|
|
197
|
+
*/
|
|
198
|
+
async retry(jobId) {
|
|
199
|
+
try {
|
|
200
|
+
const job = await this.db.queueJob.findUnique({
|
|
201
|
+
where: { id: jobId },
|
|
202
|
+
});
|
|
203
|
+
if (!job) {
|
|
204
|
+
throw new Error(`Job ${jobId} not found`);
|
|
205
|
+
}
|
|
206
|
+
if (job.status !== 'failed') {
|
|
207
|
+
throw new Error(`Job ${jobId} is not in failed state`);
|
|
208
|
+
}
|
|
209
|
+
// Reset job for retry
|
|
210
|
+
await this.db.queueJob.update({
|
|
211
|
+
where: { id: jobId },
|
|
212
|
+
data: {
|
|
213
|
+
status: 'pending',
|
|
214
|
+
attempts: 0,
|
|
215
|
+
error: null,
|
|
216
|
+
failedAt: null,
|
|
217
|
+
runAt: new Date(),
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
throw new Error(`Failed to retry database job: ${error.message}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Remove job from database
|
|
227
|
+
* @llm-rule WHEN: Canceling scheduled jobs or permanent cleanup
|
|
228
|
+
* @llm-rule AVOID: Removing active jobs - can cause worker inconsistencies
|
|
229
|
+
*/
|
|
230
|
+
async remove(jobId) {
|
|
231
|
+
try {
|
|
232
|
+
const job = await this.db.queueJob.findUnique({
|
|
233
|
+
where: { id: jobId },
|
|
234
|
+
});
|
|
235
|
+
if (!job) {
|
|
236
|
+
throw new Error(`Job ${jobId} not found`);
|
|
237
|
+
}
|
|
238
|
+
if (job.status === 'processing') {
|
|
239
|
+
throw new Error(`Cannot remove active job ${jobId}`);
|
|
240
|
+
}
|
|
241
|
+
await this.db.queueJob.delete({
|
|
242
|
+
where: { id: jobId },
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
throw new Error(`Failed to remove database job: ${error.message}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Clean old jobs from database
|
|
251
|
+
* @llm-rule WHEN: Periodic cleanup to prevent database growth
|
|
252
|
+
* @llm-rule AVOID: Aggressive cleanup without considering audit requirements
|
|
253
|
+
*/
|
|
254
|
+
async clean(status, grace = 24 * 60 * 60 * 1000) {
|
|
255
|
+
try {
|
|
256
|
+
const cutoff = new Date(Date.now() - grace);
|
|
257
|
+
const dbStatus = this.mapStatusToDb(status);
|
|
258
|
+
await this.db.queueJob.deleteMany({
|
|
259
|
+
where: {
|
|
260
|
+
status: dbStatus,
|
|
261
|
+
AND: [
|
|
262
|
+
{
|
|
263
|
+
OR: [
|
|
264
|
+
{ completedAt: { lt: cutoff } },
|
|
265
|
+
{ failedAt: { lt: cutoff } },
|
|
266
|
+
{
|
|
267
|
+
AND: [
|
|
268
|
+
{ completedAt: null },
|
|
269
|
+
{ failedAt: null },
|
|
270
|
+
{ createdAt: { lt: cutoff } }
|
|
271
|
+
]
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
throw new Error(`Failed to clean database jobs: ${error.message}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get database transport health status
|
|
285
|
+
* @llm-rule WHEN: Health checks and monitoring
|
|
286
|
+
* @llm-rule AVOID: Complex health logic - database connection is main indicator
|
|
287
|
+
*/
|
|
288
|
+
getHealth() {
|
|
289
|
+
try {
|
|
290
|
+
// Simple check - if we can import db, Prisma connection should be healthy
|
|
291
|
+
// In a real implementation, you might want to do a simple query
|
|
292
|
+
return { status: 'healthy' };
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
return { status: 'unhealthy', message: 'Database connection issues' };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Close database transport and cleanup resources
|
|
300
|
+
* @llm-rule WHEN: App shutdown or testing cleanup
|
|
301
|
+
* @llm-rule AVOID: Closing shared database connection - other parts of app use it
|
|
302
|
+
*/
|
|
303
|
+
async close() {
|
|
304
|
+
// Stop processing loops
|
|
305
|
+
if (this.processingLoop) {
|
|
306
|
+
clearTimeout(this.processingLoop);
|
|
307
|
+
this.processingLoop = null;
|
|
308
|
+
}
|
|
309
|
+
if (this.cleanupTimer) {
|
|
310
|
+
clearInterval(this.cleanupTimer);
|
|
311
|
+
this.cleanupTimer = null;
|
|
312
|
+
}
|
|
313
|
+
if (this.healthCheckTimer) {
|
|
314
|
+
clearInterval(this.healthCheckTimer);
|
|
315
|
+
this.healthCheckTimer = null;
|
|
316
|
+
}
|
|
317
|
+
// Wait for current jobs to complete
|
|
318
|
+
const timeout = this.config.worker.gracefulShutdownTimeout;
|
|
319
|
+
const startTime = Date.now();
|
|
320
|
+
while (this.processing.size > 0 && Date.now() - startTime < timeout) {
|
|
321
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
322
|
+
}
|
|
323
|
+
// Note: We don't close the database connection as it's shared with the rest of the app
|
|
324
|
+
this.handlers.clear();
|
|
325
|
+
this.paused.clear();
|
|
326
|
+
this.processing.clear();
|
|
327
|
+
}
|
|
328
|
+
// ============================================================================
|
|
329
|
+
// PRIVATE PROCESSING METHODS
|
|
330
|
+
// ============================================================================
|
|
331
|
+
/**
|
|
332
|
+
* Start background job processing
|
|
333
|
+
*/
|
|
334
|
+
startProcessing() {
|
|
335
|
+
this.processJobs();
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Main job processing loop
|
|
339
|
+
*/
|
|
340
|
+
async processJobs() {
|
|
341
|
+
try {
|
|
342
|
+
await this.processWaitingJobs();
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error('Database processing error:', error.message);
|
|
346
|
+
}
|
|
347
|
+
// Schedule next processing cycle
|
|
348
|
+
this.processingLoop = setTimeout(() => this.processJobs(), this.config.database.pollInterval);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Process waiting jobs up to concurrency limit
|
|
352
|
+
*/
|
|
353
|
+
async processWaitingJobs() {
|
|
354
|
+
const concurrency = this.config.concurrency;
|
|
355
|
+
const currentActive = this.processing.size;
|
|
356
|
+
if (currentActive >= concurrency) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
// Get ready jobs ordered by priority and creation time
|
|
361
|
+
const jobs = await this.db.queueJob.findMany({
|
|
362
|
+
where: {
|
|
363
|
+
status: 'pending',
|
|
364
|
+
runAt: { lte: new Date() },
|
|
365
|
+
queue: { in: Array.from(this.handlers.keys()) },
|
|
366
|
+
NOT: { queue: { in: Array.from(this.paused) } },
|
|
367
|
+
},
|
|
368
|
+
orderBy: [
|
|
369
|
+
{ priority: 'desc' },
|
|
370
|
+
{ createdAt: 'asc' },
|
|
371
|
+
],
|
|
372
|
+
take: concurrency - currentActive,
|
|
373
|
+
});
|
|
374
|
+
// Process each job
|
|
375
|
+
for (const job of jobs) {
|
|
376
|
+
const handler = this.handlers.get(job.queue);
|
|
377
|
+
if (handler) {
|
|
378
|
+
this.processJob(job, handler).catch(error => {
|
|
379
|
+
console.error(`Error processing database job ${job.id}:`, error);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
console.error('Error fetching waiting jobs:', error.message);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Process individual job with database state management
|
|
390
|
+
*/
|
|
391
|
+
async processJob(job, handler) {
|
|
392
|
+
// Mark as processing
|
|
393
|
+
this.processing.add(job.id);
|
|
394
|
+
try {
|
|
395
|
+
// Atomically claim the job (prevents race conditions)
|
|
396
|
+
const claimed = await this.claimJob(job);
|
|
397
|
+
if (!claimed) {
|
|
398
|
+
return; // Job was claimed by another worker
|
|
399
|
+
}
|
|
400
|
+
// Execute handler
|
|
401
|
+
const result = await handler(job.payload);
|
|
402
|
+
// Job completed successfully
|
|
403
|
+
await this.completeJob(job, result);
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
// Job failed
|
|
407
|
+
await this.failJob(job, error);
|
|
408
|
+
}
|
|
409
|
+
finally {
|
|
410
|
+
this.processing.delete(job.id);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Atomically claim job for processing
|
|
415
|
+
*/
|
|
416
|
+
async claimJob(job) {
|
|
417
|
+
try {
|
|
418
|
+
const result = await this.db.queueJob.updateMany({
|
|
419
|
+
where: {
|
|
420
|
+
id: job.id,
|
|
421
|
+
status: 'pending', // Only claim if still pending
|
|
422
|
+
},
|
|
423
|
+
data: {
|
|
424
|
+
status: 'processing',
|
|
425
|
+
processedAt: new Date(),
|
|
426
|
+
attempts: { increment: 1 },
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
return result.count > 0;
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
console.error(`Error claiming job ${job.id}:`, error.message);
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Complete job successfully
|
|
438
|
+
*/
|
|
439
|
+
async completeJob(job, result) {
|
|
440
|
+
try {
|
|
441
|
+
await this.db.queueJob.update({
|
|
442
|
+
where: { id: job.id },
|
|
443
|
+
data: {
|
|
444
|
+
status: 'completed',
|
|
445
|
+
result: result !== undefined ? result : null,
|
|
446
|
+
completedAt: new Date(),
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
catch (error) {
|
|
451
|
+
console.error(`Error completing job ${job.id}:`, error.message);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Fail job with retry logic
|
|
456
|
+
*/
|
|
457
|
+
async failJob(job, error) {
|
|
458
|
+
try {
|
|
459
|
+
const errorData = {
|
|
460
|
+
message: error.message,
|
|
461
|
+
stack: error.stack,
|
|
462
|
+
name: error.name,
|
|
463
|
+
};
|
|
464
|
+
if (job.attempts < job.maxAttempts) {
|
|
465
|
+
// Retry with backoff
|
|
466
|
+
const retryDelay = this.calculateRetryDelay(job);
|
|
467
|
+
await this.db.queueJob.update({
|
|
468
|
+
where: { id: job.id },
|
|
469
|
+
data: {
|
|
470
|
+
status: 'pending',
|
|
471
|
+
error: errorData,
|
|
472
|
+
runAt: retryDelay,
|
|
473
|
+
},
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
// Max attempts reached
|
|
478
|
+
await this.db.queueJob.update({
|
|
479
|
+
where: { id: job.id },
|
|
480
|
+
data: {
|
|
481
|
+
status: 'failed',
|
|
482
|
+
error: errorData,
|
|
483
|
+
failedAt: new Date(),
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
catch (dbError) {
|
|
489
|
+
console.error(`Error failing job ${job.id}:`, dbError.message);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Calculate retry delay with backoff
|
|
494
|
+
*/
|
|
495
|
+
calculateRetryDelay(job) {
|
|
496
|
+
const baseDelay = this.config.retryDelay;
|
|
497
|
+
let delay = baseDelay;
|
|
498
|
+
if (this.config.retryBackoff === 'exponential') {
|
|
499
|
+
delay = baseDelay * Math.pow(2, job.attempts - 1);
|
|
500
|
+
}
|
|
501
|
+
// Add jitter (±25%)
|
|
502
|
+
const jitter = delay * 0.25 * (Math.random() - 0.5);
|
|
503
|
+
delay += jitter;
|
|
504
|
+
return new Date(Date.now() + delay);
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Setup periodic cleanup
|
|
508
|
+
*/
|
|
509
|
+
setupCleanup() {
|
|
510
|
+
this.cleanupTimer = setInterval(async () => {
|
|
511
|
+
try {
|
|
512
|
+
// Clean completed jobs older than 1 hour
|
|
513
|
+
await this.clean('completed', 60 * 60 * 1000);
|
|
514
|
+
// Clean failed jobs older than 24 hours
|
|
515
|
+
await this.clean('failed', 24 * 60 * 60 * 1000);
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
console.error('Database cleanup error:', error.message);
|
|
519
|
+
}
|
|
520
|
+
}, 60 * 60 * 1000); // Every hour
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Setup periodic health checks
|
|
524
|
+
*/
|
|
525
|
+
setupHealthCheck() {
|
|
526
|
+
this.healthCheckTimer = setInterval(async () => {
|
|
527
|
+
try {
|
|
528
|
+
// Simple health check - count pending jobs
|
|
529
|
+
await this.db.queueJob.count({ where: { status: 'pending' } });
|
|
530
|
+
}
|
|
531
|
+
catch (error) {
|
|
532
|
+
console.error('Database health check failed:', error.message);
|
|
533
|
+
}
|
|
534
|
+
}, 30000); // Every 30 seconds
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Ensure queue jobs table exists
|
|
538
|
+
*/
|
|
539
|
+
async ensureTableExists() {
|
|
540
|
+
// Note: This assumes the QueueJob model is already in the Prisma schema
|
|
541
|
+
// and migrations have been run. In a real implementation, you might want
|
|
542
|
+
// to check if the table exists and provide helpful error messages.
|
|
543
|
+
try {
|
|
544
|
+
await this.db.queueJob.count();
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
throw new Error('QueueJob table not found. Please ensure the queue_jobs table exists in your database schema. ' +
|
|
548
|
+
'Add the QueueJob model to your Prisma schema and run migrations.');
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
// ============================================================================
|
|
552
|
+
// PRIVATE UTILITY METHODS
|
|
553
|
+
// ============================================================================
|
|
554
|
+
/**
|
|
555
|
+
* Map JobStatus to database status
|
|
556
|
+
*/
|
|
557
|
+
mapStatusToDb(status) {
|
|
558
|
+
const statusMap = {
|
|
559
|
+
waiting: 'pending',
|
|
560
|
+
active: 'processing',
|
|
561
|
+
completed: 'completed',
|
|
562
|
+
failed: 'failed',
|
|
563
|
+
delayed: 'pending', // Database doesn't distinguish delayed
|
|
564
|
+
paused: 'pending', // Database doesn't distinguish paused
|
|
565
|
+
};
|
|
566
|
+
return statusMap[status] || status;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Convert database job to JobInfo
|
|
570
|
+
*/
|
|
571
|
+
dbJobToInfo(job) {
|
|
572
|
+
// Map database status back to JobStatus
|
|
573
|
+
const statusMap = {
|
|
574
|
+
pending: 'waiting',
|
|
575
|
+
processing: 'active',
|
|
576
|
+
completed: 'completed',
|
|
577
|
+
failed: 'failed',
|
|
578
|
+
};
|
|
579
|
+
return {
|
|
580
|
+
id: job.id,
|
|
581
|
+
type: job.queue,
|
|
582
|
+
data: job.payload,
|
|
583
|
+
status: statusMap[job.status] || 'waiting',
|
|
584
|
+
progress: undefined, // Database model doesn't track progress
|
|
585
|
+
attempts: job.attempts,
|
|
586
|
+
maxAttempts: job.maxAttempts || this.config.maxAttempts,
|
|
587
|
+
error: job.error,
|
|
588
|
+
createdAt: job.createdAt,
|
|
589
|
+
processedAt: job.processedAt || undefined,
|
|
590
|
+
completedAt: job.completedAt || undefined,
|
|
591
|
+
failedAt: job.failedAt || undefined,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/queue/transports/database.ts"],"names":[],"mappings":"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"}
|