Fix parent messaging — allow sending to any student, not just those who messaged first

- Replace reply-by-message-ID endpoint with POST /api/admin/messages/:studentId so parent can send without a prior message existing
- Switch GET /api/admin/messages to LEFT JOIN so all students appear in the thread list, not just those who have sent messages
- Remove guard that blocked sending when no messages existed in the thread

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-08-20 13:37:08 -04:00
1 parent 556b570b60
commit 3a018a97bb
2 files changed
+9 -11

No files matched your search

+2 -3
View File
@@ -2018,13 +2018,12 @@ async function openAdminThread(studentId, meta) {
const input = $('#msg-admin-input');
const body = input.value.trim();
if (!body) return;
const lastMsgId = msgs[msgs.length - 1]?.id;
if (!lastMsgId) return;
input.value = '';
await api(`/api/messages/${lastMsgId}/reply`, { method: 'POST', body: { body } });
await api(`/api/admin/messages/${studentId}`, { method: 'POST', body: { body } });
const updated = await api(`/api/admin/messages/${studentId}`);
msgsEl.innerHTML = renderAdminMsgs(updated);
msgsEl.scrollTop = msgsEl.scrollHeight;
loadMessages();
loadMessagesBadge();
});
}
+7 -8
View File
@@ -1773,13 +1773,12 @@ app.post('/api/students/:id/messages', (req, res) => {
res.json({ id: lastInsertRowid });
});
app.post('/api/messages/:id/reply', requirePin, (req, res) => {
app.post('/api/admin/messages/:studentId', requirePin, (req, res) => {
const body = String(req.body.body || '').trim();
if (!body) return res.status(400).json({ error: 'Reply cannot be empty' });
const msg = db.prepare(`SELECT student_id FROM messages WHERE id = ?`).get(req.params.id);
if (!msg) return res.status(404).json({ error: 'No such message' });
const { lastInsertRowid } = db.prepare(`INSERT INTO messages (student_id, sender, body) VALUES (?, 'parent', ?)`).run(msg.student_id, body);
db.prepare(`UPDATE messages SET read_at = datetime('now') WHERE id = ?`).run(req.params.id);
if (!body) return res.status(400).json({ error: 'Message cannot be empty' });
const student = db.prepare(`SELECT id FROM students WHERE id = ?`).get(req.params.studentId);
if (!student) return res.status(404).json({ error: 'No such student' });
const { lastInsertRowid } = db.prepare(`INSERT INTO messages (student_id, sender, body) VALUES (?, 'parent', ?)`).run(req.params.studentId, body);
res.json({ id: lastInsertRowid });
});
@@ -1790,9 +1789,9 @@ app.get('/api/admin/messages', requirePin, (req, res) => {
MAX(m.sent_at) AS lastAt,
(SELECT body FROM messages WHERE student_id = s.id ORDER BY sent_at DESC LIMIT 1) AS lastBody
FROM students s
JOIN messages m ON m.student_id = s.id
LEFT JOIN messages m ON m.student_id = s.id
GROUP BY s.id
ORDER BY lastAt DESC
ORDER BY lastAt DESC NULLS LAST
`).all();
res.json(threads);
});