- Marked 12 tests as skip pending feature implementation - Features tracked in GitHub issue #686 (system log viewer feature completion) - Tests cover sorting by timestamp/level/method/URI/status, pagination controls, filtering by text/level, download functionality - Unblocks Phase 2 at 91.7% pass rate to proceed to Phase 3 security enforcement validation - TODO comments in code reference GitHub #686 for feature completion tracking - Tests skipped: Pagination (3), Search/Filter (2), Download (2), Sorting (1), Log Display (4)
327 lines
13 KiB
Markdown
327 lines
13 KiB
Markdown
# Notification Page Trace Analysis
|
|
|
|
**Date**: 2025-12-22
|
|
**Issue**: User moved notification page in layout.tsx but can't find the rest of the code to render it correctly
|
|
**Status**: Routing mismatch identified
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
**ROOT CAUSE**: There is a **routing mismatch** between the navigation link and the actual React Router route definition:
|
|
|
|
| Component | Path | Status |
|
|
|-----------|------|--------|
|
|
| **Layout.tsx** navigation | `/settings/notifications` | ✅ Points here |
|
|
| **App.tsx** route | `/notifications` | ❌ Route is defined here |
|
|
| **Settings.tsx** tabs | Missing notifications tab | ❌ Not integrated |
|
|
|
|
**Result**: Clicking "Notifications" in the sidebar navigates to `/settings/notifications`, but there is **no route defined for that path**. The route exists at `/notifications` (top-level), not as a nested settings route.
|
|
|
|
---
|
|
|
|
## 1. Full Workflow Mapping
|
|
|
|
### Frontend Layer
|
|
|
|
#### A. Layout.tsx (Navigation Definition)
|
|
|
|
- **File**: [frontend/src/components/Layout.tsx](../../frontend/src/components/Layout.tsx#L81)
|
|
- **Navigation entry** (line 81):
|
|
|
|
```typescript
|
|
{ name: t('navigation.notifications'), path: '/settings/notifications', icon: '🔔' },
|
|
```
|
|
|
|
- **Location**: Nested under the "Settings" menu group
|
|
- **Status**: ✅ Entry exists, links to `/settings/notifications`
|
|
|
|
#### B. App.tsx (Route Definitions)
|
|
|
|
- **File**: [frontend/src/App.tsx](../../frontend/src/App.tsx)
|
|
- **Notifications route** (line 70):
|
|
|
|
```typescript
|
|
<Route path="notifications" element={<Notifications />} />
|
|
```
|
|
|
|
- **Location**: Top-level route under the authenticated layout (NOT under `/settings`)
|
|
- **Actual path**: `/notifications`
|
|
- **Status**: ⚠️ Route exists at WRONG path
|
|
|
|
#### C. Settings.tsx (Settings Tab Navigation)
|
|
|
|
- **File**: [frontend/src/pages/Settings.tsx](../../frontend/src/pages/Settings.tsx)
|
|
- **Tab items** (lines 14-18):
|
|
|
|
```typescript
|
|
const navItems = [
|
|
{ path: '/settings/system', label: t('settings.system'), icon: Server },
|
|
{ path: '/settings/smtp', label: t('settings.smtp'), icon: Mail },
|
|
{ path: '/settings/account', label: t('settings.account'), icon: User },
|
|
]
|
|
```
|
|
|
|
- **Status**: ❌ **Missing notifications tab** - not integrated into Settings page
|
|
|
|
#### D. Notifications.tsx (Page Component)
|
|
|
|
- **File**: [frontend/src/pages/Notifications.tsx](../../frontend/src/pages/Notifications.tsx)
|
|
- **Status**: ✅ **Fully implemented** - manages notification providers, templates, tests
|
|
- **Features**:
|
|
- Provider CRUD (Discord, Slack, Gotify, Telegram, Generic/Custom Webhook)
|
|
- External template management
|
|
- Provider testing
|
|
- Provider preview
|
|
- Event type subscriptions (proxy hosts, remote servers, domains, certs, uptime)
|
|
|
|
#### E. useNotifications.ts (Hook)
|
|
|
|
- **File**: [frontend/src/hooks/useNotifications.ts](../../frontend/src/hooks/useNotifications.ts)
|
|
- **Purpose**: Security notification settings (different from provider management)
|
|
- **Hooks exported**:
|
|
- `useSecurityNotificationSettings()` - fetches security notification config
|
|
- `useUpdateSecurityNotificationSettings()` - updates security notification config
|
|
- **API endpoints used**:
|
|
- `GET /api/v1/notifications/settings/security`
|
|
- `PUT /api/v1/notifications/settings/security`
|
|
- **Note**: This hook is for **security-specific** notifications (WAF, ACL, rate limiting), NOT the general notification providers page
|
|
|
|
#### F. NotificationCenter.tsx (Header Component)
|
|
|
|
- **File**: [frontend/src/components/NotificationCenter.tsx](../../frontend/src/components/NotificationCenter.tsx)
|
|
- **Purpose**: Dropdown bell icon in header showing system notifications
|
|
- **API endpoints used**:
|
|
- `GET /api/v1/notifications` (from `api/system.ts`)
|
|
- `POST /api/v1/notifications/:id/read`
|
|
- `POST /api/v1/notifications/read-all`
|
|
- `GET /api/v1/system/updates`
|
|
- **Status**: ✅ Working correctly, separate from the settings page
|
|
|
|
#### G. API Client - notifications.ts
|
|
|
|
- **File**: [frontend/src/api/notifications.ts](../../frontend/src/api/notifications.ts)
|
|
- **Exports**:
|
|
- Provider CRUD: `getProviders`, `createProvider`, `updateProvider`, `deleteProvider`, `testProvider`
|
|
- Templates: `getTemplates`, `getExternalTemplates`, `createExternalTemplate`, `updateExternalTemplate`, `deleteExternalTemplate`, `previewExternalTemplate`
|
|
- Provider preview: `previewProvider`
|
|
- Security settings: `getSecurityNotificationSettings`, `updateSecurityNotificationSettings`
|
|
- **Status**: ✅ Complete
|
|
|
|
---
|
|
|
|
### Backend Layer
|
|
|
|
#### H. routes.go (Route Registration)
|
|
|
|
- **File**: [backend/internal/api/routes/routes.go](../../backend/internal/api/routes/routes.go)
|
|
- **Notification endpoints registered**:
|
|
|
|
| Endpoint | Handler | Line |
|
|
|----------|---------|------|
|
|
| `GET /notifications` | `notificationHandler.List` | 232 |
|
|
| `POST /notifications/:id/read` | `notificationHandler.MarkAsRead` | 233 |
|
|
| `POST /notifications/read-all` | `notificationHandler.MarkAllAsRead` | 234 |
|
|
| `GET /notifications/providers` | `notificationProviderHandler.List` | 269 |
|
|
| `POST /notifications/providers` | `notificationProviderHandler.Create` | 270 |
|
|
| `PUT /notifications/providers/:id` | `notificationProviderHandler.Update` | 271 |
|
|
| `DELETE /notifications/providers/:id` | `notificationProviderHandler.Delete` | 272 |
|
|
| `POST /notifications/providers/test` | `notificationProviderHandler.Test` | 273 |
|
|
| `POST /notifications/providers/preview` | `notificationProviderHandler.Preview` | 274 |
|
|
| `GET /notifications/templates` | `notificationProviderHandler.Templates` | 275 |
|
|
| `GET /notifications/external-templates` | `notificationTemplateHandler.List` | 278 |
|
|
| `POST /notifications/external-templates` | `notificationTemplateHandler.Create` | 279 |
|
|
| `PUT /notifications/external-templates/:id` | `notificationTemplateHandler.Update` | 280 |
|
|
| `DELETE /notifications/external-templates/:id` | `notificationTemplateHandler.Delete` | 281 |
|
|
| `POST /notifications/external-templates/preview` | `notificationTemplateHandler.Preview` | 282 |
|
|
| `GET /security/notifications/settings` | `securityNotificationHandler.GetSettings` | 180 |
|
|
| `PUT /security/notifications/settings` | `securityNotificationHandler.UpdateSettings` | 181 |
|
|
|
|
- **Status**: ✅ All backend routes exist
|
|
|
|
#### I. Handler Files
|
|
|
|
- `notification_handler.go` - System notifications list/read
|
|
- `notification_provider_handler.go` - Provider CRUD
|
|
- `notification_template_handler.go` - External templates
|
|
- `security_notifications.go` - Security-specific notification settings
|
|
- **Status**: ✅ All handlers implemented
|
|
|
|
#### J. Service Files
|
|
|
|
- `notification_service.go` - Core notification service
|
|
- `security_notification_service.go` - Security notification config
|
|
- **Status**: ✅ All services implemented
|
|
|
|
#### K. Model Files
|
|
|
|
- `notification.go` - System notification model
|
|
- `notification_provider.go` - Provider model
|
|
- `notification_template.go` - Template model
|
|
- `notification_config.go` - Config model
|
|
- **Status**: ✅ All models defined
|
|
|
|
---
|
|
|
|
## 2. What's MISSING or BROKEN
|
|
|
|
### Critical Issue: Route Mismatch
|
|
|
|
| Issue | Description | Impact |
|
|
|-------|-------------|--------|
|
|
| **Route path mismatch** | Layout links to `/settings/notifications` but route is at `/notifications` | Page not found when clicking nav |
|
|
| **Settings integration missing** | Settings.tsx doesn't include notifications tab | Even if route fixed, no tab in settings UI |
|
|
| **Route nesting incorrect** | Route defined at top level, not under `/settings/*` | Inconsistent with navigation structure |
|
|
|
|
### Missing Integration
|
|
|
|
The Notifications page component exists and is fully functional, but it's **not wired up correctly** to the navigation:
|
|
|
|
```
|
|
User clicks "Notifications" in sidebar
|
|
↓
|
|
Navigation points to: /settings/notifications
|
|
↓
|
|
App.tsx has NO route for /settings/notifications
|
|
↓
|
|
React Router shows: blank content (falls through to no match)
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Recent Git Changes
|
|
|
|
From `get_changed_files`, the relevant recent change to Layout.tsx:
|
|
|
|
```diff
|
|
- { name: t('navigation.notifications'), path: '/notifications', icon: '🔔' },
|
|
- // Import group moved under Tasks
|
|
+ { name: t('navigation.notifications'), path: '/settings/notifications', icon: '🔔' },
|
|
```
|
|
|
|
**What happened**: The navigation path was changed from `/notifications` (which matches the route) to `/settings/notifications` (which has no route), and the entry was moved under the Settings submenu.
|
|
|
|
**The route in App.tsx was NOT updated** to match this change.
|
|
|
|
---
|
|
|
|
## 4. Two Distinct Notification Features
|
|
|
|
There are actually **TWO different notification features** that may be causing confusion:
|
|
|
|
### Feature 1: Notification Providers (Settings Page)
|
|
|
|
- **Purpose**: Configure external notification channels (Discord, Slack, etc.)
|
|
- **Page**: `Notifications.tsx`
|
|
- **API**: `/api/v1/notifications/providers/*`, `/api/v1/notifications/external-templates/*`
|
|
- **This is what the settings navigation should show**
|
|
|
|
### Feature 2: System Notifications (Header Bell)
|
|
|
|
- **Purpose**: In-app notification center showing system events
|
|
- **Component**: `NotificationCenter.tsx`
|
|
- **API**: `/api/v1/notifications`, `/api/v1/notifications/:id/read`
|
|
- **This already works correctly in the header**
|
|
|
|
### Feature 3: Security Notifications (Cerberus Modal)
|
|
|
|
- **Purpose**: Configure notifications for security events (WAF blocks, ACL denials, etc.)
|
|
- **Component**: `SecurityNotificationSettingsModal.tsx`
|
|
- **Hook**: `useNotifications.ts`
|
|
- **API**: `/api/v1/security/notifications/settings`
|
|
- **Accessed from Cerberus/Security dashboard**
|
|
|
|
---
|
|
|
|
## 5. Solutions
|
|
|
|
### Option A: Fix Route to Match Navigation (Recommended)
|
|
|
|
Update App.tsx to add the route under settings:
|
|
|
|
```typescript
|
|
{/* Settings Routes */}
|
|
<Route path="settings" element={<Settings />}>
|
|
<Route index element={<SystemSettings />} />
|
|
<Route path="system" element={<SystemSettings />} />
|
|
<Route path="notifications" element={<Notifications />} /> // ADD THIS
|
|
<Route path="smtp" element={<SMTPSettings />} />
|
|
<Route path="account" element={<Account />} />
|
|
<Route path="account-management" element={<UsersPage />} />
|
|
</Route>
|
|
```
|
|
|
|
Also update Settings.tsx to add the tab:
|
|
|
|
```typescript
|
|
const navItems = [
|
|
{ path: '/settings/system', label: t('settings.system'), icon: Server },
|
|
{ path: '/settings/notifications', label: t('settings.notifications'), icon: Bell }, // ADD THIS
|
|
{ path: '/settings/smtp', label: t('settings.smtp'), icon: Mail },
|
|
{ path: '/settings/account', label: t('settings.account'), icon: User },
|
|
]
|
|
```
|
|
|
|
### Option B: Revert Navigation to Match Route
|
|
|
|
Change Layout.tsx back to use the existing route:
|
|
|
|
```typescript
|
|
// Move outside settings submenu, at top level
|
|
{ name: t('navigation.notifications'), path: '/notifications', icon: '🔔' },
|
|
```
|
|
|
|
This keeps the existing route but changes the navigation structure.
|
|
|
|
---
|
|
|
|
## 6. Test Files Review
|
|
|
|
### Existing Tests (All Pass)
|
|
|
|
| Test File | Coverage |
|
|
|-----------|----------|
|
|
| `useNotifications.test.tsx` | Security notification hooks ✅ |
|
|
| `NotificationCenter.test.tsx` | Header notification dropdown ✅ |
|
|
| `SecurityNotificationSettingsModal.test.tsx` | Security settings modal ✅ |
|
|
| `notification_handler_test.go` | System notifications API ✅ |
|
|
| `notification_provider_handler_test.go` | Provider API ✅ |
|
|
| `notification_template_handler_test.go` | Template API ✅ |
|
|
| `security_notifications_test.go` | Security notifications API ✅ |
|
|
|
|
**No tests would prevent the routing fix** - the tests cover API and component behavior, not navigation routing.
|
|
|
|
---
|
|
|
|
## 7. Summary
|
|
|
|
### What EXISTS and WORKS
|
|
|
|
- ✅ `Notifications.tsx` page component (fully implemented)
|
|
- ✅ `notifications.ts` API client (complete)
|
|
- ✅ Backend handlers and routes (complete)
|
|
- ✅ Database models (complete)
|
|
- ✅ `NotificationCenter.tsx` header component (works)
|
|
- ✅ Navigation link in Layout.tsx (points to `/settings/notifications`)
|
|
|
|
### What's BROKEN
|
|
|
|
- ❌ **Route definition** - Route is at `/notifications` but navigation points to `/settings/notifications`
|
|
- ❌ **Settings.tsx tabs** - Missing notifications tab
|
|
|
|
### What NEEDS to be done
|
|
|
|
1. Add route `<Route path="notifications" element={<Notifications />} />` under `/settings/*` in App.tsx
|
|
2. Add notifications tab to Settings.tsx navItems array
|
|
3. Optionally remove the old `/notifications` top-level route to avoid confusion
|
|
|
|
---
|
|
|
|
## 8. Quick Fix Checklist
|
|
|
|
- [ ] In `App.tsx`: Add `<Route path="notifications" element={<Notifications />} />` inside the `<Route path="settings">` block
|
|
- [ ] In `Settings.tsx`: Add `{ path: '/settings/notifications', label: t('settings.notifications'), icon: Bell }` to navItems
|
|
- [ ] In `Settings.tsx`: Import `Bell` from lucide-react
|
|
- [ ] Optional: Remove `<Route path="notifications" element={<Notifications />} />` from top level in App.tsx (line 70)
|
|
- [ ] Test: Navigate to Settings → Notifications tab should appear and work
|