Add public curator notes and U-shaped hall wall hang.

Paintings get editable curator notes with brass plates in the 3D hall, and visit order now uses the far/end wall between left and right.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila Khodjaef
2026-07-25 14:21:22 +03:00
co-authored by Cursor
parent 5ddc3fd7f0
commit bc8369e373
29 changed files with 648 additions and 70 deletions
+39
View File
@@ -836,6 +836,45 @@ app.patch('/api/paintings/:id/checkup-flags', requireCurator, async (req, res) =
}
});
// Update public curator notes on a painting
app.patch('/api/paintings/:id/curator-notes', requireCurator, async (req, res) => {
try {
const paintingId = parseInt(req.params.id, 10);
if (!Number.isFinite(paintingId)) {
return res.status(400).json({ error: 'Invalid painting id' });
}
if (typeof req.body?.curatorNotes !== 'string') {
return res.status(400).json({ error: 'curatorNotes must be a string' });
}
const curatorNotes = req.body.curatorNotes.trim();
const result = await pool.query(
`UPDATE paintings SET curator_notes = $2
WHERE id = $1
RETURNING curator_notes`,
[paintingId, curatorNotes]
);
if (result.rows.length === 0) {
return res.status(404).json({ error: 'Painting not found' });
}
res.json({ curatorNotes: result.rows[0].curator_notes ?? '' });
await logCuratorAction({
userId: req.curatorUser.id,
action: 'painting.update_curator_notes',
resourceType: 'painting',
resourceId: paintingId,
details: { length: curatorNotes.length },
req,
});
} catch (err) {
console.error('Curator notes update error:', err.message);
res.status(500).json({ error: 'Failed to update curator notes' });
}
});
// Painting detail with influences
app.get('/api/paintings/:id', async (req, res) => {
try {