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:
89
server/src/model/posts/posts.model.js
Normal file
89
server/src/model/posts/posts.model.js
Normal file
@@ -0,0 +1,89 @@
|
||||
const postsDb = require('./posts.db')
|
||||
|
||||
// URL category (kebab) <-> DB enum value.
|
||||
const CATEGORY_MAP = {
|
||||
news: 'news',
|
||||
'five-on-friday': 'five_on_friday',
|
||||
newsletter: 'newsletter',
|
||||
screenshots: 'screenshot',
|
||||
}
|
||||
const URL_CATEGORIES = Object.keys(CATEGORY_MAP)
|
||||
const DB_CATEGORIES = Object.values(CATEGORY_MAP)
|
||||
|
||||
function toDbCategory(urlCategory) {
|
||||
return CATEGORY_MAP[urlCategory] || null
|
||||
}
|
||||
|
||||
function isValidUrlCategory(urlCategory) {
|
||||
return Boolean(CATEGORY_MAP[urlCategory])
|
||||
}
|
||||
|
||||
function isValidDbCategory(dbCategory) {
|
||||
return DB_CATEGORIES.includes(dbCategory)
|
||||
}
|
||||
|
||||
async function listPublished(urlCategory) {
|
||||
return postsDb.listPublished(toDbCategory(urlCategory))
|
||||
}
|
||||
|
||||
async function getPublished(urlCategory, idOrSlug) {
|
||||
const id = Number.isInteger(Number(idOrSlug)) ? Number(idOrSlug) : -1
|
||||
return postsDb.findPublished(toDbCategory(urlCategory), id, String(idOrSlug))
|
||||
}
|
||||
|
||||
async function listAll(dbCategory) {
|
||||
return postsDb.listAll(dbCategory || null)
|
||||
}
|
||||
|
||||
async function getById(id) {
|
||||
return postsDb.findById(id)
|
||||
}
|
||||
|
||||
async function create(post) {
|
||||
const id = await postsDb.insert(post)
|
||||
return postsDb.findById(id)
|
||||
}
|
||||
|
||||
async function update(id, fields) {
|
||||
await postsDb.update(id, fields)
|
||||
return postsDb.findById(id)
|
||||
}
|
||||
|
||||
async function setPublished(id, published) {
|
||||
const current = await postsDb.findById(id)
|
||||
if (!current) return null
|
||||
const fields = { published: published ? 1 : 0 }
|
||||
// Stamp published_at the first time a post goes live.
|
||||
if (published && !current.published_at) fields.published_at = new Date()
|
||||
await postsDb.update(id, fields)
|
||||
return postsDb.findById(id)
|
||||
}
|
||||
|
||||
async function remove(id) {
|
||||
return postsDb.remove(id)
|
||||
}
|
||||
|
||||
async function counts() {
|
||||
const rows = await postsDb.countByCategory()
|
||||
return rows.reduce((acc, row) => {
|
||||
acc[row.category] = Number(row.c)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
URL_CATEGORIES,
|
||||
DB_CATEGORIES,
|
||||
toDbCategory,
|
||||
isValidUrlCategory,
|
||||
isValidDbCategory,
|
||||
listPublished,
|
||||
getPublished,
|
||||
listAll,
|
||||
getById,
|
||||
create,
|
||||
update,
|
||||
setPublished,
|
||||
remove,
|
||||
counts,
|
||||
}
|
||||
Reference in New Issue
Block a user