Initial commit: UOMysticmoon backend (Express + MariaDB + JWT)
- Layered API (router -> controller -> model -> db), serverlinkr pattern - Public / auth / admin route groups; posts, wiki, settings, users, activity models - JWT httpOnly-cookie auth (Secure auto-detected: LAN HTTP + Pangolin HTTPS) - Site LIVE/MAINTENANCE mode with admin preview bypass - Dual file+console logging (info/warn/error/debug) + HTTP access logs - Docker Compose (app + MariaDB), schema.sql + seed, .env.example - Verified end-to-end against MariaDB (27/27 smoke checks) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
84
server/src/model/posts/posts.db.js
Normal file
84
server/src/model/posts/posts.db.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const { query } = require('../../utils/db')
|
||||
|
||||
const COLS =
|
||||
'id, category, title, slug, excerpt, body, image_url, published, author_id, created_at, updated_at, published_at'
|
||||
|
||||
// Published posts for a category, newest first — public feed.
|
||||
async function listPublished(category) {
|
||||
return query(
|
||||
`SELECT ${COLS} FROM posts WHERE category = ? AND published = 1 ` +
|
||||
'ORDER BY COALESCE(published_at, created_at) DESC, id DESC',
|
||||
[category],
|
||||
)
|
||||
}
|
||||
|
||||
// All posts for a category (admin), newest first.
|
||||
async function listAll(category) {
|
||||
if (category) {
|
||||
return query(`SELECT ${COLS} FROM posts WHERE category = ? ORDER BY id DESC`, [category])
|
||||
}
|
||||
return query(`SELECT ${COLS} FROM posts ORDER BY id DESC`)
|
||||
}
|
||||
|
||||
async function findById(id) {
|
||||
const rows = await query(`SELECT ${COLS} FROM posts WHERE id = ? LIMIT 1`, [id])
|
||||
return rows[0] || null
|
||||
}
|
||||
|
||||
async function findPublished(category, id, slug) {
|
||||
const rows = await query(
|
||||
`SELECT ${COLS} FROM posts WHERE category = ? AND published = 1 AND (id = ? OR slug = ?) LIMIT 1`,
|
||||
[category, id, slug],
|
||||
)
|
||||
return rows[0] || null
|
||||
}
|
||||
|
||||
async function insert(post) {
|
||||
const res = await query(
|
||||
'INSERT INTO posts (category, title, slug, excerpt, body, image_url, published, author_id, published_at) ' +
|
||||
'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[
|
||||
post.category,
|
||||
post.title,
|
||||
post.slug || null,
|
||||
post.excerpt || null,
|
||||
post.body || null,
|
||||
post.image_url || null,
|
||||
post.published ? 1 : 0,
|
||||
post.author_id || null,
|
||||
post.published ? new Date() : null,
|
||||
],
|
||||
)
|
||||
return res.insertId
|
||||
}
|
||||
|
||||
async function update(id, fields) {
|
||||
const cols = []
|
||||
const params = []
|
||||
for (const [key, val] of Object.entries(fields)) {
|
||||
cols.push(`${key} = ?`)
|
||||
params.push(val)
|
||||
}
|
||||
if (cols.length === 0) return
|
||||
params.push(id)
|
||||
await query(`UPDATE posts SET ${cols.join(', ')} WHERE id = ?`, params)
|
||||
}
|
||||
|
||||
async function remove(id) {
|
||||
return query('DELETE FROM posts WHERE id = ?', [id])
|
||||
}
|
||||
|
||||
async function countByCategory() {
|
||||
return query('SELECT category, COUNT(*) AS c FROM posts GROUP BY category')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
listPublished,
|
||||
listAll,
|
||||
findById,
|
||||
findPublished,
|
||||
insert,
|
||||
update,
|
||||
remove,
|
||||
countByCategory,
|
||||
}
|
||||
Reference in New Issue
Block a user