릴리스: v1.4.35 에디터 검색과 공유 프리뷰 보강

This commit is contained in:
2026-04-03 01:06:30 +09:00
parent 15c03835ef
commit 5eb08e1757
7 changed files with 185 additions and 24 deletions

View File

@@ -212,28 +212,57 @@ router.post('/templates/:templateId/images', requireAdmin, upload.array('images'
const labels = Array.isArray(labelsRaw) ? labelsRaw : labelsRaw ? [labelsRaw] : []
const normalizedLabels = labels.map((label) => (typeof label === 'string' ? label.trim().slice(0, 60) : ''))
if (normalizedLabels.some((label) => label.length > 60)) return res.status(400).json({ error: 'bad_request' })
const totalBytes = files.reduce((sum, file) => sum + Number(file?.size || 0), 0)
const items = await Promise.all(
files.map(async (file, index) => {
const optimized = await writeOptimizedImage({
file,
directory: 'topics',
width: 512,
height: 512,
fit: 'inside',
quality: 84,
})
console.info('[admin] template image upload start', {
templateId: template.id,
fileCount: files.length,
totalBytes,
fileNames: files.map((file) => file.originalname),
})
return createTopicItem({
id: nanoid(),
topicId: template.id,
src: optimized.src,
label: normalizedLabels[index] || buildItemLabelFromFilename(file),
try {
const items = await Promise.all(
files.map(async (file, index) => {
const optimized = await writeOptimizedImage({
file,
directory: 'topics',
width: 512,
height: 512,
fit: 'inside',
quality: 84,
})
return createTopicItem({
id: nanoid(),
topicId: template.id,
src: optimized.src,
label: normalizedLabels[index] || buildItemLabelFromFilename(file),
})
})
)
console.info('[admin] template image upload success', {
templateId: template.id,
fileCount: items.length,
totalBytes,
})
)
res.json({ item: items[0], items })
res.json({ item: items[0], items })
} catch (error) {
console.error('[admin] template image upload failed', {
templateId: template.id,
fileCount: files.length,
totalBytes,
message: error?.message || 'upload_failed',
code: error?.code || '',
stack: error?.stack || '',
})
res.status(500).json({
error: 'template_image_upload_failed',
detail: error?.message || 'upload_failed',
})
}
})
router.delete('/templates/:templateId/items/:itemId', requireAdmin, async (req, res) => {