Commit a5a1dd45 by Augusto

assistant's + logs update

parent 336e7041
ALTER TABLE `occurrences` MODIFY COLUMN `status` enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED') NOT NULL DEFAULT 'OPEN';--> statement-breakpoint
ALTER TABLE `comments` ADD `status` enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED') DEFAULT 'OPEN' NOT NULL;--> statement-breakpoint
ALTER TABLE `occurrences` ADD `latitude` decimal(10,8);--> statement-breakpoint
ALTER TABLE `occurrences` ADD `longitude` decimal(11,8);--> statement-breakpoint
ALTER TABLE `occurrences` ADD `reference` text;--> statement-breakpoint
CREATE INDEX `location_idx` ON `occurrences` (`latitude`,`longitude`);
\ No newline at end of file
CREATE TABLE `assistants` (
`id` varchar(25) NOT NULL,
`email` varchar(255) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT (now()),
`updatedAt` timestamp NOT NULL DEFAULT (now()) ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT `assistants_id` PRIMARY KEY(`id`),
CONSTRAINT `assistants_email_unique` UNIQUE(`email`)
);
--> statement-breakpoint
CREATE INDEX `assistant_email_idx` ON `assistants` (`email`);
\ No newline at end of file
ALTER TABLE `occurrences` ADD `assistantId` varchar(25);--> statement-breakpoint
CREATE INDEX `assistant_idx` ON `occurrences` (`assistantId`);
\ No newline at end of file
CREATE TABLE `occurrence_assistants` (
`id` varchar(25) NOT NULL,
`occurrenceId` varchar(25) NOT NULL,
`assistantId` varchar(25) NOT NULL,
`assignedBy` varchar(25) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT (now()),
CONSTRAINT `occurrence_assistants_id` PRIMARY KEY(`id`),
CONSTRAINT `unique_occurrence_assistant` UNIQUE(`occurrenceId`,`assistantId`)
);
--> statement-breakpoint
DROP INDEX `assistant_idx` ON `occurrences`;--> statement-breakpoint
CREATE INDEX `occurrence_assistant_occurrence_idx` ON `occurrence_assistants` (`occurrenceId`);--> statement-breakpoint
CREATE INDEX `occurrence_assistant_assistant_idx` ON `occurrence_assistants` (`assistantId`);--> statement-breakpoint
CREATE INDEX `occurrence_assistant_assigned_by_idx` ON `occurrence_assistants` (`assignedBy`);--> statement-breakpoint
ALTER TABLE `occurrences` DROP COLUMN `assistantId`;
\ No newline at end of file
ALTER TABLE `occurrence_logs` MODIFY COLUMN `log_action` enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','ASSISTANT_ASSIGNED','ASSISTANT_UNASSIGNED','DELETED') NOT NULL;--> statement-breakpoint
ALTER TABLE `occurrence_logs` ADD `status` enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED') DEFAULT 'OPEN' NOT NULL;
\ No newline at end of file
{
"version": "5",
"dialect": "mysql",
"id": "c9e5c1d0-1b38-48e2-a3b0-93e7f0a86449",
"prevId": "bd99a92c-372f-428a-b4f6-ad46d9f0a991",
"tables": {
"attachments": {
"name": "attachments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"filename": {
"name": "filename",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"originalName": {
"name": "originalName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mimeType": {
"name": "mimeType",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"size": {
"name": "size",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"path": {
"name": "path",
"type": "varchar(500)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"attachment_occurrence_idx": {
"name": "attachment_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"attachments_id": {
"name": "attachments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"comments": {
"name": "comments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"isInternal": {
"name": "isInternal",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"authorId": {
"name": "authorId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"occurrence_idx": {
"name": "occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"author_idx": {
"name": "author_idx",
"columns": [
"authorId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"comments_id": {
"name": "comments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"conclusions": {
"name": "conclusions",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"fieldMaterial": {
"name": "fieldMaterial",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"materialUsed": {
"name": "materialUsed",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"conclusion_occurrence_idx": {
"name": "conclusion_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"conclusions_id": {
"name": "conclusions_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"conclusions_occurrenceId_unique": {
"name": "conclusions_occurrenceId_unique",
"columns": [
"occurrenceId"
]
}
},
"checkConstraint": {}
},
"occurrence_logs": {
"name": "occurrence_logs",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_action": {
"name": "log_action",
"type": "enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','DELETED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"oldValue": {
"name": "oldValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"newValue": {
"name": "newValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"performedBy": {
"name": "performedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"log_occurrence_idx": {
"name": "log_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"log_performed_by_idx": {
"name": "log_performed_by_idx",
"columns": [
"performedBy"
],
"isUnique": false
},
"log_action_idx": {
"name": "log_action_idx",
"columns": [
"log_action"
],
"isUnique": false
},
"log_created_at_idx": {
"name": "log_created_at_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_logs_id": {
"name": "occurrence_logs_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"occurrences": {
"name": "occurrences",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"priority": {
"name": "priority",
"type": "enum('LOW','MEDIUM','HIGH','URGENT')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'MEDIUM'"
},
"category": {
"name": "category",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"location": {
"name": "location",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"latitude": {
"name": "latitude",
"type": "decimal(10,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"longitude": {
"name": "longitude",
"type": "decimal(11,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reference": {
"name": "reference",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reporterId": {
"name": "reporterId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assigneeId": {
"name": "assigneeId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"managerId": {
"name": "managerId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
},
"closedAt": {
"name": "closedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"reporter_idx": {
"name": "reporter_idx",
"columns": [
"reporterId"
],
"isUnique": false
},
"assignee_idx": {
"name": "assignee_idx",
"columns": [
"assigneeId"
],
"isUnique": false
},
"manager_idx": {
"name": "manager_idx",
"columns": [
"managerId"
],
"isUnique": false
},
"status_idx": {
"name": "status_idx",
"columns": [
"status"
],
"isUnique": false
},
"location_idx": {
"name": "location_idx",
"columns": [
"latitude",
"longitude"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrences_id": {
"name": "occurrences_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_role": {
"name": "user_role",
"type": "enum('USER','MODERATOR','ADMIN')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'USER'"
},
"password": {
"name": "password",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"email_idx": {
"name": "email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"users_id": {
"name": "users_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
}
},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
}
}
\ No newline at end of file
{
"version": "5",
"dialect": "mysql",
"id": "2213d408-d903-499a-9229-2db8c7f39138",
"prevId": "c9e5c1d0-1b38-48e2-a3b0-93e7f0a86449",
"tables": {
"assistants": {
"name": "assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"assistant_email_idx": {
"name": "assistant_email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"assistants_id": {
"name": "assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"assistants_email_unique": {
"name": "assistants_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
},
"attachments": {
"name": "attachments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"filename": {
"name": "filename",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"originalName": {
"name": "originalName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mimeType": {
"name": "mimeType",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"size": {
"name": "size",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"path": {
"name": "path",
"type": "varchar(500)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"attachment_occurrence_idx": {
"name": "attachment_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"attachments_id": {
"name": "attachments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"comments": {
"name": "comments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"isInternal": {
"name": "isInternal",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"authorId": {
"name": "authorId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"occurrence_idx": {
"name": "occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"author_idx": {
"name": "author_idx",
"columns": [
"authorId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"comments_id": {
"name": "comments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"conclusions": {
"name": "conclusions",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"fieldMaterial": {
"name": "fieldMaterial",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"materialUsed": {
"name": "materialUsed",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"conclusion_occurrence_idx": {
"name": "conclusion_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"conclusions_id": {
"name": "conclusions_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"conclusions_occurrenceId_unique": {
"name": "conclusions_occurrenceId_unique",
"columns": [
"occurrenceId"
]
}
},
"checkConstraint": {}
},
"occurrence_logs": {
"name": "occurrence_logs",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_action": {
"name": "log_action",
"type": "enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','DELETED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"oldValue": {
"name": "oldValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"newValue": {
"name": "newValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"performedBy": {
"name": "performedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"log_occurrence_idx": {
"name": "log_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"log_performed_by_idx": {
"name": "log_performed_by_idx",
"columns": [
"performedBy"
],
"isUnique": false
},
"log_action_idx": {
"name": "log_action_idx",
"columns": [
"log_action"
],
"isUnique": false
},
"log_created_at_idx": {
"name": "log_created_at_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_logs_id": {
"name": "occurrence_logs_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"occurrences": {
"name": "occurrences",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"priority": {
"name": "priority",
"type": "enum('LOW','MEDIUM','HIGH','URGENT')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'MEDIUM'"
},
"category": {
"name": "category",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"location": {
"name": "location",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"latitude": {
"name": "latitude",
"type": "decimal(10,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"longitude": {
"name": "longitude",
"type": "decimal(11,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reference": {
"name": "reference",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reporterId": {
"name": "reporterId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assigneeId": {
"name": "assigneeId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"managerId": {
"name": "managerId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
},
"closedAt": {
"name": "closedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"reporter_idx": {
"name": "reporter_idx",
"columns": [
"reporterId"
],
"isUnique": false
},
"assignee_idx": {
"name": "assignee_idx",
"columns": [
"assigneeId"
],
"isUnique": false
},
"manager_idx": {
"name": "manager_idx",
"columns": [
"managerId"
],
"isUnique": false
},
"status_idx": {
"name": "status_idx",
"columns": [
"status"
],
"isUnique": false
},
"location_idx": {
"name": "location_idx",
"columns": [
"latitude",
"longitude"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrences_id": {
"name": "occurrences_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_role": {
"name": "user_role",
"type": "enum('USER','MODERATOR','ADMIN')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'USER'"
},
"password": {
"name": "password",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"email_idx": {
"name": "email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"users_id": {
"name": "users_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
}
},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
}
}
\ No newline at end of file
{
"version": "5",
"dialect": "mysql",
"id": "45797e05-80c7-4231-9bcc-43dd3943d2ce",
"prevId": "2213d408-d903-499a-9229-2db8c7f39138",
"tables": {
"assistants": {
"name": "assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"assistant_email_idx": {
"name": "assistant_email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"assistants_id": {
"name": "assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"assistants_email_unique": {
"name": "assistants_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
},
"attachments": {
"name": "attachments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"filename": {
"name": "filename",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"originalName": {
"name": "originalName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mimeType": {
"name": "mimeType",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"size": {
"name": "size",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"path": {
"name": "path",
"type": "varchar(500)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"attachment_occurrence_idx": {
"name": "attachment_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"attachments_id": {
"name": "attachments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"comments": {
"name": "comments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"isInternal": {
"name": "isInternal",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"authorId": {
"name": "authorId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"occurrence_idx": {
"name": "occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"author_idx": {
"name": "author_idx",
"columns": [
"authorId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"comments_id": {
"name": "comments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"conclusions": {
"name": "conclusions",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"fieldMaterial": {
"name": "fieldMaterial",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"materialUsed": {
"name": "materialUsed",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"conclusion_occurrence_idx": {
"name": "conclusion_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"conclusions_id": {
"name": "conclusions_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"conclusions_occurrenceId_unique": {
"name": "conclusions_occurrenceId_unique",
"columns": [
"occurrenceId"
]
}
},
"checkConstraint": {}
},
"occurrence_logs": {
"name": "occurrence_logs",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_action": {
"name": "log_action",
"type": "enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','DELETED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"oldValue": {
"name": "oldValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"newValue": {
"name": "newValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"performedBy": {
"name": "performedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"log_occurrence_idx": {
"name": "log_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"log_performed_by_idx": {
"name": "log_performed_by_idx",
"columns": [
"performedBy"
],
"isUnique": false
},
"log_action_idx": {
"name": "log_action_idx",
"columns": [
"log_action"
],
"isUnique": false
},
"log_created_at_idx": {
"name": "log_created_at_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_logs_id": {
"name": "occurrence_logs_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"occurrences": {
"name": "occurrences",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"priority": {
"name": "priority",
"type": "enum('LOW','MEDIUM','HIGH','URGENT')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'MEDIUM'"
},
"category": {
"name": "category",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"location": {
"name": "location",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"latitude": {
"name": "latitude",
"type": "decimal(10,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"longitude": {
"name": "longitude",
"type": "decimal(11,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reference": {
"name": "reference",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reporterId": {
"name": "reporterId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assigneeId": {
"name": "assigneeId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"managerId": {
"name": "managerId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"assistantId": {
"name": "assistantId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
},
"closedAt": {
"name": "closedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"reporter_idx": {
"name": "reporter_idx",
"columns": [
"reporterId"
],
"isUnique": false
},
"assignee_idx": {
"name": "assignee_idx",
"columns": [
"assigneeId"
],
"isUnique": false
},
"manager_idx": {
"name": "manager_idx",
"columns": [
"managerId"
],
"isUnique": false
},
"assistant_idx": {
"name": "assistant_idx",
"columns": [
"assistantId"
],
"isUnique": false
},
"status_idx": {
"name": "status_idx",
"columns": [
"status"
],
"isUnique": false
},
"location_idx": {
"name": "location_idx",
"columns": [
"latitude",
"longitude"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrences_id": {
"name": "occurrences_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_role": {
"name": "user_role",
"type": "enum('USER','MODERATOR','ADMIN')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'USER'"
},
"password": {
"name": "password",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"email_idx": {
"name": "email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"users_id": {
"name": "users_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
}
},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
}
}
\ No newline at end of file
{
"version": "5",
"dialect": "mysql",
"id": "887ad867-77b2-4a5c-8bd1-fc5e9b394b07",
"prevId": "45797e05-80c7-4231-9bcc-43dd3943d2ce",
"tables": {
"assistants": {
"name": "assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"assistant_email_idx": {
"name": "assistant_email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"assistants_id": {
"name": "assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"assistants_email_unique": {
"name": "assistants_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
},
"attachments": {
"name": "attachments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"filename": {
"name": "filename",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"originalName": {
"name": "originalName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mimeType": {
"name": "mimeType",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"size": {
"name": "size",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"path": {
"name": "path",
"type": "varchar(500)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"attachment_occurrence_idx": {
"name": "attachment_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"attachments_id": {
"name": "attachments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"comments": {
"name": "comments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"isInternal": {
"name": "isInternal",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"authorId": {
"name": "authorId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"occurrence_idx": {
"name": "occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"author_idx": {
"name": "author_idx",
"columns": [
"authorId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"comments_id": {
"name": "comments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"conclusions": {
"name": "conclusions",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"fieldMaterial": {
"name": "fieldMaterial",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"materialUsed": {
"name": "materialUsed",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"conclusion_occurrence_idx": {
"name": "conclusion_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"conclusions_id": {
"name": "conclusions_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"conclusions_occurrenceId_unique": {
"name": "conclusions_occurrenceId_unique",
"columns": [
"occurrenceId"
]
}
},
"checkConstraint": {}
},
"occurrence_assistants": {
"name": "occurrence_assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assistantId": {
"name": "assistantId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assignedBy": {
"name": "assignedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"occurrence_assistant_occurrence_idx": {
"name": "occurrence_assistant_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"occurrence_assistant_assistant_idx": {
"name": "occurrence_assistant_assistant_idx",
"columns": [
"assistantId"
],
"isUnique": false
},
"occurrence_assistant_assigned_by_idx": {
"name": "occurrence_assistant_assigned_by_idx",
"columns": [
"assignedBy"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_assistants_id": {
"name": "occurrence_assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"unique_occurrence_assistant": {
"name": "unique_occurrence_assistant",
"columns": [
"occurrenceId",
"assistantId"
]
}
},
"checkConstraint": {}
},
"occurrence_logs": {
"name": "occurrence_logs",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_action": {
"name": "log_action",
"type": "enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','DELETED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"oldValue": {
"name": "oldValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"newValue": {
"name": "newValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"performedBy": {
"name": "performedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"log_occurrence_idx": {
"name": "log_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"log_performed_by_idx": {
"name": "log_performed_by_idx",
"columns": [
"performedBy"
],
"isUnique": false
},
"log_action_idx": {
"name": "log_action_idx",
"columns": [
"log_action"
],
"isUnique": false
},
"log_created_at_idx": {
"name": "log_created_at_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_logs_id": {
"name": "occurrence_logs_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"occurrences": {
"name": "occurrences",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"priority": {
"name": "priority",
"type": "enum('LOW','MEDIUM','HIGH','URGENT')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'MEDIUM'"
},
"category": {
"name": "category",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"location": {
"name": "location",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"latitude": {
"name": "latitude",
"type": "decimal(10,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"longitude": {
"name": "longitude",
"type": "decimal(11,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reference": {
"name": "reference",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reporterId": {
"name": "reporterId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assigneeId": {
"name": "assigneeId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"managerId": {
"name": "managerId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
},
"closedAt": {
"name": "closedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"reporter_idx": {
"name": "reporter_idx",
"columns": [
"reporterId"
],
"isUnique": false
},
"assignee_idx": {
"name": "assignee_idx",
"columns": [
"assigneeId"
],
"isUnique": false
},
"manager_idx": {
"name": "manager_idx",
"columns": [
"managerId"
],
"isUnique": false
},
"status_idx": {
"name": "status_idx",
"columns": [
"status"
],
"isUnique": false
},
"location_idx": {
"name": "location_idx",
"columns": [
"latitude",
"longitude"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrences_id": {
"name": "occurrences_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_role": {
"name": "user_role",
"type": "enum('USER','MODERATOR','ADMIN')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'USER'"
},
"password": {
"name": "password",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"email_idx": {
"name": "email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"users_id": {
"name": "users_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
}
},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
}
}
\ No newline at end of file
{
"version": "5",
"dialect": "mysql",
"id": "eb296227-1602-457d-81cd-b6aaa05bbb03",
"prevId": "887ad867-77b2-4a5c-8bd1-fc5e9b394b07",
"tables": {
"assistants": {
"name": "assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"assistant_email_idx": {
"name": "assistant_email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"assistants_id": {
"name": "assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"assistants_email_unique": {
"name": "assistants_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
},
"attachments": {
"name": "attachments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"filename": {
"name": "filename",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"originalName": {
"name": "originalName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"mimeType": {
"name": "mimeType",
"type": "varchar(100)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"size": {
"name": "size",
"type": "int",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"path": {
"name": "path",
"type": "varchar(500)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"attachment_occurrence_idx": {
"name": "attachment_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"attachments_id": {
"name": "attachments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"comments": {
"name": "comments",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"content": {
"name": "content",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"isInternal": {
"name": "isInternal",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"authorId": {
"name": "authorId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"occurrence_idx": {
"name": "occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"author_idx": {
"name": "author_idx",
"columns": [
"authorId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"comments_id": {
"name": "comments_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"conclusions": {
"name": "conclusions",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"fieldMaterial": {
"name": "fieldMaterial",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": false
},
"materialUsed": {
"name": "materialUsed",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"conclusion_occurrence_idx": {
"name": "conclusion_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"conclusions_id": {
"name": "conclusions_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"conclusions_occurrenceId_unique": {
"name": "conclusions_occurrenceId_unique",
"columns": [
"occurrenceId"
]
}
},
"checkConstraint": {}
},
"occurrence_assistants": {
"name": "occurrence_assistants",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assistantId": {
"name": "assistantId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assignedBy": {
"name": "assignedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"occurrence_assistant_occurrence_idx": {
"name": "occurrence_assistant_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"occurrence_assistant_assistant_idx": {
"name": "occurrence_assistant_assistant_idx",
"columns": [
"assistantId"
],
"isUnique": false
},
"occurrence_assistant_assigned_by_idx": {
"name": "occurrence_assistant_assigned_by_idx",
"columns": [
"assignedBy"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_assistants_id": {
"name": "occurrence_assistants_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"unique_occurrence_assistant": {
"name": "unique_occurrence_assistant",
"columns": [
"occurrenceId",
"assistantId"
]
}
},
"checkConstraint": {}
},
"occurrence_logs": {
"name": "occurrence_logs",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"occurrenceId": {
"name": "occurrenceId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"log_action": {
"name": "log_action",
"type": "enum('CREATED','UPDATED','ASSIGNED','DUAL_ASSIGNED','UNASSIGNED','STATUS_CHANGED','PRIORITY_CHANGED','COMMENT_ADDED','ATTACHMENT_ADDED','ATTACHMENT_REMOVED','CONCLUSION_ADDED','CONCLUSION_UPDATED','ASSISTANT_ASSIGNED','ASSISTANT_UNASSIGNED','DELETED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"oldValue": {
"name": "oldValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"newValue": {
"name": "newValue",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"performedBy": {
"name": "performedBy",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
}
},
"indexes": {
"log_occurrence_idx": {
"name": "log_occurrence_idx",
"columns": [
"occurrenceId"
],
"isUnique": false
},
"log_performed_by_idx": {
"name": "log_performed_by_idx",
"columns": [
"performedBy"
],
"isUnique": false
},
"log_action_idx": {
"name": "log_action_idx",
"columns": [
"log_action"
],
"isUnique": false
},
"log_created_at_idx": {
"name": "log_created_at_idx",
"columns": [
"createdAt"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrence_logs_id": {
"name": "occurrence_logs_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"occurrences": {
"name": "occurrences",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"title": {
"name": "title",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"status": {
"name": "status",
"type": "enum('OPEN','IN_PROGRESS','RESOLVED','PAUSED','CLOSED','PARCIAL_RESOLVED','CANCELLED')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'OPEN'"
},
"priority": {
"name": "priority",
"type": "enum('LOW','MEDIUM','HIGH','URGENT')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'MEDIUM'"
},
"category": {
"name": "category",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"location": {
"name": "location",
"type": "varchar(255)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"latitude": {
"name": "latitude",
"type": "decimal(10,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"longitude": {
"name": "longitude",
"type": "decimal(11,8)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reference": {
"name": "reference",
"type": "text",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"reporterId": {
"name": "reporterId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"assigneeId": {
"name": "assigneeId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"managerId": {
"name": "managerId",
"type": "varchar(25)",
"primaryKey": false,
"notNull": false,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
},
"closedAt": {
"name": "closedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": false,
"autoincrement": false
}
},
"indexes": {
"reporter_idx": {
"name": "reporter_idx",
"columns": [
"reporterId"
],
"isUnique": false
},
"assignee_idx": {
"name": "assignee_idx",
"columns": [
"assigneeId"
],
"isUnique": false
},
"manager_idx": {
"name": "manager_idx",
"columns": [
"managerId"
],
"isUnique": false
},
"status_idx": {
"name": "status_idx",
"columns": [
"status"
],
"isUnique": false
},
"location_idx": {
"name": "location_idx",
"columns": [
"latitude",
"longitude"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"occurrences_id": {
"name": "occurrences_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {},
"checkConstraint": {}
},
"users": {
"name": "users",
"columns": {
"id": {
"name": "id",
"type": "varchar(25)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"firstName": {
"name": "firstName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"lastName": {
"name": "lastName",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"email": {
"name": "email",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"user_role": {
"name": "user_role",
"type": "enum('USER','MODERATOR','ADMIN')",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "'USER'"
},
"password": {
"name": "password",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"createdAt": {
"name": "createdAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"default": "(now())"
},
"updatedAt": {
"name": "updatedAt",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"autoincrement": false,
"onUpdate": true,
"default": "(now())"
}
},
"indexes": {
"email_idx": {
"name": "email_idx",
"columns": [
"email"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {
"users_id": {
"name": "users_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": {
"users_email_unique": {
"name": "users_email_unique",
"columns": [
"email"
]
}
},
"checkConstraint": {}
}
},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
}
}
\ No newline at end of file
...@@ -15,6 +15,41 @@ ...@@ -15,6 +15,41 @@
"when": 1757352023356, "when": 1757352023356,
"tag": "0001_perpetual_human_fly", "tag": "0001_perpetual_human_fly",
"breakpoints": true "breakpoints": true
},
{
"idx": 2,
"version": "5",
"when": 1757493222915,
"tag": "0002_flawless_mother_askani",
"breakpoints": true
},
{
"idx": 3,
"version": "5",
"when": 1757608837695,
"tag": "0003_black_stephen_strange",
"breakpoints": true
},
{
"idx": 4,
"version": "5",
"when": 1757610845102,
"tag": "0004_military_speed",
"breakpoints": true
},
{
"idx": 5,
"version": "5",
"when": 1757686691705,
"tag": "0005_flowery_deadpool",
"breakpoints": true
},
{
"idx": 6,
"version": "5",
"when": 1757687180760,
"tag": "0006_past_supernaut",
"breakpoints": true
} }
] ]
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ import { OccurrenceModule } from './modules/occurrence/occurrence.module'; ...@@ -10,6 +10,7 @@ import { OccurrenceModule } from './modules/occurrence/occurrence.module';
import { CommentModule } from './modules/comment/comment.module'; import { CommentModule } from './modules/comment/comment.module';
import { AttachmentModule } from './modules/attachment/attachment.module'; import { AttachmentModule } from './modules/attachment/attachment.module';
import { ConclusionModule } from './modules/conclusion/conclusion.module'; import { ConclusionModule } from './modules/conclusion/conclusion.module';
import { AssistantModule } from './modules/assistant/assistant.module';
import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard'; import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard';
@Module({ @Module({
...@@ -24,6 +25,7 @@ import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard'; ...@@ -24,6 +25,7 @@ import { JwtAuthGuard } from './modules/auth/guards/jwt-auth.guard';
CommentModule, CommentModule,
AttachmentModule, AttachmentModule,
ConclusionModule, ConclusionModule,
AssistantModule,
], ],
controllers: [AppController], controllers: [AppController],
providers: [ providers: [
......
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
primaryKey, primaryKey,
unique, unique,
index, index,
decimal,
} from 'drizzle-orm/mysql-core'; } from 'drizzle-orm/mysql-core';
import { relations } from 'drizzle-orm'; import { relations } from 'drizzle-orm';
...@@ -46,6 +47,8 @@ export const logActionEnum = mysqlEnum('log_action', [ ...@@ -46,6 +47,8 @@ export const logActionEnum = mysqlEnum('log_action', [
'ATTACHMENT_REMOVED', 'ATTACHMENT_REMOVED',
'CONCLUSION_ADDED', 'CONCLUSION_ADDED',
'CONCLUSION_UPDATED', 'CONCLUSION_UPDATED',
'ASSISTANT_ASSIGNED',
'ASSISTANT_UNASSIGNED',
'DELETED', 'DELETED',
]); ]);
...@@ -78,6 +81,9 @@ export const occurrences = mysqlTable( ...@@ -78,6 +81,9 @@ export const occurrences = mysqlTable(
priority: priorityEnum.notNull().default('MEDIUM'), priority: priorityEnum.notNull().default('MEDIUM'),
category: varchar('category', { length: 255 }).notNull(), category: varchar('category', { length: 255 }).notNull(),
location: varchar('location', { length: 255 }), location: varchar('location', { length: 255 }),
latitude: decimal('latitude', { precision: 10, scale: 8 }),
longitude: decimal('longitude', { precision: 11, scale: 8 }),
reference: text('reference'),
reporterId: varchar('reporterId', { length: 25 }).notNull(), reporterId: varchar('reporterId', { length: 25 }).notNull(),
assigneeId: varchar('assigneeId', { length: 25 }), assigneeId: varchar('assigneeId', { length: 25 }),
managerId: varchar('managerId', { length: 25 }), managerId: varchar('managerId', { length: 25 }),
...@@ -90,6 +96,7 @@ export const occurrences = mysqlTable( ...@@ -90,6 +96,7 @@ export const occurrences = mysqlTable(
assigneeIdx: index('assignee_idx').on(table.assigneeId), assigneeIdx: index('assignee_idx').on(table.assigneeId),
managerIdx: index('manager_idx').on(table.managerId), managerIdx: index('manager_idx').on(table.managerId),
statusIdx: index('status_idx').on(table.status), statusIdx: index('status_idx').on(table.status),
locationIdx: index('location_idx').on(table.latitude, table.longitude),
}), }),
); );
...@@ -158,6 +165,7 @@ export const occurrenceLogs = mysqlTable( ...@@ -158,6 +165,7 @@ export const occurrenceLogs = mysqlTable(
oldValue: text('oldValue'), oldValue: text('oldValue'),
newValue: text('newValue'), newValue: text('newValue'),
performedBy: varchar('performedBy', { length: 25 }).notNull(), performedBy: varchar('performedBy', { length: 25 }).notNull(),
status: occurrenceStatusEnum,
createdAt: timestamp('createdAt').notNull().defaultNow(), createdAt: timestamp('createdAt').notNull().defaultNow(),
}, },
(table) => ({ (table) => ({
...@@ -168,6 +176,47 @@ export const occurrenceLogs = mysqlTable( ...@@ -168,6 +176,47 @@ export const occurrenceLogs = mysqlTable(
}), }),
); );
// Assistants table
export const assistants = mysqlTable(
'assistants',
{
id: varchar('id', { length: 25 }).primaryKey(),
email: varchar('email', { length: 255 }).notNull().unique(),
createdAt: timestamp('createdAt').notNull().defaultNow(),
updatedAt: timestamp('updatedAt').notNull().defaultNow().onUpdateNow(),
},
(table) => ({
emailIdx: index('assistant_email_idx').on(table.email),
}),
);
// Occurrence Assistants junction table (many-to-many)
export const occurrenceAssistants = mysqlTable(
'occurrence_assistants',
{
id: varchar('id', { length: 25 }).primaryKey(),
occurrenceId: varchar('occurrenceId', { length: 25 }).notNull(),
assistantId: varchar('assistantId', { length: 25 }).notNull(),
assignedBy: varchar('assignedBy', { length: 25 }).notNull(),
createdAt: timestamp('createdAt').notNull().defaultNow(),
},
(table) => ({
occurrenceIdx: index('occurrence_assistant_occurrence_idx').on(
table.occurrenceId,
),
assistantIdx: index('occurrence_assistant_assistant_idx').on(
table.assistantId,
),
assignedByIdx: index('occurrence_assistant_assigned_by_idx').on(
table.assignedBy,
),
uniqueOccurrenceAssistant: unique('unique_occurrence_assistant').on(
table.occurrenceId,
table.assistantId,
),
}),
);
// Relations // Relations
export const usersRelations = relations(users, ({ many }) => ({ export const usersRelations = relations(users, ({ many }) => ({
reportedOccurrences: many(occurrences, { relationName: 'reportedBy' }), reportedOccurrences: many(occurrences, { relationName: 'reportedBy' }),
...@@ -193,6 +242,7 @@ export const occurrencesRelations = relations(occurrences, ({ one, many }) => ({ ...@@ -193,6 +242,7 @@ export const occurrencesRelations = relations(occurrences, ({ one, many }) => ({
references: [users.id], references: [users.id],
relationName: 'managedBy', relationName: 'managedBy',
}), }),
occurrenceAssistants: many(occurrenceAssistants),
comments: many(comments), comments: many(comments),
attachments: many(attachments), attachments: many(attachments),
conclusion: one(conclusions), conclusion: one(conclusions),
...@@ -235,6 +285,28 @@ export const occurrenceLogsRelations = relations(occurrenceLogs, ({ one }) => ({ ...@@ -235,6 +285,28 @@ export const occurrenceLogsRelations = relations(occurrenceLogs, ({ one }) => ({
}), }),
})); }));
export const assistantsRelations = relations(assistants, ({ many }) => ({
occurrenceAssistants: many(occurrenceAssistants),
}));
export const occurrenceAssistantsRelations = relations(
occurrenceAssistants,
({ one }) => ({
occurrence: one(occurrences, {
fields: [occurrenceAssistants.occurrenceId],
references: [occurrences.id],
}),
assistant: one(assistants, {
fields: [occurrenceAssistants.assistantId],
references: [assistants.id],
}),
assignedByUser: one(users, {
fields: [occurrenceAssistants.assignedBy],
references: [users.id],
}),
}),
);
// Type exports for TypeScript // Type exports for TypeScript
export type User = typeof users.$inferSelect; export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert; export type NewUser = typeof users.$inferInsert;
...@@ -248,6 +320,10 @@ export type Conclusion = typeof conclusions.$inferSelect; ...@@ -248,6 +320,10 @@ export type Conclusion = typeof conclusions.$inferSelect;
export type NewConclusion = typeof conclusions.$inferInsert; export type NewConclusion = typeof conclusions.$inferInsert;
export type OccurrenceLog = typeof occurrenceLogs.$inferSelect; export type OccurrenceLog = typeof occurrenceLogs.$inferSelect;
export type NewOccurrenceLog = typeof occurrenceLogs.$inferInsert; export type NewOccurrenceLog = typeof occurrenceLogs.$inferInsert;
export type Assistant = typeof assistants.$inferSelect;
export type NewAssistant = typeof assistants.$inferInsert;
export type OccurrenceAssistant = typeof occurrenceAssistants.$inferSelect;
export type NewOccurrenceAssistant = typeof occurrenceAssistants.$inferInsert;
// Enum types // Enum types
export type UserRole = 'USER' | 'MODERATOR' | 'ADMIN'; export type UserRole = 'USER' | 'MODERATOR' | 'ADMIN';
...@@ -272,6 +348,8 @@ export type LogAction = ...@@ -272,6 +348,8 @@ export type LogAction =
| 'ATTACHMENT_REMOVED' | 'ATTACHMENT_REMOVED'
| 'CONCLUSION_ADDED' | 'CONCLUSION_ADDED'
| 'CONCLUSION_UPDATED' | 'CONCLUSION_UPDATED'
| 'ASSISTANT_ASSIGNED'
| 'ASSISTANT_UNASSIGNED'
| 'DELETED'; | 'DELETED';
// Enum constants for runtime usage // Enum constants for runtime usage
...@@ -310,5 +388,7 @@ export const LogActionEnum = { ...@@ -310,5 +388,7 @@ export const LogActionEnum = {
ATTACHMENT_REMOVED: 'ATTACHMENT_REMOVED' as const, ATTACHMENT_REMOVED: 'ATTACHMENT_REMOVED' as const,
CONCLUSION_ADDED: 'CONCLUSION_ADDED' as const, CONCLUSION_ADDED: 'CONCLUSION_ADDED' as const,
CONCLUSION_UPDATED: 'CONCLUSION_UPDATED' as const, CONCLUSION_UPDATED: 'CONCLUSION_UPDATED' as const,
ASSISTANT_ASSIGNED: 'ASSISTANT_ASSIGNED' as const,
ASSISTANT_UNASSIGNED: 'ASSISTANT_UNASSIGNED' as const,
DELETED: 'DELETED' as const, DELETED: 'DELETED' as const,
} as const; } as const;
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiParam,
ApiBody,
ApiBearerAuth,
} from '@nestjs/swagger';
import { AssistantService } from './assistant.service';
import { CreateAssistantDto } from './dto/create-assistant.dto';
import { UpdateAssistantDto } from './dto/update-assistant.dto';
import { AssistantResponseDto } from './dto/assistant-response.dto';
@ApiTags('assistants')
@ApiBearerAuth('JWT-auth')
@Controller('assistants')
export class AssistantController {
constructor(private readonly assistantService: AssistantService) {}
@Post()
@ApiOperation({ summary: 'Create a new assistant' })
@ApiBody({ type: CreateAssistantDto })
@ApiResponse({
status: 201,
description: 'Assistant created successfully',
type: AssistantResponseDto,
})
@ApiResponse({
status: 409,
description: 'Assistant with this email already exists',
})
@ApiResponse({
status: 400,
description: 'Invalid input data',
})
async create(
@Body() createAssistantDto: CreateAssistantDto,
): Promise<AssistantResponseDto> {
return this.assistantService.create(createAssistantDto);
}
@Get()
@ApiOperation({ summary: 'Get all assistants' })
@ApiResponse({
status: 200,
description: 'List of all assistants',
type: [AssistantResponseDto],
})
async findAll(): Promise<AssistantResponseDto[]> {
return this.assistantService.findAll();
}
@Get('count')
@ApiOperation({ summary: 'Get total number of assistants' })
@ApiResponse({
status: 200,
description: 'Total number of assistants',
schema: {
type: 'object',
properties: {
count: {
type: 'number',
example: 5,
},
},
},
})
async getCount(): Promise<{ count: number }> {
const count = await this.assistantService.count();
return { count };
}
@Get(':id')
@ApiOperation({ summary: 'Get assistant by ID' })
@ApiParam({
name: 'id',
description: 'Assistant unique identifier',
example: 'clxyz123abc456def',
})
@ApiResponse({
status: 200,
description: 'Assistant found',
type: AssistantResponseDto,
})
@ApiResponse({
status: 404,
description: 'Assistant not found',
})
async findOne(@Param('id') id: string): Promise<AssistantResponseDto> {
return this.assistantService.findOne(id);
}
@Get('email/:email')
@ApiOperation({ summary: 'Get assistant by email' })
@ApiParam({
name: 'email',
description: 'Assistant email address',
example: 'assistant@example.com',
})
@ApiResponse({
status: 200,
description: 'Assistant found',
type: AssistantResponseDto,
})
@ApiResponse({
status: 404,
description: 'Assistant not found',
})
async findByEmail(
@Param('email') email: string,
): Promise<AssistantResponseDto | null> {
return this.assistantService.findByEmail(email);
}
@Patch(':id')
@ApiOperation({ summary: 'Update assistant by ID' })
@ApiParam({
name: 'id',
description: 'Assistant unique identifier',
example: 'clxyz123abc456def',
})
@ApiBody({ type: UpdateAssistantDto })
@ApiResponse({
status: 200,
description: 'Assistant updated successfully',
type: AssistantResponseDto,
})
@ApiResponse({
status: 404,
description: 'Assistant not found',
})
@ApiResponse({
status: 409,
description: 'Assistant with this email already exists',
})
@ApiResponse({
status: 400,
description: 'Invalid input data',
})
async update(
@Param('id') id: string,
@Body() updateAssistantDto: UpdateAssistantDto,
): Promise<AssistantResponseDto> {
return this.assistantService.update(id, updateAssistantDto);
}
@Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Delete assistant by ID' })
@ApiParam({
name: 'id',
description: 'Assistant unique identifier',
example: 'clxyz123abc456def',
})
@ApiResponse({
status: 204,
description: 'Assistant deleted successfully',
})
@ApiResponse({
status: 404,
description: 'Assistant not found',
})
async remove(@Param('id') id: string): Promise<void> {
return this.assistantService.remove(id);
}
}
import { Module } from '@nestjs/common';
import { AssistantController } from './assistant.controller';
import { AssistantService } from './assistant.service';
import { DrizzleService } from '../../common/drizzle.service';
@Module({
controllers: [AssistantController],
providers: [AssistantService, DrizzleService],
exports: [AssistantService],
})
export class AssistantModule {}
import {
Injectable,
NotFoundException,
ConflictException,
} from '@nestjs/common';
import { DrizzleService } from '../../common/drizzle.service';
import { assistants } from '../../drizzle/schema';
import { eq, and, ne } from 'drizzle-orm';
import { CreateAssistantDto } from './dto/create-assistant.dto';
import { UpdateAssistantDto } from './dto/update-assistant.dto';
import { AssistantResponseDto } from './dto/assistant-response.dto';
@Injectable()
export class AssistantService {
constructor(private readonly drizzle: DrizzleService) {}
async create(
createAssistantDto: CreateAssistantDto,
): Promise<AssistantResponseDto> {
// Check if assistant with email already exists
const existingAssistant = await this.drizzle.db
.select()
.from(assistants)
.where(eq(assistants.email, createAssistantDto.email))
.limit(1);
if (existingAssistant.length > 0) {
throw new ConflictException('Assistant with this email already exists');
}
// Create assistant
const assistantId = this.drizzle.generateId();
await this.drizzle.db.insert(assistants).values({
id: assistantId,
email: createAssistantDto.email,
});
// Get the created assistant
const [assistant] = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
createdAt: assistants.createdAt,
updatedAt: assistants.updatedAt,
})
.from(assistants)
.where(eq(assistants.id, assistantId))
.limit(1);
return assistant;
}
async findAll(): Promise<AssistantResponseDto[]> {
const assistantsList = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
createdAt: assistants.createdAt,
updatedAt: assistants.updatedAt,
})
.from(assistants)
.orderBy(assistants.createdAt);
return assistantsList;
}
async findOne(id: string): Promise<AssistantResponseDto> {
const [assistant] = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
createdAt: assistants.createdAt,
updatedAt: assistants.updatedAt,
})
.from(assistants)
.where(eq(assistants.id, id))
.limit(1);
if (!assistant) {
throw new NotFoundException(`Assistant with ID ${id} not found`);
}
return assistant;
}
async findByEmail(email: string): Promise<AssistantResponseDto | null> {
const [assistant] = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
createdAt: assistants.createdAt,
updatedAt: assistants.updatedAt,
})
.from(assistants)
.where(eq(assistants.email, email))
.limit(1);
return assistant || null;
}
async update(
id: string,
updateAssistantDto: UpdateAssistantDto,
): Promise<AssistantResponseDto> {
// Check if assistant exists
await this.findOne(id);
// If email is being updated, check for conflicts
if (updateAssistantDto.email) {
const existingAssistant = await this.drizzle.db
.select()
.from(assistants)
.where(
and(
eq(assistants.email, updateAssistantDto.email),
ne(assistants.id, id),
),
)
.limit(1);
if (existingAssistant.length > 0) {
throw new ConflictException('Assistant with this email already exists');
}
}
await this.drizzle.db
.update(assistants)
.set(updateAssistantDto)
.where(eq(assistants.id, id));
// Get the updated assistant
const [assistant] = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
createdAt: assistants.createdAt,
updatedAt: assistants.updatedAt,
})
.from(assistants)
.where(eq(assistants.id, id))
.limit(1);
return assistant;
}
async remove(id: string): Promise<void> {
// Check if assistant exists
await this.findOne(id);
await this.drizzle.db.delete(assistants).where(eq(assistants.id, id));
}
async count(): Promise<number> {
const result = await this.drizzle.db
.select({ count: assistants.id })
.from(assistants);
return result.length;
}
}
import { ApiProperty } from '@nestjs/swagger';
export class AssistantResponseDto {
@ApiProperty({
description: 'Assistant unique identifier',
example: 'clxyz123abc456def',
})
id: string;
@ApiProperty({
description: 'Assistant email address',
example: 'assistant@example.com',
})
email: string;
@ApiProperty({
description: 'Assistant creation timestamp',
example: '2024-01-15T10:30:00.000Z',
})
createdAt: Date;
@ApiProperty({
description: 'Assistant last update timestamp',
example: '2024-01-15T10:30:00.000Z',
})
updatedAt: Date;
}
import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsNotEmpty } from 'class-validator';
export class CreateAssistantDto {
@ApiProperty({
description: 'Assistant email address',
example: 'assistant@example.com',
})
@IsEmail({}, { message: 'Please provide a valid email address' })
@IsNotEmpty({ message: 'Email is required' })
email: string;
}
import { PartialType } from '@nestjs/swagger';
import { CreateAssistantDto } from './create-assistant.dto';
export class UpdateAssistantDto extends PartialType(CreateAssistantDto) {}
export * from './assistant.controller';
export * from './assistant.service';
export * from './assistant.module';
export * from './dto/assistant-response.dto';
export * from './dto/create-assistant.dto';
export * from './dto/update-assistant.dto';
...@@ -24,6 +24,7 @@ export class CommentService { ...@@ -24,6 +24,7 @@ export class CommentService {
id: comments.id, id: comments.id,
content: comments.content, content: comments.content,
isInternal: comments.isInternal, isInternal: comments.isInternal,
status: comments.status,
occurrenceId: comments.occurrenceId, occurrenceId: comments.occurrenceId,
authorId: comments.authorId, authorId: comments.authorId,
createdAt: comments.createdAt, createdAt: comments.createdAt,
...@@ -79,6 +80,7 @@ export class CommentService { ...@@ -79,6 +80,7 @@ export class CommentService {
id: commentId, id: commentId,
content: createCommentDto.content, content: createCommentDto.content,
isInternal: createCommentDto.isInternal || false, isInternal: createCommentDto.isInternal || false,
status: createCommentDto.status,
occurrenceId: createCommentDto.occurrenceId, occurrenceId: createCommentDto.occurrenceId,
authorId: authorId, authorId: authorId,
}); });
...@@ -121,6 +123,7 @@ export class CommentService { ...@@ -121,6 +123,7 @@ export class CommentService {
id: comments.id, id: comments.id,
content: comments.content, content: comments.content,
isInternal: comments.isInternal, isInternal: comments.isInternal,
status: comments.status,
occurrenceId: comments.occurrenceId, occurrenceId: comments.occurrenceId,
authorId: comments.authorId, authorId: comments.authorId,
createdAt: comments.createdAt, createdAt: comments.createdAt,
...@@ -184,23 +187,53 @@ export class CommentService { ...@@ -184,23 +187,53 @@ export class CommentService {
throw new ForbiddenException('You can only edit your own comments'); throw new ForbiddenException('You can only edit your own comments');
} }
// Only admins and moderators can change the isInternal flag // Only admins and moderators can change the isInternal flag and status
const updateData: { const updateData: {
content?: string; content?: string;
isInternal?: boolean; isInternal?: boolean;
} = { content: updateCommentDto.content }; status?: string;
} = {};
// Only include content if it's provided
if (updateCommentDto.content !== undefined) {
updateData.content = updateCommentDto.content;
}
if (updateCommentDto.isInternal !== undefined) { if (updateCommentDto.isInternal !== undefined) {
if ( // Only check permissions if the value is actually being changed
userRole !== UserRoleEnum.ADMIN && if (updateCommentDto.isInternal !== comment.isInternal) {
userRole !== UserRoleEnum.MODERATOR if (
) { userRole !== UserRoleEnum.ADMIN &&
throw new ForbiddenException( userRole !== UserRoleEnum.MODERATOR
'Only admins and moderators can change internal status', ) {
); throw new ForbiddenException(
'Only admins and moderators can change internal status',
);
}
} }
updateData.isInternal = updateCommentDto.isInternal; updateData.isInternal = updateCommentDto.isInternal;
} }
if (updateCommentDto.status !== undefined) {
// Only check permissions if the value is actually being changed
if (updateCommentDto.status !== comment.status) {
if (
userRole !== UserRoleEnum.ADMIN &&
userRole !== UserRoleEnum.MODERATOR
) {
throw new ForbiddenException(
'Only admins and moderators can change status',
);
}
}
updateData.status = updateCommentDto.status;
}
// Check if there's anything to update
if (Object.keys(updateData).length === 0) {
throw new BadRequestException('No fields provided for update');
}
await this.drizzle.db await this.drizzle.db
.update(comments) .update(comments)
.set(updateData) .set(updateData)
......
...@@ -83,6 +83,7 @@ export class CommentResponseDto { ...@@ -83,6 +83,7 @@ export class CommentResponseDto {
'OPEN', 'OPEN',
'IN_PROGRESS', 'IN_PROGRESS',
'RESOLVED', 'RESOLVED',
'PAUSED',
'CLOSED', 'CLOSED',
'PARCIAL_RESOLVED', 'PARCIAL_RESOLVED',
'CANCELLED', 'CANCELLED',
...@@ -93,6 +94,7 @@ export class CommentResponseDto { ...@@ -93,6 +94,7 @@ export class CommentResponseDto {
| 'OPEN' | 'OPEN'
| 'IN_PROGRESS' | 'IN_PROGRESS'
| 'RESOLVED' | 'RESOLVED'
| 'PAUSED'
| 'CLOSED' | 'CLOSED'
| 'PARCIAL_RESOLVED' | 'PARCIAL_RESOLVED'
| 'CANCELLED'; | 'CANCELLED';
......
...@@ -41,6 +41,7 @@ export class CreateCommentDto { ...@@ -41,6 +41,7 @@ export class CreateCommentDto {
'OPEN', 'OPEN',
'IN_PROGRESS', 'IN_PROGRESS',
'RESOLVED', 'RESOLVED',
'PAUSED',
'CLOSED', 'CLOSED',
'PARCIAL_RESOLVED', 'PARCIAL_RESOLVED',
'CANCELLED', 'CANCELLED',
...@@ -52,6 +53,7 @@ export class CreateCommentDto { ...@@ -52,6 +53,7 @@ export class CreateCommentDto {
'OPEN', 'OPEN',
'IN_PROGRESS', 'IN_PROGRESS',
'RESOLVED', 'RESOLVED',
'PAUSED',
'CLOSED', 'CLOSED',
'PARCIAL_RESOLVED', 'PARCIAL_RESOLVED',
'CANCELLED', 'CANCELLED',
...@@ -60,6 +62,7 @@ export class CreateCommentDto { ...@@ -60,6 +62,7 @@ export class CreateCommentDto {
| 'OPEN' | 'OPEN'
| 'IN_PROGRESS' | 'IN_PROGRESS'
| 'RESOLVED' | 'RESOLVED'
| 'PAUSED'
| 'CLOSED' | 'CLOSED'
| 'PARCIAL_RESOLVED' | 'PARCIAL_RESOLVED'
| 'CANCELLED'; | 'CANCELLED';
......
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class AssignAssistantDto {
@ApiProperty({
description: 'ID of the assistant to assign to the occurrence',
example: 'clxyz123abc456def',
})
@IsNotEmpty({ message: 'Assistant ID is required' })
@IsString()
assistantId: string;
}
import { ApiProperty } from '@nestjs/swagger';
import { IsArray, IsNotEmpty, IsString, ArrayMinSize } from 'class-validator';
export class AssignMultipleAssistantsDto {
@ApiProperty({
description: 'Array of assistant IDs to assign to the occurrence',
example: ['clxyz123abc456def', 'clxyz789def012ghi'],
type: [String],
})
@IsArray({ message: 'assistantIds must be an array' })
@ArrayMinSize(1, { message: 'At least one assistant ID is required' })
@IsString({ each: true, message: 'Each assistant ID must be a string' })
@IsNotEmpty({ each: true, message: 'Assistant IDs cannot be empty' })
assistantIds: string[];
}
...@@ -5,6 +5,8 @@ import { ...@@ -5,6 +5,8 @@ import {
IsOptional, IsOptional,
IsString, IsString,
MaxLength, MaxLength,
IsNumber,
IsDecimal,
} from 'class-validator'; } from 'class-validator';
import { import {
OccurrenceStatus, OccurrenceStatus,
...@@ -50,6 +52,32 @@ export class CreateOccurrenceDto { ...@@ -50,6 +52,32 @@ export class CreateOccurrenceDto {
location?: string; location?: string;
@ApiPropertyOptional({ @ApiPropertyOptional({
description: 'GPS latitude coordinate',
example: -23.5505,
type: 'number',
})
@IsOptional()
@IsNumber()
latitude?: number;
@ApiPropertyOptional({
description: 'GPS longitude coordinate',
example: -46.6333,
type: 'number',
})
@IsOptional()
@IsNumber()
longitude?: number;
@ApiPropertyOptional({
description: 'Reference information for the occurrence location',
example: 'Near the main entrance, next to the parking lot',
})
@IsOptional()
@IsString()
reference?: string;
@ApiPropertyOptional({
description: 'Occurrence priority level', description: 'Occurrence priority level',
enum: PriorityEnum, enum: PriorityEnum,
example: PriorityEnum.HIGH, example: PriorityEnum.HIGH,
......
...@@ -45,6 +45,12 @@ export class LogResponseDto { ...@@ -45,6 +45,12 @@ export class LogResponseDto {
}) })
performedBy: string; performedBy: string;
@ApiPropertyOptional({
description: 'Status of the occurrence at the time of this log entry',
example: 'IN_PROGRESS',
})
status?: string | null;
@ApiProperty({ @ApiProperty({
description: 'Date and time when the action was performed', description: 'Date and time when the action was performed',
example: '2024-01-01T12:00:00.000Z', example: '2024-01-01T12:00:00.000Z',
......
...@@ -52,6 +52,26 @@ export class OccurrenceResponseDto { ...@@ -52,6 +52,26 @@ export class OccurrenceResponseDto {
}) })
location?: string | null; location?: string | null;
@ApiPropertyOptional({
description: 'GPS latitude coordinate',
example: -23.5505,
type: 'number',
})
latitude?: number | null;
@ApiPropertyOptional({
description: 'GPS longitude coordinate',
example: -46.6333,
type: 'number',
})
longitude?: number | null;
@ApiPropertyOptional({
description: 'Reference information for the occurrence location',
example: 'Near the main entrance, next to the parking lot',
})
reference?: string | null;
@ApiProperty({ @ApiProperty({
description: 'ID of the user who reported the occurrence', description: 'ID of the user who reported the occurrence',
example: 'clxyz123abc456def', example: 'clxyz123abc456def',
...@@ -140,6 +160,39 @@ export class OccurrenceResponseDto { ...@@ -140,6 +160,39 @@ export class OccurrenceResponseDto {
} | null; } | null;
@ApiPropertyOptional({ @ApiPropertyOptional({
description: 'Assistants assigned to the occurrence',
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string', example: 'clxyz123abc456def' },
email: { type: 'string', example: 'assistant@example.com' },
assignedAt: { type: 'string', example: '2024-01-01T12:00:00.000Z' },
assignedBy: {
type: 'object',
properties: {
id: { type: 'string', example: 'clxyz123abc456def' },
firstName: { type: 'string', example: 'John' },
lastName: { type: 'string', example: 'Doe' },
email: { type: 'string', example: 'john.doe@example.com' },
},
},
},
},
})
assistants?: Array<{
id: string;
email: string;
assignedAt: Date;
assignedBy: {
id: string;
firstName: string;
lastName: string;
email: string;
};
}>;
@ApiPropertyOptional({
description: 'Number of comments on this occurrence', description: 'Number of comments on this occurrence',
example: 5, example: 5,
}) })
......
...@@ -16,6 +16,7 @@ export class OccurrenceLogService { ...@@ -16,6 +16,7 @@ export class OccurrenceLogService {
performedBy: string, performedBy: string,
oldValue?: string, oldValue?: string,
newValue?: string, newValue?: string,
status?: string,
): Promise<void> { ): Promise<void> {
const logId = this.drizzle.generateId(); const logId = this.drizzle.generateId();
...@@ -27,6 +28,7 @@ export class OccurrenceLogService { ...@@ -27,6 +28,7 @@ export class OccurrenceLogService {
oldValue: oldValue || null, oldValue: oldValue || null,
newValue: newValue || null, newValue: newValue || null,
performedBy, performedBy,
status: status || null,
}); });
} }
...@@ -40,6 +42,7 @@ export class OccurrenceLogService { ...@@ -40,6 +42,7 @@ export class OccurrenceLogService {
oldValue: occurrenceLogs.oldValue, oldValue: occurrenceLogs.oldValue,
newValue: occurrenceLogs.newValue, newValue: occurrenceLogs.newValue,
performedBy: occurrenceLogs.performedBy, performedBy: occurrenceLogs.performedBy,
status: occurrenceLogs.status,
createdAt: occurrenceLogs.createdAt, createdAt: occurrenceLogs.createdAt,
performedByUser: { performedByUser: {
id: users.id, id: users.id,
...@@ -61,6 +64,7 @@ export class OccurrenceLogService { ...@@ -61,6 +64,7 @@ export class OccurrenceLogService {
oldValue: log.oldValue, oldValue: log.oldValue,
newValue: log.newValue, newValue: log.newValue,
performedBy: log.performedBy, performedBy: log.performedBy,
status: log.status,
createdAt: log.createdAt, createdAt: log.createdAt,
performedByUser: log.performedByUser || undefined, performedByUser: log.performedByUser || undefined,
})); }));
...@@ -240,4 +244,38 @@ export class OccurrenceLogService { ...@@ -240,4 +244,38 @@ export class OccurrenceLogService {
performedBy, performedBy,
); );
} }
async logAssistantAssigned(
occurrenceId: string,
performedBy: string,
assistantName: string,
status?: string,
): Promise<void> {
await this.createLog(
occurrenceId,
'ASSISTANT_ASSIGNED',
`Assistant ${assistantName} was assigned to the occurrence`,
performedBy,
undefined,
undefined,
status,
);
}
async logAssistantUnassigned(
occurrenceId: string,
performedBy: string,
assistantName: string,
status?: string,
): Promise<void> {
await this.createLog(
occurrenceId,
'ASSISTANT_UNASSIGNED',
`Assistant ${assistantName} was unassigned from the occurrence`,
performedBy,
undefined,
undefined,
status,
);
}
} }
...@@ -27,6 +27,8 @@ import { UpdateOccurrenceDto } from './dto/update-occurrence.dto'; ...@@ -27,6 +27,8 @@ import { UpdateOccurrenceDto } from './dto/update-occurrence.dto';
import { OccurrenceResponseDto } from './dto/occurrence-response.dto'; import { OccurrenceResponseDto } from './dto/occurrence-response.dto';
import { AssignOccurrenceDto } from './dto/assign-occurrence.dto'; import { AssignOccurrenceDto } from './dto/assign-occurrence.dto';
import { DualAssignOccurrenceDto } from './dto/dual-assign-occurrence.dto'; import { DualAssignOccurrenceDto } from './dto/dual-assign-occurrence.dto';
import { AssignAssistantDto } from './dto/assign-assistant.dto';
import { AssignMultipleAssistantsDto } from './dto/assign-multiple-assistants.dto';
import { LogResponseDto } from './dto/log-response.dto'; import { LogResponseDto } from './dto/log-response.dto';
import { import {
OccurrenceStatus, OccurrenceStatus,
...@@ -484,6 +486,117 @@ export class OccurrenceController { ...@@ -484,6 +486,117 @@ export class OccurrenceController {
return this.occurrenceService.unassignOccurrence(id, user.id); return this.occurrenceService.unassignOccurrence(id, user.id);
} }
@Patch(':id/assign-assistant')
@ApiOperation({
summary: 'Assign assistant to occurrence',
description:
'Assign an assistant to help with the occurrence. Available to all authenticated users.',
})
@ApiParam({
name: 'id',
description: 'Occurrence unique identifier',
example: 'clxyz123abc456def',
})
@ApiBody({ type: AssignAssistantDto })
@ApiResponse({
status: 200,
description: 'Assistant assigned successfully',
type: OccurrenceResponseDto,
})
@ApiResponse({
status: 404,
description: 'Occurrence not found',
})
@ApiResponse({
status: 400,
description: 'Assistant not found',
})
async assignAssistant(
@Param('id') id: string,
@Body() assignAssistantDto: AssignAssistantDto,
@CurrentUser() user: UserResponseDto,
): Promise<OccurrenceResponseDto> {
return this.occurrenceService.assignAssistant(
id,
assignAssistantDto,
user.id,
);
}
@Patch(':id/assign-multiple-assistants')
@ApiOperation({
summary: 'Assign multiple assistants to occurrence',
description:
'Assign multiple assistants to help with the occurrence in a single request. Available to all authenticated users.',
})
@ApiParam({
name: 'id',
description: 'Occurrence unique identifier',
example: 'clxyz123abc456def',
})
@ApiBody({ type: AssignMultipleAssistantsDto })
@ApiResponse({
status: 200,
description: 'Assistants assigned successfully',
type: OccurrenceResponseDto,
})
@ApiResponse({
status: 404,
description: 'Occurrence not found',
})
@ApiResponse({
status: 400,
description: 'One or more assistants not found or already assigned',
})
async assignMultipleAssistants(
@Param('id') id: string,
@Body() assignMultipleAssistantsDto: AssignMultipleAssistantsDto,
@CurrentUser() user: UserResponseDto,
): Promise<OccurrenceResponseDto> {
return this.occurrenceService.assignMultipleAssistants(
id,
assignMultipleAssistantsDto,
user.id,
);
}
@Patch(':id/unassign-assistant/:assistantId')
@ApiOperation({
summary: 'Unassign assistant from occurrence',
description:
'Remove a specific assistant from the occurrence. Available to all authenticated users.',
})
@ApiParam({
name: 'id',
description: 'Occurrence unique identifier',
example: 'clxyz123abc456def',
})
@ApiParam({
name: 'assistantId',
description: 'Assistant unique identifier',
example: 'clxyz789def012ghi',
})
@ApiResponse({
status: 200,
description: 'Assistant unassigned successfully',
type: OccurrenceResponseDto,
})
@ApiResponse({
status: 404,
description: 'Occurrence not found',
})
@ApiResponse({
status: 400,
description: 'Assistant is not assigned to this occurrence',
})
async unassignAssistant(
@Param('id') id: string,
@Param('assistantId') assistantId: string,
@CurrentUser() user: UserResponseDto,
): Promise<OccurrenceResponseDto> {
return this.occurrenceService.unassignAssistant(id, assistantId, user.id);
}
@Delete(':id') @Delete(':id')
@HttpCode(HttpStatus.NO_CONTENT) @HttpCode(HttpStatus.NO_CONTENT)
@ApiOperation({ summary: 'Delete occurrence by ID' }) @ApiOperation({ summary: 'Delete occurrence by ID' })
......
...@@ -22,6 +22,8 @@ import { ...@@ -22,6 +22,8 @@ import {
comments, comments,
attachments, attachments,
conclusions, conclusions,
assistants,
occurrenceAssistants,
} from '../../drizzle/schema'; } from '../../drizzle/schema';
import { eq, and, or, like, desc, count, sql } from 'drizzle-orm'; import { eq, and, or, like, desc, count, sql } from 'drizzle-orm';
...@@ -45,6 +47,9 @@ export class OccurrenceService { ...@@ -45,6 +47,9 @@ export class OccurrenceService {
priority: occurrences.priority, priority: occurrences.priority,
category: occurrences.category, category: occurrences.category,
location: occurrences.location, location: occurrences.location,
latitude: occurrences.latitude,
longitude: occurrences.longitude,
reference: occurrences.reference,
reporterId: occurrences.reporterId, reporterId: occurrences.reporterId,
assigneeId: occurrences.assigneeId, assigneeId: occurrences.assigneeId,
managerId: occurrences.managerId, managerId: occurrences.managerId,
...@@ -101,6 +106,24 @@ export class OccurrenceService { ...@@ -101,6 +106,24 @@ export class OccurrenceService {
managedBy = manager; managedBy = manager;
} }
// Get assistants if any exist
const assistantsList = await this.drizzle.db
.select({
id: assistants.id,
email: assistants.email,
assignedAt: occurrenceAssistants.createdAt,
assignedBy: {
id: users.id,
firstName: users.firstName,
lastName: users.lastName,
email: users.email,
},
})
.from(occurrenceAssistants)
.leftJoin(assistants, eq(occurrenceAssistants.assistantId, assistants.id))
.leftJoin(users, eq(occurrenceAssistants.assignedBy, users.id))
.where(eq(occurrenceAssistants.occurrenceId, occurrenceId));
// Get conclusion if exists // Get conclusion if exists
const [conclusion] = await this.drizzle.db const [conclusion] = await this.drizzle.db
.select() .select()
...@@ -124,6 +147,7 @@ export class OccurrenceService { ...@@ -124,6 +147,7 @@ export class OccurrenceService {
reportedBy: occurrence.reportedBy || undefined, reportedBy: occurrence.reportedBy || undefined,
assignedTo, assignedTo,
managedBy, managedBy,
assistants: assistantsList.length > 0 ? assistantsList : undefined,
conclusion: conclusion || undefined, conclusion: conclusion || undefined,
_count: { _count: {
comments: commentCount.count, comments: commentCount.count,
...@@ -224,6 +248,9 @@ export class OccurrenceService { ...@@ -224,6 +248,9 @@ export class OccurrenceService {
priority: occurrences.priority, priority: occurrences.priority,
category: occurrences.category, category: occurrences.category,
location: occurrences.location, location: occurrences.location,
latitude: occurrences.latitude,
longitude: occurrences.longitude,
reference: occurrences.reference,
reporterId: occurrences.reporterId, reporterId: occurrences.reporterId,
assigneeId: occurrences.assigneeId, assigneeId: occurrences.assigneeId,
managerId: occurrences.managerId, managerId: occurrences.managerId,
...@@ -286,11 +313,12 @@ export class OccurrenceService { ...@@ -286,11 +313,12 @@ export class OccurrenceService {
updateData.closedAt = new Date(); updateData.closedAt = new Date();
} }
// If status is being changed back to OPEN or IN_PROGRESS, clear closedAt // If status is being changed back to OPEN, IN_PROGRESS, or PAUSED, clear closedAt
if ( if (
updateOccurrenceDto.status && updateOccurrenceDto.status &&
(updateOccurrenceDto.status === OccurrenceStatusEnum.OPEN || (updateOccurrenceDto.status === OccurrenceStatusEnum.OPEN ||
updateOccurrenceDto.status === OccurrenceStatusEnum.IN_PROGRESS) updateOccurrenceDto.status === OccurrenceStatusEnum.IN_PROGRESS ||
updateOccurrenceDto.status === OccurrenceStatusEnum.PAUSED)
) { ) {
updateData.closedAt = null; updateData.closedAt = null;
} }
...@@ -427,6 +455,9 @@ export class OccurrenceService { ...@@ -427,6 +455,9 @@ export class OccurrenceService {
priority: occurrences.priority, priority: occurrences.priority,
category: occurrences.category, category: occurrences.category,
location: occurrences.location, location: occurrences.location,
latitude: occurrences.latitude,
longitude: occurrences.longitude,
reference: occurrences.reference,
reporterId: occurrences.reporterId, reporterId: occurrences.reporterId,
assigneeId: occurrences.assigneeId, assigneeId: occurrences.assigneeId,
managerId: occurrences.managerId, managerId: occurrences.managerId,
...@@ -634,4 +665,214 @@ export class OccurrenceService { ...@@ -634,4 +665,214 @@ export class OccurrenceService {
return this.getOccurrenceWithRelations(occurrenceId); return this.getOccurrenceWithRelations(occurrenceId);
} }
async assignAssistant(
occurrenceId: string,
assignAssistantDto: { assistantId: string },
performedBy: string,
): Promise<OccurrenceResponseDto> {
// Check if occurrence exists
await this.findOne(occurrenceId);
// Validate that assistant exists
const [assistant] = await this.drizzle.db
.select()
.from(assistants)
.where(eq(assistants.id, assignAssistantDto.assistantId))
.limit(1);
if (!assistant) {
throw new BadRequestException('Assistant not found');
}
// Check if assistant is already assigned to this occurrence
const [existingAssignment] = await this.drizzle.db
.select()
.from(occurrenceAssistants)
.where(
and(
eq(occurrenceAssistants.occurrenceId, occurrenceId),
eq(occurrenceAssistants.assistantId, assignAssistantDto.assistantId),
),
)
.limit(1);
if (existingAssignment) {
throw new BadRequestException(
'Assistant is already assigned to this occurrence',
);
}
// Create new assignment
const assignmentId = this.drizzle.generateId();
await this.drizzle.db.insert(occurrenceAssistants).values({
id: assignmentId,
occurrenceId: occurrenceId,
assistantId: assignAssistantDto.assistantId,
assignedBy: performedBy,
});
// Get current occurrence status for logging
const [currentOccurrence] = await this.drizzle.db
.select({ status: occurrences.status })
.from(occurrences)
.where(eq(occurrences.id, occurrenceId))
.limit(1);
// Log the assistant assignment
await this.logService.logAssistantAssigned(
occurrenceId,
performedBy,
assistant.email,
currentOccurrence?.status,
);
return this.getOccurrenceWithRelations(occurrenceId);
}
async unassignAssistant(
occurrenceId: string,
assistantId: string,
performedBy: string,
): Promise<OccurrenceResponseDto> {
// Check if occurrence exists
await this.findOne(occurrenceId);
// Check if assignment exists
const [assignment] = await this.drizzle.db
.select()
.from(occurrenceAssistants)
.where(
and(
eq(occurrenceAssistants.occurrenceId, occurrenceId),
eq(occurrenceAssistants.assistantId, assistantId),
),
)
.limit(1);
if (!assignment) {
throw new BadRequestException(
'Assistant is not assigned to this occurrence',
);
}
// Get assistant info for logging
const [assistant] = await this.drizzle.db
.select()
.from(assistants)
.where(eq(assistants.id, assistantId))
.limit(1);
// Remove assignment
await this.drizzle.db
.delete(occurrenceAssistants)
.where(
and(
eq(occurrenceAssistants.occurrenceId, occurrenceId),
eq(occurrenceAssistants.assistantId, assistantId),
),
);
// Get current occurrence status for logging
const [currentOccurrence] = await this.drizzle.db
.select({ status: occurrences.status })
.from(occurrences)
.where(eq(occurrences.id, occurrenceId))
.limit(1);
// Log the assistant unassignment
await this.logService.logAssistantUnassigned(
occurrenceId,
performedBy,
assistant?.email || 'Unknown Assistant',
currentOccurrence?.status,
);
return this.getOccurrenceWithRelations(occurrenceId);
}
async assignMultipleAssistants(
occurrenceId: string,
assignMultipleAssistantsDto: { assistantIds: string[] },
performedBy: string,
): Promise<OccurrenceResponseDto> {
// Check if occurrence exists
await this.findOne(occurrenceId);
// Validate that all assistants exist
const foundAssistants = await this.drizzle.db
.select()
.from(assistants)
.where(
or(
...assignMultipleAssistantsDto.assistantIds.map((id) =>
eq(assistants.id, id),
),
),
);
if (
foundAssistants.length !== assignMultipleAssistantsDto.assistantIds.length
) {
const foundIds = foundAssistants.map((a) => a.id);
const missingIds = assignMultipleAssistantsDto.assistantIds.filter(
(id) => !foundIds.includes(id),
);
throw new BadRequestException(
`Assistants not found: ${missingIds.join(', ')}`,
);
}
// Check for existing assignments
const existingAssignments = await this.drizzle.db
.select()
.from(occurrenceAssistants)
.where(
and(
eq(occurrenceAssistants.occurrenceId, occurrenceId),
or(
...assignMultipleAssistantsDto.assistantIds.map((id) =>
eq(occurrenceAssistants.assistantId, id),
),
),
),
);
if (existingAssignments.length > 0) {
const alreadyAssignedIds = existingAssignments.map((a) => a.assistantId);
throw new BadRequestException(
`Assistants already assigned: ${alreadyAssignedIds.join(', ')}`,
);
}
// Create all assignments
const assignments = assignMultipleAssistantsDto.assistantIds.map(
(assistantId) => ({
id: this.drizzle.generateId(),
occurrenceId: occurrenceId,
assistantId: assistantId,
assignedBy: performedBy,
}),
);
await this.drizzle.db.insert(occurrenceAssistants).values(assignments);
// Get current occurrence status for logging
const [currentOccurrence] = await this.drizzle.db
.select({ status: occurrences.status })
.from(occurrences)
.where(eq(occurrences.id, occurrenceId))
.limit(1);
// Log the bulk assignment
const assistantEmails = foundAssistants.map((a) => a.email).join(', ');
await this.logService.logAssistantAssigned(
occurrenceId,
performedBy,
`Multiple Assistants: ${assistantEmails}`,
currentOccurrence?.status,
);
return this.getOccurrenceWithRelations(occurrenceId);
}
} }
...@@ -4,6 +4,7 @@ export type OccurrenceStatus = ...@@ -4,6 +4,7 @@ export type OccurrenceStatus =
| 'OPEN' | 'OPEN'
| 'IN_PROGRESS' | 'IN_PROGRESS'
| 'RESOLVED' | 'RESOLVED'
| 'PAUSED'
| 'CLOSED' | 'CLOSED'
| 'PARCIAL_RESOLVED' | 'PARCIAL_RESOLVED'
| 'CANCELLED'; | 'CANCELLED';
...@@ -21,6 +22,8 @@ export type LogAction = ...@@ -21,6 +22,8 @@ export type LogAction =
| 'ATTACHMENT_REMOVED' | 'ATTACHMENT_REMOVED'
| 'CONCLUSION_ADDED' | 'CONCLUSION_ADDED'
| 'CONCLUSION_UPDATED' | 'CONCLUSION_UPDATED'
| 'ASSISTANT_ASSIGNED'
| 'ASSISTANT_UNASSIGNED'
| 'DELETED'; | 'DELETED';
// Enum constants for runtime usage // Enum constants for runtime usage
...@@ -34,6 +37,7 @@ export const OccurrenceStatusEnum = { ...@@ -34,6 +37,7 @@ export const OccurrenceStatusEnum = {
OPEN: 'OPEN' as const, OPEN: 'OPEN' as const,
IN_PROGRESS: 'IN_PROGRESS' as const, IN_PROGRESS: 'IN_PROGRESS' as const,
RESOLVED: 'RESOLVED' as const, RESOLVED: 'RESOLVED' as const,
PAUSED: 'PAUSED' as const,
CLOSED: 'CLOSED' as const, CLOSED: 'CLOSED' as const,
PARCIAL_RESOLVED: 'PARCIAL_RESOLVED' as const, PARCIAL_RESOLVED: 'PARCIAL_RESOLVED' as const,
CANCELLED: 'CANCELLED' as const, CANCELLED: 'CANCELLED' as const,
...@@ -59,5 +63,7 @@ export const LogActionEnum = { ...@@ -59,5 +63,7 @@ export const LogActionEnum = {
ATTACHMENT_REMOVED: 'ATTACHMENT_REMOVED' as const, ATTACHMENT_REMOVED: 'ATTACHMENT_REMOVED' as const,
CONCLUSION_ADDED: 'CONCLUSION_ADDED' as const, CONCLUSION_ADDED: 'CONCLUSION_ADDED' as const,
CONCLUSION_UPDATED: 'CONCLUSION_UPDATED' as const, CONCLUSION_UPDATED: 'CONCLUSION_UPDATED' as const,
ASSISTANT_ASSIGNED: 'ASSISTANT_ASSIGNED' as const,
ASSISTANT_UNASSIGNED: 'ASSISTANT_UNASSIGNED' as const,
DELETED: 'DELETED' as const, DELETED: 'DELETED' as const,
} as const; } as const;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment