Added tag and category API endpoints

This commit is contained in:
MattLeo 2025-12-05 16:55:33 -06:00
parent f0ebd192a1
commit 6870d304b4

View File

@ -15,7 +15,15 @@ const {
getAllUsers,
updateUserRole,
deleteUser,
getOwnedDrafts
getOwnedDrafts,
getAllCategories,
getAllTags,
getArticleCategories,
getArticleTags,
getOrCreateCategory,
getOrCreateTag,
setArticleCategories,
setArticleTags
} = require('./db');
const { generateToken, authenticateToken, authorizeRoles } = require('./auth');
const app = express();
@ -55,6 +63,12 @@ initDb().then(() => {
app.get('/api/articles', authenticateToken, (req, res) => {
try {
const articles = getAllArticles();
articles.forEach(article => {
article.categories = getArticleCategories(article.id);
article.tags = getArticleTags(article.id);
});
res.json(articles);
} catch (error) {
console.error('Error fetching articles:', error);
@ -80,6 +94,9 @@ initDb().then(() => {
return res.status(404).json({ error: 'Article not found' });
}
article.categories = getArticleCategories(article.id);
article.tags = getArticleTags(article.id);
res.json(article);
} catch (error) {
console.error('Error fetching article:', error);
@ -162,6 +179,47 @@ initDb().then(() => {
}
});
app.get('/api/search/advanced', authenticateToken, (req, res) => {
try {
const { query, categories, tags } = req.query;
let articles = getAllArticles();
articles.forEach(article => {
article.categories = getArticleCategories(article.id);
article.tags = getArticleTags(article.id);
});
if (query) {
const searchTerm = query.toLowerCase();
articles = articles.filter(article =>
article.title.toLowerCase().includes(searchTerm) ||
article.content.toLowerCase().includes(searchTerm) ||
article.ka_number.toLowerCase().includes(searchTerm)
);
}
if (categories) {
const categoryList = categories.split(',').map(c => c.trim().toLowerCase());
articles = articles.filter(article =>
article.categories.some(cat => categoryList.includes(cat.toLowerCase()))
);
}
if (tags) {
const tagList = tags.split(',').map(t => t.trim().toLowerCase());
articles = articles.filter(article =>
article.tags.some(tag => tagList.includes(tag.toLowerCase()))
);
}
res.json(articles);
} catch (error) {
console.error('Error searching articles:', error);
res.status(500).json({ error: 'Failed to search articles', details: String(error) });
}
});
app.post('/api/auth/register', async (req, res) => {
try {
const { username, email, password, display_name } = req.body;
@ -473,6 +531,137 @@ initDb().then(() => {
app.use('/media', express.static('./media'));
app.get('/api/categories', authenticateToken, (req, res) => {
try {
const categories = getAllCategories();
res.json(categories);
} catch (error) {
console.error('Error fetching categories:', error);
res.status(500).json({ error: 'Failed to fetch categories', details: String(error) });
}
});
app.post('/api/categories', authenticateToken, authorizeRoles('Admin', 'Editor'), (req, res) => {
try {
const { name } = req.body;
if (!name || !name.trim()) {
return res.status(400).json({ error: 'Category name is required' });
}
const category = getOrCreateCategory(name.trim());
res.status(201).json(category);
} catch (error) {
console.error('Error creating category:', error);
res.status(500).json({ error: 'Failed to create category', details: String(error) });
}
});
app.get('/api/tags', authenticateToken, (req, res) => {
try {
const tags = getAllTags();
res.json(tags);
} catch (error) {
console.error('Error fetching tags:', error);
res.status(500).json({ error: 'Failed to fetch tags', details: String(error) });
}
});
app.post('/api/tags', authenticateToken, authorizeRoles('Admin', 'Editor'), (req, res) => {
try {
const { name } = req.body;
if (!name || !name.trim()) {
return res.status(400).json({ error: 'Tag name is required' });
}
const tag = getOrCreateTag(name.trim());
res.status(201).json(tag);
} catch (error) {
console.error('Error creating tag:', error);
res.status(500).json({ error: 'Failed to create tag', details: String(error) });
}
});
app.put('/api/articles/:ka_number/categories', authenticateToken, authorizeRoles('Admin', 'Editor'), (req, res) => {
try {
const kaNumber = req.params.ka_number;
const { categories } = req.body;
if (!Array.isArray(categories)) {
return res.status(400).json({ error: 'Categories must be an array' });
}
const article = getArticle(kaNumber);
if (!article) {
return res.status(404).json({ error: 'Article not found' });
}
setArticleCategories(article.id, categories);
res.json({ message: 'Categories updated successfully', categories });
} catch (error) {
console.error('Error updating article categories:', error);
res.status(500).json({ error: 'Failed to update categories', details: String(error) });
}
});
app.put('/api/articles/:ka_number/tags', authenticateToken, authorizeRoles('Admin', 'Editor'), (req, res) => {
try {
const kaNumber = req.params.ka_number;
const { tags } = req.body;
if (!Array.isArray(tags)) {
return res.status(400).json({ error: 'Tags must be an array' });
}
const article = getArticle(kaNumber);
if (!article) {
return res.status(404).json({ error: 'Article not found' });
}
setArticleTags(article.id, tags);
res.json({ message: 'Tags updated successfully', tags });
} catch (error) {
console.error('Error updating article tags:', error);
res.status(500).json({ error: 'Failed to update tags', details: String(error) });
}
});
app.get('/api/articles/:ka_number/categories', authenticateToken, (req, res) => {
try {
const article = getArticle(req.params.ka_number);
if (!article) {
return res.status(404).json({ error: 'Article not found' });
}
const categories = getArticleCategories(article.id);
res.json(categories);
} catch (error) {
console.error('Error fetching article categories:', error);
res.status(500).json({ error: 'Failed to fetch categories', details: String(error) });
}
});
app.get('/api/articles/:ka_number/tags', authenticateToken, (req, res) => {
try {
const article = getArticle(req.params.ka_number);
if (!article) {
return res.status(404).json({ error: 'Article not found' });
}
const tags = getArticleTags(article.id);
res.json(tags);
} catch (error) {
console.error('Error fetching article tags:', error);
res.status(500).json({ error: 'Failed to fetch tags', details: String(error) });
}
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});