@soulbatical/tetra-core 0.1.39 → 0.1.41

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.

Potentially problematic release.


This version of @soulbatical/tetra-core might be problematic. Click here for more details.

Files changed (56) hide show
  1. package/dist/core/dualWriteProxy.d.ts +11 -0
  2. package/dist/core/dualWriteProxy.d.ts.map +1 -1
  3. package/dist/core/dualWriteProxy.js +142 -198
  4. package/dist/core/dualWriteProxy.js.map +1 -1
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/shared/email/EmailService.d.ts +9 -1
  10. package/dist/shared/email/EmailService.d.ts.map +1 -1
  11. package/dist/shared/email/EmailService.js +83 -7
  12. package/dist/shared/email/EmailService.js.map +1 -1
  13. package/dist/shared/email/adminRoutes.d.ts +30 -0
  14. package/dist/shared/email/adminRoutes.d.ts.map +1 -0
  15. package/dist/shared/email/adminRoutes.js +227 -0
  16. package/dist/shared/email/adminRoutes.js.map +1 -0
  17. package/dist/shared/email/index.d.ts +3 -1
  18. package/dist/shared/email/index.d.ts.map +1 -1
  19. package/dist/shared/email/index.js +3 -0
  20. package/dist/shared/email/index.js.map +1 -1
  21. package/dist/shared/email/mailgun.d.ts +4 -1
  22. package/dist/shared/email/mailgun.d.ts.map +1 -1
  23. package/dist/shared/email/mailgun.js +41 -10
  24. package/dist/shared/email/mailgun.js.map +1 -1
  25. package/dist/shared/email/smtp.d.ts +4 -1
  26. package/dist/shared/email/smtp.d.ts.map +1 -1
  27. package/dist/shared/email/smtp.js +14 -2
  28. package/dist/shared/email/smtp.js.map +1 -1
  29. package/dist/shared/email/types.d.ts +23 -1
  30. package/dist/shared/email/types.d.ts.map +1 -1
  31. package/dist/shared/email/webhookRoutes.d.ts +29 -0
  32. package/dist/shared/email/webhookRoutes.d.ts.map +1 -0
  33. package/dist/shared/email/webhookRoutes.js +125 -0
  34. package/dist/shared/email/webhookRoutes.js.map +1 -0
  35. package/dist/shared/planner/GoogleCalendarService.d.ts +103 -0
  36. package/dist/shared/planner/GoogleCalendarService.d.ts.map +1 -0
  37. package/dist/shared/planner/GoogleCalendarService.js +365 -0
  38. package/dist/shared/planner/GoogleCalendarService.js.map +1 -0
  39. package/dist/shared/planner/PlannerService.d.ts +170 -0
  40. package/dist/shared/planner/PlannerService.d.ts.map +1 -0
  41. package/dist/shared/planner/PlannerService.js +860 -0
  42. package/dist/shared/planner/PlannerService.js.map +1 -0
  43. package/dist/shared/planner/index.d.ts +35 -0
  44. package/dist/shared/planner/index.d.ts.map +1 -0
  45. package/dist/shared/planner/index.js +34 -0
  46. package/dist/shared/planner/index.js.map +1 -0
  47. package/dist/shared/planner/routes.d.ts +67 -0
  48. package/dist/shared/planner/routes.d.ts.map +1 -0
  49. package/dist/shared/planner/routes.js +524 -0
  50. package/dist/shared/planner/routes.js.map +1 -0
  51. package/dist/shared/planner/types.d.ts +262 -0
  52. package/dist/shared/planner/types.d.ts.map +1 -0
  53. package/dist/shared/planner/types.js +9 -0
  54. package/dist/shared/planner/types.js.map +1 -0
  55. package/package.json +1 -1
  56. package/src/shared/email/migrations/004_add_email_logs_tracking_columns.sql +15 -0
