Implement reminders system with full CRUD and background processors
- Reminders service: create, update, delete, complete, snooze, dismiss - List with filters (status, priority, assignee, entity, date range) - My/overdue/upcoming convenience endpoints - BullMQ processors: auto-follow-up creation (BR-060) and overdue notifications - Snooze with presets (1h, 4h, tomorrow, next week) and custom datetime - Un-snooze logic: snoozed reminders auto-revert to pending when snooze expires - UI: filterable list with my/all toggle, priority badges, overdue indicators - Permission-gated: view_own, view_all, create, assign_others - Entity linking: reminders can link to clients, interests, or berths Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
47
src/lib/validators/reminders.ts
Normal file
47
src/lib/validators/reminders.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { z } from 'zod';
|
||||
import { baseListQuerySchema } from '@/lib/api/route-helpers';
|
||||
|
||||
export const createReminderSchema = z.object({
|
||||
title: z.string().min(1).max(300),
|
||||
note: z.string().max(2000).optional(),
|
||||
dueAt: z.string().datetime(),
|
||||
priority: z.enum(['low', 'medium', 'high', 'urgent']).default('medium'),
|
||||
assignedTo: z.string().optional(),
|
||||
clientId: z.string().uuid().optional(),
|
||||
interestId: z.string().uuid().optional(),
|
||||
berthId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
export type CreateReminderInput = z.infer<typeof createReminderSchema>;
|
||||
|
||||
export const updateReminderSchema = z.object({
|
||||
title: z.string().min(1).max(300).optional(),
|
||||
note: z.string().max(2000).nullable().optional(),
|
||||
dueAt: z.string().datetime().optional(),
|
||||
priority: z.enum(['low', 'medium', 'high', 'urgent']).optional(),
|
||||
assignedTo: z.string().nullable().optional(),
|
||||
clientId: z.string().uuid().nullable().optional(),
|
||||
interestId: z.string().uuid().nullable().optional(),
|
||||
berthId: z.string().uuid().nullable().optional(),
|
||||
});
|
||||
|
||||
export type UpdateReminderInput = z.infer<typeof updateReminderSchema>;
|
||||
|
||||
export const snoozeReminderSchema = z.object({
|
||||
snoozeUntil: z.string().datetime(),
|
||||
});
|
||||
|
||||
export type SnoozeReminderInput = z.infer<typeof snoozeReminderSchema>;
|
||||
|
||||
export const reminderListQuerySchema = baseListQuerySchema.extend({
|
||||
status: z.enum(['pending', 'snoozed', 'completed', 'dismissed']).optional(),
|
||||
priority: z.enum(['low', 'medium', 'high', 'urgent']).optional(),
|
||||
assignedTo: z.string().optional(),
|
||||
clientId: z.string().uuid().optional(),
|
||||
interestId: z.string().uuid().optional(),
|
||||
berthId: z.string().uuid().optional(),
|
||||
dueBefore: z.string().datetime().optional(),
|
||||
dueAfter: z.string().datetime().optional(),
|
||||
});
|
||||
|
||||
export type ReminderListQuery = z.infer<typeof reminderListQuerySchema>;
|
||||
Reference in New Issue
Block a user