diff --git a/src/controllers/company.controller.js b/src/controllers/company.controller.js index 3dc7937..f0accda 100644 --- a/src/controllers/company.controller.js +++ b/src/controllers/company.controller.js @@ -208,11 +208,12 @@ export const addCompanyNote = async (req, res, next) => { try { const userId = req.userId; const { companyId } = req.params; - const { content } = req.body; + const { content, dueDate } = req.body; const note = await noteService.createNote(userId, { content, companyId, + dueDate, }); res.status(201).json({ @@ -232,10 +233,11 @@ export const addCompanyNote = async (req, res, next) => { export const updateCompanyNote = async (req, res, next) => { try { const { noteId } = req.params; - const { content } = req.body; + const { content, dueDate } = req.body; const note = await noteService.updateNote(noteId, { content, + dueDate, }); res.status(200).json({ diff --git a/src/controllers/project.controller.js b/src/controllers/project.controller.js index ddc1d30..8414268 100644 --- a/src/controllers/project.controller.js +++ b/src/controllers/project.controller.js @@ -165,12 +165,12 @@ export const addProjectNote = async (req, res, next) => { try { const userId = req.userId; const { projectId } = req.params; - const { content, reminderAt } = req.body; + const { content, dueDate } = req.body; const note = await noteService.createNote(userId, { content, projectId, - reminderDate: reminderAt, // Map reminderAt to reminderDate + dueDate, }); res.status(201).json({ @@ -190,11 +190,11 @@ export const addProjectNote = async (req, res, next) => { export const updateProjectNote = async (req, res, next) => { try { const { noteId } = req.params; - const { content, reminderAt } = req.body; + const { content, dueDate } = req.body; const note = await noteService.updateNote(noteId, { content, - reminderDate: reminderAt, // Map reminderAt to reminderDate + dueDate, }); res.status(200).json({ diff --git a/src/db/schema.js b/src/db/schema.js index 700c2e5..683c3a3 100644 --- a/src/db/schema.js +++ b/src/db/schema.js @@ -210,7 +210,7 @@ export const todoUsers = pgTable('todo_users', { todoUserUnique: unique('todo_user_unique').on(table.todoId, table.userId), })); -// Notes table - poznámky (bez reminder funkcionalít) +// Notes table - poznámky s voliteľným dátumom a časom splnenia export const notes = pgTable('notes', { id: uuid('id').primaryKey().defaultRandom(), title: text('title'), @@ -219,6 +219,7 @@ export const notes = pgTable('notes', { projectId: uuid('project_id').references(() => projects.id, { onDelete: 'cascade' }), // alebo projektu todoId: uuid('todo_id').references(() => todos.id, { onDelete: 'cascade' }), // alebo todo contactId: uuid('contact_id').references(() => contacts.id, { onDelete: 'cascade' }), // alebo kontaktu + dueDate: timestamp('due_date'), // voliteľný dátum a čas splnenia (24h formát) createdBy: uuid('created_by').references(() => users.id, { onDelete: 'set null' }), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at').defaultNow().notNull(), diff --git a/src/routes/company.routes.js b/src/routes/company.routes.js index 9de01c4..3f0659c 100644 --- a/src/routes/company.routes.js +++ b/src/routes/company.routes.js @@ -83,6 +83,7 @@ router.post( validateParams(z.object({ companyId: z.string().uuid() })), validateBody(z.object({ content: z.string().min(1), + dueDate: z.string().optional().or(z.literal('')), })), companyController.addCompanyNote ); @@ -96,6 +97,7 @@ router.patch( })), validateBody(z.object({ content: z.string().min(1).optional(), + dueDate: z.string().optional().or(z.literal('').or(z.null())), })), companyController.updateCompanyNote ); diff --git a/src/routes/project.routes.js b/src/routes/project.routes.js index f726e67..ef38d69 100644 --- a/src/routes/project.routes.js +++ b/src/routes/project.routes.js @@ -66,7 +66,7 @@ router.post( validateParams(z.object({ projectId: z.string().uuid() })), validateBody(z.object({ content: z.string().min(1), - reminderAt: z.string().optional().or(z.literal('')), + dueDate: z.string().optional().or(z.literal('')), })), projectController.addProjectNote ); @@ -80,7 +80,7 @@ router.patch( })), validateBody(z.object({ content: z.string().min(1).optional(), - reminderAt: z.string().optional().or(z.literal('').or(z.null())), + dueDate: z.string().optional().or(z.literal('').or(z.null())), })), projectController.updateProjectNote ); diff --git a/src/services/note.service.js b/src/services/note.service.js index fd00d15..a8fbeb4 100644 --- a/src/services/note.service.js +++ b/src/services/note.service.js @@ -20,6 +20,7 @@ export const getAllNotes = async (filters = {}) => { projectId: notes.projectId, todoId: notes.todoId, contactId: notes.contactId, + dueDate: notes.dueDate, createdBy: notes.createdBy, createdAt: notes.createdAt, updatedAt: notes.updatedAt, @@ -86,7 +87,7 @@ export const getNoteById = async (noteId) => { * Create new note */ export const createNote = async (userId, data) => { - const { title, content, companyId, projectId, todoId, contactId } = data; + const { title, content, companyId, projectId, todoId, contactId, dueDate } = data; // Verify company exists if provided if (companyId) { @@ -149,6 +150,7 @@ export const createNote = async (userId, data) => { projectId: projectId || null, todoId: todoId || null, contactId: contactId || null, + dueDate: dueDate ? new Date(dueDate) : null, createdBy: userId, }) .returning(); @@ -162,7 +164,7 @@ export const createNote = async (userId, data) => { export const updateNote = async (noteId, data) => { const note = await getNoteById(noteId); - const { title, content, companyId, projectId, todoId, contactId } = data; + const { title, content, companyId, projectId, todoId, contactId, dueDate } = data; // Verify company exists if being changed if (companyId !== undefined && companyId !== null && companyId !== note.companyId) { @@ -216,6 +218,12 @@ export const updateNote = async (noteId, data) => { } } + // Spracovanie dueDate - konverzia na Date objekt alebo null + let parsedDueDate = note.dueDate; + if (dueDate !== undefined) { + parsedDueDate = dueDate ? new Date(dueDate) : null; + } + const [updated] = await db .update(notes) .set({ @@ -225,6 +233,7 @@ export const updateNote = async (noteId, data) => { projectId: projectId !== undefined ? projectId : note.projectId, todoId: todoId !== undefined ? todoId : note.todoId, contactId: contactId !== undefined ? contactId : note.contactId, + dueDate: parsedDueDate, updatedAt: new Date(), }) .where(eq(notes.id, noteId)) @@ -258,6 +267,7 @@ export const getNotesByCompanyId = async (companyId) => { projectId: notes.projectId, todoId: notes.todoId, contactId: notes.contactId, + dueDate: notes.dueDate, createdBy: notes.createdBy, createdAt: notes.createdAt, updatedAt: notes.updatedAt, @@ -286,6 +296,7 @@ export const getNotesByProjectId = async (projectId) => { projectId: notes.projectId, todoId: notes.todoId, contactId: notes.contactId, + dueDate: notes.dueDate, createdBy: notes.createdBy, createdAt: notes.createdAt, updatedAt: notes.updatedAt, diff --git a/src/validators/crm.validators.js b/src/validators/crm.validators.js index 1a78371..9d410f7 100644 --- a/src/validators/crm.validators.js +++ b/src/validators/crm.validators.js @@ -81,7 +81,7 @@ export const updateTodoSchema = z.object({ dueDate: z.string().optional().or(z.literal('').or(z.null())), }); -// Note validators (without reminder functionality) +// Note validators (s voliteľným dueDate pre dátum a čas) export const createNoteSchema = z.object({ title: z.string().max(255).optional(), content: z @@ -94,6 +94,7 @@ export const createNoteSchema = z.object({ projectId: z.string().uuid('Neplatný formát project ID').optional().or(z.literal('')), todoId: z.string().uuid('Neplatný formát todo ID').optional().or(z.literal('')), contactId: z.string().uuid('Neplatný formát contact ID').optional().or(z.literal('')), + dueDate: z.string().optional().or(z.literal('')), // ISO string s dátumom a časom (24h formát) }); export const updateNoteSchema = z.object({ @@ -103,6 +104,7 @@ export const updateNoteSchema = z.object({ projectId: z.string().uuid('Neplatný formát project ID').optional().or(z.literal('').or(z.null())), todoId: z.string().uuid('Neplatný formát todo ID').optional().or(z.literal('').or(z.null())), contactId: z.string().uuid('Neplatný formát contact ID').optional().or(z.literal('').or(z.null())), + dueDate: z.string().optional().or(z.literal('').or(z.null())), // ISO string s dátumom a časom (24h formát) }); // Company reminder validators (with dueDate)