feat: Add comprehensive design documentation for Krates
- 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
This commit is contained in:
312
design/architecture.md
Normal file
312
design/architecture.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# 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)
|
||||
```typescript
|
||||
// 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)
|
||||
```typescript
|
||||
// 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
|
||||
```dockerfile
|
||||
# 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
|
||||
1. **Virtualization**: Don't render off-screen krates if world is large
|
||||
2. **Debounce**: 16ms debouncing on all frequent events
|
||||
3. **Web Workers**: Fuzzy search in worker for large datasets
|
||||
4. **Memoization**: Reuse expensive calculations (transforms, layouts)
|
||||
5. **CSS optimization**: Use transforms, avoid layout thrashing
|
||||
|
||||
### Backend
|
||||
1. **Caching**: Cache static resource lists (with watch for updates)
|
||||
2. **Connection pooling**: Reuse k8s API connections
|
||||
3. **Rate limiting**: Per-user limits on WebSocket connections
|
||||
4. **Compression**: WebSocket message compression
|
||||
5. **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)
|
||||
Reference in New Issue
Block a user