@revealui/db 0.2.0

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 (191) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +137 -0
  3. package/dist/audit-store.d.ts +56 -0
  4. package/dist/audit-store.d.ts.map +1 -0
  5. package/dist/audit-store.js +120 -0
  6. package/dist/audit-store.js.map +1 -0
  7. package/dist/client/index.d.ts +214 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +396 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/client/types.d.ts +109 -0
  12. package/dist/client/types.d.ts.map +1 -0
  13. package/dist/client/types.js +10 -0
  14. package/dist/client/types.js.map +1 -0
  15. package/dist/crypto.d.ts +27 -0
  16. package/dist/crypto.d.ts.map +1 -0
  17. package/dist/crypto.js +68 -0
  18. package/dist/crypto.js.map +1 -0
  19. package/dist/index.d.ts +29 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +31 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/log-transport.d.ts +20 -0
  24. package/dist/log-transport.d.ts.map +1 -0
  25. package/dist/log-transport.js +49 -0
  26. package/dist/log-transport.js.map +1 -0
  27. package/dist/pool.d.ts +36 -0
  28. package/dist/pool.d.ts.map +1 -0
  29. package/dist/pool.js +218 -0
  30. package/dist/pool.js.map +1 -0
  31. package/dist/queries/boards.d.ts +138 -0
  32. package/dist/queries/boards.d.ts.map +1 -0
  33. package/dist/queries/boards.js +87 -0
  34. package/dist/queries/boards.js.map +1 -0
  35. package/dist/queries/code-provenance.d.ts +250 -0
  36. package/dist/queries/code-provenance.d.ts.map +1 -0
  37. package/dist/queries/code-provenance.js +130 -0
  38. package/dist/queries/code-provenance.js.map +1 -0
  39. package/dist/queries/optimized-queries.d.ts +89 -0
  40. package/dist/queries/optimized-queries.d.ts.map +1 -0
  41. package/dist/queries/optimized-queries.js +371 -0
  42. package/dist/queries/optimized-queries.js.map +1 -0
  43. package/dist/queries/ticket-comments.d.ts +37 -0
  44. package/dist/queries/ticket-comments.d.ts.map +1 -0
  45. package/dist/queries/ticket-comments.js +52 -0
  46. package/dist/queries/ticket-comments.js.map +1 -0
  47. package/dist/queries/ticket-labels.d.ts +69 -0
  48. package/dist/queries/ticket-labels.d.ts.map +1 -0
  49. package/dist/queries/ticket-labels.js +51 -0
  50. package/dist/queries/ticket-labels.js.map +1 -0
  51. package/dist/queries/tickets.d.ts +301 -0
  52. package/dist/queries/tickets.d.ts.map +1 -0
  53. package/dist/queries/tickets.js +89 -0
  54. package/dist/queries/tickets.js.map +1 -0
  55. package/dist/queries/todos.d.ts +37 -0
  56. package/dist/queries/todos.d.ts.map +1 -0
  57. package/dist/queries/todos.js +37 -0
  58. package/dist/queries/todos.js.map +1 -0
  59. package/dist/schema/agents.d.ts +1413 -0
  60. package/dist/schema/agents.d.ts.map +1 -0
  61. package/dist/schema/agents.js +207 -0
  62. package/dist/schema/agents.js.map +1 -0
  63. package/dist/schema/api-keys.d.ts +298 -0
  64. package/dist/schema/api-keys.d.ts.map +1 -0
  65. package/dist/schema/api-keys.js +53 -0
  66. package/dist/schema/api-keys.js.map +1 -0
  67. package/dist/schema/app-logs.d.ts +168 -0
  68. package/dist/schema/app-logs.d.ts.map +1 -0
  69. package/dist/schema/app-logs.js +25 -0
  70. package/dist/schema/app-logs.js.map +1 -0
  71. package/dist/schema/audit-log.d.ts +174 -0
  72. package/dist/schema/audit-log.d.ts.map +1 -0
  73. package/dist/schema/audit-log.js +37 -0
  74. package/dist/schema/audit-log.js.map +1 -0
  75. package/dist/schema/cms.d.ts +1015 -0
  76. package/dist/schema/cms.d.ts.map +1 -0
  77. package/dist/schema/cms.js +137 -0
  78. package/dist/schema/cms.js.map +1 -0
  79. package/dist/schema/code-provenance.d.ts +488 -0
  80. package/dist/schema/code-provenance.d.ts.map +1 -0
  81. package/dist/schema/code-provenance.js +72 -0
  82. package/dist/schema/code-provenance.js.map +1 -0
  83. package/dist/schema/collab-edits.d.ts +165 -0
  84. package/dist/schema/collab-edits.d.ts.map +1 -0
  85. package/dist/schema/collab-edits.js +21 -0
  86. package/dist/schema/collab-edits.js.map +1 -0
  87. package/dist/schema/crdt-operations.d.ts +153 -0
  88. package/dist/schema/crdt-operations.d.ts.map +1 -0
  89. package/dist/schema/crdt-operations.js +30 -0
  90. package/dist/schema/crdt-operations.js.map +1 -0
  91. package/dist/schema/error-events.d.ts +223 -0
  92. package/dist/schema/error-events.d.ts.map +1 -0
  93. package/dist/schema/error-events.js +44 -0
  94. package/dist/schema/error-events.js.map +1 -0
  95. package/dist/schema/index.d.ts +130 -0
  96. package/dist/schema/index.d.ts.map +1 -0
  97. package/dist/schema/index.js +310 -0
  98. package/dist/schema/index.js.map +1 -0
  99. package/dist/schema/licenses.d.ts +189 -0
  100. package/dist/schema/licenses.d.ts.map +1 -0
  101. package/dist/schema/licenses.js +39 -0
  102. package/dist/schema/licenses.js.map +1 -0
  103. package/dist/schema/node-ids.d.ts +122 -0
  104. package/dist/schema/node-ids.d.ts.map +1 -0
  105. package/dist/schema/node-ids.js +25 -0
  106. package/dist/schema/node-ids.js.map +1 -0
  107. package/dist/schema/pages.d.ts +488 -0
  108. package/dist/schema/pages.d.ts.map +1 -0
  109. package/dist/schema/pages.js +70 -0
  110. package/dist/schema/pages.js.map +1 -0
  111. package/dist/schema/password-reset-tokens.d.ts +137 -0
  112. package/dist/schema/password-reset-tokens.d.ts.map +1 -0
  113. package/dist/schema/password-reset-tokens.js +26 -0
  114. package/dist/schema/password-reset-tokens.js.map +1 -0
  115. package/dist/schema/query.d.ts +11 -0
  116. package/dist/schema/query.d.ts.map +1 -0
  117. package/dist/schema/query.js +11 -0
  118. package/dist/schema/query.js.map +1 -0
  119. package/dist/schema/rate-limits.d.ts +212 -0
  120. package/dist/schema/rate-limits.d.ts.map +1 -0
  121. package/dist/schema/rate-limits.js +38 -0
  122. package/dist/schema/rate-limits.js.map +1 -0
  123. package/dist/schema/rest.d.ts +31 -0
  124. package/dist/schema/rest.d.ts.map +1 -0
  125. package/dist/schema/rest.js +37 -0
  126. package/dist/schema/rest.js.map +1 -0
  127. package/dist/schema/sites.d.ts +365 -0
  128. package/dist/schema/sites.d.ts.map +1 -0
  129. package/dist/schema/sites.js +62 -0
  130. package/dist/schema/sites.js.map +1 -0
  131. package/dist/schema/tickets.d.ts +1118 -0
  132. package/dist/schema/tickets.d.ts.map +1 -0
  133. package/dist/schema/tickets.js +150 -0
  134. package/dist/schema/tickets.js.map +1 -0
  135. package/dist/schema/todos.d.ts +98 -0
  136. package/dist/schema/todos.d.ts.map +1 -0
  137. package/dist/schema/todos.js +12 -0
  138. package/dist/schema/todos.js.map +1 -0
  139. package/dist/schema/users.d.ts +503 -0
  140. package/dist/schema/users.d.ts.map +1 -0
  141. package/dist/schema/users.js +75 -0
  142. package/dist/schema/users.js.map +1 -0
  143. package/dist/schema/vector.d.ts +9 -0
  144. package/dist/schema/vector.d.ts.map +1 -0
  145. package/dist/schema/vector.js +9 -0
  146. package/dist/schema/vector.js.map +1 -0
  147. package/dist/schema/waitlist.d.ts +151 -0
  148. package/dist/schema/waitlist.d.ts.map +1 -0
  149. package/dist/schema/waitlist.js +17 -0
  150. package/dist/schema/waitlist.js.map +1 -0
  151. package/dist/schema/yjs-documents.d.ts +116 -0
  152. package/dist/schema/yjs-documents.d.ts.map +1 -0
  153. package/dist/schema/yjs-documents.js +15 -0
  154. package/dist/schema/yjs-documents.js.map +1 -0
  155. package/dist/types/database.d.ts +740 -0
  156. package/dist/types/database.d.ts.map +1 -0
  157. package/dist/types/database.js +151 -0
  158. package/dist/types/database.js.map +1 -0
  159. package/dist/types/discover.d.ts +83 -0
  160. package/dist/types/discover.d.ts.map +1 -0
  161. package/dist/types/discover.js +271 -0
  162. package/dist/types/discover.js.map +1 -0
  163. package/dist/types/extract-relationships.d.ts +115 -0
  164. package/dist/types/extract-relationships.d.ts.map +1 -0
  165. package/dist/types/extract-relationships.js +455 -0
  166. package/dist/types/extract-relationships.js.map +1 -0
  167. package/dist/types/generate-contracts.d.ts +19 -0
  168. package/dist/types/generate-contracts.d.ts.map +1 -0
  169. package/dist/types/generate-contracts.js +128 -0
  170. package/dist/types/generate-contracts.js.map +1 -0
  171. package/dist/types/generate-zod-schemas.d.ts +20 -0
  172. package/dist/types/generate-zod-schemas.d.ts.map +1 -0
  173. package/dist/types/generate-zod-schemas.js +128 -0
  174. package/dist/types/generate-zod-schemas.js.map +1 -0
  175. package/dist/types/generate.d.ts +17 -0
  176. package/dist/types/generate.d.ts.map +1 -0
  177. package/dist/types/generate.js +298 -0
  178. package/dist/types/generate.js.map +1 -0
  179. package/dist/types/index.d.ts +19 -0
  180. package/dist/types/index.d.ts.map +1 -0
  181. package/dist/types/index.js +19 -0
  182. package/dist/types/index.js.map +1 -0
  183. package/dist/types/introspect.d.ts +75 -0
  184. package/dist/types/introspect.d.ts.map +1 -0
  185. package/dist/types/introspect.js +187 -0
  186. package/dist/types/introspect.js.map +1 -0
  187. package/dist/types/stripe-schema.d.ts +893 -0
  188. package/dist/types/stripe-schema.d.ts.map +1 -0
  189. package/dist/types/stripe-schema.js +112 -0
  190. package/dist/types/stripe-schema.js.map +1 -0
  191. package/package.json +154 -0
