@gravito/zenith 0.1.0-beta.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/bin.js +38846 -27303
- package/dist/client/assets/index-C332gZ-J.css +1 -0
- package/dist/client/assets/index-D4HibwTK.js +436 -0
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +38846 -27303
- package/docs/ALERTING_GUIDE.md +71 -0
- package/docs/LARAVEL_ZENITH_ROADMAP.md +109 -0
- package/docs/QUASAR_MASTER_PLAN.md +140 -0
- package/package.json +52 -48
- package/scripts/debug_redis_keys.ts +24 -0
- package/specs/PULSE_SPEC.md +86 -0
- package/src/client/App.tsx +2 -0
- package/src/client/Layout.tsx +18 -0
- package/src/client/Sidebar.tsx +2 -1
- package/src/client/WorkerStatus.tsx +121 -76
- package/src/client/components/BrandIcons.tsx +138 -0
- package/src/client/components/ConfirmDialog.tsx +0 -1
- package/src/client/components/JobInspector.tsx +18 -6
- package/src/client/components/PageHeader.tsx +38 -0
- package/src/client/pages/OverviewPage.tsx +17 -20
- package/src/client/pages/PulsePage.tsx +478 -0
- package/src/client/pages/QueuesPage.tsx +1 -3
- package/src/client/pages/SettingsPage.tsx +640 -78
- package/src/client/pages/WorkersPage.tsx +71 -3
- package/src/client/pages/index.ts +1 -0
- package/src/server/index.ts +311 -11
- package/src/server/services/AlertService.ts +189 -41
- package/src/server/services/CommandService.ts +137 -0
- package/src/server/services/PulseService.ts +80 -0
- package/src/server/services/QueueService.ts +63 -6
- package/src/shared/types.ts +99 -0
- package/tsconfig.json +2 -2
- package/ARCHITECTURE.md +0 -88
- package/BATCH_OPERATIONS_IMPLEMENTATION.md +0 -159
- package/EVOLUTION_BLUEPRINT.md +0 -112
- package/JOBINSPECTOR_SCROLL_FIX.md +0 -152
- package/PULSE_IMPLEMENTATION_PLAN.md +0 -111
- package/TESTING_BATCH_OPERATIONS.md +0 -252
- package/dist/client/assets/index-DGYEwTDL.css +0 -1
- package/dist/client/assets/index-oyTdySX0.js +0 -421
- /package/{DEPLOYMENT.md → docs/DEPLOYMENT.md} +0 -0
- /package/{DOCS_INTERNAL.md → docs/DOCS_INTERNAL.md} +0 -0
- /package/{QUICK_TEST_GUIDE.md → docs/QUICK_TEST_GUIDE.md} +0 -0
- /package/{ROADMAP.md → docs/ROADMAP.md} +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export interface PulseCpu {
|
|
2
|
+
system: number // Percentage 0-100
|
|
3
|
+
process: number // Percentage 0-100
|
|
4
|
+
cores: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface PulseMemory {
|
|
8
|
+
system: {
|
|
9
|
+
total: number // bytes
|
|
10
|
+
free: number // bytes
|
|
11
|
+
used: number // bytes
|
|
12
|
+
}
|
|
13
|
+
process: {
|
|
14
|
+
rss: number // bytes
|
|
15
|
+
heapTotal: number // bytes
|
|
16
|
+
heapUsed: number // bytes
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PulseRuntime {
|
|
21
|
+
uptime: number // seconds
|
|
22
|
+
framework: string // e.g. "Node 20.1", "Laravel 10.0"
|
|
23
|
+
status?: string
|
|
24
|
+
errors?: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface QueueSnapshot {
|
|
28
|
+
name: string
|
|
29
|
+
driver: 'redis' | 'sqs' | 'rabbitmq'
|
|
30
|
+
size: {
|
|
31
|
+
waiting: number
|
|
32
|
+
active: number
|
|
33
|
+
failed: number
|
|
34
|
+
delayed: number
|
|
35
|
+
}
|
|
36
|
+
throughput?: {
|
|
37
|
+
in: number // jobs/min
|
|
38
|
+
out: number // jobs/min
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface PulseNode {
|
|
43
|
+
id: string // Unique Instance ID
|
|
44
|
+
service: string // Group name
|
|
45
|
+
language: 'node' | 'bun' | 'deno' | 'php' | 'go' | 'python' | 'other'
|
|
46
|
+
version: string // App Version
|
|
47
|
+
pid: number
|
|
48
|
+
hostname: string
|
|
49
|
+
platform: string
|
|
50
|
+
cpu: PulseCpu
|
|
51
|
+
memory: PulseMemory
|
|
52
|
+
queues?: QueueSnapshot[]
|
|
53
|
+
runtime: PulseRuntime
|
|
54
|
+
meta?: any // Extra metadata like Laravel workers
|
|
55
|
+
timestamp: number // Last heartbeat
|
|
56
|
+
}
|
|
57
|
+
export interface AlertRule {
|
|
58
|
+
id: string
|
|
59
|
+
name: string
|
|
60
|
+
type: 'backlog' | 'failure' | 'worker_lost' | 'node_cpu' | 'node_ram'
|
|
61
|
+
threshold: number
|
|
62
|
+
queue?: string // Optional: specific queue or all
|
|
63
|
+
cooldownMinutes: number
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface AlertEvent {
|
|
67
|
+
ruleId: string
|
|
68
|
+
timestamp: number
|
|
69
|
+
message: string
|
|
70
|
+
severity: 'warning' | 'critical'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface AlertConfig {
|
|
74
|
+
channels: {
|
|
75
|
+
slack?: {
|
|
76
|
+
enabled: boolean
|
|
77
|
+
webhookUrl: string
|
|
78
|
+
}
|
|
79
|
+
discord?: {
|
|
80
|
+
enabled: boolean
|
|
81
|
+
webhookUrl: string
|
|
82
|
+
}
|
|
83
|
+
email?: {
|
|
84
|
+
enabled: boolean
|
|
85
|
+
smtpHost: string
|
|
86
|
+
smtpPort: number
|
|
87
|
+
smtpUser: string
|
|
88
|
+
smtpPass: string
|
|
89
|
+
from: string
|
|
90
|
+
to: string // Comma separated list
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface MaintenanceConfig {
|
|
96
|
+
autoCleanup: boolean
|
|
97
|
+
retentionDays: number
|
|
98
|
+
lastRun?: number // Timestamp
|
|
99
|
+
}
|
package/tsconfig.json
CHANGED
package/ARCHITECTURE.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# 🏗️ Gravito Flux Console Architecture
|
|
3
|
-
|
|
4
|
-
> The official, standalone visualization and management console for Gravito Flux & Stream.
|
|
5
|
-
|
|
6
|
-
## 1. Project Manifesto
|
|
7
|
-
|
|
8
|
-
- **Dogfooding First**: Uses `@gravito/photon` for HTTP serving and `@gravito/stream` for queue interaction.
|
|
9
|
-
- **Zero-Config**: Should work out-of-the-box via `npx` with minimal arguments.
|
|
10
|
-
- **Stateless**: The console itself holds no long-term state; Redis is the source of truth.
|
|
11
|
-
- **Micro-Frontend Ready**: Built with React, matching the Gravito Admin ecosystem, but capable of running standalone.
|
|
12
|
-
|
|
13
|
-
## 2. System Architecture
|
|
14
|
-
|
|
15
|
-
```mermaid
|
|
16
|
-
graph TD
|
|
17
|
-
CLI[CLI Entry (bin)] --> Boot[Bootstrapper]
|
|
18
|
-
Boot -->|Init| Server[Photon Server (Node/Bun)]
|
|
19
|
-
|
|
20
|
-
subgraph "Backend Layer"
|
|
21
|
-
Server -->|Serve| API[Management API]
|
|
22
|
-
Server -->|Serve| Static[Frontend Assets]
|
|
23
|
-
|
|
24
|
-
API -->|Command| QM[QueueManager (@gravito/stream)]
|
|
25
|
-
QM -->|Protocol| Redis[(Redis)]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
subgraph "Frontend Layer (React/Vite)"
|
|
29
|
-
UI[Dashboard UI] -->|Fetch| API
|
|
30
|
-
end
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 3. Technical Stack
|
|
34
|
-
|
|
35
|
-
### Backend
|
|
36
|
-
- **Runtime**: Bun / Node.js (Compat)
|
|
37
|
-
- **Framework**: **`@gravito/photon`** (Hono wrapper)
|
|
38
|
-
- **Data Access**: **`@gravito/stream`** (Directly uses QueueDrivers)
|
|
39
|
-
- **Persistence**: **`MySQLPersistence`** / **`SQLitePersistence`** for long-term auditing.
|
|
40
|
-
|
|
41
|
-
### Frontend
|
|
42
|
-
- **Framework**: React 19
|
|
43
|
-
- **Build Tool**: Vite
|
|
44
|
-
- **Styling**: TailwindCSS (keeping consistent with `admin-shell`)
|
|
45
|
-
- **State Management**: React Query (TanStack Query) for real-time polling.
|
|
46
|
-
|
|
47
|
-
## 4. Key Features (Phase 1 MVP)
|
|
48
|
-
|
|
49
|
-
### A. Dashboard
|
|
50
|
-
- **System Overview**: Connection status, Driver type (Redis/Rabbit/Kafka).
|
|
51
|
-
- **Throughput Metrics**: Jobs processed per second (calculated window).
|
|
52
|
-
|
|
53
|
-
### B. Queue Management
|
|
54
|
-
- **List Queues**: Show all active queues with counts (Waiting, Active, Failed).
|
|
55
|
-
- **Inspect Queue**: View jobs in a paginated list.
|
|
56
|
-
- **Job Detail**: View JSON payload and stack trace.
|
|
57
|
-
|
|
58
|
-
### C. Actions
|
|
59
|
-
- **Retry Job**: Move job from `failed` to `waiting`.
|
|
60
|
-
- **Delete Job**: Remove job permanently.
|
|
61
|
-
|
|
62
|
-
### D. Persistence & Auditing
|
|
63
|
-
- **Job Archive**: Completed and Failed jobs move to SQL storage.
|
|
64
|
-
- **Operational Log Archiving**: Persistent storage for system events and worker activities with history search.
|
|
65
|
-
- **Hybrid Search**: Query both Redis (Live) and SQL (Archive) simultaneously.
|
|
66
|
-
- **Retention Management**: Configurable auto-cleanup for historical data.
|
|
67
|
-
|
|
68
|
-
### E. Alerting System
|
|
69
|
-
- **Real-time Checks**: Monitoring for failure spikes and worker loss.
|
|
70
|
-
- **Notifications**: Slack integration via Webhooks.
|
|
71
|
-
- **Cool-down Logic**: Prevents duplicated alerts for the same event.
|
|
72
|
-
|
|
73
|
-
## 5. Deployment Strategy
|
|
74
|
-
|
|
75
|
-
The package is published as a standard NPM package. It contains a `bin` entry point.
|
|
76
|
-
|
|
77
|
-
### Usage Scenarios
|
|
78
|
-
1. **Local Ad-hoc**: `npx @gravito/flux-console start --url redis://...`
|
|
79
|
-
2. **Project Integration**: Add to `package.json` scripts.
|
|
80
|
-
3. **Docker**: Official image wrapping the CLI.
|
|
81
|
-
|
|
82
|
-
## 6. Development Workflow
|
|
83
|
-
|
|
84
|
-
Since this is a monolithic package (Backend + Frontend):
|
|
85
|
-
- `npm run dev` should start:
|
|
86
|
-
1. Vite Dev Server (Frontend)
|
|
87
|
-
2. Photon Watch Mode (Backend)
|
|
88
|
-
- Backend should proxy `/` requests to Vite during development.
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
# Batch Operations Implementation Summary
|
|
2
|
-
|
|
3
|
-
## ✅ Completed Features
|
|
4
|
-
|
|
5
|
-
### 1. Backend Enhancements
|
|
6
|
-
|
|
7
|
-
#### New Service Methods (`QueueService.ts`)
|
|
8
|
-
- **`getJobCount(queueName, type)`**: Get total count of jobs by type (waiting/delayed/failed)
|
|
9
|
-
- **`deleteAllJobs(queueName, type)`**: Delete ALL jobs of a specific type from a queue
|
|
10
|
-
- **`retryAllJobs(queueName, type)`**: Retry ALL jobs of a specific type (delayed or failed)
|
|
11
|
-
|
|
12
|
-
#### New API Endpoints (`server/index.ts`)
|
|
13
|
-
- **`GET /api/queues/:name/jobs/count`**: Returns total count of jobs by type
|
|
14
|
-
- **`POST /api/queues/:name/jobs/bulk-delete-all`**: Deletes ALL jobs of a specific type
|
|
15
|
-
- **`POST /api/queues/:name/jobs/bulk-retry-all`**: Retries ALL jobs of a specific type
|
|
16
|
-
|
|
17
|
-
### 2. Frontend Enhancements
|
|
18
|
-
|
|
19
|
-
#### New Component: `ConfirmDialog.tsx`
|
|
20
|
-
- Reusable confirmation dialog with:
|
|
21
|
-
- Animated entrance/exit (Framer Motion)
|
|
22
|
-
- Loading state support
|
|
23
|
-
- Variant support (danger/warning/info)
|
|
24
|
-
- Customizable messages and buttons
|
|
25
|
-
|
|
26
|
-
#### Enhanced `JobInspector` Component
|
|
27
|
-
**State Management:**
|
|
28
|
-
- `totalCount`: Tracks total jobs matching current view
|
|
29
|
-
- `isProcessing`: Loading state for bulk operations
|
|
30
|
-
- `confirmDialog`: Manages confirmation dialog state
|
|
31
|
-
|
|
32
|
-
**New Features:**
|
|
33
|
-
1. **Total Count Display**
|
|
34
|
-
- Fetches and displays total job count for non-archive views
|
|
35
|
-
- Shows "X of Y total" in the selection bar
|
|
36
|
-
|
|
37
|
-
2. **"Select All Matching Query" UI**
|
|
38
|
-
- Warning banner when showing partial results
|
|
39
|
-
- "Delete All X" and "Retry All X" buttons
|
|
40
|
-
- Only shown when total count exceeds visible jobs
|
|
41
|
-
|
|
42
|
-
3. **Confirmation Dialogs**
|
|
43
|
-
- Replaces browser `confirm()` with custom modal
|
|
44
|
-
- Shows job counts and queue names
|
|
45
|
-
- Warning emoji for destructive "ALL" operations
|
|
46
|
-
- Loading spinner during processing
|
|
47
|
-
|
|
48
|
-
4. **Keyboard Shortcuts**
|
|
49
|
-
- **Ctrl+A / Cmd+A**: Select all visible jobs on current page
|
|
50
|
-
- **Escape**: Clear selection → Close dialog → Close inspector (cascading)
|
|
51
|
-
|
|
52
|
-
5. **Improved UX**
|
|
53
|
-
- "Select All (Page)" label clarifies scope
|
|
54
|
-
- Total count shown next to checkbox
|
|
55
|
-
- Disabled state for processing operations
|
|
56
|
-
- Error handling with user-friendly messages
|
|
57
|
-
|
|
58
|
-
### 3. Visual Enhancements
|
|
59
|
-
|
|
60
|
-
- **Amber warning banner** for "Select All Matching" feature
|
|
61
|
-
- **AlertCircle icon** for visual emphasis
|
|
62
|
-
- **Loading spinners** in confirmation buttons
|
|
63
|
-
- **Disabled states** prevent double-clicks
|
|
64
|
-
- **Color-coded buttons**:
|
|
65
|
-
- Red for delete operations
|
|
66
|
-
- Amber for retry operations
|
|
67
|
-
- Primary color for standard actions
|
|
68
|
-
|
|
69
|
-
## 🎯 User Workflows
|
|
70
|
-
|
|
71
|
-
### Workflow 1: Bulk Delete Selected Jobs
|
|
72
|
-
1. User opens JobInspector for a queue
|
|
73
|
-
2. Clicks checkboxes to select specific jobs
|
|
74
|
-
3. Clicks "Delete Selected" button
|
|
75
|
-
4. Confirms in dialog
|
|
76
|
-
5. Jobs are deleted, UI refreshes
|
|
77
|
-
|
|
78
|
-
### Workflow 2: Delete ALL Jobs of a Type
|
|
79
|
-
1. User opens JobInspector for a queue
|
|
80
|
-
2. Switches to "failed" view (for example)
|
|
81
|
-
3. Sees warning banner: "Showing 50 of 1,234 total failed jobs"
|
|
82
|
-
4. Clicks "Delete All 1,234" button
|
|
83
|
-
5. Sees strong warning dialog with ⚠️ emoji
|
|
84
|
-
6. Confirms action
|
|
85
|
-
7. ALL 1,234 failed jobs are deleted
|
|
86
|
-
|
|
87
|
-
### Workflow 3: Keyboard Power User
|
|
88
|
-
1. User opens JobInspector
|
|
89
|
-
2. Presses **Ctrl+A** to select all visible jobs
|
|
90
|
-
3. Presses **Delete** button
|
|
91
|
-
4. Presses **Escape** to cancel dialog
|
|
92
|
-
5. Presses **Escape** again to close inspector
|
|
93
|
-
|
|
94
|
-
## 🔧 Technical Details
|
|
95
|
-
|
|
96
|
-
### Backend Implementation
|
|
97
|
-
- **Redis Operations**: Uses `LLEN`, `ZCARD` for counts; `DEL` for bulk deletion
|
|
98
|
-
- **Atomic Operations**: Existing `retryDelayedJob()` and `retryAllFailedJobs()` reused
|
|
99
|
-
- **Type Safety**: Full TypeScript support with proper type guards
|
|
100
|
-
|
|
101
|
-
### Frontend Implementation
|
|
102
|
-
- **React Hooks**: `useState`, `useEffect`, `useQuery` for state management
|
|
103
|
-
- **TanStack Query**: Automatic cache invalidation after bulk operations
|
|
104
|
-
- **Framer Motion**: Smooth animations for dialog entrance/exit
|
|
105
|
-
- **Event Handling**: Keyboard event listeners with proper cleanup
|
|
106
|
-
|
|
107
|
-
### Error Handling
|
|
108
|
-
- Try-catch blocks around all API calls
|
|
109
|
-
- User-friendly error messages
|
|
110
|
-
- Console logging for debugging
|
|
111
|
-
- Graceful degradation if API fails
|
|
112
|
-
|
|
113
|
-
## 📊 Performance Considerations
|
|
114
|
-
|
|
115
|
-
- **Lazy Loading**: Total count fetched only when needed
|
|
116
|
-
- **Debouncing**: Could be added for rapid selection changes (future enhancement)
|
|
117
|
-
- **Pagination**: Archive view supports pagination for large datasets
|
|
118
|
-
- **Redis Efficiency**: Uses pipelined commands where possible
|
|
119
|
-
|
|
120
|
-
## 🧪 Testing Recommendations
|
|
121
|
-
|
|
122
|
-
- [ ] Test with 10, 100, 1,000+ jobs
|
|
123
|
-
- [ ] Test keyboard shortcuts across browsers
|
|
124
|
-
- [ ] Test confirmation dialog cancellation
|
|
125
|
-
- [ ] Test error scenarios (network failures, Redis errors)
|
|
126
|
-
- [ ] Test archive view (should not show "Delete All" buttons)
|
|
127
|
-
- [ ] Test concurrent bulk operations
|
|
128
|
-
- [ ] Test UI responsiveness during long operations
|
|
129
|
-
|
|
130
|
-
## 📝 Documentation Updates
|
|
131
|
-
|
|
132
|
-
- ✅ Updated `ROADMAP.md` to mark feature as completed
|
|
133
|
-
- ✅ Added detailed task checklist
|
|
134
|
-
- ✅ Included keyboard shortcuts in documentation
|
|
135
|
-
|
|
136
|
-
## 🚀 Future Enhancements
|
|
137
|
-
|
|
138
|
-
1. **Progress Indicators**: Show "Deleting 500/1000..." for large batches
|
|
139
|
-
2. **Undo Functionality**: Temporary recovery window for accidental deletions
|
|
140
|
-
3. **Bulk Edit**: Modify job data in bulk
|
|
141
|
-
4. **Export/Import**: Export selected jobs to JSON, import later
|
|
142
|
-
5. **Advanced Filters**: Select jobs by date range, error type, etc.
|
|
143
|
-
6. **Bulk Scheduling**: Reschedule multiple delayed jobs at once
|
|
144
|
-
|
|
145
|
-
## 🎉 Summary
|
|
146
|
-
|
|
147
|
-
The Batch Operations feature is now **fully implemented** and **production-ready**. Users can:
|
|
148
|
-
- Select multiple jobs with checkboxes
|
|
149
|
-
- Perform bulk delete/retry on selected jobs
|
|
150
|
-
- Delete/retry ALL jobs of a specific type with a single click
|
|
151
|
-
- Use keyboard shortcuts for faster workflows
|
|
152
|
-
- Get clear confirmation dialogs with loading states
|
|
153
|
-
- See total counts and visual feedback throughout
|
|
154
|
-
|
|
155
|
-
**Estimated Implementation Time**: ~3 hours
|
|
156
|
-
**Actual Implementation Time**: ~2.5 hours
|
|
157
|
-
**Lines of Code Added**: ~350 lines
|
|
158
|
-
**Files Modified**: 4 files
|
|
159
|
-
**New Files Created**: 2 files
|
package/EVOLUTION_BLUEPRINT.md
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# Gravito Zenith Evolution Blueprint
|
|
2
|
-
**Target**: Zenith v2.0 - The Universal Application Control Plane
|
|
3
|
-
**Core Philosophy**: Lightweight, Redis-Native, Language-Agnostic.
|
|
4
|
-
|
|
5
|
-
## 🧭 Strategic Vision
|
|
6
|
-
|
|
7
|
-
We aim to evolve Zenith from a **Queue Manager** into a **Lightweight Application Control Plane**. We will absorb the best features from industry leaders (Laravel Pulse, Sidekiq, BullMQ) while strictly avoiding their architectural pitfalls (heavy deps, SQL locks, language coupling).
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 📅 Roadmap Structure
|
|
12
|
-
|
|
13
|
-
### Phase 1: Deep Visibility (Queue Insights)
|
|
14
|
-
**Focus**: Enhance the depth of information for the current Queue System.
|
|
15
|
-
**Benchmarks**: Sidekiq, BullMQ.
|
|
16
|
-
|
|
17
|
-
#### 1.1 Worker "X-Ray" Vision (The "Busy" State)
|
|
18
|
-
- **Concept**: Instead of just showing "Busy", show *what* the worker is doing.
|
|
19
|
-
- **Implementation**: Update Heartbeat Protocol to include `currentJobId` and `jobName`.
|
|
20
|
-
- **UI**: Workers table shows "Processing: Order #1024 (SendEmail)".
|
|
21
|
-
- **Benefit**: Instantly identify which job is hogging a worker.
|
|
22
|
-
- **Difference**: Unlike Sidekiq which uses expensive extensive locking, we use ephemeral keys.
|
|
23
|
-
|
|
24
|
-
#### 1.2 Enhanced Payload Inspector
|
|
25
|
-
- **Concept**: Developer-friendly data inspection.
|
|
26
|
-
- **Implementation**:
|
|
27
|
-
- Syntax-highlighted JSON viewer with folding.
|
|
28
|
-
- "Copy as cURL" or "Copy to Clipboard" actions.
|
|
29
|
-
- Display stack traces with click-to-open (if local) potential.
|
|
30
|
-
- **UX Rule**: Always lazy-load heavy payloads. Never fetch them in the list view.
|
|
31
|
-
|
|
32
|
-
#### 1.3 Timeline Visualization (Gantt-lite)
|
|
33
|
-
- **Concept**: Visualize concurrency.
|
|
34
|
-
- **Implementation**: A canvas-based timeline showing job execution durations overlapping in time.
|
|
35
|
-
- **Benefit**: Spot resource contention or gaps in processing.
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Phase 2: System Pulse (Resource Monitoring)
|
|
40
|
-
**Focus**: Lightweight APM (Application Performance Monitoring).
|
|
41
|
-
**Benchmarks**: Laravel Pulse, PM2.
|
|
42
|
-
|
|
43
|
-
#### 2.1 Gravito Pulse Protocol (GPP)
|
|
44
|
-
- **Concept**: A standardized JSON structure for services to report health.
|
|
45
|
-
- **Structure**: `pulse:{service}:{id}` (TTL 30s).
|
|
46
|
-
- **Metrics**: CPU%, RAM (RSS/Heap), Disk Usage, Uptime, Event Loop Lag.
|
|
47
|
-
- **Avoidance**: Do NOT store historical time-series data in SQL. Use Redis Lists/Streams with aggressive trimming (e.g., keep last 1 hour).
|
|
48
|
-
|
|
49
|
-
#### 2.2 Grid Dashboard
|
|
50
|
-
- **Concept**: Customizable "Mission Control" view.
|
|
51
|
-
- **UI**: Drag-and-drop grid system.
|
|
52
|
-
- **Widgets**:
|
|
53
|
-
- Host Health (CPU/RAM guages).
|
|
54
|
-
- Queue Backlog (Sparklines).
|
|
55
|
-
- Exception Rate (Counter).
|
|
56
|
-
- Slowest Routes (List).
|
|
57
|
-
|
|
58
|
-
#### 2.3 Cross-Language Recorders
|
|
59
|
-
- **Goal**: Provide simple SDKs.
|
|
60
|
-
- `@gravito/recorder-node`: For Express/Hono/Nest.
|
|
61
|
-
- `@gravito/recorder-php`: For Laravel/Symfony.
|
|
62
|
-
- `@gravito/recorder-python`: For Django/FastAPI.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Phase 3: Intelligent Operations (Proactive Ops)
|
|
67
|
-
**Focus**: Alerting and Anomaly Detection.
|
|
68
|
-
**Benchmarks**: New Relic (Lite), Oban.
|
|
69
|
-
|
|
70
|
-
#### 3.1 Outlier Detection (The "Slow" & "Error" Trap)
|
|
71
|
-
- **Concept**: Only capture interesting data.
|
|
72
|
-
- **Logic**:
|
|
73
|
-
- If `duration > threshold`: Push to `pulse:slow_jobs`.
|
|
74
|
-
- If `status >= 500`: Push to `pulse:exceptions`.
|
|
75
|
-
- **Benefit**: Zero overhead for successful, fast requests.
|
|
76
|
-
|
|
77
|
-
#### 3.2 Smart Alerting Engine
|
|
78
|
-
- **Concept**: "Don't spam me."
|
|
79
|
-
- **Features**:
|
|
80
|
-
- **Thresholds**: "CPU > 90% for 5 minutes".
|
|
81
|
-
- **Cooldown**: "Alert once per hour per rule".
|
|
82
|
-
- **Channels**: Slack, Discord, Email, Webhook.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## 🎨 UI/UX Unification Strategy
|
|
87
|
-
|
|
88
|
-
To prevent "Feature Bloat" (UI Clutter), we will enforce strict design rules:
|
|
89
|
-
|
|
90
|
-
### 1. Navigation Hierarchy
|
|
91
|
-
Refactor Sidebar into logical groups:
|
|
92
|
-
- **Dashboards** (Overview, System Pulse)
|
|
93
|
-
- **Queues** (Active, Waiting, Delayed, Failed)
|
|
94
|
-
- **Infrastructure** (Workers, Databases, Redis)
|
|
95
|
-
- **Settings** (Alerts, API Keys)
|
|
96
|
-
|
|
97
|
-
### 2. Contextual Density
|
|
98
|
-
- **List View**: Minimal info (ID, Name, Status, Time).
|
|
99
|
-
- **Detail Panel**: Slide-over panel for deep inspection (Payloads, Stack Traces, Logs).
|
|
100
|
-
- **Avoidance**: Don't try to cram everything into the table rows.
|
|
101
|
-
|
|
102
|
-
### 3. Unified Filters
|
|
103
|
-
- Create a shared "Filter Bar" component (Date Range, Status, Queue Name) that works consistently across Logs, Jobs, and Pulse views.
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## ✅ Implementation Checklist (Next Steps)
|
|
108
|
-
|
|
109
|
-
1. **[ ] Protocol Definition**: Document `GPP` (Gravito Pulse Protocol).
|
|
110
|
-
2. **[ ] Backend Core**: Implement `SystemMonitor` service in Zenith.
|
|
111
|
-
3. **[ ] Frontend Core**: Create the `GridDashboard` component layout.
|
|
112
|
-
4. **[ ] Feature**: Implement `Worker X-Ray` (easiest win from Phase 1).
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# JobInspector 滾動修復
|
|
2
|
-
|
|
3
|
-
## 🐛 問題描述
|
|
4
|
-
|
|
5
|
-
當佇列中有大量工作(例如 100+ 個)時,JobInspector 側邊欄會被撐得很高,導致:
|
|
6
|
-
- 整個側邊欄超出螢幕高度
|
|
7
|
-
- 無法看到底部的 "Dismiss" 按鈕
|
|
8
|
-
- 需要滾動整個頁面才能查看所有內容
|
|
9
|
-
- UX 體驗很差
|
|
10
|
-
|
|
11
|
-
## ✅ 修復方案
|
|
12
|
-
|
|
13
|
-
### 修改的 CSS 類別
|
|
14
|
-
|
|
15
|
-
#### 1. 主容器 (`motion.div`)
|
|
16
|
-
```tsx
|
|
17
|
-
// 修改前
|
|
18
|
-
className="bg-card border-l h-full w-full max-w-2xl shadow-2xl flex flex-col"
|
|
19
|
-
|
|
20
|
-
// 修改後
|
|
21
|
-
className="bg-card border-l h-screen max-h-screen w-full max-w-2xl shadow-2xl flex flex-col overflow-hidden"
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**變更說明:**
|
|
25
|
-
- `h-full` → `h-screen max-h-screen`: 明確限制高度為視窗高度
|
|
26
|
-
- 新增 `overflow-hidden`: 防止內容溢出
|
|
27
|
-
|
|
28
|
-
#### 2. 頂部標題區域
|
|
29
|
-
```tsx
|
|
30
|
-
// 修改前
|
|
31
|
-
className="p-6 border-b flex justify-between items-center bg-muted/20"
|
|
32
|
-
|
|
33
|
-
// 修改後
|
|
34
|
-
className="p-6 border-b flex justify-between items-center bg-muted/20 flex-shrink-0"
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**變更說明:**
|
|
38
|
-
- 新增 `flex-shrink-0`: 防止標題區域被壓縮
|
|
39
|
-
|
|
40
|
-
#### 3. 內容滾動區域
|
|
41
|
-
```tsx
|
|
42
|
-
// 修改前
|
|
43
|
-
className="p-0 overflow-y-auto flex-1 bg-muted/5"
|
|
44
|
-
|
|
45
|
-
// 修改後
|
|
46
|
-
className="flex-1 overflow-y-auto bg-muted/5 min-h-0"
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**變更說明:**
|
|
50
|
-
- 移除 `p-0`(padding 由內部元素控制)
|
|
51
|
-
- 新增 `min-h-0`: 允許 flex 子元素縮小到 0,確保滾動正常運作
|
|
52
|
-
|
|
53
|
-
#### 4. 底部按鈕區域
|
|
54
|
-
```tsx
|
|
55
|
-
// 修改前
|
|
56
|
-
className="p-4 border-t bg-card text-right"
|
|
57
|
-
|
|
58
|
-
// 修改後
|
|
59
|
-
className="p-4 border-t bg-card text-right flex-shrink-0"
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**變更說明:**
|
|
63
|
-
- 新增 `flex-shrink-0`: 防止按鈕區域被壓縮
|
|
64
|
-
|
|
65
|
-
## 🎯 修復效果
|
|
66
|
-
|
|
67
|
-
### 修復前
|
|
68
|
-
```
|
|
69
|
-
┌─────────────────────────────┐
|
|
70
|
-
│ Header (標題區) │ ← 正常
|
|
71
|
-
├─────────────────────────────┤
|
|
72
|
-
│ Job 1 │
|
|
73
|
-
│ Job 2 │
|
|
74
|
-
│ Job 3 │
|
|
75
|
-
│ ... │
|
|
76
|
-
│ Job 98 │
|
|
77
|
-
│ Job 99 │
|
|
78
|
-
│ Job 100 │ ← 超出螢幕
|
|
79
|
-
├─────────────────────────────┤
|
|
80
|
-
│ [Dismiss] 按鈕 │ ← 看不到
|
|
81
|
-
└─────────────────────────────┘
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### 修復後
|
|
85
|
-
```
|
|
86
|
-
┌─────────────────────────────┐
|
|
87
|
-
│ Header (標題區) │ ← 固定在頂部
|
|
88
|
-
├─────────────────────────────┤
|
|
89
|
-
│ Job 1 │ ↕️
|
|
90
|
-
│ Job 2 │ ↕️
|
|
91
|
-
│ Job 3 │ ↕️ 可滾動區域
|
|
92
|
-
│ ... │ ↕️
|
|
93
|
-
│ Job 50 │ ↕️
|
|
94
|
-
├─────────────────────────────┤
|
|
95
|
-
│ [Dismiss] 按鈕 │ ← 固定在底部
|
|
96
|
-
└─────────────────────────────┘
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## 📊 技術細節
|
|
100
|
-
|
|
101
|
-
### Flexbox 佈局結構
|
|
102
|
-
```
|
|
103
|
-
motion.div (h-screen, flex flex-col, overflow-hidden)
|
|
104
|
-
├─ Header (flex-shrink-0) ← 不會被壓縮
|
|
105
|
-
├─ Content (flex-1, overflow-y-auto, min-h-0) ← 可滾動,佔據剩餘空間
|
|
106
|
-
└─ Footer (flex-shrink-0) ← 不會被壓縮
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### 關鍵 CSS 屬性
|
|
110
|
-
|
|
111
|
-
1. **`h-screen max-h-screen`**: 限制容器高度為視窗高度
|
|
112
|
-
2. **`overflow-hidden`**: 防止容器本身滾動
|
|
113
|
-
3. **`flex-shrink-0`**: 防止 header 和 footer 被壓縮
|
|
114
|
-
4. **`flex-1`**: 讓內容區域佔據所有剩餘空間
|
|
115
|
-
5. **`overflow-y-auto`**: 只在內容區域啟用垂直滾動
|
|
116
|
-
6. **`min-h-0`**: 允許 flex 子元素縮小(CSS flexbox 的特殊行為)
|
|
117
|
-
|
|
118
|
-
## 🧪 測試驗證
|
|
119
|
-
|
|
120
|
-
### 測試案例
|
|
121
|
-
1. ✅ 打開有 100+ 工作的佇列
|
|
122
|
-
2. ✅ 側邊欄高度固定為螢幕高度
|
|
123
|
-
3. ✅ 工作列表可以滾動
|
|
124
|
-
4. ✅ 頂部標題始終可見
|
|
125
|
-
5. ✅ 底部 Dismiss 按鈕始終可見
|
|
126
|
-
6. ✅ 滾動流暢,無卡頓
|
|
127
|
-
|
|
128
|
-
### 測試步驟
|
|
129
|
-
```bash
|
|
130
|
-
# 1. 確保測試資料存在
|
|
131
|
-
bun scripts/test-batch-operations.ts create
|
|
132
|
-
|
|
133
|
-
# 2. 打開 Flux Console
|
|
134
|
-
# http://localhost:3000
|
|
135
|
-
|
|
136
|
-
# 3. 點擊 test-batch 佇列的 Inspect
|
|
137
|
-
# 4. 確認可以看到頂部標題和底部按鈕
|
|
138
|
-
# 5. 滾動工作列表,確認滾動流暢
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## 📝 相關文件
|
|
142
|
-
|
|
143
|
-
- `src/client/pages/QueuesPage.tsx` - JobInspector 元件
|
|
144
|
-
- 修改行數: 255, 258, 294, 505
|
|
145
|
-
|
|
146
|
-
## 🎉 總結
|
|
147
|
-
|
|
148
|
-
這個修復確保了 JobInspector 在處理大量工作時:
|
|
149
|
-
- ✅ 高度固定為螢幕高度
|
|
150
|
-
- ✅ 內容區域可以獨立滾動
|
|
151
|
-
- ✅ 頂部和底部區域始終可見
|
|
152
|
-
- ✅ UX 體驗大幅改善
|