Files
JRedisDesktop/docs/superpowers/specs/2026-07-04-jredisdesktop-v2-design.md
T
Jokul 7e5d61c099 feat(phase1): architecture skeleton
- Electron 33 main process with frameless window, IPC, win-state persistence
- Preload with contextBridge typed API (window, theme, dialog)
- Vue 3 + Pinia + Element Plus + Vue Router renderer
- Dark/light dual theme via CSS custom properties
- TitleBar with window controls + theme toggle
- StatusBar placeholder
- Design spec document
2026-07-04 17:21:00 +08:00

9.5 KiB

JRedisDesktop v2 — Design Spec

Date: 2026-07-04 Status: Approved

1. Project Identity

Fork of AnotherRedisDesktopManager. Full rewrite of the legacy Vue 2 + Webpack 4 + Electron 12 codebase (archived in legacy/) to Electron 33 + Vue 3 + Vite 6 + TypeScript 5.

2. Scope & Phasing

Phase 1: Architecture Skeleton (Week 1-2)

  • Electron main process with contextIsolation + preload + contextBridge
  • Vue 3 SPA with Vue Router + Element Plus + Pinia
  • electron-vite three-target build pipeline (main/preload/renderer)
  • Dark/light dual theme system via CSS variables
  • Window management (min/max/close, win-state persistence)

Phase 2: Connection Management MVP (Week 2-3)

  • Standalone Redis connections (host:port + password/ACL)
  • TLS support (CA/cert/key file reading via main process)
  • Connection list CRUD with drag-to-reorder
  • Secure credential storage (electron-store + safeStorage encryption)
  • SSH tunnel support (single node)

Phase 3: Key Browser MVP (Week 3-4)

  • Key list with SCAN-based pagination + tree view (key separator)
  • String viewer/editor (plain text, JSON formatting)
  • Hash viewer/editor (field table, pagination, add/edit/delete)
  • Server INFO status dashboard
  • Database switching

Phase 4: Advanced Features (Iterative)

  • List/Set/Zset/Stream editors
  • Format viewers (Msgpack, Protobuf, Pickle, Brotli, Gzip, etc.)
  • Redis CLI terminal
  • Cluster/Sentinel connections
  • Slow log, memory analysis, batch delete
  • i18n (13 languages from legacy)
  • Monaco JSON editor
  • Custom shell formatters

3. Architecture

Process Model

┌─────────────────────────────────────────────┐
│ Main Process                                 │
│  ├── Window management                       │
│  ├── RedisService (ioredis + SSH + TLS)      │
│  ├── electron-store (persistence)            │
│  ├── safeStorage (credential encryption)     │
│  └── IPC handlers (typed channels)           │
├─────────────────────────────────────────────┤
│ Preload (contextBridge)                      │
│  └── window.electronAPI (typed IPC methods)  │
├─────────────────────────────────────────────┤
│ Renderer (Vue 3 SPA)                         │
│  ├── Pinia stores (connection, key, app)     │
│  ├── Vue Router                              │
│  ├── Element Plus                            │
│  └── Composition API components              │
└─────────────────────────────────────────────┘

Key Architectural Decision: RedisService in Main Process

ioredis depends on Node net/tls modules and cannot run in a contextIsolation renderer. All Redis operations go through typed IPC:

Renderer (Pinia action) → IPC invoke → Main (RedisService) → ioredis → Redis

IPC latency (~1ms) is negligible vs Redis network latency (1-100ms). High-frequency operations (SCAN) use batch IPC to minimize round trips.

Renderer Component Tree (MVP)

App.vue
├── TitleBar.vue              (window controls, connection badge)
├── Sidebar.vue
│   ├── ConnectionSearch.vue  (filter connections)
│   ├── ConnectionList.vue    (card list, drag sort)
│   │   └── ConnectionCard.vue
│   └── NewConnectionBtn.vue
├── MainArea.vue              (tab host)
│   ├── StatusView.vue        (INFO dashboard with stat cards)
│   ├── KeyBrowser.vue        (key list + tree + detail)
│   │   ├── KeyList.vue       (SCAN pagination, tree toggle)
│   │   └── KeyDetail.vue     (type dispatcher)
│   │       ├── StringEditor.vue
│   │       └── HashEditor.vue
│   └── CliView.vue           (Phase 4)
└── StatusBar.vue             (connection status, latency)

Pinia Stores

Store Responsibility
useConnectionStore Connections CRUD, active connection, RedisService proxy
useKeyStore Key list, tree view, selected key, key data cache
useAppStore Theme (dark/light), settings, i18n locale, UI state

IPC Channel Design

