First commit
This commit is contained in:
827
CLAUDE.md
Normal file
827
CLAUDE.md
Normal file
@@ -0,0 +1,827 @@
|
||||
# CLAUDE.md - Developer Documentation
|
||||
|
||||
## Project Overview
|
||||
|
||||
**Datacenter Designer** is a web-based visual design tool for datacenter infrastructure. It allows users to create, manage, and visualize rack layouts, network devices, and their interconnections in both physical and logical views.
|
||||
|
||||
### Core Purpose
|
||||
- Visual rack layout planning (physical positioning)
|
||||
- Device placement within racks (U1-U42 slots with multi-unit form factors)
|
||||
- Network connection mapping between devices
|
||||
- Logical topology view (independent of physical layout)
|
||||
- Export/import for data portability
|
||||
|
||||
### Technology Stack
|
||||
- **Frontend**: Vanilla JavaScript (ES6 modules), Konva.js (canvas library), ag-Grid (tables), SheetJS (Excel export)
|
||||
- **Backend**: Node.js, Express 4.x
|
||||
- **Database**: SQLite3
|
||||
- **No build process**: Direct ES6 modules, no bundler required
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
### High-Level Structure
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ Browser │
|
||||
│ ┌────────────────────────────────────────────┐ │
|
||||
│ │ app.js (Main Controller) │ │
|
||||
│ │ - Orchestrates all managers │ │
|
||||
│ │ - Handles modals and UI │ │
|
||||
│ │ - API client │ │
|
||||
│ │ - View switching (Physical/Logical) │ │
|
||||
│ └────────────────────────────────────────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │
|
||||
│ │ Rack │ │ Device │ │Connect │ │ Table │ │
|
||||
│ │Manager │ │Manager │ │Manager │ │Manager │ │
|
||||
│ └────────┘ └─────────┘ └─────────┘ └────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ └──────────┴───────────┴──────────┘ │
|
||||
│ │ │
|
||||
│ Konva.js Canvas │
|
||||
└────────────────────│──────────────────────────────┘
|
||||
│ HTTP/REST API
|
||||
┌────────────────────▼──────────────────────────────┐
|
||||
│ Server │
|
||||
│ ┌──────────────────────────────────────────────┐│
|
||||
│ │ server.js (Express Router) ││
|
||||
│ │ - RESTful endpoints ││
|
||||
│ │ - Request/response handling ││
|
||||
│ └──────────────────────────────────────────────┘│
|
||||
│ │ │
|
||||
│ ┌──────────────────▼──────────────────────────┐ │
|
||||
│ │ db.js (Database Layer) │ │
|
||||
│ │ - Promise-wrapped SQLite operations │ │
|
||||
│ │ - Schema management │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ SQLite Database File │
|
||||
└───────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### File Organization
|
||||
|
||||
```
|
||||
datacenter-designer/
|
||||
├── server/
|
||||
│ ├── server.js (276 LOC) - Express routes
|
||||
│ └── db.js (547 LOC) - Database operations
|
||||
├── public/
|
||||
│ ├── index.html (193 LOC) - Main HTML structure
|
||||
│ ├── css/
|
||||
│ │ └── style.css (741 LOC) - All styles
|
||||
│ └── js/
|
||||
│ ├── app.js (1719 LOC) - Main controller
|
||||
│ ├── rack-manager.js (488 LOC) - Rack rendering/interaction
|
||||
│ ├── device-manager.js (513 LOC) - Device rendering/interaction
|
||||
│ ├── connection-manager.js (901 LOC) - Connection lines/waypoints
|
||||
│ └── table-manager.js (792 LOC) - ag-Grid table views
|
||||
├── database/
|
||||
│ └── datacenter.db (Created at runtime)
|
||||
├── package.json
|
||||
└── README.md
|
||||
|
||||
Total: ~5,236 lines of code
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Critical Review
|
||||
|
||||
### ✅ Strengths
|
||||
|
||||
1. **Clean Separation of Concerns**: Manager pattern isolates rack, device, connection, and table logic
|
||||
2. **Simple Tech Stack**: No build process, direct ES6 modules, minimal dependencies
|
||||
3. **RESTful API**: Clear HTTP API with predictable endpoints
|
||||
4. **SQLite Persistence**: Appropriate for local/desktop deployment
|
||||
5. **Konva.js Integration**: Good choice for canvas-based diagramming
|
||||
6. **Dual View System**: Physical (rack-based) and logical (topology) views
|
||||
|
||||
### ❌ Issues & Anti-Patterns
|
||||
|
||||
#### 1. **Monolithic `app.js` (1719 lines)**
|
||||
- **Violation**: Single Responsibility Principle
|
||||
- **Contains**: API client, modal management, zoom/pan, view switching, event coordination, export/import
|
||||
- **Should be**: Split into smaller modules (API client, ModalManager, StateManager, UIController)
|
||||
|
||||
#### 2. **Repetitive Code (DRY Violations)**
|
||||
```javascript
|
||||
// Repeated everywhere in server.js:
|
||||
try {
|
||||
// ... logic
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
|
||||
// Repeated modal patterns in app.js
|
||||
modal.classList.remove('hidden');
|
||||
// ...setup
|
||||
modal.classList.add('hidden');
|
||||
```
|
||||
|
||||
#### 3. **Database Layer Issues**
|
||||
- **Callback-based sqlite3**: Manually wrapping every query in Promises
|
||||
- **No migration system**: Schema changes via ALTER TABLE with error swallowing (lines 106-140 in db.js)
|
||||
- **Verbose**: Every CRUD operation is 10-15 lines of boilerplate
|
||||
- **Better alternative**: `better-sqlite3` (synchronous, simpler, faster)
|
||||
|
||||
#### 4. **Hard-Coded Magic Numbers**
|
||||
```javascript
|
||||
// Scattered throughout codebase:
|
||||
const maxSlots = 42; // Rack slots
|
||||
const rackWidth = 520; // Rack dimensions
|
||||
const rackHeight = 1510;
|
||||
const gridSize = 600; // Grid spacing
|
||||
const deviceHeight = 32;
|
||||
const deviceSpacing = 2;
|
||||
const topMargin = 10;
|
||||
```
|
||||
**Should be**: Centralized in `config.js` with semantic names
|
||||
|
||||
#### 5. **API Client Design**
|
||||
```javascript
|
||||
class API {
|
||||
// One method per endpoint - not scalable
|
||||
getRacks() { return this.request('/api/racks?projectId=...'); }
|
||||
createRack(...) { return this.request(...); }
|
||||
updateRackPosition(...) { return this.request(...); }
|
||||
// ... 30+ methods
|
||||
}
|
||||
```
|
||||
**Should be**: Generic resource methods or use a library
|
||||
|
||||
#### 6. **CSS Organization**
|
||||
- **741 lines in one file**: No modularity
|
||||
- **Hard-coded colors**: `#4A90E2`, `#f5f5f5`, etc. repeated
|
||||
- **No CSS variables**: Should use `--primary-color`, `--bg-color`, etc.
|
||||
- **No responsiveness**: No media queries, fixed dimensions
|
||||
- **No dark mode support**: Hard-coded light theme only
|
||||
|
||||
#### 7. **State Management**
|
||||
- **Scattered state**: Each manager holds its own state in Maps
|
||||
- **DOM as state**: Using localStorage without versioning
|
||||
- **No synchronization**: Manual `canvas-data-changed` events
|
||||
- **No undo/redo**: No state history
|
||||
|
||||
#### 8. **Input Validation**
|
||||
- **Server**: Minimal validation (trusts client)
|
||||
- **Client**: No form validation, uses `prompt()` for input
|
||||
- **No schema validation**: No Zod, Joi, or similar
|
||||
|
||||
#### 9. **Error Handling**
|
||||
```javascript
|
||||
// Current:
|
||||
catch (err) {
|
||||
console.error('Failed:', err);
|
||||
alert('Failed: ' + err.message);
|
||||
}
|
||||
```
|
||||
**Should be**: Toast notifications, user-friendly messages, error boundaries
|
||||
|
||||
#### 10. **Export/Import**
|
||||
- **No versioning**: Export format has version field but isn't checked properly
|
||||
- **Monolithic**: One giant JSON blob
|
||||
- **No incremental import**: All-or-nothing
|
||||
|
||||
### ⚠️ Over-Engineering
|
||||
|
||||
1. **View-Specific Waypoints**: `waypoints_physical` and `waypoints_logical` stored separately
|
||||
- **Better**: Store once, transform with view matrix
|
||||
2. **Separate `rack_units` column**: Could be derived from `device_type`
|
||||
3. **Multiple modal patterns**: Overlapping modal handling code
|
||||
|
||||
### ⚠️ Under-Engineering
|
||||
|
||||
1. **No undo/redo**: Critical for a design tool
|
||||
2. **No keyboard shortcuts**: Only `Esc` and `Del` supported
|
||||
3. **No search/filter**: As data grows, navigation becomes difficult
|
||||
4. **No loading states**: UI freezes during operations
|
||||
5. **No optimistic updates**: Waits for server before updating UI
|
||||
6. **No batch operations**: Can't select multiple racks/devices
|
||||
7. **No auto-save**: Only manual saves via export
|
||||
|
||||
---
|
||||
|
||||
## Better Technologies / Alternatives
|
||||
|
||||
### Database
|
||||
**Current**: `sqlite3` (callback-based)
|
||||
**Better**: `better-sqlite3`
|
||||
- Synchronous API (simpler code)
|
||||
- 2-3x faster
|
||||
- No callback hell
|
||||
```javascript
|
||||
// Current:
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.get('SELECT * FROM racks WHERE id = ?', [id], (err, row) => {
|
||||
if (err) reject(err);
|
||||
else resolve(row);
|
||||
});
|
||||
});
|
||||
|
||||
// With better-sqlite3:
|
||||
return db.prepare('SELECT * FROM racks WHERE id = ?').get(id);
|
||||
```
|
||||
|
||||
### State Management
|
||||
**Current**: Scattered Maps in each manager
|
||||
**Better Options**:
|
||||
1. **Zustand** (100 lines, minimal API)
|
||||
2. **Valtio** (proxy-based reactivity)
|
||||
3. **Nanostores** (atomic stores)
|
||||
|
||||
### API Client
|
||||
**Current**: Custom 30+ method API class
|
||||
**Better**: **ky** or **axios** with interceptors
|
||||
```javascript
|
||||
// Generic resource client:
|
||||
const api = {
|
||||
get: (url) => ky.get(url).json(),
|
||||
post: (url, data) => ky.post(url, { json: data }).json(),
|
||||
// ... + error handling in interceptors
|
||||
};
|
||||
```
|
||||
|
||||
### CSS Organization
|
||||
**Current**: 741-line monolithic file
|
||||
**Better**: Split by concern + CSS variables
|
||||
```css
|
||||
/* config.css */
|
||||
:root {
|
||||
--primary-color: #4A90E2;
|
||||
--bg-color: #f5f5f5;
|
||||
--rack-width: 520px;
|
||||
--rack-height: 1510px;
|
||||
}
|
||||
|
||||
/* components/rack.css */
|
||||
/* components/device.css */
|
||||
/* layout.css */
|
||||
/* theme.css */
|
||||
```
|
||||
|
||||
### Configuration
|
||||
**Current**: Hard-coded everywhere
|
||||
**Better**: `config.js`
|
||||
```javascript
|
||||
export const RACK_CONFIG = {
|
||||
WIDTH: 520,
|
||||
HEIGHT: 1510,
|
||||
SLOTS: 42,
|
||||
MARGIN: { top: 10, right: 10, bottom: 10, left: 10 }
|
||||
};
|
||||
|
||||
export const GRID_CONFIG = {
|
||||
HORIZONTAL: 600,
|
||||
VERTICAL: 1610
|
||||
};
|
||||
```
|
||||
|
||||
### Validation
|
||||
**Current**: None
|
||||
**Better**: **Zod** for schema validation
|
||||
```javascript
|
||||
const RackSchema = z.object({
|
||||
name: z.string().min(1).max(50),
|
||||
x: z.number().finite(),
|
||||
y: z.number().finite()
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommended Refactoring Strategy
|
||||
|
||||
### Option A: In-Place Refactoring (Direct Edit)
|
||||
**Pros**:
|
||||
- Keep git history
|
||||
- Incremental changes
|
||||
- Can test at each step
|
||||
|
||||
**Cons**:
|
||||
- Risk of breaking working features
|
||||
- Harder to compare old vs new
|
||||
- No fallback
|
||||
|
||||
### Option B: Release Candidate Approach (Recommended)
|
||||
**Pros**:
|
||||
- Clean slate while keeping original
|
||||
- Can compare side-by-side
|
||||
- Easy to revert
|
||||
- Clear migration path
|
||||
|
||||
**Cons**:
|
||||
- Duplicated files temporarily
|
||||
- Need to sync any new features
|
||||
|
||||
**Proposed Structure**:
|
||||
```
|
||||
datacenter-designer/
|
||||
├── rc/ # New refactored version
|
||||
│ ├── server/
|
||||
│ │ ├── config.js # NEW: Configuration
|
||||
│ │ ├── db.js # REFACTORED: better-sqlite3
|
||||
│ │ ├── routes/ # NEW: Split routes
|
||||
│ │ │ ├── projects.js
|
||||
│ │ │ ├── racks.js
|
||||
│ │ │ ├── devices.js
|
||||
│ │ │ └── connections.js
|
||||
│ │ └── server.js # SIMPLIFIED: Just setup
|
||||
│ ├── public/
|
||||
│ │ ├── index.html # UPDATED: More semantic
|
||||
│ │ ├── css/
|
||||
│ │ │ ├── config.css # NEW: CSS variables
|
||||
│ │ │ ├── layout.css
|
||||
│ │ │ ├── components.css
|
||||
│ │ │ └── theme.css
|
||||
│ │ └── js/
|
||||
│ │ ├── config.js # NEW: Constants
|
||||
│ │ ├── lib/
|
||||
│ │ │ ├── api.js # REFACTORED: Simplified
|
||||
│ │ │ ├── state.js # NEW: State manager
|
||||
│ │ │ └── ui.js # NEW: UI utilities
|
||||
│ │ ├── managers/
|
||||
│ │ │ ├── rack-manager.js
|
||||
│ │ │ ├── device-manager.js
|
||||
│ │ │ ├── connection-manager.js
|
||||
│ │ │ └── table-manager.js
|
||||
│ │ └── app.js # SLIMMED: Orchestrator only
|
||||
│ └── database/
|
||||
│ └── .gitkeep
|
||||
├── server/ # OLD: Keep during transition
|
||||
├── public/ # OLD: Keep during transition
|
||||
├── .gitignore
|
||||
├── CLAUDE.md # This file
|
||||
├── README.md
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Refactoring Checklist
|
||||
|
||||
### Phase 1: Foundation (Day 1-2)
|
||||
- [ ] Create `rc/` directory structure
|
||||
- [ ] Setup `.gitignore` properly
|
||||
- [ ] Create `rc/server/config.js` with all constants
|
||||
- [ ] Create `rc/public/js/config.js` with frontend constants
|
||||
- [ ] Port database to `better-sqlite3`
|
||||
- [ ] Create migration system
|
||||
- [ ] Split CSS into modules with CSS variables
|
||||
- [ ] Make layout responsive (media queries)
|
||||
|
||||
### Phase 2: Backend (Day 3)
|
||||
- [ ] Split routes into separate files
|
||||
- [ ] Add input validation (Zod or similar)
|
||||
- [ ] Implement error middleware
|
||||
- [ ] Add request logging
|
||||
- [ ] Create API documentation (OpenAPI/Swagger)
|
||||
|
||||
### Phase 3: Frontend Core (Day 4-5)
|
||||
- [ ] Extract API client to `lib/api.js`
|
||||
- [ ] Extract state management to `lib/state.js`
|
||||
- [ ] Extract UI utilities to `lib/ui.js` (modal manager, toast, etc.)
|
||||
- [ ] Slim down `app.js` to orchestration only
|
||||
- [ ] Refactor managers to use new state system
|
||||
|
||||
### Phase 4: Features & UX (Day 6-7)
|
||||
- [ ] Add toast notifications (replace `alert()`)
|
||||
- [ ] Add loading states
|
||||
- [ ] Add keyboard shortcuts
|
||||
- [ ] Add undo/redo system
|
||||
- [ ] Add search/filter
|
||||
- [ ] Add batch operations
|
||||
- [ ] Improve error messages
|
||||
|
||||
### Phase 5: Testing & Documentation (Day 8)
|
||||
- [ ] Add unit tests for backend
|
||||
- [ ] Add integration tests
|
||||
- [ ] Update README.md
|
||||
- [ ] Update CLAUDE.md
|
||||
- [ ] Add inline JSDoc comments
|
||||
- [ ] Performance testing
|
||||
|
||||
### Phase 6: Migration (Day 9-10)
|
||||
- [ ] Test thoroughly
|
||||
- [ ] Migrate data from old DB if needed
|
||||
- [ ] Move `rc/` to root
|
||||
- [ ] Archive old code to `old/`
|
||||
- [ ] Update package.json scripts
|
||||
- [ ] Final testing
|
||||
|
||||
---
|
||||
|
||||
## Key Principles to Follow
|
||||
|
||||
### KISS (Keep It Simple, Stupid)
|
||||
- Avoid abstractions unless proven necessary
|
||||
- Prefer composition over inheritance
|
||||
- Use vanilla JS unless library provides clear value
|
||||
|
||||
### DRY (Don't Repeat Yourself)
|
||||
- Extract repeated patterns (error handling, modal management)
|
||||
- Use constants instead of magic numbers
|
||||
- Create reusable utility functions
|
||||
|
||||
### SOLID Principles
|
||||
- **S**: Single Responsibility - Each module does one thing
|
||||
- **O**: Open/Closed - Extend without modifying
|
||||
- **L**: Liskov Substitution - Subtypes must be substitutable
|
||||
- **I**: Interface Segregation - Many specific interfaces > one general
|
||||
- **D**: Dependency Inversion - Depend on abstractions
|
||||
|
||||
### WORM (Write Once, Read Many)
|
||||
- Optimize for read performance
|
||||
- Use indices on frequently queried columns
|
||||
- Cache frequently accessed data
|
||||
- Minimize database writes
|
||||
|
||||
### Additional Principles
|
||||
- **Fail Fast**: Validate early, throw errors quickly
|
||||
- **Convention over Configuration**: Sensible defaults
|
||||
- **Progressive Enhancement**: Works without JS, enhanced with it
|
||||
- **Accessibility**: Keyboard navigation, ARIA labels, screen reader support
|
||||
|
||||
---
|
||||
|
||||
## Responsive Design Strategy
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
/* Mobile: < 768px */
|
||||
@media (max-width: 767px) {
|
||||
/* Stack toolbar items, hide non-essential controls */
|
||||
}
|
||||
|
||||
/* Tablet: 768px - 1024px */
|
||||
@media (min-width: 768px) and (max-width: 1024px) {
|
||||
/* Optimize for touch, larger buttons */
|
||||
}
|
||||
|
||||
/* Desktop: > 1024px */
|
||||
@media (min-width: 1025px) {
|
||||
/* Full feature set */
|
||||
}
|
||||
```
|
||||
|
||||
### Layout Strategies
|
||||
1. **Toolbar**: Collapse to hamburger menu on mobile
|
||||
2. **Canvas**: Always full viewport minus toolbar
|
||||
3. **Tables**: Horizontal scroll on mobile, fixed on desktop
|
||||
4. **Modals**: Full-screen on mobile, centered on desktop
|
||||
5. **Context Menus**: Bottom sheet on mobile, popup on desktop
|
||||
|
||||
### Touch Support
|
||||
- Increase hit targets to 44x44px minimum
|
||||
- Add touch gestures (pinch-zoom, two-finger pan)
|
||||
- Show hover states on touch as active states
|
||||
- Use native select/input elements on mobile
|
||||
|
||||
---
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Canvas Rendering
|
||||
- Use `batchDraw()` instead of `draw()` for multiple updates
|
||||
- Implement viewport culling (don't render off-screen items)
|
||||
- Use `cache()` for static shapes
|
||||
- Debounce pan/zoom updates
|
||||
|
||||
### Database
|
||||
- Add indices on foreign keys
|
||||
- Use transactions for bulk operations
|
||||
- Implement connection pooling (if moving to client-server)
|
||||
- Lazy-load connections (don't load all at startup)
|
||||
|
||||
### Network
|
||||
- Implement request debouncing for auto-save
|
||||
- Use HTTP caching headers
|
||||
- Compress API responses (gzip)
|
||||
- Implement pagination for large datasets
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### SQL Injection
|
||||
- ✅ Already using parameterized queries
|
||||
- [ ] Add input sanitization layer
|
||||
- [ ] Validate all inputs on server
|
||||
|
||||
### XSS (Cross-Site Scripting)
|
||||
- [ ] Sanitize user input before displaying
|
||||
- [ ] Use `textContent` instead of `innerHTML` where possible
|
||||
- [ ] Add Content Security Policy headers
|
||||
|
||||
### CSRF (Cross-Site Request Forgery)
|
||||
- [ ] Add CSRF tokens for state-changing operations
|
||||
- [ ] Use SameSite cookies
|
||||
|
||||
### File Upload
|
||||
- If adding import from file:
|
||||
- [ ] Validate file size
|
||||
- [ ] Validate file type
|
||||
- [ ] Scan for malicious content
|
||||
|
||||
---
|
||||
|
||||
## .gitignore Strategy
|
||||
|
||||
To avoid pushing sensitive or generated files:
|
||||
|
||||
```gitignore
|
||||
# Dependencies
|
||||
node_modules/
|
||||
package-lock.json # Optional: some include, some exclude
|
||||
|
||||
# Database (user data)
|
||||
database/*.db
|
||||
database/*.db-shm
|
||||
database/*.db-wal
|
||||
*.db
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.DS_Store
|
||||
|
||||
# Build outputs (if added later)
|
||||
dist/
|
||||
build/
|
||||
.cache/
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
|
||||
# OS files
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
|
||||
# Claude-specific (optional)
|
||||
.claude/
|
||||
```
|
||||
|
||||
**Important**: If database contains sample data for demonstrations, create a separate `database/sample.db` and explicitly include it:
|
||||
```gitignore
|
||||
# Ignore user databases
|
||||
database/*.db
|
||||
# But include sample
|
||||
!database/sample.db
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- Test database operations in isolation
|
||||
- Test utility functions
|
||||
- Test state management
|
||||
- Use: **Vitest** or **Jest**
|
||||
|
||||
### Integration Tests
|
||||
- Test API endpoints
|
||||
- Test full CRUD workflows
|
||||
- Use: **Supertest** + **Vitest**
|
||||
|
||||
### E2E Tests
|
||||
- Test critical user journeys
|
||||
- Test cross-browser compatibility
|
||||
- Use: **Playwright** or **Cypress**
|
||||
|
||||
### Test Structure
|
||||
```javascript
|
||||
// Example: tests/db.test.js
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import db from '../server/db.js';
|
||||
|
||||
describe('Database - Racks', () => {
|
||||
beforeEach(() => {
|
||||
// Reset database to known state
|
||||
});
|
||||
|
||||
it('should create a rack', () => {
|
||||
const rack = db.createRack(1, 'RACK01', 0, 0);
|
||||
expect(rack.id).toBeDefined();
|
||||
expect(rack.name).toBe('RACK01');
|
||||
});
|
||||
|
||||
it('should not create duplicate rack names in same project', () => {
|
||||
db.createRack(1, 'RACK01', 0, 0);
|
||||
expect(() => db.createRack(1, 'RACK01', 100, 0)).toThrow();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements Roadmap
|
||||
|
||||
### Phase 1: Core UX Improvements
|
||||
- [ ] Undo/redo system
|
||||
- [ ] Enhanced keyboard shortcuts
|
||||
- [ ] Toast notifications (replace browser alerts)
|
||||
- [ ] Loading states
|
||||
- [ ] Search and filter functionality
|
||||
- [ ] Batch operations (select multiple items)
|
||||
- [ ] Auto-save functionality
|
||||
|
||||
### Phase 2: Multi-User Support
|
||||
- [ ] User management system
|
||||
- [ ] Authentication and authorization
|
||||
- [ ] OIDC-compatible external SSO integration
|
||||
- [ ] Project sharing between users
|
||||
- [ ] Role-based access control (view/edit/admin)
|
||||
- [ ] User profile management
|
||||
|
||||
### Phase 3: Collaboration
|
||||
- [ ] Real-time collaborative editing (WebSocket)
|
||||
- [ ] Concurrent access management
|
||||
- [ ] User presence indicators
|
||||
- [ ] Change notifications
|
||||
- [ ] Conflict resolution
|
||||
- [ ] Version history / snapshots
|
||||
- [ ] Activity audit logging
|
||||
|
||||
### Phase 4: Advanced Features
|
||||
- [ ] Custom device types (user-defined)
|
||||
- [ ] Cable labeling and management
|
||||
- [ ] VLAN visualization
|
||||
- [ ] IP address management
|
||||
- [ ] Documentation generation (diagrams, BOMs)
|
||||
- [ ] Import from other formats (Visio, Lucidchart)
|
||||
- [ ] PostgreSQL/MySQL support
|
||||
|
||||
### Phase 5: Platform Enhancements
|
||||
- [ ] Dark mode
|
||||
- [ ] Mobile/tablet responsive design
|
||||
- [ ] 3D rack visualization
|
||||
- [ ] Cable routing visualization
|
||||
- [ ] Enhanced export formats
|
||||
- [ ] API for 3rd party integrations
|
||||
- [ ] Backup/restore automation
|
||||
|
||||
---
|
||||
|
||||
## Common Gotchas & Pitfalls
|
||||
|
||||
### Konva-Specific
|
||||
1. **Coordinate Systems**: Konva uses top-left origin, racks use bottom-up slot numbering (U1 at bottom)
|
||||
2. **Event Bubbling**: Events on canvas can propagate unexpectedly - use `e.cancelBubble = true`
|
||||
3. **Memory Leaks**: Always destroy unused layers/shapes
|
||||
4. **Performance**: Too many shapes? Use `virtualizer` pattern
|
||||
|
||||
### SQLite-Specific
|
||||
1. **Foreign Keys**: Must enable explicitly with `PRAGMA foreign_keys = ON`
|
||||
2. **Concurrency**: Only one write at a time - queue writes or use WAL mode
|
||||
3. **Migrations**: No built-in system - roll your own or use library
|
||||
4. **Type System**: Dynamic typing can surprise you (stores as INTEGER, returns as Number)
|
||||
|
||||
### CSS/Canvas Interaction
|
||||
1. **Canvas Size**: Must set both CSS size and Konva stage size
|
||||
2. **DPI Scaling**: High-DPI displays may need pixel ratio adjustment
|
||||
3. **Touch Events**: Handle both mouse and touch events separately
|
||||
|
||||
---
|
||||
|
||||
## Contributing Guidelines
|
||||
|
||||
### Code Style
|
||||
- **Indentation**: 2 spaces
|
||||
- **Quotes**: Single quotes for strings
|
||||
- **Semicolons**: Required
|
||||
- **Naming**: camelCase for variables/functions, PascalCase for classes
|
||||
- **Line Length**: 100 characters max
|
||||
- **Comments**: JSDoc for public APIs, inline for complex logic
|
||||
|
||||
### Commit Messages
|
||||
Follow Conventional Commits:
|
||||
```
|
||||
feat: add undo/redo system
|
||||
fix: correct device positioning in logical view
|
||||
docs: update CLAUDE.md with testing strategy
|
||||
refactor: extract API client to separate file
|
||||
test: add unit tests for database operations
|
||||
chore: update dependencies
|
||||
```
|
||||
|
||||
### Pull Request Process
|
||||
1. Create feature branch from `main`
|
||||
2. Make changes with tests
|
||||
3. Update documentation
|
||||
4. Run linter and tests
|
||||
5. Submit PR with description
|
||||
6. Address review comments
|
||||
7. Merge when approved
|
||||
|
||||
---
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### Backend Debugging
|
||||
```bash
|
||||
# Enable SQLite query logging
|
||||
DEBUG=sqlite3 npm start
|
||||
|
||||
# Enable Express debug logging
|
||||
DEBUG=express:* npm start
|
||||
|
||||
# Enable all debug logging
|
||||
DEBUG=* npm start
|
||||
```
|
||||
|
||||
### Frontend Debugging
|
||||
```javascript
|
||||
// Enable Konva debugging
|
||||
Konva.showWarnings = true;
|
||||
|
||||
// Log all API calls
|
||||
api.request = new Proxy(api.request, {
|
||||
apply(target, thisArg, args) {
|
||||
console.log('[API]', args[0], args[1]);
|
||||
return target.apply(thisArg, args);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
1. **Canvas not updating**: Call `.batchDraw()` on layer
|
||||
2. **Events not firing**: Check if shape is `listening(true)`
|
||||
3. **Drag not working**: Check if shape is `draggable(true)` and parent layer is listening
|
||||
4. **Database locked**: Close all connections, check for transactions
|
||||
5. **CORS errors**: Ensure frontend and backend are on same origin or CORS is enabled
|
||||
|
||||
---
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Rack**: Physical equipment cabinet with 42U slots
|
||||
- **U / Rack Unit**: Standard height measurement (1U = 1.75 inches)
|
||||
- **Slot**: Position within a rack (U1 at bottom, U42 at top)
|
||||
- **Device**: Network equipment (switch, router, firewall, etc.)
|
||||
- **Form Factor**: Device height in rack units (1U, 2U, 4U, etc.)
|
||||
- **Connection**: Network link between two device ports
|
||||
- **Waypoint**: Intermediate point in a connection line for routing
|
||||
- **Physical View**: Rack-based layout showing physical positioning
|
||||
- **Logical View**: Topology view ignoring physical constraints
|
||||
- **Project**: Isolated workspace containing racks, devices, connections
|
||||
- **Canvas**: Konva.js drawing surface
|
||||
- **Stage**: Top-level Konva container
|
||||
- **Layer**: Konva organizational unit (rack layer, device layer, connection layer)
|
||||
- **Shape**: Individual Konva element (rectangle, text, line, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Links & Resources
|
||||
|
||||
### Dependencies
|
||||
- [Konva.js Documentation](https://konvajs.org/docs/)
|
||||
- [ag-Grid Documentation](https://www.ag-grid.com/javascript-data-grid/)
|
||||
- [SheetJS Documentation](https://docs.sheetjs.com/)
|
||||
- [SQLite Documentation](https://www.sqlite.org/docs.html)
|
||||
- [better-sqlite3](https://github.com/WiseLibs/better-sqlite3)
|
||||
|
||||
### Design Patterns
|
||||
- [JavaScript Design Patterns](https://www.patterns.dev/)
|
||||
- [SOLID Principles](https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design)
|
||||
- [Martin Fowler - Refactoring](https://refactoring.com/)
|
||||
|
||||
### Best Practices
|
||||
- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
|
||||
- [Clean Code JavaScript](https://github.com/ryanmcdermott/clean-code-javascript)
|
||||
- [Web Performance Best Practices](https://web.dev/fast/)
|
||||
|
||||
---
|
||||
|
||||
## Revision History
|
||||
|
||||
| Version | Date | Author | Changes |
|
||||
|---------|------|--------|---------|
|
||||
| 0.1.0 | 2025-10-26 | Claude | Initial release - comprehensive documentation |
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT License - See LICENSE file for details
|
||||
Reference in New Issue
Block a user