Improve movement flow layout/animation and fix Byzantine hall doors, styles, and preload.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila Khodjaef
2026-07-28 20:36:55 +03:00
co-authored by Cursor
parent 23e1210e86
commit 8111cd0163
13 changed files with 632 additions and 166 deletions
+23 -3
View File
@@ -12,7 +12,7 @@ const { requirePermission } = require('./middleware/auth');
const { logCuratorAction } = require('./audit-log');
const authRoutes = require('./routes/auth');
const usersRoutes = require('./routes/users');
const { ensurePaintingImages, preloadArtistImagesLocal, replacePaintingImageFromUrl, replaceArtistPortraitFromUrl, clearPaintingImage, deletePainting, clearArtistPortrait, replacePaintingImageFromBuffer, replaceArtistPortraitFromBuffer, enrichPaintingRow, enrichArtistRow, IMAGE_DIR } = require('./image-service');
const { ensurePaintingImages, preloadArtistImagesLocal, preloadMovementImagesLocal, replacePaintingImageFromUrl, replaceArtistPortraitFromUrl, clearPaintingImage, deletePainting, clearArtistPortrait, replacePaintingImageFromBuffer, replaceArtistPortraitFromBuffer, enrichPaintingRow, enrichArtistRow, IMAGE_DIR } = require('./image-service');
const { getVersionInfo } = require('./version-info');
const { searchCatalog } = require('./search-service');
const {
@@ -90,10 +90,18 @@ async function fetchTimelineErasAndMovements(startYear, endYear) {
[startYear, endYear]
),
pool.query(
`SELECT DISTINCT m.*, e.name as era_name
`SELECT DISTINCT m.*, e.name as era_name,
COALESCE(ic.link_count, 0)::int AS influence_link_count
FROM art_movements m
LEFT JOIN historical_eras e ON m.era_id = e.id
INNER JOIN artists a ON a.movement_id = m.id
LEFT JOIN (
SELECT a2.movement_id, COUNT(pis.id)::int AS link_count
FROM painting_influence_sources pis
JOIN paintings p ON p.id = pis.painting_id
JOIN artists a2 ON a2.id = p.artist_id
GROUP BY a2.movement_id
) ic ON ic.movement_id = m.id
WHERE m.end_year >= $1 AND m.start_year <= $2
AND (a.death_year IS NULL OR a.death_year >= $1)
AND (a.birth_year IS NULL OR a.birth_year <= $2)
@@ -126,7 +134,8 @@ async function catalogBootstrapEtag() {
(SELECT COUNT(*)::int FROM artists) AS artist_count,
(SELECT COUNT(*)::int FROM art_movements) AS movement_count,
(SELECT COUNT(*)::int FROM historical_eras) AS era_count,
(SELECT COUNT(*)::int FROM paintings) AS painting_count
(SELECT COUNT(*)::int FROM paintings) AS painting_count,
(SELECT COUNT(*)::int FROM painting_influence_sources) AS influence_count
`);
return result.rows[0];
}
@@ -942,6 +951,17 @@ app.post('/api/artists/:id/preload-images', async (req, res) => {
}
});
app.post('/api/movements/:id/preload-images', async (req, res) => {
try {
const movementId = parseInt(req.params.id, 10);
const result = await preloadMovementImagesLocal(movementId);
res.json(result);
} catch (err) {
console.error('Movement preload error:', err.message);
res.status(500).json({ error: 'Preload failed' });
}
});
// Developer debug: Google Images first result for image audit
app.get('/api/paintings/:id/debug-image-search/more', requirePermission('images'), async (req, res) => {
try {