mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
293506217e
Server-side notice registry with per-user condition evaluation (firstLogin, existingUserBeforeVersion, addonEnabled, dateWindow, role, custom). Notices are sorted by priority then severity, filtered against dismissals stored in a new user_notice_dismissals table, and served via GET /api/system-notices/active + POST /api/system-notices/:id/dismiss. Client renders notices through a host component that partitions by display type (modal / banner / toast). The modal renderer supports multi-page pagination with directional slide transitions, keyboard navigation, and correct dismiss-all semantics on CTA / X / ESC. Dismissals are optimistic with a single background retry. Includes 3.0.0 upgrade notices (v3-photos, v3-journey, v3-features), onboarding welcome modal, and full i18n coverage across 15 languages. The /journey route is addon-gated on both client and server. Also includes: unit + integration test suites, registry integrity test that validates action CTA IDs against client source, and technical documentation in docs/system-notices.md.
30 lines
942 B
TypeScript
30 lines
942 B
TypeScript
import { Router } from 'express';
|
|
import { authenticate } from '../middleware/auth.js';
|
|
import { getActiveNoticesFor, dismissNotice } from '../systemNotices/service.js';
|
|
import type { AuthRequest } from '../types.js';
|
|
|
|
const router = Router();
|
|
|
|
// GET /api/system-notices/active
|
|
// Returns notices active for the authenticated user.
|
|
router.get('/active', authenticate, (req, res) => {
|
|
const userId = (req as AuthRequest).user!.id;
|
|
const notices = getActiveNoticesFor(userId);
|
|
res.json(notices);
|
|
});
|
|
|
|
// POST /api/system-notices/:id/dismiss
|
|
// Marks a notice as dismissed for the authenticated user. Idempotent.
|
|
router.post('/:id/dismiss', authenticate, (req, res) => {
|
|
const userId = (req as AuthRequest).user!.id;
|
|
const noticeId = req.params.id;
|
|
const ok = dismissNotice(userId, noticeId);
|
|
if (!ok) {
|
|
res.status(404).json({ error: 'NOTICE_NOT_FOUND' });
|
|
return;
|
|
}
|
|
res.status(204).end();
|
|
});
|
|
|
|
export default router;
|