92 lines
3.9 KiB
JavaScript
92 lines
3.9 KiB
JavaScript
import { Router } from 'express'
|
|
import db from '../db.js'
|
|
import { auth } from '../middleware/auth.js'
|
|
|
|
const router = Router({ mergeParams: true })
|
|
router.use(auth)
|
|
|
|
function getStory(storyId, userId) {
|
|
return db.prepare('SELECT id FROM stories WHERE id = ? AND user_id = ?').get(storyId, userId)
|
|
}
|
|
|
|
// GET /api/stories/:storyId/characters
|
|
router.get('/', (req, res) => {
|
|
if (!getStory(req.params.storyId, req.user.id)) return res.status(404).json({ error: 'Not found' })
|
|
const rows = db.prepare(
|
|
'SELECT * FROM characters WHERE story_id = ? AND user_id = ? ORDER BY name ASC'
|
|
).all(req.params.storyId, req.user.id)
|
|
res.json(rows)
|
|
})
|
|
|
|
// POST /api/stories/:storyId/characters
|
|
router.post('/', (req, res) => {
|
|
if (!getStory(req.params.storyId, req.user.id)) return res.status(404).json({ error: 'Not found' })
|
|
const { name = 'New Character', role = 'supporting', age = '', description = '', notes = '', photo = null } = req.body || {}
|
|
const { lastInsertRowid } = db.prepare(
|
|
'INSERT INTO characters (story_id, user_id, name, role, age, description, notes, photo) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
|
).run(req.params.storyId, req.user.id, name, role, age, description, notes, photo)
|
|
res.json(db.prepare('SELECT * FROM characters WHERE id = ?').get(lastInsertRowid))
|
|
})
|
|
|
|
// POST /api/stories/:storyId/characters/import-from
|
|
router.post('/import-from', (req, res) => {
|
|
if (!getStory(req.params.storyId, req.user.id)) return res.status(404).json({ error: 'Not found' })
|
|
const { from_story_id, character_ids } = req.body || {}
|
|
if (!from_story_id || !Array.isArray(character_ids) || character_ids.length === 0)
|
|
return res.status(400).json({ error: 'Missing from_story_id or character_ids' })
|
|
if (!getStory(from_story_id, req.user.id)) return res.status(404).json({ error: 'Source story not found' })
|
|
|
|
const placeholders = character_ids.map(() => '?').join(',')
|
|
const sourceChars = db.prepare(
|
|
`SELECT * FROM characters WHERE id IN (${placeholders}) AND story_id = ? AND user_id = ?`
|
|
).all(...character_ids, from_story_id, req.user.id)
|
|
|
|
const insert = db.prepare(
|
|
'INSERT INTO characters (story_id, user_id, name, role, age, description, notes, photo) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
|
)
|
|
const inserted = db.transaction(() =>
|
|
sourceChars.map(c => {
|
|
const { lastInsertRowid } = insert.run(
|
|
req.params.storyId, req.user.id, c.name, c.role, c.age, c.description, c.notes, c.photo ?? null
|
|
)
|
|
return db.prepare('SELECT * FROM characters WHERE id = ?').get(lastInsertRowid)
|
|
})
|
|
)()
|
|
|
|
res.json(inserted)
|
|
})
|
|
|
|
// PUT /api/stories/:storyId/characters/:charId
|
|
router.put('/:charId', (req, res) => {
|
|
const char = db.prepare(
|
|
'SELECT * FROM characters WHERE id = ? AND story_id = ? AND user_id = ?'
|
|
).get(req.params.charId, req.params.storyId, req.user.id)
|
|
if (!char) return res.status(404).json({ error: 'Not found' })
|
|
|
|
const { name, role, age, description, notes, photo } = req.body || {}
|
|
db.prepare(
|
|
'UPDATE characters SET name = ?, role = ?, age = ?, description = ?, notes = ?, photo = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?'
|
|
).run(
|
|
name !== undefined ? name : char.name,
|
|
role !== undefined ? role : char.role,
|
|
age !== undefined ? age : char.age,
|
|
description !== undefined ? description : char.description,
|
|
notes !== undefined ? notes : char.notes,
|
|
photo !== undefined ? photo : char.photo,
|
|
char.id
|
|
)
|
|
res.json(db.prepare('SELECT * FROM characters WHERE id = ?').get(char.id))
|
|
})
|
|
|
|
// DELETE /api/stories/:storyId/characters/:charId
|
|
router.delete('/:charId', (req, res) => {
|
|
const char = db.prepare(
|
|
'SELECT * FROM characters WHERE id = ? AND story_id = ? AND user_id = ?'
|
|
).get(req.params.charId, req.params.storyId, req.user.id)
|
|
if (!char) return res.status(404).json({ error: 'Not found' })
|
|
db.prepare('DELETE FROM characters WHERE id = ?').run(char.id)
|
|
res.json({ ok: true })
|
|
})
|
|
|
|
export default router
|