- Canvas: Infinite zoomable workspace with LOD and navigation - Spotlight: Fuzzy search with type filters and view shortcuts - Krate: Window group container with non-overlapping placement - Detail Window: YAML/Describe/Logs/Shell views with maximize - Top Bar: Cluster info, user presence, admin toggle - Admin Drawer: Multi-user presence and spectate functionality - Minimap: Browse and navigate canvas overview - Collection Window: List/tree views with filtering and sorting - Shell/Logs: Real-time terminal and log streaming - Backend: Go service with K8s API, WebSocket handlers, CRDT sync - Architecture: Full project structure and tech stack
7.9 KiB
7.9 KiB
Top-Level Application Architecture
Tech Stack Recommendations
Frontend
- Framework: React 18 + TypeScript
- Styling: CSS-in-JS (styled-components or vanilla-extract) or Tailwind CSS
- Terminal: xterm.js
- Real-Time: Yjs + y-websocket (CRDT collaboration)
- Build Tool: Vite
- Fonts: IBM Plex Sans + IBM Plex Mono (Google Fonts or self-hosted)
- State Management: Zustand or React Context (keep it simple)
Backend
- Language: Go
- Kubernetes Client: kubernetes/client-go
- WebSockets: gorilla/websocket
- CRDT Backend: Redis (single-node) or y-leveldb/y-mongodb (multi-node)
- Build/Deployment: Docker, Kubernetes
Project Structure
krates/
├── client/ # Frontend application
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── canvas/ # Canvas and world layer
│ │ │ │ ├── WorldLayer.tsx
│ │ │ │ ├── GridOverlay.tsx
│ │ │ │ └── Minimap.tsx
│ │ │ ├── krate/ # Krate and windows
│ │ │ │ ├── Krate.tsx
│ │ │ │ ├── KrateHeader.tsx
│ │ │ │ ├── DetailWindow.tsx
│ │ │ │ └── CollectionWindow.tsx
│ │ │ ├── Spotlight.tsx
│ │ │ ├── TopBar.tsx
│ │ │ ├── AdminDrawer.tsx
│ │ │ ├── ShellTerminal.tsx # xterm.js wrapper
│ │ │ └── LogsViewer.tsx
│ │ ├── hooks/ # Custom React hooks
│ │ │ ├── useCanvas.ts
│ │ │ ├── useSpotlight.ts
│ │ │ ├── useWebSocket.ts
│ │ │ └── useKubernetes.ts
│ │ ├── state/ # State management
│ │ │ ├── canvasStore.ts
│ │ │ ├── krateStore.ts
│ │ │ └── spotlightStore.ts
│ │ ├── utils/
│ │ │ ├── fuzzy.ts # Fuzzy search algorithm
│ │ │ ├── crdt.ts # Yjs setup
│ │ │ ├── keyboard.ts # Keyboard handling
│ │ │ └── math.ts # Canvas math helpers
│ │ ├── App.tsx
│ │ └── main.tsx
│ ├── public/ # Static assets
│ └── package.json
│
├── server/ # Backend service
│ ├── cmd/
│ │ └── server/
│ │ └── main.go
│ ├── internal/
│ │ ├── api/ # HTTP endpoints
│ │ │ ├── handlers/
│ │ │ └── routes.go
│ │ ├── ws/ # WebSocket handlers
│ │ │ ├── shell.go
│ │ │ ├── logs.go
│ │ │ └── watch.go
│ │ ├── k8s/ # Kubernetes client wrappers
│ │ │ ├── client.go
│ │ │ ├── resources.go
│ │ │ └── watch.go
│ │ ├── crdt/ # Yjs integration
│ │ │ └── provider.go
│ │ └── auth/ # Authentication/authorization
│ │ └── token.go
│ ├── pkg/ # Reusable packages
│ └── go.mod
│
├── design/ # This folder
│ ├── canvas.md
│ ├── spotlight.md
│ ├── krate.md
│ ├── detail-window.md
│ ├── top-bar.md
│ ├── admin-drawer.md
│ ├── minimap.md
│ ├── backend.md
│ └── architecture.md
│
└── README.md
State Management Strategy
Global State (Zustand)
// canvasStore.ts
interface CanvasState {
camX: number;
camY: number;
zoom: number;
flying: boolean;
dragging: boolean;
collapsed: boolean;
spacePanning: boolean;
}
// krateStore.ts
interface KrateStore {
krates: Map<string, Krate>;
selectedKrateId: string | null;
}
// spotlightStore.ts
interface SpotlightStore {
open: boolean;
query: string;
filterType: string | null;
sel: number;
navigated: boolean;
}
// userStore.ts
interface UserStore {
currentUser: User;
presence: Map<string, UserPresence>;
}
Collection State (Per-Window)
// stored in krate.windows[].state or separate map
interface CollectionState {
search: string;
view: 'list' | 'tree';
sel: number;
}
WebSocket Architecture
Connection Setup
1. Connect to /ws/sync (CRDT + awareness)
2. Connect to /ws/watch (resource updates)
3. On-demand connections:
- /ws/shell (when shell window opened)
- /ws/logs (when logs window opened)
Message Format
// CRDT sync
{
type: 'sync',
payload: Uint8Array // Yjs update encoded
}
// Awareness presence
{
type: 'awareness',
updates: UserPresence[]
}
// Resource watch
{
type: 'resource',
action: 'add' | 'update' | 'delete',
kind: string, // 'Pod', 'Deployment', etc.
resource: K8sObject
}
// Shell output
{
type: 'shell:output',
data: string // stdout/stderr
}
// Shell input
{
type: 'shell:input',
data: string // keypresses, etc.
}
Build & Deployment
Development
# Frontend
cd client
npm install
npm run dev # Vite dev server
# Backend
cd server
go run cmd/server/main.go
Production
# Backend
cd server
go build -o krates-server
./krates-server --config config.yaml
# Frontend
cd client
npm run build
# Serve static files with nginx or similar
Docker
# Backend Dockerfile
FROM golang:1.21-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o /krates ./cmd/server
CMD ["/krates"]
# Frontend Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
CMD ["npm", "start"]
Performance Optimization
Frontend
- Virtualization: Don't render off-screen krates if world is large
- Debounce: 16ms debouncing on all frequent events
- Web Workers: Fuzzy search in worker for large datasets
- Memoization: Reuse expensive calculations (transforms, layouts)
- CSS optimization: Use transforms, avoid layout thrashing
Backend
- Caching: Cache static resource lists (with watch for updates)
- Connection pooling: Reuse k8s API connections
- Rate limiting: Per-user limits on WebSocket connections
- Compression: WebSocket message compression
- Batching: Batch resource updates when possible
Testing Strategy
Unit Tests
- Fuzzy search algorithm
- Coordinate transformations
- CRDT conflict resolution
- WebSocket message formatting
Integration Tests
- Kubernetes API integration
- WebSocket connection lifecycle
- Multi-user presence sync
E2E Tests
- User flows: search → spotlight → krate creation
- Multi-user: user A creates krate, user B sees it
- Drag/drop and resize interactions
Security Checklist
Authentication
- JWT or session-based auth on all WebSocket connections
- Token validation on every message
- Expire inactive sessions
Authorization
- Namespace-level RBAC enforcement
- Block access to unauthorized resources
- Audit logging
Data Protection
- Never log sensitive data (especially decoded secrets)
- Sanitize user inputs
- Escape HTML in text display
- CSP headers on frontend
Network
- TLS/HTTPS for all connections
- WSS for WebSocket connections
- Origin validation on WebSocket upgrade
Future Enhancements (Backlog)
Already Identified
- Tile layout presets (logs hero, split, grid)
- Port-forwarding window
- Events window
- Diff view (compare YAMLs)
- Multi-cluster support
Additional Ideas
- Keyboard shortcuts customization
- Workspace presets (save/restore layouts)
- Annotations/markers on canvas
- Shared annotations (multi-user notes)
- History/undo stack
- Keyboard macro recording
- Export workspace (screenshots, layouts)