feat: add immutable level template lifecycle
This commit is contained in:
+26
-1
@@ -23,6 +23,9 @@ const levels = createLevelRepository(pool, editingEnabled)
|
||||
function wantsEdit(req: express.Request) {
|
||||
return editingEnabled && req.query.edit === '1'
|
||||
}
|
||||
function slug(value: unknown, fallback: string) {
|
||||
return String(value || fallback).trim().toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '')
|
||||
}
|
||||
|
||||
export const app = express()
|
||||
app.disable('x-powered-by')
|
||||
@@ -41,14 +44,36 @@ app.get('/api/levels', async (_req, res, next) => {
|
||||
try { res.json(await levels.listLevels()) }
|
||||
catch (error) { next(error) }
|
||||
})
|
||||
app.get('/api/templates', async (_req, res, next) => {
|
||||
try { res.json(await levels.listTemplates()) }
|
||||
catch (error) { next(error) }
|
||||
})
|
||||
app.post('/api/templates/:slug/levels', async (req, res, next) => {
|
||||
try {
|
||||
if (!wantsEdit(req)) return res.status(403).json({ error: 'Level editing is disabled' })
|
||||
const title = String(req.body?.title || '').trim() || undefined
|
||||
const levelSlug = slug(req.body?.id, `${req.params.slug}-${Date.now()}`)
|
||||
const level = await levels.instantiateTemplate(req.params.slug, { id: levelSlug, title, version: req.body?.version })
|
||||
level ? res.status(201).json(level) : res.status(404).json({ error: 'Template version not found' })
|
||||
} catch (error) { next(error) }
|
||||
})
|
||||
app.post('/api/levels', async (req, res, next) => {
|
||||
try {
|
||||
if (!editingEnabled) return res.status(403).json({ error: 'Level editing is disabled' })
|
||||
const title = String(req.body?.title || 'Untitled Investigation').trim()
|
||||
const id = String(req.body?.id || `level-${Date.now()}`).trim().toLowerCase().replace(/[^a-z0-9-]+/g, '-')
|
||||
const id = slug(req.body?.id, `level-${Date.now()}`)
|
||||
res.status(201).json(await levels.createLevel({ id, title, subtitle: String(req.body?.subtitle || '') }))
|
||||
} catch (error) { next(error) }
|
||||
})
|
||||
app.post('/api/levels/:id/templates', async (req, res, next) => {
|
||||
try {
|
||||
if (!wantsEdit(req)) return res.status(403).json({ error: 'Level editing is disabled' })
|
||||
const name = String(req.body?.name || 'Untitled Template').trim()
|
||||
const templateSlug = slug(req.body?.slug, name)
|
||||
const template = await levels.saveLevelAsTemplate(req.params.id, { slug: templateSlug, name })
|
||||
template ? res.status(201).json(template) : res.status(404).json({ error: 'Level not found' })
|
||||
} catch (error) { next(error) }
|
||||
})
|
||||
app.get('/api/assets/:id', async (req, res, next) => {
|
||||
try {
|
||||
const asset = await levels.getAsset(req.params.id)
|
||||
|
||||
Reference in New Issue
Block a user