업로드 이미지 WebP 최적화 1차 적용

This commit is contained in:
2026-03-31 17:33:52 +09:00
parent ebe7a4408f
commit d760c7331a
7 changed files with 694 additions and 66 deletions

View File

@@ -1,5 +1,4 @@
const express = require('express')
const path = require('path')
const multer = require('multer')
const { z } = require('zod')
const { nanoid } = require('nanoid')
@@ -18,6 +17,7 @@ const {
duplicateTierListForUser,
} = require('../db')
const { requireAuth } = require('../middleware/auth')
const { createMemoryUpload, writeOptimizedImage } = require('../lib/image-storage')
const router = express.Router()
const FREEFORM_GAME_ID = 'freeform'
@@ -55,27 +55,8 @@ function getCustomTemplateItems(tierList) {
})
}
function buildUploadFilename(file) {
const ext = path.extname(file.originalname || '').toLowerCase()
const safeExt = ext && /^[.a-z0-9]+$/.test(ext) ? ext : ''
return `${Date.now()}-${nanoid()}${safeExt}`
}
const upload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => cb(null, path.join(__dirname, '..', '..', 'uploads', 'custom')),
filename: (req, file, cb) => cb(null, buildUploadFilename(file)),
}),
limits: { fileSize: 6 * 1024 * 1024 },
})
const thumbnailUpload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => cb(null, path.join(__dirname, '..', '..', 'uploads', 'tierlists')),
filename: (req, file, cb) => cb(null, buildUploadFilename(file)),
}),
limits: { fileSize: 6 * 1024 * 1024 },
})
const upload = createMemoryUpload(multer, { fileSize: 6 * 1024 * 1024 })
const thumbnailUpload = createMemoryUpload(multer, { fileSize: 8 * 1024 * 1024 })
const tierListUpsertSchema = z.object({
id: z.string().optional(),
@@ -179,10 +160,19 @@ router.post('/custom-items', requireAuth, upload.single('image'), async (req, re
const parsed = schema.safeParse(req.body)
if (!parsed.success) return res.status(400).json({ error: 'bad_request' })
const optimized = await writeOptimizedImage({
file: req.file,
directory: 'custom',
width: 512,
height: 512,
fit: 'inside',
quality: 84,
})
const item = await createCustomItem({
id: nanoid(),
ownerId: req.session.userId,
src: `/uploads/custom/${req.file.filename}`,
src: optimized.src,
label: parsed.data.label,
})
@@ -191,7 +181,17 @@ router.post('/custom-items', requireAuth, upload.single('image'), async (req, re
router.post('/thumbnail', requireAuth, thumbnailUpload.single('thumbnail'), async (req, res) => {
if (!req.file) return res.status(400).json({ error: 'file_required' })
res.json({ thumbnailSrc: `/uploads/tierlists/${req.file.filename}` })
const optimized = await writeOptimizedImage({
file: req.file,
directory: 'tierlists',
width: 1280,
height: 1280,
fit: 'inside',
quality: 84,
})
res.json({ thumbnailSrc: optimized.src })
})
router.post('/:id/template-request', requireAuth, async (req, res) => {