Upload files to "/" #19

Merged
jason merged 1 commits from p4-hotfixes into master 2026-03-06 18:00:01 -06:00

View File

@@ -70,7 +70,7 @@ app.get('/api/violations/employee/:id', (req, res) => {
res.json(rows); res.json(rows);
}); });
// NEW helper: compute prior_active_points at time of insert (excluding this violation) // Helper: compute prior_active_points at time of insert
function getPriorActivePoints(employeeId, incidentDate) { function getPriorActivePoints(employeeId, incidentDate) {
const row = db.prepare( const row = db.prepare(
`SELECT COALESCE(SUM(points),0) AS pts `SELECT COALESCE(SUM(points),0) AS pts
@@ -116,9 +116,63 @@ app.post('/api/violations', (req, res) => {
res.status(201).json({ id: result.lastInsertRowid }); res.status(201).json({ id: result.lastInsertRowid });
}); });
// Negate / restore / delete endpoints unchanged ... // ── Negate a violation ──────────────────────────────────────────────────────
app.patch('/api/violations/:id/negate', (req, res) => {
const { resolution_type, details, resolved_by } = req.body;
const id = req.params.id;
// PDF endpoint — use stored prior_active_points snapshot const violation = db.prepare('SELECT * FROM violations WHERE id = ?').get(id);
if (!violation) return res.status(404).json({ error: 'Violation not found' });
// Mark negated
db.prepare('UPDATE violations SET negated = 1 WHERE id = ?').run(id);
// Upsert resolution record
const existing = db.prepare('SELECT id FROM violation_resolutions WHERE violation_id = ?').get(id);
if (existing) {
db.prepare(`
UPDATE violation_resolutions
SET resolution_type = ?, details = ?, resolved_by = ?, created_at = datetime('now')
WHERE violation_id = ?
`).run(resolution_type || 'Resolved', details || null, resolved_by || null, id);
} else {
db.prepare(`
INSERT INTO violation_resolutions (violation_id, resolution_type, details, resolved_by)
VALUES (?, ?, ?, ?)
`).run(id, resolution_type || 'Resolved', details || null, resolved_by || null);
}
res.json({ success: true });
});
// ── Restore a negated violation ─────────────────────────────────────────────
app.patch('/api/violations/:id/restore', (req, res) => {
const id = req.params.id;
const violation = db.prepare('SELECT * FROM violations WHERE id = ?').get(id);
if (!violation) return res.status(404).json({ error: 'Violation not found' });
db.prepare('UPDATE violations SET negated = 0 WHERE id = ?').run(id);
db.prepare('DELETE FROM violation_resolutions WHERE violation_id = ?').run(id);
res.json({ success: true });
});
// ── Hard delete a violation ─────────────────────────────────────────────────
app.delete('/api/violations/:id', (req, res) => {
const id = req.params.id;
const violation = db.prepare('SELECT * FROM violations WHERE id = ?').get(id);
if (!violation) return res.status(404).json({ error: 'Violation not found' });
// Delete resolution first (FK safety)
db.prepare('DELETE FROM violation_resolutions WHERE violation_id = ?').run(id);
db.prepare('DELETE FROM violations WHERE id = ?').run(id);
res.json({ success: true });
});
// ── PDF endpoint ─────────────────────────────────────────────────────────────
app.get('/api/violations/:id/pdf', async (req, res) => { app.get('/api/violations/:id/pdf', async (req, res) => {
try { try {
const violation = db.prepare(` const violation = db.prepare(`
@@ -130,13 +184,11 @@ app.get('/api/violations/:id/pdf', async (req, res) => {
if (!violation) return res.status(404).json({ error: 'Violation not found' }); if (!violation) return res.status(404).json({ error: 'Violation not found' });
// For PDF, compute score row but pass stored prior_active_points so math is stable
const active = db.prepare('SELECT * FROM active_cpas_scores WHERE employee_id = ?') const active = db.prepare('SELECT * FROM active_cpas_scores WHERE employee_id = ?')
.get(violation.employee_id) || { active_points: 0, violation_count: 0 }; .get(violation.employee_id) || { active_points: 0, violation_count: 0 };
const scoreForPdf = { const scoreForPdf = {
employee_id: violation.employee_id, employee_id: violation.employee_id,
// snapshot at time of violation (if present); fall back to current
active_points: violation.prior_active_points != null ? violation.prior_active_points : active.active_points, active_points: violation.prior_active_points != null ? violation.prior_active_points : active.active_points,
violation_count: active.violation_count, violation_count: active.violation_count,
}; };