@@ -0,0 +1,371 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable */
3
+ /**
4
+ * Optimized Database Queries
5
+ *
6
+ * Examples of N+1 query elimination and query optimization
7
+ * NOTE: This is example/documentation code - not actively used in production
8
+ */
9
+ import { getClient } from '../client/index.js';
10
+ // TODO: Import from @revealui/core package once exports are configured
11
+ // import { monitorQuery } from '@revealui/core/monitoring/query-monitor'
12
+ // import { cacheQuery, cacheList } from '@revealui/core/cache/query-cache'
13
+ // Temporary stubs for build - replace with actual imports once core package exports are set up
14
+ const monitorQuery = (_name, fn) => fn();
15
+ const _cacheQuery = (_key, fn) => fn();
16
+ const cacheList = (_key, fn) => fn();
17
+ // Get db client instance
18
+ const db = getClient();
19
+ // ============================================================================
20
+ // N+1 QUERY ELIMINATION
21
+ // ============================================================================
22
+ /**
23
+ * BAD: N+1 Query Pattern
24
+ * Fetches posts, then makes separate query for each author
25
+ */
26
+ export async function getPostsWithAuthorsN1() {
27
+ // First query: Get all posts
28
+ const posts = await db.query('SELECT * FROM posts WHERE status = $1', ['published']);
29
+ // N additional queries: One for each post's author
30
+ for (const post of posts.rows) {
31
+ const author = await db.query('SELECT * FROM users WHERE id = $1', [post.author_id]);
32
+ post.author = author.rows[0];
33
+ }
34
+ return posts.rows;
35
+ }
36
+ /**
37
+ * GOOD: Optimized with JOIN
38
+ * Single query with all necessary data
39
+ */
40
+ export async function getPostsWithAuthorsOptimized() {
41
+ return monitorQuery('getPostsWithAuthors', async () => {
42
+ const query = `
43
+ SELECT
44
+ p.id,
45
+ p.title,
46
+ p.slug,
47
+ p.content,
48
+ p.published_at,
49
+ p.created_at,
50
+ p.updated_at,
51
+ json_build_object(
52
+ 'id', u.id,
53
+ 'name', u.name,
54
+ 'email', u.email,
55
+ 'avatar', u.avatar
56
+ ) as author
57
+ FROM posts p
58
+ INNER JOIN users u ON u.id = p.author_id
59
+ WHERE p.status = 'published'
60
+ ORDER BY p.published_at DESC
61
+ `;
62
+ const result = await db.query(query);
63
+ return result.rows;
64
+ });
65
+ }
66
+ /**
67
+ * BETTER: Optimized with caching
68
+ */
69
+ export async function getPostsWithAuthorsCached() {
70
+ return cacheList('posts', { status: 'published' }, () => getPostsWithAuthorsOptimized(), 300);
71
+ }
72
+ // ============================================================================
73
+ // PAGINATION OPTIMIZATION
74
+ // ============================================================================
75
+ /**
76
+ * BAD: OFFSET-based pagination (slow for large offsets)
77
+ */
78
+ export async function getPostsPaginatedOffset(page, perPage) {
79
+ const offset = (page - 1) * perPage;
80
+ const query = `
81
+ SELECT * FROM posts
82
+ WHERE status = 'published'
83
+ ORDER BY published_at DESC
84
+ LIMIT $1 OFFSET $2
85
+ `;
86
+ const result = await db.query(query, [perPage, offset]);
87
+ return result.rows;
88
+ }
89
+ /**
90
+ * GOOD: Cursor-based pagination (faster for all positions)
91
+ */
92
+ export async function getPostsPaginatedCursor(cursor, perPage = 20) {
93
+ return monitorQuery('getPostsPaginated', async () => {
94
+ const query = cursor
95
+ ? `
96
+ SELECT * FROM posts
97
+ WHERE status = 'published'
98
+ AND published_at < (
99
+ SELECT published_at FROM posts WHERE id = $1
100
+ )
101
+ ORDER BY published_at DESC
102
+ LIMIT $2
103
+ `
104
+ : `
105
+ SELECT * FROM posts
106
+ WHERE status = 'published'
107
+ ORDER BY published_at DESC
108
+ LIMIT $1
109
+ `;
110
+ const params = cursor ? [cursor, perPage] : [perPage];
111
+ const result = await db.query(query, params);
112
+ return {
113
+ items: result.rows,
114
+ nextCursor: result.rows.length === perPage ? result.rows[result.rows.length - 1].id : null,
115
+ };
116
+ });
117
+ }
118
+ // ============================================================================
119
+ // AGGREGATION OPTIMIZATION
120
+ // ============================================================================
121
+ /**
122
+ * BAD: Multiple count queries
123
+ */
124
+ export async function getPostStatsN1() {
125
+ const totalPosts = await db.query('SELECT COUNT(*) FROM posts');
126
+ const publishedPosts = await db.query("SELECT COUNT(*) FROM posts WHERE status = 'published'");
127
+ const draftPosts = await db.query("SELECT COUNT(*) FROM posts WHERE status = 'draft'");
128
+ return {
129
+ total: totalPosts.rows[0].count,
130
+ published: publishedPosts.rows[0].count,
131
+ draft: draftPosts.rows[0].count,
132
+ };
133
+ }
134
+ /**
135
+ * GOOD: Single aggregation query
136
+ */
137
+ export async function getPostStatsOptimized() {
138
+ return monitorQuery('getPostStats', async () => {
139
+ const query = `
140
+ SELECT
141
+ COUNT(*) as total,
142
+ COUNT(*) FILTER (WHERE status = 'published') as published,
143
+ COUNT(*) FILTER (WHERE status = 'draft') as draft
144
+ FROM posts
145
+ `;
146
+ const result = await db.query(query);
147
+ return result.rows[0];
148
+ });
149
+ }
150
+ // ============================================================================
151
+ // BATCH LOADING
152
+ // ============================================================================
153
+ /**
154
+ * BAD: Individual queries in loop
155
+ */
156
+ export async function getUsersByIdsN1(ids) {
157
+ const users = [];
158
+ for (const id of ids) {
159
+ const result = await db.query('SELECT * FROM users WHERE id = $1', [id]);
160
+ users.push(result.rows[0]);
161
+ }
162
+ return users;
163
+ }
164
+ /**
165
+ * GOOD: Single query with IN clause
166
+ */
167
+ export async function getUsersByIdsOptimized(ids) {
168
+ return monitorQuery('getUsersByIds', async () => {
169
+ const query = 'SELECT * FROM users WHERE id = ANY($1)';
170
+ const result = await db.query(query, [ids]);
171
+ return result.rows;
172
+ });
173
+ }
174
+ // ============================================================================
175
+ // NESTED RELATIONSHIPS
176
+ // ============================================================================
177
+ /**
178
+ * GOOD: Fetch posts with authors and comments in one query
179
+ */
180
+ export async function getPostsWithRelations() {
181
+ return monitorQuery('getPostsWithRelations', async () => {
182
+ const query = `
183
+ SELECT
184
+ p.id,
185
+ p.title,
186
+ p.slug,
187
+ p.content,
188
+ p.published_at,
189
+ json_build_object(
190
+ 'id', u.id,
191
+ 'name', u.name,
192
+ 'email', u.email
193
+ ) as author,
194
+ COALESCE(
195
+ json_agg(
196
+ json_build_object(
197
+ 'id', c.id,
198
+ 'content', c.content,
199
+ 'created_at', c.created_at,
200
+ 'author', json_build_object(
201
+ 'id', cu.id,
202
+ 'name', cu.name
203
+ )
204
+ )
205
+ ORDER BY c.created_at DESC
206
+ ) FILTER (WHERE c.id IS NOT NULL),
207
+ '[]'
208
+ ) as comments
209
+ FROM posts p
210
+ INNER JOIN users u ON u.id = p.author_id
211
+ LEFT JOIN comments c ON c.post_id = p.id AND c.approved_at IS NOT NULL
212
+ LEFT JOIN users cu ON cu.id = c.author_id
213
+ WHERE p.status = 'published'
214
+ GROUP BY p.id, u.id
215
+ ORDER BY p.published_at DESC
216
+ LIMIT 20
217
+ `;
218
+ const result = await db.query(query);
219
+ return result.rows;
220
+ });
221
+ }
222
+ // ============================================================================
223
+ // SEARCH OPTIMIZATION
224
+ // ============================================================================
225
+ /**
226
+ * BAD: LIKE query without index
227
+ */
228
+ export async function searchPostsSlow(query) {
229
+ const sql = `
230
+ SELECT * FROM posts
231
+ WHERE title ILIKE $1 OR content ILIKE $1
232
+ ORDER BY published_at DESC
233
+ `;
234
+ const result = await db.query(sql, [`%${query}%`]);
235
+ return result.rows;
236
+ }
237
+ /**
238
+ * GOOD: Full-text search with GIN index
239
+ */
240
+ export async function searchPostsOptimized(query) {
241
+ return monitorQuery('searchPosts', async () => {
242
+ const sql = `
243
+ SELECT
244
+ p.*,
245
+ ts_rank(
246
+ to_tsvector('english', coalesce(p.title, '') || ' ' || coalesce(p.content, '')),
247
+ plainto_tsquery('english', $1)
248
+ ) as rank
249
+ FROM posts p
250
+ WHERE to_tsvector('english', coalesce(p.title, '') || ' ' || coalesce(p.content, ''))
251
+ @@ plainto_tsquery('english', $1)
252
+ AND p.status = 'published'
253
+ ORDER BY rank DESC, p.published_at DESC
254
+ LIMIT 50
255
+ `;
256
+ const result = await db.query(sql, [query]);
257
+ return result.rows;
258
+ });
259
+ }
260
+ // ============================================================================
261
+ // CONDITIONAL QUERIES
262
+ // ============================================================================
263
+ /**
264
+ * Build dynamic query with proper indexing
265
+ */
266
+ export async function getPostsFiltered(filters) {
267
+ return monitorQuery('getPostsFiltered', async () => {
268
+ const conditions = [];
269
+ const params = [];
270
+ let paramCount = 1;
271
+ if (filters.status) {
272
+ conditions.push(`status = $${paramCount}`);
273
+ params.push(filters.status);
274
+ paramCount++;
275
+ }
276
+ if (filters.authorId) {
277
+ conditions.push(`author_id = $${paramCount}`);
278
+ params.push(filters.authorId);
279
+ paramCount++;
280
+ }
281
+ if (filters.fromDate) {
282
+ conditions.push(`published_at >= $${paramCount}`);
283
+ params.push(filters.fromDate);
284
+ paramCount++;
285
+ }
286
+ if (filters.toDate) {
287
+ conditions.push(`published_at <= $${paramCount}`);
288
+ params.push(filters.toDate);
289
+ paramCount++;
290
+ }
291
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
292
+ const query = `
293
+ SELECT * FROM posts
294
+ ${whereClause}
295
+ ORDER BY published_at DESC
296
+ LIMIT 100
297
+ `;
298
+ const result = await db.query(query, params);
299
+ return result.rows;
300
+ });
301
+ }
302
+ // ============================================================================
303
+ // MATERIALIZED VIEWS
304
+ // ============================================================================
305
+ /**
306
+ * Create materialized view for expensive aggregations
307
+ */
308
+ export async function createPostStatsMaterializedView() {
309
+ const query = `
310
+ CREATE MATERIALIZED VIEW IF NOT EXISTS post_stats_mv AS
311
+ SELECT
312
+ DATE_TRUNC('day', published_at) as date,
313
+ COUNT(*) as post_count,
314
+ COUNT(DISTINCT author_id) as author_count,
315
+ AVG(LENGTH(content)) as avg_content_length
316
+ FROM posts
317
+ WHERE status = 'published'
318
+ GROUP BY DATE_TRUNC('day', published_at)
319
+ ORDER BY date DESC;
320
+
321
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_post_stats_mv_date
322
+ ON post_stats_mv(date);
323
+ `;
324
+ await db.query(query);
325
+ }
326
+ /**
327
+ * Refresh materialized view
328
+ */
329
+ export async function refreshPostStats() {
330
+ await db.query('REFRESH MATERIALIZED VIEW CONCURRENTLY post_stats_mv');
331
+ }
332
+ /**
333
+ * Query materialized view (fast)
334
+ */
335
+ export async function getPostStatsByDate(fromDate, toDate) {
336
+ const query = `
337
+ SELECT * FROM post_stats_mv
338
+ WHERE date BETWEEN $1 AND $2
339
+ ORDER BY date DESC
340
+ `;
341
+ const result = await db.query(query, [fromDate, toDate]);
342
+ return result.rows;
343
+ }
344
+ // ============================================================================
345
+ // QUERY RESULT TRANSFORMATION
346
+ // ============================================================================
347
+ /**
348
+ * Efficient JSON aggregation
349
+ */
350
+ export async function getUsersWithPostCounts() {
351
+ return monitorQuery('getUsersWithPostCounts', async () => {
352
+ const query = `
353
+ SELECT
354
+ u.id,
355
+ u.name,
356
+ u.email,
357
+ json_build_object(
358
+ 'total', COUNT(p.id),
359
+ 'published', COUNT(p.id) FILTER (WHERE p.status = 'published'),
360
+ 'draft', COUNT(p.id) FILTER (WHERE p.status = 'draft')
361
+ ) as post_stats
362
+ FROM users u
363
+ LEFT JOIN posts p ON p.author_id = u.id
364
+ GROUP BY u.id
365
+ ORDER BY COUNT(p.id) DESC
366
+ `;
367
+ const result = await db.query(query);
368
+ return result.rows;
369
+ });
370
+ }
371
+ //# sourceMappingURL=optimized-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimized-queries.js","sourceRoot":"","sources":["../../src/queries/optimized-queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Ticket comment database queries
3
+ */
4
+ import type { DatabaseClient } from '../client/types.js';
5
+ export declare function getCommentsByTicket(db: DatabaseClient, ticketId: string): Promise<{
6
+ id: string;
7
+ ticketId: string;
8
+ authorId: string | null;
9
+ body: unknown;
10
+ createdAt: Date;
11
+ updatedAt: Date;
12
+ }[]>;
13
+ export declare function createComment(db: DatabaseClient, data: {
14
+ id: string;
15
+ ticketId: string;
16
+ authorId?: string;
17
+ body: unknown;
18
+ }): Promise<{
19
+ id: string;
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ authorId: string | null;
23
+ ticketId: string;
24
+ body: unknown;
25
+ } | undefined>;
26
+ export declare function updateComment(db: DatabaseClient, id: string, data: {
27
+ body: unknown;
28
+ }): Promise<{
29
+ id: string;
30
+ ticketId: string;
31
+ authorId: string | null;
32
+ body: unknown;
33
+ createdAt: Date;
34
+ updatedAt: Date;
35
+ } | null>;
36
+ export declare function deleteComment(db: DatabaseClient, id: string): Promise<void>;
37
+ //# sourceMappingURL=ticket-comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-comments.d.ts","sourceRoot":"","sources":["../../src/queries/ticket-comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGxD,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM;;;;;;;KAM7E;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE;;;;;;;eAczE;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;;;;;;;UAQ1F;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,iBAoBjE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Ticket comment database queries
3
+ */
4
+ import { eq, sql } from 'drizzle-orm';
5
+ import { ticketComments, tickets } from '../schema/tickets.js';
6
+ export async function getCommentsByTicket(db, ticketId) {
7
+ return db
8
+ .select()
9
+ .from(ticketComments)
10
+ .where(eq(ticketComments.ticketId, ticketId))
11
+ .orderBy(ticketComments.createdAt);
12
+ }
13
+ export async function createComment(db, data) {
14
+ const result = await db.insert(ticketComments).values(data).returning();
15
+ // Increment comment count on the ticket
16
+ await db
17
+ .update(tickets)
18
+ .set({
19
+ commentCount: sql `${tickets.commentCount} + 1`,
20
+ updatedAt: new Date(),
21
+ })
22
+ .where(eq(tickets.id, data.ticketId));
23
+ return result[0];
24
+ }
25
+ export async function updateComment(db, id, data) {
26
+ const result = await db
27
+ .update(ticketComments)
28
+ .set({ body: data.body, updatedAt: new Date() })
29
+ .where(eq(ticketComments.id, id))
30
+ .returning();
31
+ return result[0] ?? null;
32
+ }
33
+ export async function deleteComment(db, id) {
34
+ // Get the ticket ID before deleting
35
+ const comment = await db
36
+ .select({ ticketId: ticketComments.ticketId })
37
+ .from(ticketComments)
38
+ .where(eq(ticketComments.id, id))
39
+ .limit(1);
40
+ await db.delete(ticketComments).where(eq(ticketComments.id, id));
41
+ // Decrement comment count
42
+ if (comment[0]) {
43
+ await db
44
+ .update(tickets)
45
+ .set({
46
+ commentCount: sql `GREATEST(${tickets.commentCount} - 1, 0)`,
47
+ updatedAt: new Date(),
48
+ })
49
+ .where(eq(tickets.id, comment[0].ticketId));
50
+ }
51
+ }
52
+ //# sourceMappingURL=ticket-comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-comments.js","sourceRoot":"","sources":["../../src/queries/ticket-comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAErC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAE9D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAkB,EAAE,QAAgB;IAC5E,OAAO,EAAE;SACN,MAAM,EAAE;SACR,IAAI,CAAC,cAAc,CAAC;SACpB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;SAC5C,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAkB,EAClB,IAAwE;IAExE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAA;IAEvE,wCAAwC;IACxC,MAAM,EAAE;SACL,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC;QACH,YAAY,EAAE,GAAG,CAAA,GAAG,OAAO,CAAC,YAAY,MAAM;QAC9C,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC;SACD,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEvC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAkB,EAAE,EAAU,EAAE,IAAuB;IACzF,MAAM,MAAM,GAAG,MAAM,EAAE;SACpB,MAAM,CAAC,cAAc,CAAC;SACtB,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;SAC/C,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAChC,SAAS,EAAE,CAAA;IAEd,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAkB,EAAE,EAAU;IAChE,oCAAoC;IACpC,MAAM,OAAO,GAAG,MAAM,EAAE;SACrB,MAAM,CAAC,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE,CAAC;SAC7C,IAAI,CAAC,cAAc,CAAC;SACpB,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SAChC,KAAK,CAAC,CAAC,CAAC,CAAA;IAEX,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAEhE,0BAA0B;IAC1B,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,EAAE;aACL,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC;YACH,YAAY,EAAE,GAAG,CAAA,YAAY,OAAO,CAAC,YAAY,UAAU;YAC3D,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC;aACD,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Ticket label database queries
3
+ */
4
+ import type { DatabaseClient } from '../client/types.js';
5
+ export declare function getAllLabels(db: DatabaseClient, tenantId?: string): Promise<{
6
+ id: string;
7
+ tenantId: string | null;
8
+ name: string;
9
+ slug: string;
10
+ color: string;
11
+ description: string | null;
12
+ createdAt: Date;
13
+ updatedAt: Date;
14
+ }[]>;
15
+ export declare function createLabel(db: DatabaseClient, data: {
16
+ id: string;
17
+ name: string;
18
+ slug: string;
19
+ color?: string;
20
+ description?: string;
21
+ tenantId?: string;
22
+ }): Promise<{
23
+ id: string;
24
+ name: string;
25
+ createdAt: Date;
26
+ updatedAt: Date;
27
+ slug: string;
28
+ description: string | null;
29
+ tenantId: string | null;
30
+ color: string;
31
+ } | undefined>;
32
+ export declare function updateLabel(db: DatabaseClient, id: string, data: Partial<{
33
+ name: string;
34
+ slug: string;
35
+ color: string;
36
+ description: string;
37
+ }>): Promise<{
38
+ id: string;
39
+ tenantId: string | null;
40
+ name: string;
41
+ slug: string;
42
+ color: string;
43
+ description: string | null;
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ } | null>;
47
+ export declare function deleteLabel(db: DatabaseClient, id: string): Promise<void>;
48
+ export declare function assignLabel(db: DatabaseClient, data: {
49
+ id: string;
50
+ ticketId: string;
51
+ labelId: string;
52
+ }): Promise<{
53
+ id: string;
54
+ ticketId: string;
55
+ labelId: string;
56
+ assignedAt: Date;
57
+ } | undefined>;
58
+ export declare function removeLabel(db: DatabaseClient, ticketId: string, labelId: string): Promise<void>;
59
+ export declare function getLabelsForTicket(db: DatabaseClient, ticketId: string): Promise<{
60
+ id: string;
61
+ tenantId: string | null;
62
+ name: string;
63
+ slug: string;
64
+ color: string;
65
+ description: string | null;
66
+ createdAt: Date;
67
+ updatedAt: Date;
68
+ }[]>;
69
+ //# sourceMappingURL=ticket-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-labels.d.ts","sourceRoot":"","sources":["../../src/queries/ticket-labels.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAGxD,wBAAsB,YAAY,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;KASvE;AAED,wBAAsB,WAAW,CAC/B,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE;IACJ,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;;;;;;;;;eAIF;AAED,wBAAsB,WAAW,CAC/B,EAAE,EAAE,cAAc,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;;;;;;;;;UASlF;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,iBAE/D;AAED,wBAAsB,WAAW,CAC/B,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;eAIxD;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAStF;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;KAW5E"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Ticket label database queries
3
+ */
4
+ import { and, eq } from 'drizzle-orm';
5
+ import { ticketLabelAssignments, ticketLabels } from '../schema/tickets.js';
6
+ export async function getAllLabels(db, tenantId) {
7
+ if (tenantId) {
8
+ return db
9
+ .select()
10
+ .from(ticketLabels)
11
+ .where(eq(ticketLabels.tenantId, tenantId))
12
+ .orderBy(ticketLabels.name);
13
+ }
14
+ return db.select().from(ticketLabels).orderBy(ticketLabels.name);
15
+ }
16
+ export async function createLabel(db, data) {
17
+ const result = await db.insert(ticketLabels).values(data).returning();
18
+ return result[0];
19
+ }
20
+ export async function updateLabel(db, id, data) {
21
+ const result = await db
22
+ .update(ticketLabels)
23
+ .set({ ...data, updatedAt: new Date() })
24
+ .where(eq(ticketLabels.id, id))
25
+ .returning();
26
+ return result[0] ?? null;
27
+ }
28
+ export async function deleteLabel(db, id) {
29
+ await db.delete(ticketLabels).where(eq(ticketLabels.id, id));
30
+ }
31
+ export async function assignLabel(db, data) {
32
+ const result = await db.insert(ticketLabelAssignments).values(data).returning();
33
+ return result[0];
34
+ }
35
+ export async function removeLabel(db, ticketId, labelId) {
36
+ await db
37
+ .delete(ticketLabelAssignments)
38
+ .where(and(eq(ticketLabelAssignments.ticketId, ticketId), eq(ticketLabelAssignments.labelId, labelId)));
39
+ }
40
+ export async function getLabelsForTicket(db, ticketId) {
41
+ const assignments = await db
42
+ .select({
43
+ label: ticketLabels,
44
+ })
45
+ .from(ticketLabelAssignments)
46
+ .innerJoin(ticketLabels, eq(ticketLabelAssignments.labelId, ticketLabels.id))
47
+ .where(eq(ticketLabelAssignments.ticketId, ticketId))
48
+ .orderBy(ticketLabels.name);
49
+ return assignments.map((a) => a.label);
50
+ }
51
+ //# sourceMappingURL=ticket-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket-labels.js","sourceRoot":"","sources":["../../src/queries/ticket-labels.ts"],"names":[],"mappings":"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"}