feat: Implement user tracking in projects
- Added user tracking features to the projects module, including: - Database schema updates to track project creator and assignee. - API enhancements for user management and project filtering by user. - UI components for user assignment in project forms and listings. - New query functions for retrieving users and filtering projects. - Security integration with role-based access and authentication requirements. chore: Create utility scripts for database checks and project testing - Added scripts to check the structure of the projects table. - Created tests for project creation and user tracking functionality. - Implemented API tests to verify project retrieval and user assignment. fix: Update project creation and update functions to include user tracking - Modified createProject and updateProject functions to handle user IDs for creator and assignee. - Ensured that project updates reflect the correct user assignments and timestamps.
This commit is contained in:
@@ -1,21 +1,48 @@
|
||||
import db from "../db.js";
|
||||
|
||||
export function getAllProjects(contractId = null) {
|
||||
const baseQuery = `
|
||||
SELECT
|
||||
p.*,
|
||||
creator.name as created_by_name,
|
||||
creator.email as created_by_email,
|
||||
assignee.name as assigned_to_name,
|
||||
assignee.email as assigned_to_email
|
||||
FROM projects p
|
||||
LEFT JOIN users creator ON p.created_by = creator.id
|
||||
LEFT JOIN users assignee ON p.assigned_to = assignee.id
|
||||
`;
|
||||
|
||||
if (contractId) {
|
||||
return db
|
||||
.prepare(
|
||||
"SELECT * FROM projects WHERE contract_id = ? ORDER BY finish_date DESC"
|
||||
baseQuery + " WHERE p.contract_id = ? ORDER BY p.finish_date DESC"
|
||||
)
|
||||
.all(contractId);
|
||||
}
|
||||
return db.prepare("SELECT * FROM projects ORDER BY finish_date DESC").all();
|
||||
return db.prepare(baseQuery + " ORDER BY p.finish_date DESC").all();
|
||||
}
|
||||
|
||||
export function getProjectById(id) {
|
||||
return db.prepare("SELECT * FROM projects WHERE project_id = ?").get(id);
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
SELECT
|
||||
p.*,
|
||||
creator.name as created_by_name,
|
||||
creator.email as created_by_email,
|
||||
assignee.name as assigned_to_name,
|
||||
assignee.email as assigned_to_email
|
||||
FROM projects p
|
||||
LEFT JOIN users creator ON p.created_by = creator.id
|
||||
LEFT JOIN users assignee ON p.assigned_to = assignee.id
|
||||
WHERE p.project_id = ?
|
||||
`
|
||||
)
|
||||
.get(id);
|
||||
}
|
||||
|
||||
export function createProject(data) {
|
||||
export function createProject(data, userId = null) {
|
||||
// 1. Get the contract number and count existing projects
|
||||
const contractInfo = db
|
||||
.prepare(
|
||||
@@ -37,12 +64,16 @@ export function createProject(data) {
|
||||
|
||||
// 2. Generate sequential number and project number
|
||||
const sequentialNumber = (contractInfo.project_count || 0) + 1;
|
||||
const projectNumber = `${sequentialNumber}/${contractInfo.contract_number}`; const stmt = db.prepare(`
|
||||
const projectNumber = `${sequentialNumber}/${contractInfo.contract_number}`;
|
||||
|
||||
const stmt = db.prepare(`
|
||||
INSERT INTO projects (
|
||||
contract_id, project_name, project_number, address, plot, district, unit, city, investment_number, finish_date,
|
||||
wp, contact, notes, project_type, project_status, coordinates
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);stmt.run(
|
||||
wp, contact, notes, project_type, project_status, coordinates, created_by, assigned_to, created_at, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||
`);
|
||||
|
||||
const result = stmt.run(
|
||||
data.contract_id,
|
||||
data.project_name,
|
||||
projectNumber,
|
||||
@@ -55,16 +86,23 @@ export function createProject(data) {
|
||||
data.finish_date,
|
||||
data.wp,
|
||||
data.contact,
|
||||
data.notes, data.project_type || "design",
|
||||
data.notes,
|
||||
data.project_type || "design",
|
||||
data.project_status || "registered",
|
||||
data.coordinates || null
|
||||
data.coordinates || null,
|
||||
userId,
|
||||
data.assigned_to || null
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function updateProject(id, data) { const stmt = db.prepare(`
|
||||
export function updateProject(id, data, userId = null) {
|
||||
const stmt = db.prepare(`
|
||||
UPDATE projects SET
|
||||
contract_id = ?, project_name = ?, project_number = ?, address = ?, plot = ?, district = ?, unit = ?, city = ?,
|
||||
investment_number = ?, finish_date = ?, wp = ?, contact = ?, notes = ?, project_type = ?, project_status = ?, coordinates = ?
|
||||
investment_number = ?, finish_date = ?, wp = ?, contact = ?, notes = ?, project_type = ?, project_status = ?,
|
||||
coordinates = ?, assigned_to = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE project_id = ?
|
||||
`);
|
||||
stmt.run(
|
||||
@@ -80,9 +118,11 @@ export function updateProject(id, data) { const stmt = db.prepare(`
|
||||
data.finish_date,
|
||||
data.wp,
|
||||
data.contact,
|
||||
data.notes, data.project_type || "design",
|
||||
data.notes,
|
||||
data.project_type || "design",
|
||||
data.project_status || "registered",
|
||||
data.coordinates || null,
|
||||
data.assigned_to || null,
|
||||
id
|
||||
);
|
||||
}
|
||||
@@ -91,6 +131,75 @@ export function deleteProject(id) {
|
||||
db.prepare("DELETE FROM projects WHERE project_id = ?").run(id);
|
||||
}
|
||||
|
||||
// Get all users for assignment dropdown
|
||||
export function getAllUsersForAssignment() {
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
SELECT id, name, email, role
|
||||
FROM users
|
||||
WHERE is_active = 1
|
||||
ORDER BY name
|
||||
`
|
||||
)
|
||||
.all();
|
||||
}
|
||||
|
||||
// Get projects assigned to a specific user
|
||||
export function getProjectsByAssignedUser(userId) {
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
SELECT
|
||||
p.*,
|
||||
creator.name as created_by_name,
|
||||
creator.email as created_by_email,
|
||||
assignee.name as assigned_to_name,
|
||||
assignee.email as assigned_to_email
|
||||
FROM projects p
|
||||
LEFT JOIN users creator ON p.created_by = creator.id
|
||||
LEFT JOIN users assignee ON p.assigned_to = assignee.id
|
||||
WHERE p.assigned_to = ?
|
||||
ORDER BY p.finish_date DESC
|
||||
`
|
||||
)
|
||||
.all(userId);
|
||||
}
|
||||
|
||||
// Get projects created by a specific user
|
||||
export function getProjectsByCreator(userId) {
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
SELECT
|
||||
p.*,
|
||||
creator.name as created_by_name,
|
||||
creator.email as created_by_email,
|
||||
assignee.name as assigned_to_name,
|
||||
assignee.email as assigned_to_email
|
||||
FROM projects p
|
||||
LEFT JOIN users creator ON p.created_by = creator.id
|
||||
LEFT JOIN users assignee ON p.assigned_to = assignee.id
|
||||
WHERE p.created_by = ?
|
||||
ORDER BY p.finish_date DESC
|
||||
`
|
||||
)
|
||||
.all(userId);
|
||||
}
|
||||
|
||||
// Update project assignment
|
||||
export function updateProjectAssignment(projectId, assignedToUserId) {
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
UPDATE projects
|
||||
SET assigned_to = ?, updated_at = CURRENT_TIMESTAMP
|
||||
WHERE project_id = ?
|
||||
`
|
||||
)
|
||||
.run(assignedToUserId, projectId);
|
||||
}
|
||||
|
||||
export function getProjectWithContract(id) {
|
||||
return db
|
||||
.prepare(
|
||||
|
||||
Reference in New Issue
Block a user