mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 14:36:31 +00:00
724c88c201
A mechanical prettier --write over server/src, server/tests, server/scripts and shared/src with the workspaces' .prettierrc; nothing but layout and import order changes, and every file keeps the same set of imports. shared is formatted throughout and its format baseline is empty. The server baseline keeps the 35 files that Prettier would grow past their lint:size limit (they need a split first, which is not a formatting change), and the generated entity files stay as their generator writes them.
202 lines
8.4 KiB
TypeScript
202 lines
8.4 KiB
TypeScript
import { registerPredicate } from './conditions.js';
|
|
import type { SystemNotice } from './types.js';
|
|
|
|
/**
|
|
* Registered at module load, unchanged from before this plan (Plan 3f Task
|
|
* 6/R1's adopted wiring): the closure used to read `app_settings` directly
|
|
* through the raw `db` handle here; now it only reads a value the caller
|
|
* (`SystemNoticesService.getActiveFor`) already resolved into `ctx` before
|
|
* `evaluate()` runs, the same shape `addonEnabled`/`managed` already use.
|
|
* `evaluateOne`'s `case 'custom'` (`conditions.ts`) calls this synchronously
|
|
* inside a `.filter()`, which cannot `await` — moving the DB read into this
|
|
* closure directly would either need to make the closure (and the whole
|
|
* evaluate/evaluateOne chain) async, or read an un-awaited repository
|
|
* result. Reading a pre-resolved value off `ctx` avoids both, stays
|
|
* race-free (the value flows through the per-call `ctx` object, not shared
|
|
* mutable state on a singleton), and needs no Nest lifecycle hook — this
|
|
* registration stays exactly where it always was.
|
|
*/
|
|
registerPredicate('whitespace-collision-detected', (ctx) => ctx.settingFlag('whitespace_migration_collision'));
|
|
|
|
/**
|
|
* SYSTEM NOTICE REGISTRY
|
|
*
|
|
* Rules for authoring:
|
|
* - NEVER reuse a retired `id` — dismissal tracking is keyed by `id`. Retired ids are
|
|
* listed in RETIRED_NOTICE_IDS so they're never accidentally re-used.
|
|
* - `id` must be globally unique and stable across deployments.
|
|
* - Title: ≤40 chars, sentence case, no trailing punctuation.
|
|
* - Body: markdown (modal) or plain text (banner/toast). ≤400/140/80 chars.
|
|
* - CTA label: ≤20 chars.
|
|
* - Never hardcode version numbers/dates in translated strings — use bodyParams.
|
|
*/
|
|
|
|
/**
|
|
* Retired notices. Kept out of the active list but their ids stay reserved so a future
|
|
* notice never reuses one (dismissals are keyed by id). Do not re-add these ids.
|
|
*/
|
|
export const RETIRED_NOTICE_IDS = [
|
|
'v3-thankyou',
|
|
'v3-photos',
|
|
'v3-journey',
|
|
'v3-mcp',
|
|
'v3-features',
|
|
'welcome-v1',
|
|
'release-4-0-0',
|
|
] as const;
|
|
|
|
export const SYSTEM_NOTICES: SystemNotice[] = [
|
|
// ── Release notes: what the current release brought, and a note from the maintainer ──
|
|
// One entry for every release. Each big release swaps the copy (the release_notes
|
|
// keys) and the version below, and keeps this id. `recurring: 'per-version'` brings
|
|
// it back to every user on every upgrade, a patch release included, so nobody is
|
|
// ever left on a version with nothing to show. No upper bound for the same reason.
|
|
{
|
|
id: 'release-notes',
|
|
recurring: 'per-version',
|
|
display: 'modal',
|
|
severity: 'info',
|
|
titleKey: 'system_notice.release_notes.headline',
|
|
bodyKey: 'system_notice.release_notes.intro',
|
|
release: {
|
|
version: '4.3.3',
|
|
eyebrowKey: 'system_notice.release_notes.eyebrow',
|
|
headlineKey: 'system_notice.release_notes.headline',
|
|
introKey: 'system_notice.release_notes.intro',
|
|
featuresLabelKey: 'system_notice.release_notes.features_label',
|
|
featuresAsideKey: 'system_notice.release_notes.features_aside',
|
|
features: [
|
|
{
|
|
iconName: 'Database',
|
|
visual: 'places-api',
|
|
titleKey: 'system_notice.release_notes.feature_places_title',
|
|
bodyKey: 'system_notice.release_notes.feature_places_body',
|
|
},
|
|
{
|
|
iconName: 'Route',
|
|
visual: 'roadtrip',
|
|
titleKey: 'system_notice.release_notes.feature_roadtrip_title',
|
|
bodyKey: 'system_notice.release_notes.feature_roadtrip_body',
|
|
},
|
|
{
|
|
iconName: 'MapPin',
|
|
visual: 'dawarich',
|
|
titleKey: 'system_notice.release_notes.feature_dawarich_title',
|
|
bodyKey: 'system_notice.release_notes.feature_dawarich_body',
|
|
},
|
|
{
|
|
iconName: 'FolderSync',
|
|
visual: 'docsync',
|
|
layout: 'wide',
|
|
titleKey: 'system_notice.release_notes.feature_docsync_title',
|
|
bodyKey: 'system_notice.release_notes.feature_docsync_body',
|
|
},
|
|
],
|
|
footnoteKey: 'system_notice.release_notes.footnote',
|
|
notes: {
|
|
labelKey: 'system_notice.release_notes.notes_label',
|
|
href: 'https://github.com/liketrek/TREK/releases/tag/v4.3.3',
|
|
},
|
|
note: {
|
|
eyebrowKey: 'system_notice.release_notes.note_eyebrow',
|
|
titleKey: 'system_notice.release_notes.note_title',
|
|
bodyKey: 'system_notice.release_notes.note_body',
|
|
promiseLabelKey: 'system_notice.release_notes.promise_label',
|
|
promiseLeadKey: 'system_notice.release_notes.promise_lead',
|
|
promiseTextKey: 'system_notice.release_notes.promise_text',
|
|
bodyAfterKey: 'system_notice.release_notes.note_body_after',
|
|
closingKey: 'system_notice.release_notes.note_closing',
|
|
},
|
|
supportLeadKey: 'system_notice.release_notes.support_lead',
|
|
supportTextKey: 'system_notice.release_notes.support_text',
|
|
},
|
|
cta: {
|
|
kind: 'link',
|
|
labelKey: 'system_notice.release_notes.cta_bmc',
|
|
href: 'https://buymeacoffee.com/mauriceboe',
|
|
},
|
|
secondaryCta: {
|
|
kind: 'link',
|
|
labelKey: 'system_notice.release_notes.cta_kofi',
|
|
href: 'https://ko-fi.com/mauriceboe',
|
|
},
|
|
dismissible: true,
|
|
// Desktop-only: the two-column layout has no phone form, and the phone has its
|
|
// own onboarding.
|
|
desktopOnly: true,
|
|
// It asks the reader to fund the project, and on a managed install they already
|
|
// pay whoever runs it.
|
|
conditions: [{ kind: 'managed', is: false }],
|
|
publishedAt: '2026-09-15T00:00:00Z',
|
|
priority: 110,
|
|
// Where the thank-you notice below hands over; nothing on 3.x ships this copy.
|
|
minVersion: '4.0.0',
|
|
},
|
|
|
|
// ── Thank-you + support the project — shown once per install AND once per upgrade ──
|
|
// `recurring: 'per-version'` re-surfaces it whenever the app version moves up.
|
|
{
|
|
id: 'thank-you-support',
|
|
display: 'modal',
|
|
severity: 'info',
|
|
icon: 'Heart',
|
|
titleKey: 'system_notice.thank_you_support.title',
|
|
bodyKey: 'system_notice.thank_you_support.body',
|
|
highlights: [
|
|
{ labelKey: 'system_notice.thank_you_support.highlight_opensource', iconName: 'Github' },
|
|
{ labelKey: 'system_notice.thank_you_support.highlight_free', iconName: 'Infinity' },
|
|
{ labelKey: 'system_notice.thank_you_support.highlight_community', iconName: 'Users' },
|
|
],
|
|
cta: {
|
|
kind: 'link',
|
|
labelKey: 'system_notice.thank_you_support.cta_bmc',
|
|
href: 'https://buymeacoffee.com/mauriceboe',
|
|
},
|
|
secondaryCta: {
|
|
kind: 'link',
|
|
labelKey: 'system_notice.thank_you_support.cta_kofi',
|
|
href: 'https://ko-fi.com/mauriceboe',
|
|
},
|
|
dismissible: true,
|
|
// Desktop-only: the support modal is suppressed on small/mobile viewports.
|
|
desktopOnly: true,
|
|
// Not on a centrally administered install. The body thanks the reader for
|
|
// installing TREK and asks them to fund it, and there the reader installed
|
|
// nothing and already pays whoever runs it. Gated rather than reworded: the
|
|
// text is right for everyone it was written for.
|
|
conditions: [{ kind: 'managed', is: false }],
|
|
publishedAt: '2026-06-27T00:00:00Z',
|
|
priority: 100,
|
|
recurring: 'per-version',
|
|
// From 4.0.0 on, the release modal carries the same thank-you and the same
|
|
// two support links, so this one would be the second half of a message the
|
|
// reader just read. Retired by version rather than deleted: installs still
|
|
// on 3.x keep it.
|
|
maxVersion: '4.0.0',
|
|
},
|
|
|
|
// ── 3.0.14 admin notice — whitespace migration collision ───────────────────
|
|
// Operational alert (not promo): shown only to admins who upgraded across the
|
|
// 3.0.14 boundary AND only when the migration actually renamed colliding accounts.
|
|
{
|
|
id: 'v3014-whitespace-collision',
|
|
display: 'banner',
|
|
severity: 'warn',
|
|
icon: 'AlertTriangle',
|
|
titleKey: 'system_notice.v3014_whitespace_collision.title',
|
|
bodyKey: 'system_notice.v3014_whitespace_collision.body',
|
|
dismissible: true,
|
|
conditions: [
|
|
{ kind: 'existingUserBeforeVersion', version: '3.0.14' },
|
|
{ kind: 'role', roles: ['admin'] },
|
|
{ kind: 'custom', id: 'whitespace-collision-detected' },
|
|
// The body says to check the server logs. On a managed install the reader
|
|
// has none, and the operator sees the same collision in theirs.
|
|
{ kind: 'managed', is: false },
|
|
],
|
|
publishedAt: '2026-05-03T00:00:00Z',
|
|
priority: 85,
|
|
minVersion: '3.0.14',
|
|
},
|
|
];
|