@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.
Files changed (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +902 -0
  3. package/bin/appkit.js +71 -0
  4. package/bin/commands/generate.js +1050 -0
  5. package/bin/templates/backend/README.md.template +39 -0
  6. package/bin/templates/backend/api.http.template +0 -0
  7. package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
  8. package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
  9. package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
  10. package/bin/templates/backend/package.json.template +34 -0
  11. package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
  12. package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
  13. package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
  14. package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
  15. package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
  16. package/bin/templates/backend/src/api/server.ts.template +188 -0
  17. package/bin/templates/backend/tsconfig.api.json.template +24 -0
  18. package/bin/templates/backend/tsconfig.json.template +40 -0
  19. package/bin/templates/feature/feature.http.template +63 -0
  20. package/bin/templates/feature/feature.route.ts.template +36 -0
  21. package/bin/templates/feature/feature.service.ts.template +81 -0
  22. package/bin/templates/feature/feature.types.ts.template +23 -0
  23. package/bin/templates/feature-db/feature.http.template +63 -0
  24. package/bin/templates/feature-db/feature.model.ts.template +74 -0
  25. package/bin/templates/feature-db/feature.route.ts.template +58 -0
  26. package/bin/templates/feature-db/feature.service.ts.template +231 -0
  27. package/bin/templates/feature-db/feature.types.ts.template +25 -0
  28. package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
  29. package/bin/templates/feature-db/seeding/README.md.template +57 -0
  30. package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
  31. package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
  32. package/bin/templates/feature-user/user.http.template +157 -0
  33. package/bin/templates/feature-user/user.model.ts.template +244 -0
  34. package/bin/templates/feature-user/user.route.ts.template +379 -0
  35. package/bin/templates/feature-user/user.seed.js.template +182 -0
  36. package/bin/templates/feature-user/user.service.ts.template +426 -0
  37. package/bin/templates/feature-user/user.types.ts.template +127 -0
  38. package/dist/auth/auth.d.ts +182 -0
  39. package/dist/auth/auth.d.ts.map +1 -0
  40. package/dist/auth/auth.js +477 -0
  41. package/dist/auth/auth.js.map +1 -0
  42. package/dist/auth/defaults.d.ts +104 -0
  43. package/dist/auth/defaults.d.ts.map +1 -0
  44. package/dist/auth/defaults.js +374 -0
  45. package/dist/auth/defaults.js.map +1 -0
  46. package/dist/auth/index.d.ts +70 -0
  47. package/dist/auth/index.d.ts.map +1 -0
  48. package/dist/auth/index.js +94 -0
  49. package/dist/auth/index.js.map +1 -0
  50. package/dist/cache/cache.d.ts +118 -0
  51. package/dist/cache/cache.d.ts.map +1 -0
  52. package/dist/cache/cache.js +249 -0
  53. package/dist/cache/cache.js.map +1 -0
  54. package/dist/cache/defaults.d.ts +63 -0
  55. package/dist/cache/defaults.d.ts.map +1 -0
  56. package/dist/cache/defaults.js +193 -0
  57. package/dist/cache/defaults.js.map +1 -0
  58. package/dist/cache/index.d.ts +101 -0
  59. package/dist/cache/index.d.ts.map +1 -0
  60. package/dist/cache/index.js +203 -0
  61. package/dist/cache/index.js.map +1 -0
  62. package/dist/cache/strategies/memory.d.ts +138 -0
  63. package/dist/cache/strategies/memory.d.ts.map +1 -0
  64. package/dist/cache/strategies/memory.js +348 -0
  65. package/dist/cache/strategies/memory.js.map +1 -0
  66. package/dist/cache/strategies/redis.d.ts +105 -0
  67. package/dist/cache/strategies/redis.d.ts.map +1 -0
  68. package/dist/cache/strategies/redis.js +318 -0
  69. package/dist/cache/strategies/redis.js.map +1 -0
  70. package/dist/config/config.d.ts +62 -0
  71. package/dist/config/config.d.ts.map +1 -0
  72. package/dist/config/config.js +107 -0
  73. package/dist/config/config.js.map +1 -0
  74. package/dist/config/defaults.d.ts +44 -0
  75. package/dist/config/defaults.d.ts.map +1 -0
  76. package/dist/config/defaults.js +217 -0
  77. package/dist/config/defaults.js.map +1 -0
  78. package/dist/config/index.d.ts +105 -0
  79. package/dist/config/index.d.ts.map +1 -0
  80. package/dist/config/index.js +163 -0
  81. package/dist/config/index.js.map +1 -0
  82. package/dist/database/adapters/mongoose.d.ts +106 -0
  83. package/dist/database/adapters/mongoose.d.ts.map +1 -0
  84. package/dist/database/adapters/mongoose.js +480 -0
  85. package/dist/database/adapters/mongoose.js.map +1 -0
  86. package/dist/database/adapters/prisma.d.ts +106 -0
  87. package/dist/database/adapters/prisma.d.ts.map +1 -0
  88. package/dist/database/adapters/prisma.js +494 -0
  89. package/dist/database/adapters/prisma.js.map +1 -0
  90. package/dist/database/defaults.d.ts +87 -0
  91. package/dist/database/defaults.d.ts.map +1 -0
  92. package/dist/database/defaults.js +271 -0
  93. package/dist/database/defaults.js.map +1 -0
  94. package/dist/database/index.d.ts +137 -0
  95. package/dist/database/index.d.ts.map +1 -0
  96. package/dist/database/index.js +490 -0
  97. package/dist/database/index.js.map +1 -0
  98. package/dist/email/defaults.d.ts +100 -0
  99. package/dist/email/defaults.d.ts.map +1 -0
  100. package/dist/email/defaults.js +400 -0
  101. package/dist/email/defaults.js.map +1 -0
  102. package/dist/email/email.d.ts +139 -0
  103. package/dist/email/email.d.ts.map +1 -0
  104. package/dist/email/email.js +316 -0
  105. package/dist/email/email.js.map +1 -0
  106. package/dist/email/index.d.ts +176 -0
  107. package/dist/email/index.d.ts.map +1 -0
  108. package/dist/email/index.js +251 -0
  109. package/dist/email/index.js.map +1 -0
  110. package/dist/email/strategies/console.d.ts +90 -0
  111. package/dist/email/strategies/console.d.ts.map +1 -0
  112. package/dist/email/strategies/console.js +268 -0
  113. package/dist/email/strategies/console.js.map +1 -0
  114. package/dist/email/strategies/resend.d.ts +84 -0
  115. package/dist/email/strategies/resend.d.ts.map +1 -0
  116. package/dist/email/strategies/resend.js +266 -0
  117. package/dist/email/strategies/resend.js.map +1 -0
  118. package/dist/email/strategies/smtp.d.ts +77 -0
  119. package/dist/email/strategies/smtp.d.ts.map +1 -0
  120. package/dist/email/strategies/smtp.js +286 -0
  121. package/dist/email/strategies/smtp.js.map +1 -0
  122. package/dist/error/defaults.d.ts +40 -0
  123. package/dist/error/defaults.d.ts.map +1 -0
  124. package/dist/error/defaults.js +75 -0
  125. package/dist/error/defaults.js.map +1 -0
  126. package/dist/error/error.d.ts +140 -0
  127. package/dist/error/error.d.ts.map +1 -0
  128. package/dist/error/error.js +200 -0
  129. package/dist/error/error.js.map +1 -0
  130. package/dist/error/index.d.ts +145 -0
  131. package/dist/error/index.d.ts.map +1 -0
  132. package/dist/error/index.js +145 -0
  133. package/dist/error/index.js.map +1 -0
  134. package/dist/event/defaults.d.ts +111 -0
  135. package/dist/event/defaults.d.ts.map +1 -0
  136. package/dist/event/defaults.js +378 -0
  137. package/dist/event/defaults.js.map +1 -0
  138. package/dist/event/event.d.ts +171 -0
  139. package/dist/event/event.d.ts.map +1 -0
  140. package/dist/event/event.js +391 -0
  141. package/dist/event/event.js.map +1 -0
  142. package/dist/event/index.d.ts +173 -0
  143. package/dist/event/index.d.ts.map +1 -0
  144. package/dist/event/index.js +302 -0
  145. package/dist/event/index.js.map +1 -0
  146. package/dist/event/strategies/memory.d.ts +122 -0
  147. package/dist/event/strategies/memory.d.ts.map +1 -0
  148. package/dist/event/strategies/memory.js +331 -0
  149. package/dist/event/strategies/memory.js.map +1 -0
  150. package/dist/event/strategies/redis.d.ts +115 -0
  151. package/dist/event/strategies/redis.d.ts.map +1 -0
  152. package/dist/event/strategies/redis.js +434 -0
  153. package/dist/event/strategies/redis.js.map +1 -0
  154. package/dist/index.d.ts +58 -0
  155. package/dist/index.d.ts.map +1 -0
  156. package/dist/index.js +72 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/logger/defaults.d.ts +67 -0
  159. package/dist/logger/defaults.d.ts.map +1 -0
  160. package/dist/logger/defaults.js +213 -0
  161. package/dist/logger/defaults.js.map +1 -0
  162. package/dist/logger/index.d.ts +84 -0
  163. package/dist/logger/index.d.ts.map +1 -0
  164. package/dist/logger/index.js +101 -0
  165. package/dist/logger/index.js.map +1 -0
  166. package/dist/logger/logger.d.ts +165 -0
  167. package/dist/logger/logger.d.ts.map +1 -0
  168. package/dist/logger/logger.js +843 -0
  169. package/dist/logger/logger.js.map +1 -0
  170. package/dist/logger/transports/console.d.ts +102 -0
  171. package/dist/logger/transports/console.d.ts.map +1 -0
  172. package/dist/logger/transports/console.js +276 -0
  173. package/dist/logger/transports/console.js.map +1 -0
  174. package/dist/logger/transports/database.d.ts +153 -0
  175. package/dist/logger/transports/database.d.ts.map +1 -0
  176. package/dist/logger/transports/database.js +539 -0
  177. package/dist/logger/transports/database.js.map +1 -0
  178. package/dist/logger/transports/file.d.ts +146 -0
  179. package/dist/logger/transports/file.d.ts.map +1 -0
  180. package/dist/logger/transports/file.js +464 -0
  181. package/dist/logger/transports/file.js.map +1 -0
  182. package/dist/logger/transports/http.d.ts +128 -0
  183. package/dist/logger/transports/http.d.ts.map +1 -0
  184. package/dist/logger/transports/http.js +401 -0
  185. package/dist/logger/transports/http.js.map +1 -0
  186. package/dist/logger/transports/webhook.d.ts +152 -0
  187. package/dist/logger/transports/webhook.d.ts.map +1 -0
  188. package/dist/logger/transports/webhook.js +485 -0
  189. package/dist/logger/transports/webhook.js.map +1 -0
  190. package/dist/queue/defaults.d.ts +66 -0
  191. package/dist/queue/defaults.d.ts.map +1 -0
  192. package/dist/queue/defaults.js +205 -0
  193. package/dist/queue/defaults.js.map +1 -0
  194. package/dist/queue/index.d.ts +124 -0
  195. package/dist/queue/index.d.ts.map +1 -0
  196. package/dist/queue/index.js +116 -0
  197. package/dist/queue/index.js.map +1 -0
  198. package/dist/queue/queue.d.ts +156 -0
  199. package/dist/queue/queue.d.ts.map +1 -0
  200. package/dist/queue/queue.js +387 -0
  201. package/dist/queue/queue.js.map +1 -0
  202. package/dist/queue/transports/database.d.ts +165 -0
  203. package/dist/queue/transports/database.d.ts.map +1 -0
  204. package/dist/queue/transports/database.js +595 -0
  205. package/dist/queue/transports/database.js.map +1 -0
  206. package/dist/queue/transports/memory.d.ts +143 -0
  207. package/dist/queue/transports/memory.d.ts.map +1 -0
  208. package/dist/queue/transports/memory.js +415 -0
  209. package/dist/queue/transports/memory.js.map +1 -0
  210. package/dist/queue/transports/redis.d.ts +203 -0
  211. package/dist/queue/transports/redis.d.ts.map +1 -0
  212. package/dist/queue/transports/redis.js +744 -0
  213. package/dist/queue/transports/redis.js.map +1 -0
  214. package/dist/security/defaults.d.ts +64 -0
  215. package/dist/security/defaults.d.ts.map +1 -0
  216. package/dist/security/defaults.js +159 -0
  217. package/dist/security/defaults.js.map +1 -0
  218. package/dist/security/index.d.ts +110 -0
  219. package/dist/security/index.d.ts.map +1 -0
  220. package/dist/security/index.js +160 -0
  221. package/dist/security/index.js.map +1 -0
  222. package/dist/security/security.d.ts +138 -0
  223. package/dist/security/security.d.ts.map +1 -0
  224. package/dist/security/security.js +419 -0
  225. package/dist/security/security.js.map +1 -0
  226. package/dist/storage/defaults.d.ts +79 -0
  227. package/dist/storage/defaults.d.ts.map +1 -0
  228. package/dist/storage/defaults.js +358 -0
  229. package/dist/storage/defaults.js.map +1 -0
  230. package/dist/storage/index.d.ts +153 -0
  231. package/dist/storage/index.d.ts.map +1 -0
  232. package/dist/storage/index.js +242 -0
  233. package/dist/storage/index.js.map +1 -0
  234. package/dist/storage/storage.d.ts +151 -0
  235. package/dist/storage/storage.d.ts.map +1 -0
  236. package/dist/storage/storage.js +439 -0
  237. package/dist/storage/storage.js.map +1 -0
  238. package/dist/storage/strategies/local.d.ts +117 -0
  239. package/dist/storage/strategies/local.d.ts.map +1 -0
  240. package/dist/storage/strategies/local.js +368 -0
  241. package/dist/storage/strategies/local.js.map +1 -0
  242. package/dist/storage/strategies/r2.d.ts +130 -0
  243. package/dist/storage/strategies/r2.d.ts.map +1 -0
  244. package/dist/storage/strategies/r2.js +470 -0
  245. package/dist/storage/strategies/r2.js.map +1 -0
  246. package/dist/storage/strategies/s3.d.ts +121 -0
  247. package/dist/storage/strategies/s3.d.ts.map +1 -0
  248. package/dist/storage/strategies/s3.js +461 -0
  249. package/dist/storage/strategies/s3.js.map +1 -0
  250. package/dist/util/defaults.d.ts +77 -0
  251. package/dist/util/defaults.d.ts.map +1 -0
  252. package/dist/util/defaults.js +193 -0
  253. package/dist/util/defaults.js.map +1 -0
  254. package/dist/util/index.d.ts +97 -0
  255. package/dist/util/index.d.ts.map +1 -0
  256. package/dist/util/index.js +165 -0
  257. package/dist/util/index.js.map +1 -0
  258. package/dist/util/util.d.ts +145 -0
  259. package/dist/util/util.d.ts.map +1 -0
  260. package/dist/util/util.js +481 -0
  261. package/dist/util/util.js.map +1 -0
  262. 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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"}