mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-19 13:21:46 +00:00
Merge pull request #683 from mauriceboe/feat/system-notices
Feat/system notices
This commit is contained in:
@@ -72,17 +72,18 @@ describe('BannerRenderer', () => {
|
||||
expect(screen.getByText('Second notice')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('FE-SN-BANNER-004: third banner is not rendered (only last 2 shown)', async () => {
|
||||
const n1 = makeBanner({ id: 'banner-1', titleKey: 'Oldest notice' });
|
||||
it('FE-SN-BANNER-004: third banner is not rendered (only top 2 shown)', async () => {
|
||||
// Server returns notices highest-priority first; BannerRenderer takes slice(0,2)
|
||||
const n1 = makeBanner({ id: 'banner-1', titleKey: 'Highest notice' });
|
||||
const n2 = makeBanner({ id: 'banner-2', titleKey: 'Second notice' });
|
||||
const n3 = makeBanner({ id: 'banner-3', titleKey: 'Newest notice' });
|
||||
const n3 = makeBanner({ id: 'banner-3', titleKey: 'Lowest notice' });
|
||||
await act(async () => {
|
||||
render(<BannerRenderer notices={[n1, n2, n3]} />);
|
||||
});
|
||||
|
||||
expect(screen.queryByText('Oldest notice')).toBeNull();
|
||||
expect(screen.getByText('Highest notice')).toBeTruthy();
|
||||
expect(screen.getByText('Second notice')).toBeTruthy();
|
||||
expect(screen.getByText('Newest notice')).toBeTruthy();
|
||||
expect(screen.queryByText('Lowest notice')).toBeNull();
|
||||
});
|
||||
|
||||
it('FE-SN-BANNER-005: critical banner has aria-live="assertive"', async () => {
|
||||
|
||||
@@ -2011,6 +2011,14 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'وضع لا اتصال كامل كتطبيق PWA',
|
||||
'system_notice.v3_features.highlight_search': 'إكمال تلقائي في الوقت الفعلي',
|
||||
'system_notice.v3_features.highlight_import': 'استيراد أماكن من ملفات KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: ترقية OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'تمت إعادة تصميم تكامل MCP بالكامل. OAuth 2.1 هو الآن طريقة المصادقة الموصى بها. الرموز الثابتة (trek_…) مهملة وستُزال في إصدار مستقبلي.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 موصى به (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 نطاق أذونات دقيق',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'الرموز الثابتة trek_ مهملة',
|
||||
'system_notice.v3_mcp.highlight_tools': 'مجموعة أدوات وإرشادات موسعة',
|
||||
}
|
||||
|
||||
export default ar
|
||||
|
||||
@@ -2214,6 +2214,14 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Modo offline completo como PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Autocompleção de lugares em tempo real',
|
||||
'system_notice.v3_features.highlight_import': 'Importar lugares de arquivos KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: atualização OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'A integração MCP foi completamente reformulada. OAuth 2.1 agora é o método de autenticação recomendado. Tokens estáticos (trek_…) foram descontinuados e serão removidos em uma versão futura.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 recomendado (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 escopos de permissão granulares',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Tokens estáticos trek_ descontinuados',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Conjunto de ferramentas e prompts expandido',
|
||||
}
|
||||
|
||||
export default br
|
||||
|
||||
@@ -2218,6 +2218,14 @@ const cs: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Plný offline režim jako PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Autodoplňování vyhledávání míst',
|
||||
'system_notice.v3_features.highlight_import': 'Import míst ze souborů KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: aktualizace OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'Integrace MCP byla kompletně přepracována. OAuth 2.1 je nyní doporučenou metodou ověřování. Statické tokeny (trek_…) jsou zastaralé a budou v budoucí verzi odstraněny.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 doporučeno (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 jemnozrnných oprávnění',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Statické tokeny trek_ zastaralé',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Rozšířená sada nástrojů a promptů',
|
||||
}
|
||||
|
||||
export default cs
|
||||
|
||||
@@ -2218,6 +2218,14 @@ const de: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Vollständiger Offline-Modus als PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Echtzeit-Autovervollständigung für Orte',
|
||||
'system_notice.v3_features.highlight_import': 'Orte aus KMZ/KML-Dateien importieren',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: OAuth 2.1-Upgrade',
|
||||
'system_notice.v3_mcp.body': 'Die MCP-Integration wurde vollständig überarbeitet. OAuth 2.1 ist jetzt die empfohlene Authentifizierungsmethode. Statische Tokens (trek_…) sind veraltet und werden in einer zukünftigen Version entfernt.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 empfohlen (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 feingranulare Berechtigungs-Scopes',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Statische trek_-Tokens veraltet',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Erweitertes Toolset & Prompts',
|
||||
}
|
||||
|
||||
export default de
|
||||
|
||||
@@ -2240,6 +2240,14 @@ const en: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_search': 'Real-time place search autocomplete',
|
||||
'system_notice.v3_features.highlight_import': 'Import places from KMZ/KML files',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: OAuth 2.1 upgrade',
|
||||
'system_notice.v3_mcp.body': 'The MCP integration has been fully overhauled. OAuth 2.1 is now the recommended auth method. Legacy static tokens (trek_\u2026) are deprecated and will be removed in a future release.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 recommended (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 fine-grained permission scopes',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Static trek_ tokens deprecated',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Expanded toolset & prompts',
|
||||
|
||||
// System notices — onboarding
|
||||
'system_notice.welcome_v1.title': 'Welcome to TREK',
|
||||
'system_notice.welcome_v1.body': 'Your all-in-one travel planner. Build itineraries, share trips with friends, and stay organized — online or offline.',
|
||||
|
||||
@@ -2220,6 +2220,14 @@ const es: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Modo sin conexión completo como PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Autocompletado de lugares en tiempo real',
|
||||
'system_notice.v3_features.highlight_import': 'Importar lugares desde archivos KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: actualización OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'La integración MCP ha sido completamente renovada. OAuth 2.1 es ahora el método de autenticación recomendado. Los tokens estáticos (trek_…) están obsoletos y se eliminarán en una versión futura.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 recomendado (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 ámbitos de permisos granulares',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Tokens estáticos trek_ obsoletos',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Herramientas y prompts ampliados',
|
||||
}
|
||||
|
||||
export default es
|
||||
|
||||
@@ -2214,6 +2214,14 @@ const fr: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Mode hors ligne complet en PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Autocomplétion des lieux en temps réel',
|
||||
'system_notice.v3_features.highlight_import': 'Importer des lieux depuis KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP : mise à niveau OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': "L'intégration MCP a été entièrement repensée. OAuth 2.1 est désormais la méthode d'authentification recommandée. Les tokens statiques (trek_\u2026) sont dépréciés et seront supprimés dans une future version.",
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 recommandé (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 scopes de permissions granulaires',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Tokens statiques trek_ dépréciés',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Outils et prompts étendus',
|
||||
}
|
||||
|
||||
export default fr
|
||||
|
||||
@@ -2215,6 +2215,14 @@ const hu: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Teljes offline mód PWA-ként',
|
||||
'system_notice.v3_features.highlight_search': 'Valós idejű helykeresés-kiegészítés',
|
||||
'system_notice.v3_features.highlight_import': 'Helyek importálása KMZ/KML fájlokból',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: OAuth 2.1 frissítés',
|
||||
'system_notice.v3_mcp.body': 'Az MCP integráció teljesen megújult. Az OAuth 2.1 mostantól az ajánlott hitelesítési módszer. A statikus tokenek (trek_…) elavultak és egy jövőbeli kiadásban eltávolításra kerülnek.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 ajánlott (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 részletes engedélyezési hatókör',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Statikus trek_ tokenek elavultak',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Bővített eszközkészlet és promptok',
|
||||
}
|
||||
|
||||
export default hu
|
||||
|
||||
@@ -2256,6 +2256,14 @@ const id: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Mode offline penuh sebagai PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Pelengkapan otomatis tempat secara real-time',
|
||||
'system_notice.v3_features.highlight_import': 'Impor tempat dari file KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: pembaruan OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'Integrasi MCP telah sepenuhnya diperbarui. OAuth 2.1 kini menjadi metode autentikasi yang direkomendasikan. Token statis (trek_…) sudah usang dan akan dihapus pada versi mendatang.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 direkomendasikan (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 cakupan izin yang terperinci',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Token statis trek_ sudah usang',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Perangkat dan prompt yang diperluas',
|
||||
};
|
||||
|
||||
export default id;
|
||||
|
||||
@@ -2215,6 +2215,14 @@ const it: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Modalità offline completa come PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Completamento automatico luoghi in tempo reale',
|
||||
'system_notice.v3_features.highlight_import': 'Importa luoghi da file KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: aggiornamento OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': "L'integrazione MCP è stata completamente rinnovata. OAuth 2.1 è ora il metodo di autenticazione consigliato. I token statici (trek_\u2026) sono deprecati e verranno rimossi in una versione futura.",
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 consigliato (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 scope di autorizzazione granulari',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Token statici trek_ deprecati',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Strumenti e prompt estesi',
|
||||
}
|
||||
|
||||
export default it
|
||||
|
||||
@@ -2214,6 +2214,14 @@ const nl: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Volledige offline modus als PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Realtime plaatsautocomplete',
|
||||
'system_notice.v3_features.highlight_import': 'Importeer plaatsen uit KMZ/KML-bestanden',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: OAuth 2.1-upgrade',
|
||||
'system_notice.v3_mcp.body': 'De MCP-integratie is volledig vernieuwd. OAuth 2.1 is nu de aanbevolen authenticatiemethode. Statische tokens (trek_…) zijn verouderd en worden verwijderd in een toekomstige versie.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 aanbevolen (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 gedetailleerde toestemmingsscopes',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Statische trek_-tokens verouderd',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Uitgebreide tools & prompts',
|
||||
}
|
||||
|
||||
export default nl
|
||||
|
||||
@@ -2207,6 +2207,14 @@ const pl: Record<string, string | { name: string; category: string }[]> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Pełny tryb offline jako PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Autouzupełnianie wyszukiwania miejsc',
|
||||
'system_notice.v3_features.highlight_import': 'Import miejsc z plików KMZ/KML',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: aktualizacja OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'Integracja MCP została całkowicie przeprojektowana. OAuth 2.1 jest teraz zalecaną metodą uwierzytelniania. Statyczne tokeny (trek_…) są przestarzałe i zostaną usunięte w przyszłej wersji.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 zalecany (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 szczegółowe zakresy uprawnień',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Statyczne tokeny trek_ przestarzałe',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Rozszerzony zestaw narzędzi i promptów',
|
||||
}
|
||||
|
||||
export default pl
|
||||
|
||||
@@ -2214,6 +2214,14 @@ const ru: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': 'Полный офлайн-режим как PWA',
|
||||
'system_notice.v3_features.highlight_search': 'Автодополнение поиска мест в реальном времени',
|
||||
'system_notice.v3_features.highlight_import': 'Импорт мест из KMZ/KML-файлов',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP: обновление OAuth 2.1',
|
||||
'system_notice.v3_mcp.body': 'Интеграция MCP была полностью переработана. OAuth 2.1 теперь является рекомендуемым методом аутентификации. Статические токены (trek_…) устарели и будут удалены в будущей версии.',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 рекомендуется (mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 детальных области разрешений',
|
||||
'system_notice.v3_mcp.highlight_deprecated': 'Статические токены trek_ устарели',
|
||||
'system_notice.v3_mcp.highlight_tools': 'Расширенный набор инструментов',
|
||||
}
|
||||
|
||||
export default ru
|
||||
|
||||
@@ -2214,6 +2214,14 @@ const zh: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': '作为 PWA 的完整离线模式',
|
||||
'system_notice.v3_features.highlight_search': '地点搜索实时自动补全',
|
||||
'system_notice.v3_features.highlight_import': '从 KMZ/KML 文件导入地点',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP:OAuth 2.1 升级',
|
||||
'system_notice.v3_mcp.body': 'MCP 集成已全面重构。OAuth 2.1 现为推荐的身份验证方式。静态令牌(trek_…)已弃用,将在未来版本中移除。',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 推荐(mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 个细粒度权限范围',
|
||||
'system_notice.v3_mcp.highlight_deprecated': '静态 trek_ 令牌已弃用',
|
||||
'system_notice.v3_mcp.highlight_tools': '扩展工具集与提示词',
|
||||
}
|
||||
|
||||
export default zh
|
||||
|
||||
@@ -2215,6 +2215,14 @@ const zhTw: Record<string, string> = {
|
||||
'system_notice.v3_features.highlight_offline': '作為 PWA 的完整離線模式',
|
||||
'system_notice.v3_features.highlight_search': '地點搜尋即時自動補全',
|
||||
'system_notice.v3_features.highlight_import': '從 KMZ/KML 檔案匯入地點',
|
||||
|
||||
// System notices — MCP OAuth 2.1 upgrade
|
||||
'system_notice.v3_mcp.title': 'MCP:OAuth 2.1 升級',
|
||||
'system_notice.v3_mcp.body': 'MCP 整合已全面重構。OAuth 2.1 現為建議的身份驗證方式。靜態令牌(trek_…)已棄用,將於未來版本移除。',
|
||||
'system_notice.v3_mcp.highlight_oauth': 'OAuth 2.1 建議(mcp-remote)',
|
||||
'system_notice.v3_mcp.highlight_scopes': '24 個細粒度權限範圍',
|
||||
'system_notice.v3_mcp.highlight_deprecated': '靜態 trek_ 令牌已棄用',
|
||||
'system_notice.v3_mcp.highlight_tools': '擴展工具集與提示詞',
|
||||
}
|
||||
|
||||
export default zhTw
|
||||
@@ -151,6 +151,7 @@ export const useAuthStore = create<AuthState>()(
|
||||
|
||||
logout: () => {
|
||||
disconnect()
|
||||
useSystemNoticeStore.getState().reset()
|
||||
// Tell server to clear the httpOnly cookie
|
||||
fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }).catch(() => {})
|
||||
// Clear service worker caches containing sensitive data
|
||||
|
||||
@@ -31,6 +31,7 @@ interface SystemNoticeState {
|
||||
fetching: boolean;
|
||||
fetch: () => Promise<void>;
|
||||
dismiss: (id: string) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
export const useSystemNoticeStore = create<SystemNoticeState>()((set, get) => ({
|
||||
@@ -51,6 +52,10 @@ export const useSystemNoticeStore = create<SystemNoticeState>()((set, get) => ({
|
||||
}
|
||||
},
|
||||
|
||||
reset() {
|
||||
set({ notices: [], loaded: false, fetching: false });
|
||||
},
|
||||
|
||||
dismiss(id: string) {
|
||||
// Optimistic: remove immediately
|
||||
const prev = get().notices;
|
||||
|
||||
@@ -1614,6 +1614,7 @@ function runMigrations(db: Database.Database): void {
|
||||
// Migration 102: Add check_in_end column for check-in time ranges
|
||||
() => {
|
||||
try { db.exec('ALTER TABLE day_accommodations ADD COLUMN check_in_end TEXT'); } catch (err: any) { if (!err.message?.includes('duplicate column name')) throw err; }
|
||||
},
|
||||
// Migration 103: System notices — user tracking columns + dismissals table
|
||||
() => {
|
||||
db.exec(`ALTER TABLE users ADD COLUMN first_seen_version TEXT NOT NULL DEFAULT '0.0.0'`);
|
||||
|
||||
@@ -30,9 +30,11 @@ function evaluateOne(condition: NoticeCondition, ctx: ConditionContext): boolean
|
||||
const userVersion = semver.valid(ctx.user.first_seen_version) ?? '0.0.0';
|
||||
const noticeVersion = semver.valid(condition.version);
|
||||
if (!noticeVersion) return false;
|
||||
// Strip prerelease/build metadata so '3.0.0-pre.42' is treated as '3.0.0'.
|
||||
const appVersion = semver.coerce(ctx.currentAppVersion)?.version ?? '0.0.0';
|
||||
return (
|
||||
semver.lt(userVersion, noticeVersion) &&
|
||||
semver.gte(semver.valid(ctx.currentAppVersion) ?? '0.0.0', noticeVersion)
|
||||
semver.gte(appVersion, noticeVersion)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,30 @@ export const SYSTEM_NOTICES: SystemNotice[] = [
|
||||
},
|
||||
|
||||
{
|
||||
// Page 3 — other highlights
|
||||
// Page 3 — MCP OAuth 2.1 upgrade (only when MCP addon is enabled)
|
||||
id: 'v3-mcp',
|
||||
display: 'modal',
|
||||
severity: 'warn',
|
||||
icon: 'Bot',
|
||||
titleKey: 'system_notice.v3_mcp.title',
|
||||
bodyKey: 'system_notice.v3_mcp.body',
|
||||
highlights: [
|
||||
{ labelKey: 'system_notice.v3_mcp.highlight_oauth', iconName: 'KeyRound' },
|
||||
{ labelKey: 'system_notice.v3_mcp.highlight_scopes', iconName: 'ShieldCheck' },
|
||||
{ labelKey: 'system_notice.v3_mcp.highlight_deprecated', iconName: 'AlertTriangle' },
|
||||
{ labelKey: 'system_notice.v3_mcp.highlight_tools', iconName: 'Wrench' },
|
||||
],
|
||||
dismissible: true,
|
||||
conditions: [
|
||||
{ kind: 'existingUserBeforeVersion', version: '3.0.0' },
|
||||
{ kind: 'addonEnabled', addonId: 'mcp' },
|
||||
],
|
||||
publishedAt: '2026-04-16T00:00:00Z',
|
||||
priority: 75,
|
||||
},
|
||||
|
||||
{
|
||||
// Page 4 — other highlights
|
||||
id: 'v3-features',
|
||||
display: 'modal',
|
||||
severity: 'info',
|
||||
|
||||
@@ -40,6 +40,12 @@ describe('existingUserBeforeVersion', () => {
|
||||
it('fails when current app version < notice version', () => {
|
||||
expect(evaluate(notice, { ...baseCtx, currentAppVersion: '1.5.0' })).toBe(false);
|
||||
});
|
||||
it('passes when current app version is a prerelease of the notice version', () => {
|
||||
expect(evaluate(notice, { ...baseCtx, currentAppVersion: '2.0.0-pre.42' })).toBe(true);
|
||||
});
|
||||
it('passes when current app version is a prerelease beyond the notice version', () => {
|
||||
expect(evaluate(notice, { ...baseCtx, currentAppVersion: '2.1.0-pre.1' })).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateWindow', () => {
|
||||
|
||||
Reference in New Issue
Block a user