릴리스: v0.1.6 MariaDB 개발 환경 및 저장소 설정 정리
This commit is contained in:
64
backend/src/routes/admin.js
Normal file
64
backend/src/routes/admin.js
Normal file
@@ -0,0 +1,64 @@
|
||||
const path = require('path')
|
||||
const express = require('express')
|
||||
const multer = require('multer')
|
||||
const { z } = require('zod')
|
||||
const { nanoid } = require('nanoid')
|
||||
const {
|
||||
findGameById,
|
||||
createGame,
|
||||
updateGameThumbnail,
|
||||
createGameItem,
|
||||
} = require('../db')
|
||||
const { requireAdmin } = require('../middleware/auth')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
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', 'games')),
|
||||
filename: (req, file, cb) => cb(null, buildUploadFilename(file)),
|
||||
}),
|
||||
limits: { fileSize: 6 * 1024 * 1024 },
|
||||
})
|
||||
|
||||
router.post('/games', requireAdmin, async (req, res) => {
|
||||
const schema = z.object({ id: z.string().min(1), name: z.string().min(1).max(60) })
|
||||
const parsed = schema.safeParse(req.body)
|
||||
if (!parsed.success) return res.status(400).json({ error: 'bad_request' })
|
||||
const exists = await findGameById(parsed.data.id)
|
||||
if (exists) return res.status(409).json({ error: 'game_id_taken' })
|
||||
const game = await createGame({ id: parsed.data.id, name: parsed.data.name })
|
||||
res.json({ game })
|
||||
})
|
||||
|
||||
router.post('/games/:gameId/thumbnail', requireAdmin, upload.single('thumbnail'), async (req, res) => {
|
||||
if (!req.file) return res.status(400).json({ error: 'file_required' })
|
||||
const game = await findGameById(req.params.gameId)
|
||||
if (!game) return res.status(404).json({ error: 'not_found' })
|
||||
const updated = await updateGameThumbnail(req.params.gameId, `/uploads/games/${req.file.filename}`)
|
||||
res.json({ game: updated })
|
||||
})
|
||||
|
||||
router.post('/games/:gameId/images', requireAdmin, upload.single('image'), async (req, res) => {
|
||||
if (!req.file) return res.status(400).json({ error: 'file_required' })
|
||||
const schema = z.object({ label: z.string().min(1).max(60) })
|
||||
const parsed = schema.safeParse(req.body)
|
||||
if (!parsed.success) return res.status(400).json({ error: 'bad_request' })
|
||||
const game = await findGameById(req.params.gameId)
|
||||
if (!game) return res.status(404).json({ error: 'not_found' })
|
||||
const item = await createGameItem({
|
||||
id: nanoid(),
|
||||
gameId: game.id,
|
||||
src: `/uploads/games/${req.file.filename}`,
|
||||
label: parsed.data.label,
|
||||
})
|
||||
res.json({ item })
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
Reference in New Issue
Block a user