makerstash/server/routes/collections.js

171 lines
4.4 KiB
JavaScript

import express from 'express';
import db from '../database.js';
import { authenticateToken, optionalAuth } from '../middleware/auth.js';
const router = express.Router();
// Get all collections (hierarchical)
router.get('/', authenticateToken, (req, res) => {
const query = `
SELECT c.*,
p.name as parent_name,
COUNT(DISTINCT m.id) as model_count
FROM collections c
LEFT JOIN collections p ON c.parent_id = p.id
LEFT JOIN models m ON c.id = m.collection_id
WHERE c.user_id = ?
GROUP BY c.id
ORDER BY c.parent_id ASC, c.created_at DESC
`;
db.all(query, [req.user.id], (err, collections) => {
if (err) {
return res.status(500).json({ error: err.message });
}
// Build hierarchical structure
const collectionMap = new Map();
const rootCollections = [];
collections.forEach(c => {
c.children = [];
collectionMap.set(c.id, c);
});
collections.forEach(c => {
if (c.parent_id) {
const parent = collectionMap.get(c.parent_id);
if (parent) {
parent.children.push(c);
}
} else {
rootCollections.push(c);
}
});
res.json({ collections: rootCollections, all: collections });
});
});
// Get single collection with models
router.get('/:id', authenticateToken, (req, res) => {
const collectionQuery = `
SELECT c.*, COUNT(m.id) as model_count
FROM collections c
LEFT JOIN models m ON c.id = m.collection_id
WHERE c.id = ? AND c.user_id = ?
GROUP BY c.id
`;
db.get(collectionQuery, [req.params.id, req.user.id], (err, collection) => {
if (err) {
return res.status(500).json({ error: err.message });
}
if (!collection) {
return res.status(404).json({ error: 'Collection not found' });
}
const modelsQuery = `
SELECT m.*, GROUP_CONCAT(t.name) as tags
FROM models m
LEFT JOIN model_tags mt ON m.id = mt.model_id
LEFT JOIN tags t ON mt.tag_id = t.id
WHERE m.collection_id = ?
GROUP BY m.id
ORDER BY m.created_at DESC
`;
db.all(modelsQuery, [req.params.id], (err, models) => {
if (err) {
return res.status(500).json({ error: err.message });
}
collection.models = models.map(model => ({
...model,
tags: model.tags ? model.tags.split(',') : []
}));
res.json(collection);
});
});
});
// Create collection
router.post('/', authenticateToken, (req, res) => {
const { name, description, parentId } = req.body;
if (!name) {
return res.status(400).json({ error: 'Collection name is required' });
}
const query = 'INSERT INTO collections (name, description, parent_id, user_id) VALUES (?, ?, ?, ?)';
db.run(query, [name, description || null, parentId || null, req.user.id], function (err) {
if (err) {
return res.status(500).json({ error: err.message });
}
res.status(201).json({
message: 'Collection created successfully',
collectionId: this.lastID,
collection: {
id: this.lastID,
name,
description,
parent_id: parentId
}
});
});
});
// Update collection
router.put('/:id', authenticateToken, (req, res) => {
const { name, description } = req.body;
const updates = [];
const params = [];
if (name !== undefined) {
updates.push('name = ?');
params.push(name);
}
if (description !== undefined) {
updates.push('description = ?');
params.push(description);
}
if (updates.length === 0) {
return res.status(400).json({ error: 'No fields to update' });
}
params.push(req.params.id);
const query = `UPDATE collections SET ${updates.join(', ')} WHERE id = ?`;
db.run(query, params, function (err) {
if (err) {
return res.status(500).json({ error: err.message });
}
if (this.changes === 0) {
return res.status(404).json({ error: 'Collection not found' });
}
res.json({ message: 'Collection updated successfully' });
});
});
// Delete collection
router.delete('/:id', authenticateToken, (req, res) => {
db.run('DELETE FROM collections WHERE id = ?', [req.params.id], function (err) {
if (err) {
return res.status(500).json({ error: err.message });
}
if (this.changes === 0) {
return res.status(404).json({ error: 'Collection not found' });
}
res.json({ message: 'Collection deleted successfully' });
});
});
export default router;