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:
25
server/src/model/activity/activity.model.js
Normal file
25
server/src/model/activity/activity.model.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const activityDb = require('./activity.db')
|
||||
|
||||
const logger = require('../../utils/logger')('activity')
|
||||
|
||||
/**
|
||||
* Record an admin action. `detail` may be an object (stored as JSON). Never throws
|
||||
* into the request path — logging must not break the action it records.
|
||||
*/
|
||||
async function log({ req, userId, action, detail }) {
|
||||
try {
|
||||
const resolvedUserId = userId ?? (req && req.user ? req.user.id : null)
|
||||
const ip = req ? req.ip : null
|
||||
const detailStr =
|
||||
detail == null ? null : typeof detail === 'string' ? detail : JSON.stringify(detail)
|
||||
await activityDb.insert({ userId: resolvedUserId, action, detail: detailStr, ip })
|
||||
} catch (err) {
|
||||
logger.error(`failed to record action "${action}"`, { error: err.message })
|
||||
}
|
||||
}
|
||||
|
||||
async function list(opts) {
|
||||
return activityDb.list(opts)
|
||||
}
|
||||
|
||||
module.exports = { log, list }
|
||||
Reference in New Issue
Block a user