@@ -0,0 +1,524 @@
1
+ /**
2
+ * Planner Route Factories — standard scheduling endpoints
3
+ *
4
+ * Usage:
5
+ * ```typescript
6
+ * import { addPlannerRoutes, addPlannerPublicRoutes, addPlannerCalendarRoutes } from '@soulbatical/tetra-core';
7
+ *
8
+ * // Authenticated (behind auth middleware)
9
+ * addPlannerRoutes(router, { config });
10
+ *
11
+ * // Public booking (no auth)
12
+ * addPlannerPublicRoutes(publicRouter, { config, getSystemDB });
13
+ *
14
+ * // Google Calendar OAuth (behind auth middleware)
15
+ * addPlannerCalendarRoutes(calendarRouter, { google: {...} });
16
+ * ```
17
+ */
18
+ import { PlannerService } from './PlannerService.js';
19
+ import { GoogleCalendarService } from './GoogleCalendarService.js';
20
+ import { RFC7807ErrorResponse } from '../rfc7807ErrorResponse.js';
21
+ import { createLogger } from '../../utils/logger.js';
22
+ const logger = createLogger('planner:routes');
23
+ const TIME_REGEX = /^\d{2}:\d{2}(:\d{2})?$/;
24
+ const DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
25
+ // ─── Authenticated Planner Routes ───────────────────────────
26
+ /**
27
+ * Add authenticated planner routes to a router.
28
+ *
29
+ * Adds:
30
+ * - GET /availability — Get own availability
31
+ * - PUT /availability — Set own availability
32
+ * - GET /owners/:ownerId/availability — Get an owner's availability
33
+ * - GET /owners/:ownerId/available-slots — Get bookable slots for a date
34
+ * - POST /owners/:ownerId/book — Book a slot with an owner
35
+ * - GET /vacations — List own vacations
36
+ * - POST /vacations — Create vacation
37
+ * - DELETE /vacations/:id — Delete vacation
38
+ * - GET /scheduler-settings — Get own scheduler settings
39
+ * - PUT /scheduler-settings — Update own scheduler settings
40
+ * - GET /appointments — List own appointments
41
+ * - POST /appointments — Create appointment
42
+ * - PUT /appointments/:id — Update appointment
43
+ * - DELETE /appointments/:id — Cancel appointment
44
+ * - POST /appointments/:id/complete — Complete appointment
45
+ * - GET /team-availability — Team availability for a date (admin)
46
+ *
47
+ * Returns the PlannerService instance for external use.
48
+ */
49
+ export function addPlannerRoutes(router, options) {
50
+ const service = new PlannerService(options.config);
51
+ // ── Availability ────────────────────────────────────────
52
+ // GET /availability — own
53
+ router.get('/availability', async (req, res) => {
54
+ try {
55
+ const user = req.user;
56
+ if (!user?.id)
57
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
58
+ const { adminDB } = await import('../../core/adminDb.js');
59
+ const db = await adminDB(req);
60
+ const slots = await service.getAvailability(db, user.id);
61
+ res.json({ success: true, data: slots });
62
+ }
63
+ catch (err) {
64
+ logger.error({ error: err }, 'Get availability error');
65
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
66
+ }
67
+ });
68
+ // PUT /availability — set own
69
+ router.put('/availability', async (req, res) => {
70
+ try {
71
+ const user = req.user;
72
+ if (!user?.id || !user?.organizationId)
73
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
74
+ const { slots } = req.body;
75
+ if (!Array.isArray(slots))
76
+ return RFC7807ErrorResponse.badRequest(res, 'slots must be an array');
77
+ const { adminDB } = await import('../../core/adminDb.js');
78
+ const db = await adminDB(req);
79
+ const result = await service.setAvailability(db, user.id, user.organizationId, slots);
80
+ res.json({ success: true, data: result });
81
+ }
82
+ catch (err) {
83
+ logger.error({ error: err }, 'Set availability error');
84
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
85
+ }
86
+ });
87
+ // GET /owners/:ownerId/availability
88
+ router.get('/owners/:ownerId/availability', async (req, res) => {
89
+ try {
90
+ const user = req.user;
91
+ if (!user?.id)
92
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
93
+ const { adminDB } = await import('../../core/adminDb.js');
94
+ const db = await adminDB(req);
95
+ const slots = await service.getAvailability(db, req.params.ownerId);
96
+ res.json({ success: true, data: slots });
97
+ }
98
+ catch (err) {
99
+ logger.error({ error: err }, 'Get owner availability error');
100
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
101
+ }
102
+ });
103
+ // GET /owners/:ownerId/available-slots?date=YYYY-MM-DD
104
+ router.get('/owners/:ownerId/available-slots', async (req, res) => {
105
+ try {
106
+ const user = req.user;
107
+ if (!user?.id)
108
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
109
+ const date = req.query.date;
110
+ if (!date || !DATE_REGEX.test(date))
111
+ return RFC7807ErrorResponse.badRequest(res, 'date query parameter required (YYYY-MM-DD)');
112
+ const { adminDB } = await import('../../core/adminDb.js');
113
+ const db = await adminDB(req);
114
+ const result = await service.getAvailableSlots(db, req.params.ownerId, date);
115
+ res.json({ success: true, data: result });
116
+ }
117
+ catch (err) {
118
+ logger.error({ error: err }, 'Get available slots error');
119
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
120
+ }
121
+ });
122
+ // POST /owners/:ownerId/book
123
+ router.post('/owners/:ownerId/book', async (req, res) => {
124
+ try {
125
+ const user = req.user;
126
+ if (!user?.id || !user?.organizationId)
127
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
128
+ const { parentId, date, startTime, endTime, title } = req.body;
129
+ if (!date || !startTime || !endTime)
130
+ return RFC7807ErrorResponse.badRequest(res, 'date, startTime, and endTime are required');
131
+ const startISO = `${date}T${startTime.length === 5 ? startTime + ':00' : startTime}Z`;
132
+ const endISO = `${date}T${endTime.length === 5 ? endTime + ':00' : endTime}Z`;
133
+ const { adminDB } = await import('../../core/adminDb.js');
134
+ const db = await adminDB(req);
135
+ const appointment = await service.createAppointment(db, user.id, user.organizationId, {
136
+ title: title || 'Session',
137
+ parentId,
138
+ startTime: startISO,
139
+ endTime: endISO,
140
+ });
141
+ res.status(201).json({ success: true, data: appointment });
142
+ }
143
+ catch (err) {
144
+ logger.error({ error: err }, 'Book slot error');
145
+ if (err.message.includes('conflict') || err.message.includes('outside')) {
146
+ RFC7807ErrorResponse.conflict(res, err.message);
147
+ }
148
+ else {
149
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
150
+ }
151
+ }
152
+ });
153
+ // ── Vacations ───────────────────────────────────────────
154
+ router.get('/vacations', async (req, res) => {
155
+ try {
156
+ const user = req.user;
157
+ if (!user?.id)
158
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
159
+ const { adminDB } = await import('../../core/adminDb.js');
160
+ const db = await adminDB(req);
161
+ const vacations = await service.getVacations(db, user.id);
162
+ res.json({ success: true, data: vacations });
163
+ }
164
+ catch (err) {
165
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
166
+ }
167
+ });
168
+ router.post('/vacations', async (req, res) => {
169
+ try {
170
+ const user = req.user;
171
+ if (!user?.id || !user?.organizationId)
172
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
173
+ const { startDate, endDate, description } = req.body;
174
+ if (!startDate || !endDate)
175
+ return RFC7807ErrorResponse.badRequest(res, 'startDate and endDate are required');
176
+ const { adminDB } = await import('../../core/adminDb.js');
177
+ const db = await adminDB(req);
178
+ const vacation = await service.createVacation(db, user.id, user.organizationId, startDate, endDate, description);
179
+ res.status(201).json({ success: true, data: vacation });
180
+ }
181
+ catch (err) {
182
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
183
+ }
184
+ });
185
+ router.delete('/vacations/:id', async (req, res) => {
186
+ try {
187
+ const user = req.user;
188
+ if (!user?.id)
189
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
190
+ const { adminDB } = await import('../../core/adminDb.js');
191
+ const db = await adminDB(req);
192
+ await service.deleteVacation(db, req.params.id);
193
+ res.json({ success: true });
194
+ }
195
+ catch (err) {
196
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
197
+ }
198
+ });
199
+ // ── Scheduler Settings ──────────────────────────────────
200
+ router.get('/scheduler-settings', async (req, res) => {
201
+ try {
202
+ const user = req.user;
203
+ if (!user?.id)
204
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
205
+ const { adminDB } = await import('../../core/adminDb.js');
206
+ const db = await adminDB(req);
207
+ const settings = await service.getSettings(db, user.id);
208
+ res.json({ success: true, data: settings });
209
+ }
210
+ catch (err) {
211
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
212
+ }
213
+ });
214
+ router.put('/scheduler-settings', async (req, res) => {
215
+ try {
216
+ const user = req.user;
217
+ if (!user?.id || !user?.organizationId)
218
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
219
+ const { adminDB } = await import('../../core/adminDb.js');
220
+ const db = await adminDB(req);
221
+ const result = await service.updateSettings(db, user.id, user.organizationId, req.body);
222
+ res.json({ success: true, data: result });
223
+ }
224
+ catch (err) {
225
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
226
+ }
227
+ });
228
+ // ── Appointments ────────────────────────────────────────
229
+ router.get('/appointments', async (req, res) => {
230
+ try {
231
+ const user = req.user;
232
+ if (!user?.id)
233
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
234
+ const { adminDB } = await import('../../core/adminDb.js');
235
+ const db = await adminDB(req);
236
+ const appointments = await service.listAppointments(db, user.id, {
237
+ status: req.query.status,
238
+ });
239
+ res.json({ success: true, data: appointments });
240
+ }
241
+ catch (err) {
242
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
243
+ }
244
+ });
245
+ router.post('/appointments', async (req, res) => {
246
+ try {
247
+ const user = req.user;
248
+ if (!user?.id || !user?.organizationId)
249
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
250
+ const { title, parentId, description, startTime, endTime, location, type, attendeeIds } = req.body;
251
+ if (!title || !startTime || !endTime)
252
+ return RFC7807ErrorResponse.badRequest(res, 'title, startTime, and endTime are required');
253
+ const { adminDB } = await import('../../core/adminDb.js');
254
+ const db = await adminDB(req);
255
+ const appointment = await service.createAppointment(db, user.id, user.organizationId, {
256
+ title, parentId, description, startTime, endTime, location, type, attendeeIds,
257
+ });
258
+ res.status(201).json({ success: true, data: appointment });
259
+ }
260
+ catch (err) {
261
+ if (err.message.includes('Invalid'))
262
+ RFC7807ErrorResponse.badRequest(res, err.message);
263
+ else
264
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
265
+ }
266
+ });
267
+ router.put('/appointments/:id', async (req, res) => {
268
+ try {
269
+ const user = req.user;
270
+ if (!user?.id)
271
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
272
+ const { adminDB } = await import('../../core/adminDb.js');
273
+ const db = await adminDB(req);
274
+ const appointment = await service.updateAppointment(db, req.params.id, req.body);
275
+ res.json({ success: true, data: appointment });
276
+ }
277
+ catch (err) {
278
+ if (err.message === 'Appointment not found')
279
+ RFC7807ErrorResponse.notFound(res, 'Appointment');
280
+ else
281
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
282
+ }
283
+ });
284
+ router.delete('/appointments/:id', async (req, res) => {
285
+ try {
286
+ const user = req.user;
287
+ if (!user?.id || !user?.organizationId)
288
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
289
+ const { adminDB } = await import('../../core/adminDb.js');
290
+ const db = await adminDB(req);
291
+ const appointment = await service.cancelAppointment(db, req.params.id, user.organizationId);
292
+ res.json({ success: true, data: appointment });
293
+ }
294
+ catch (err) {
295
+ if (err.message === 'Appointment not found')
296
+ RFC7807ErrorResponse.notFound(res, 'Appointment');
297
+ else
298
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
299
+ }
300
+ });
301
+ router.post('/appointments/:id/complete', async (req, res) => {
302
+ try {
303
+ const user = req.user;
304
+ if (!user?.id || !user?.organizationId)
305
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
306
+ const { adminDB } = await import('../../core/adminDb.js');
307
+ const db = await adminDB(req);
308
+ const appointment = await service.completeAppointment(db, req.params.id, user.organizationId);
309
+ res.json({ success: true, data: appointment });
310
+ }
311
+ catch (err) {
312
+ if (err.message === 'Appointment not found')
313
+ RFC7807ErrorResponse.notFound(res, 'Appointment');
314
+ else
315
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
316
+ }
317
+ });
318
+ // ── Team Availability ───────────────────────────────────
319
+ router.get('/team-availability', async (req, res) => {
320
+ try {
321
+ const user = req.user;
322
+ if (!user?.id || !user?.organizationId)
323
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
324
+ const date = req.query.date;
325
+ if (!date || !DATE_REGEX.test(date))
326
+ return RFC7807ErrorResponse.badRequest(res, 'date query parameter required (YYYY-MM-DD)');
327
+ const { adminDB } = await import('../../core/adminDb.js');
328
+ const db = await adminDB(req);
329
+ const result = await service.getTeamAvailability(db, user.organizationId, date);
330
+ res.json({ success: true, data: result });
331
+ }
332
+ catch (err) {
333
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
334
+ }
335
+ });
336
+ return service;
337
+ }
338
+ // ─── Public Planner Routes (no auth) ────────────────────────
339
+ /**
340
+ * Add public booking routes (Calendly-style, no authentication).
341
+ *
342
+ * Adds:
343
+ * - GET /scheduler/:ownerId — Scheduler page data
344
+ * - GET /scheduler/:ownerId/slots — Available slots for a date
345
+ * - POST /scheduler/:ownerId/book — Book a slot
346
+ */
347
+ export function addPlannerPublicRoutes(router, options) {
348
+ const service = new PlannerService(options.config);
349
+ const getDB = async () => {
350
+ if (options.getSystemDB)
351
+ return options.getSystemDB();
352
+ const { systemDB } = await import('../../core/systemDb.js');
353
+ return systemDB('planner:public');
354
+ };
355
+ // GET /scheduler/:ownerId
356
+ router.get('/scheduler/:ownerId', async (req, res) => {
357
+ try {
358
+ const db = await getDB();
359
+ const data = await service.getPublicSchedulerData(db, req.params.ownerId);
360
+ if (!data)
361
+ return RFC7807ErrorResponse.notFound(res, 'Owner');
362
+ res.json({ success: true, data });
363
+ }
364
+ catch (err) {
365
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
366
+ }
367
+ });
368
+ // GET /scheduler/:ownerId/slots?date=YYYY-MM-DD
369
+ router.get('/scheduler/:ownerId/slots', async (req, res) => {
370
+ try {
371
+ const date = req.query.date;
372
+ if (!date || !DATE_REGEX.test(date))
373
+ return RFC7807ErrorResponse.badRequest(res, 'date required (YYYY-MM-DD)');
374
+ const db = await getDB();
375
+ const result = await service.getAvailableSlots(db, req.params.ownerId, date);
376
+ res.json({ success: true, data: result });
377
+ }
378
+ catch (err) {
379
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
380
+ }
381
+ });
382
+ // POST /scheduler/:ownerId/book
383
+ router.post('/scheduler/:ownerId/book', async (req, res) => {
384
+ try {
385
+ const db = await getDB();
386
+ const appointment = await service.publicBook(db, req.params.ownerId, req.body);
387
+ res.status(201).json({ success: true, data: appointment });
388
+ }
389
+ catch (err) {
390
+ if (err.message.includes('outside') || err.message.includes('no longer') || err.message.includes('vacation')) {
391
+ RFC7807ErrorResponse.conflict(res, err.message);
392
+ }
393
+ else if (err.message.includes('required') || err.message.includes('Invalid')) {
394
+ RFC7807ErrorResponse.badRequest(res, err.message);
395
+ }
396
+ else {
397
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
398
+ }
399
+ }
400
+ });
401
+ return service;
402
+ }
403
+ // ─── Google Calendar Routes ─────────────────────────────────
404
+ /**
405
+ * Add Google Calendar OAuth routes.
406
+ *
407
+ * Adds:
408
+ * - GET /auth-url — Generate OAuth URL
409
+ * - GET /callback — Handle OAuth callback
410
+ * - GET /status — Connection status
411
+ * - GET /calendars — List available calendars
412
+ * - PUT /calendar-id — Select calendar
413
+ * - POST /disconnect — Remove connection
414
+ */
415
+ export function addPlannerCalendarRoutes(router, config) {
416
+ const calService = new GoogleCalendarService(config);
417
+ // GET /auth-url
418
+ router.get('/auth-url', async (req, res) => {
419
+ try {
420
+ const user = req.user;
421
+ if (!user?.id)
422
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
423
+ const url = await calService.getAuthUrl(user.id);
424
+ res.json({ success: true, data: { url } });
425
+ }
426
+ catch (err) {
427
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
428
+ }
429
+ });
430
+ // GET /callback
431
+ router.get('/callback', async (req, res) => {
432
+ try {
433
+ const code = req.query.code;
434
+ const stateRaw = req.query.state;
435
+ if (!code || !stateRaw)
436
+ return RFC7807ErrorResponse.badRequest(res, 'Missing code or state');
437
+ let state;
438
+ try {
439
+ state = JSON.parse(Buffer.from(stateRaw, 'base64').toString());
440
+ }
441
+ catch {
442
+ return RFC7807ErrorResponse.badRequest(res, 'Invalid state');
443
+ }
444
+ // Look up org for user
445
+ const { systemDB } = await import('../../core/systemDb.js');
446
+ const db = await systemDB('planner:calendar-callback');
447
+ const { data: userData } = await db
448
+ .from('users_public')
449
+ .select('active_organization_id')
450
+ .eq('id', state.userId)
451
+ .single();
452
+ if (!userData)
453
+ return RFC7807ErrorResponse.notFound(res, 'User');
454
+ await calService.handleCallback(code, state.userId, userData.active_organization_id);
455
+ // Redirect to frontend settings
456
+ const frontendUrl = process.env.FRONTEND_URL || '';
457
+ res.redirect(`${frontendUrl}/settings?calendar=connected`);
458
+ }
459
+ catch (err) {
460
+ logger.error({ error: err }, 'Calendar callback error');
461
+ const frontendUrl = process.env.FRONTEND_URL || '';
462
+ res.redirect(`${frontendUrl}/settings?calendar=error&reason=exchange_failed`);
463
+ }
464
+ });
465
+ // GET /status
466
+ router.get('/status', async (req, res) => {
467
+ try {
468
+ const user = req.user;
469
+ if (!user?.id)
470
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
471
+ const connected = await calService.isConnected(user.id);
472
+ res.json({ success: true, data: { connected } });
473
+ }
474
+ catch (err) {
475
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
476
+ }
477
+ });
478
+ // GET /calendars
479
+ router.get('/calendars', async (req, res) => {
480
+ try {
481
+ const user = req.user;
482
+ if (!user?.id)
483
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
484
+ const calendars = await calService.listCalendars(user.id);
485
+ res.json({ success: true, data: calendars || [] });
486
+ }
487
+ catch (err) {
488
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
489
+ }
490
+ });
491
+ // PUT /calendar-id
492
+ router.put('/calendar-id', async (req, res) => {
493
+ try {
494
+ const user = req.user;
495
+ if (!user?.id)
496
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
497
+ const { calendarId } = req.body;
498
+ if (!calendarId)
499
+ return RFC7807ErrorResponse.badRequest(res, 'calendarId is required');
500
+ const success = await calService.selectCalendar(user.id, calendarId);
501
+ if (!success)
502
+ return RFC7807ErrorResponse.internalError(res, 'Failed to select calendar');
503
+ res.json({ success: true });
504
+ }
505
+ catch (err) {
506
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
507
+ }
508
+ });
509
+ // POST /disconnect
510
+ router.post('/disconnect', async (req, res) => {
511
+ try {
512
+ const user = req.user;
513
+ if (!user?.id)
514
+ return RFC7807ErrorResponse.unauthorized(res, 'Authentication required');
515
+ await calService.disconnect(user.id);
516
+ res.json({ success: true });
517
+ }
518
+ catch (err) {
519
+ RFC7807ErrorResponse.internalError(res, err.message || 'Failed');
520
+ }
521
+ });
522
+ return calService;
523
+ }
524
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/shared/planner/routes.ts"],"names":[],"mappings":"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"}