|
| 1 | +# Fluidd AI Development Guide |
| 2 | + |
| 3 | +Fluidd is a Vue 2.7 + TypeScript web interface for Klipper 3D printers that communicates with Moonraker via WebSocket. |
| 4 | + |
| 5 | +## Architecture Overview |
| 6 | + |
| 7 | +- **Vue 2.7 + Vuetify 2**: UI framework with Material Design components |
| 8 | +- **Vuex Store**: Modular state management mirroring Klipper/Moonraker domains (`printer/`, `files/`, `console/`, etc.) |
| 9 | +- **WebSocket Communication**: Real-time bidirectional communication with Moonraker API via `socketActions.ts` |
| 10 | +- **Component Structure**: Mixins-based architecture with `StateMixin` providing common printer state access |
| 11 | + |
| 12 | +## Key Patterns |
| 13 | + |
| 14 | +### State Management |
| 15 | +- Store modules in `src/store/` mirror Moonraker API endpoints (printer, files, macros, etc.) |
| 16 | +- Use `$typedState` and `$typedGetters` for type-safe store access |
| 17 | +- WebSocket actions in `api/socketActions.ts` follow pattern: `baseEmit(method, {dispatch, wait, params})` |
| 18 | + |
| 19 | +### Component Architecture |
| 20 | +```typescript |
| 21 | +// Standard component pattern |
| 22 | +@Component({ |
| 23 | + components: { /* ... */ } |
| 24 | +}) |
| 25 | +export default class MyComponent extends Vue { |
| 26 | + // Component logic here |
| 27 | +} |
| 28 | + |
| 29 | +// Widget component needing printer state |
| 30 | +@Component({ |
| 31 | + components: { /* ... */ } |
| 32 | +}) |
| 33 | +export default class PrinterWidget extends Mixins(StateMixin) { |
| 34 | + // Access printer state via StateMixin getters |
| 35 | + get printerState() { return this.printerState } // 'printing' | 'paused' | etc. |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +### WebSocket Integration |
| 40 | +- All printer communication through `SocketActions` (not direct HTTP) |
| 41 | +- Use `wait` parameter for loading states: `wait: Waits.onPrintStart` |
| 42 | +- Real-time updates handled via store mutations from socket events |
| 43 | + |
| 44 | +## Development Workflow |
| 45 | + |
| 46 | +### Essential Commands |
| 47 | +```bash |
| 48 | +npm run bootstrap # Install git hooks (after clone) |
| 49 | +npm run dev # Start development server |
| 50 | +npm run build # Production build |
| 51 | +npm run type-check # TypeScript validation |
| 52 | +npm run lint # ESLint with Vue/TS rules |
| 53 | +npm run test # Vitest unit tests |
| 54 | +``` |
| 55 | + |
| 56 | +### File Organization |
| 57 | +- `src/components/widgets/`: Dashboard cards organized by domain (status/, thermals/, macros/) |
| 58 | +- `src/views/`: Page-level components (Dashboard.vue, Console.vue, etc.) |
| 59 | +- `src/store/[domain]/`: Vuex modules matching Moonraker API structure |
| 60 | +- `src/api/`: WebSocket and HTTP client abstractions |
| 61 | + |
| 62 | +### Router & Authentication |
| 63 | +- Routes in `src/router/` with authentication guards |
| 64 | + |
| 65 | +### Icons & Theming |
| 66 | +- Material Design Icons via `src/globals.ts` constants |
| 67 | +- Vuetify theme system with custom color schemes |
| 68 | +- PWA support with service worker in `src/sw.ts` |
| 69 | + |
| 70 | +## Integration Points |
| 71 | + |
| 72 | +### Klipper/Moonraker Communication |
| 73 | +- All printer commands via `SocketActions` methods |
| 74 | +- Store updates from WebSocket events (not polling) |
| 75 | +- File operations through Moonraker's file API (`src/store/files/`) |
| 76 | + |
| 77 | +### Component Communication |
| 78 | +- Parent-child: Props down, events up |
| 79 | +- Cross-component: Vuex store or event bus |
| 80 | +- Use `vue-property-decorator` for TypeScript components |
| 81 | + |
| 82 | +## Testing Conventions |
| 83 | +- Unit tests in `tests/unit/` with Vitest + jsdom |
| 84 | +- Mock WebSocket connections for component testing |
| 85 | +- Test store actions/mutations independently from UI |
| 86 | + |
| 87 | +## Code Style |
| 88 | +- Vue class-style components with `vue-property-decorator` |
| 89 | +- ESLint enforced: neostandard + Vue 2 rules and further rules defined in 'eslint.config.mjs' |
| 90 | +- camelCase for variables/methods, PascalCase for components |
| 91 | +- Use `consola` for logging, not `console.log` |
| 92 | +- Type imports: `import type { ... }` for types only |
| 93 | + |
| 94 | +## Common Gotchas |
| 95 | +- Vue 2.7 limitations: No Composition API in production builds |
| 96 | +- WebSocket reconnection handled automatically by `socketClient.ts` |
| 97 | +- File uploads use FormData with progress tracking in store |
| 98 | +- Dynamic imports for code splitting (see `vue-echarts-chunk.ts`) |
0 commit comments