Channel Type Direction Purpose
redis:connect invoke renderer→main Create Redis connection, return client ID
redis:disconnect invoke renderer→main Close connection by ID
redis:execute invoke renderer→main Execute Redis command, return result
redis:event on main→renderer Connection events (ready, error, close)
storage:get invoke renderer→main Read from electron-store
storage:set invoke renderer→main Write to electron-store
credential:encrypt invoke renderer→main Encrypt via safeStorage
credential:decrypt invoke renderer→main Decrypt via safeStorage
dialog:openFile invoke renderer→main Open file picker, return file content
window:minimize send renderer→main Minimize window
window:maximize send renderer→main Toggle maximize
window:close send renderer→main Close window
theme:set send renderer→main Set nativeTheme source
theme:os-updated on main→renderer OS theme change notification

4. UI Design

Visual Style

  • Dark theme: Deep blue-black gradient background, perspective cards with rotateY/X micro-angles, ambient light overlays, glow dot status indicators, multi-tier shadows for depth hierarchy
  • Light theme: Clean white background, soft shadows, purple-blue accent, light frosted glass effects
  • Dual theme: CSS custom properties (--bg, --text, --border, --accent, --shadow) switch at root level. Follows OS preference by default, manual toggle persisted.

Layout

  • Left sidebar (~260px): connection cards with search + new connection button
  • Right main area: stat cards row + tab bar + content panel
  • Bottom status bar: connection status + latency + app version
  • Resizable sidebar (drag handle)

5. Data Persistence

Strategy: Mixed

  • electron-store (main process): Non-sensitive data — connection list, settings, UI preferences
  • safeStorage (main process): Sensitive data — passwords, SSH private keys, TLS certs

Data Shape

// electron-store schema
interface AppStorage {
  connections: Connection[];
  settings: AppSettings;
  windowState: { x: number; y: number; width: number; height: number; maximized: boolean };
}

interface Connection {
  id: string;
  name: string;
  host: string;
  port: number;
  auth: string;          // encrypted via safeStorage
  username: string;       // ACL username
  tls: boolean;
  tlsCaPath: string;
  tlsCertPath: string;
  tlsKeyPath: string;
  sshEnabled: boolean;
  sshHost: string;
  sshPort: number;
  sshUsername: string;
  sshPassword: string;    // encrypted via safeStorage
  sshPrivateKeyPath: string;
  cluster: boolean;
  sentinelMasterName: string;
  separator: string;      // key tree separator, default ":"
  order: number;
  createdAt: number;
}

interface AppSettings {
  theme: 'system' | 'dark' | 'light';
  locale: string;
  fontSize: number;
  scanCount: number;      // keys per SCAN page
  // ... more settings as needed
}

6. Security Model

  • contextIsolation: true — renderer has zero Node.js/Electron API access
  • nodeIntegration: false — no Node globals in renderer
  • contextBridge — only typed API surface exposed via window.electronAPI
  • safeStorage — OS-level encryption for credentials (DPAPI on Windows, Keychain on macOS, libsecret on Linux)
  • IPC validation — all IPC handlers validate input before executing
  • No remote module — all main-process features accessed via IPC

7. Compatibility Mitigations

Legacy Pattern v2 Approach
redisClient.js in renderer RedisService in main, typed IPC proxy
fs.readFileSync for TLS dialog:openFile IPC → main reads file
remote.app sandbox bookmarks Main process handles file access
vue.$bus / vue.$message mitt EventEmitter + ElMessage composable
Vue.prototype.$storage useConnectionStore() composable
Vue.prototype.$util Pure functions in utils/
Node zlib for decompression Web DecompressionStream + WASM fallback
child_process.exec formatters IPC → main process spawn (Phase 4)
window.localStorage electron-store IPC
Monaco + webpack plugin ESM Monaco + vite plugin (Phase 4)

8. Build & Dev

npm run dev            # electron-vite dev (HMR, renderer on :5173)
npm run build          # production build → out/
npm start              # preview built app
npm run build:unpack   # build + electron-builder --dir
npm run build:win      # build + electron-builder --win
npm run build:mac      # build + electron-builder --mac
npm run build:linux    # build + electron-builder --linux

9. Dependencies

Runtime

  • ioredis ^5.7.0 — Redis client (main process)
  • tunnel-ssh ^5.x — SSH tunneling (main process)
  • electron-store ^10.x — persistence (main process)

Dev / Renderer

  • electron ^33.4.0
  • electron-vite ^3.0.0
  • vue ^3.5.0
  • vue-router ^4.5.0
  • pinia ^2.x
  • element-plus ^2.9.0
  • typescript ^5.7.0
  • vite ^6.0.0
  • electron-builder ^25.1.0