1. Current Architecture (As‑Is)
The project currently contains two overlapping architectures:
Active/Live Architecture (Works)
- Entry point:
cmd/airmouse-server/main.go - UI Layer:
ui/package – Fyne‑based desktop GUI. - Application/Control Layer:
control/package – mouse controller, AI smoothers, predictors, gesture detection. - Protocol Layer:
protocol/package – TCP, WebSocket, UDP, Bluetooth, USB servers. ContainsProtocolServerthat coordinates all protocols and thedevice.Manager. - Device Management:
device/package (not fully provided, but referenced) manages device states and persistence. - Configuration & Utils:
config/,utils/,auth/packages.
Duplicate/Stub Architecture (Not Used)
- Domain Layer:
domain/package – entities (entity/), service interfaces (service/), repository interfaces (repository/). - Infrastructure Layer:
infra/package – repository implementations (repository/), WebSocket hub (websocket/), HTTP router (http/), DTOs (dto/). - **This layer is not wired into
main.goand has many stubs/no‑ops.
Additionally, there are ignored / experimental files (//go:build ignore) like particle filter, duplicate mouse implementations, and a duplicate protocol server.
2. Recommended Clean Architecture
We will follow a clean, layered architecture with clear separation of concerns. I recommend adopting the DDD‑style layer (domain, application, infrastructure) instead of the current protocol/control approach, but only if you are willing to refactor. For most practical purposes, the existing protocol/control layer is simpler and already working.
I recommend the following structure (which merges the best of both worlds):
airmouse-go/
├── cmd/
│ └── airmouse-server/ # Main entry point
├── internal/
│ ├── app/ # Application orchestration
│ │ ├── server.go # Creates ProtocolServer, UI, services
│ │ └── lifecycle.go # Start/stop hooks
│ ├── domain/ # Core business logic (entities, value objects)
│ │ ├── entity/ # Device, Client, Gesture, MouseProfile, Statistics
│ │ ├── repository/ # Interfaces for persistence/retrieval
│ │ └── service/ # Interfaces for use cases (MouseService, GestureService, ConnectionService)
│ ├── application/ # Implementation of services (use cases)
│ │ ├── mouse/
│ │ │ └── service.go # Implements MouseService interface
│ │ ├── gesture/
│ │ │ └── service.go # Implements GestureService (with recognizer)
│ │ └── connection/
│ │ └── service.go # Implements ConnectionService
│ ├── infrastructure/ # External dependencies (repositories, protocol adapters)
│ │ ├── protocol/ # All protocol servers (TCP, WebSocket, UDP, Bluetooth, USB)
│ │ │ ├── tcp/
│ │ │ ├── websocket/
│ │ │ ├── udp/
│ │ │ ├── bluetooth/
│ │ │ ├── usb/
│ │ │ └── protocol.go # ProtocolServer (orchestrates all)
│ │ ├── mouse/ # Platform‑specific mouse control (CoreGraphics, WinAPI, uinput)
│ │ │ ├── mouse.go # MouseController interface
│ │ │ ├── darwin.go
│ │ │ ├── windows.go
│ │ │ └── linux.go
│ │ ├── repository/ # Concrete repository implementations (in‑memory, file, DB)
│ │ │ ├── client_repo.go
│ │ │ ├── gesture_repo.go
│ │ │ └── mouse_repo.go
│ │ ├── config/ # Configuration loader/saver
│ │ ├── auth/ # Authentication (token validation)
│ │ ├── device/ # Device manager (could be merged with client repo)
│ │ └── utils/ # Helpers (ID generation, logging, IP, crypto)
│ ├── ui/ # Fyne‑based GUI
│ │ ├── app.go # Main window, tabs
│ │ ├── dashboard.go
│ │ ├── devices.go
│ │ ├── network.go
│ │ ├── gestures.go
│ │ ├── proximity.go
│ │ ├── analytics.go
│ │ ├── settings.go
│ │ ├── logs.go
│ │ ├── protocol_guide.go
│ │ ├── statusbar.go
│ │ ├── glass_card.go
│ │ ├── helpers.go
│ │ └── ... (other UI components)
│ └── pkg/ # Shared libraries (if any)
│ └── ...
└── go.mod
Key Architectural Principles:
- Dependency Inversion: High‑level modules (UI, application services) depend on interfaces (domain/service, domain/repository), not on concrete implementations.
- Separation of Concerns:
- UI: Only deals with presentation and user input. It calls application services.
- Application Services: Orchestrate use cases, call repositories and infrastructure adapters.
- Domain: Contains business rules, entities, and value objects (no external dependencies).
- Infrastructure: Implements repositories, protocol servers, mouse control, etc.
- Single Responsibility: Each package has a clear purpose and minimal overlap.
3. Component Interactions (How They Talk to Each Other)
+------------------+ +---------------------------+
| UI (fyne) | -------> | Application Services |
| (ui/*) | | (mouse, gesture, connect) |
+------------------+ +-------------+-------------+
|
v
+---------------------------+
| Domain Entities & Repos |
| (domain/entity, repo) |
+-------------+-------------+
|
v
+------------------+ +---------------------------+
| Protocol Server | <------> | Repository Implementations|
| (infra/protocol) | | (infra/repository) |
+------------------+ +---------------------------+
|
v
+---------------------------+
| External Systems |
| (OS mouse, network, etc.) |
+---------------------------+
- UI calls services (e.g.,
mouseService.Move(),connectionService.ListClients()). - Services use repositories to read/write data (clients, gestures, statistics) and call infrastructure adapters (e.g.,
protocolServer.Broadcast(),mouseRepo.Move()). - Protocol Servers handle raw network connections, decode messages, and call back into the application (e.g., on new client, on mouse move, on gesture). They are infrastructure and should not contain business logic.
4. Which Files to Keep, Delete, or Complete
Based on the current state, here is a concrete action plan:
✅ Keep (Active, working)
cmd/airmouse-server/main.goui/(all.gofiles) – they already call the active services (but you may refactor them to call the new application services later).control/(all active files:mouse.go,movement_predictor.go,pause.go, plus platform‑specific*_darwin.go,*_linux.go,*_windows.go). Keep these for now if you stick with the old architecture. If you refactor, you can replace them withinfrastructure/mouse/.protocol/(all active*.goexcept the ignoredserver.go). Keepprotocol.go,message.go, and sub‑packages (tcp, websocket, udp, bluetooth, usb).device/– keep (used by protocol servers).auth/– keep.config/– keep.utils/– keep.personalization/– keep (if used).
❌ Delete / Archive (Duplicates, stubs, ignore)
- All
//go:build ignorefiles:control/mouse_darwin.goprotocol/server.goparticlefilter/(entire folder) – unless you plan to use it; then you could move it toinfrastructure/gesture/recognizer.predictive/test.go– rename tokalman2d_test.goif needed, but it's not integrated.control/predictor.go(duplicate ofmovement_predictor.go).
- The entire DDD‑style layer (
domain/,infra/except forinfra/mouseandinfra/repositoryif you decide to use them) – if you are not going to refactor. If you are going to refactor, then you should complete and integrate them, not delete.
🔧 Complete (if you choose to adopt the new architecture)
domain/entity/– define all entities (already done, but ensure they match the active ones).domain/repository/– interfaces (already defined).domain/service/– interfaces (already defined).infra/repository/– implement all methods (already done for client and gesture; mouse repo needs real OS integration).infra/websocket/– if used, integrate with protocol; but I'd rather keep the existingprotocol/websocket.infra/http/– if you want a separate HTTP server for health/metrics, it's fine.
5. Fully Completed File Structure (After Cleanup)
Here is the final file tree you should aim for (with no duplicates, all necessary files present and functional):
airmouse-go/
├── cmd/
│ └── airmouse-server/
│ └── main.go # Initializes app, starts UI, protocol, services
├── internal/
│ ├── app/
│ │ ├── app.go # Application bootstrap, dependency injection
│ │ └── lifecycle.go # Start/stop hooks (optional)
│ ├── ui/ # All UI files (no changes needed)
│ │ ├── about.go
│ │ ├── analytics.go
│ │ ├── app.go # Main window, tabs, menu
│ │ ├── connection.go # Quality widget
│ │ ├── dashboard.go
│ │ ├── devices.go
│ │ ├── gestures.go
│ │ ├── glass_card.go
│ │ ├── helpers.go
│ │ ├── icons.go
│ │ ├── logs.go
│ │ ├── network.go
│ │ ├── pairing.go
│ │ ├── premium_dashboard.go
│ │ ├── premium_theme.go
│ │ ├── protocol_guide.go
│ │ ├── proximity.go
│ │ ├── settings.go
│ │ ├── shortcuts.go
│ │ ├── speedchart.go
│ │ ├── statusbar.go
│ │ └── themes.go
│ ├── domain/ # Core business entities and repository/service interfaces
│ │ ├── entity/
│ │ │ ├── client.go
│ │ │ ├── device.go # (if not already in device package)
│ │ │ ├── gesture.go
│ │ │ ├── mouse.go
│ │ │ └── statistics.go
│ │ ├── repository/
│ │ │ ├── client_repository.go # Interface
│ │ │ ├── gesture_repository.go # Interface
│ │ │ └── mouse_repository.go # Interface
│ │ └── service/
│ │ ├── connection_service.go # Interface
│ │ ├── gesture_service.go # Interface
│ │ └── mouse_service.go # Interface
│ ├── application/ # Implementations of services (use cases)
│ │ ├── mouse/
│ │ │ └── service.go # MouseService impl (using repos and mouse controller)
│ │ ├── gesture/
│ │ │ ├── service.go # GestureService impl (with recognizer)
│ │ │ └── recognizer.go # (optional) internal recognizer
│ │ └── connection/
│ │ └── service.go # ConnectionService impl (using client repo)
│ ├── infrastructure/ # External adapters
│ │ ├── protocol/ # All protocol servers (keep current)
│ │ │ ├── tcp/
│ │ │ ├── websocket/
│ │ │ ├── udp/
│ │ │ ├── bluetooth/
│ │ │ ├── usb/
│ │ │ └── protocol.go # ProtocolServer (orchestrates all, calls services?)
│ │ ├── mouse/ # Platform‑specific mouse control
│ │ │ ├── mouse.go # Interface and common logic
│ │ │ ├── darwin.go
│ │ │ ├── windows.go
│ │ │ └── linux.go
│ │ ├── repository/ # Repository implementations
│ │ │ ├── client_repository_impl.go
│ │ │ ├── gesture_repository_impl.go
│ │ │ └── mouse_repository_impl.go # Uses mouse controller from infra/mouse
│ │ ├── config/ # Configuration (keep)
│ │ ├── auth/ # Auth (keep)
│ │ ├── device/ # Device manager (could be replaced by client repo)
│ │ └── utils/ # Helpers (keep)
│ └── pkg/ # (optional) shared libraries
│ └── ...
├── go.mod
└── go.sum
6. Recommended Migration Path
- First, stabilise the current working version – fix the critical bugs (WebSocket error propagation, data races, welcome message) so that the app connects reliably.
- Decide which architecture to keep – either keep the simple
protocol/controlapproach or adopt the clean DDD architecture. - If you adopt the DDD architecture:
- Move all protocol servers to
infrastructure/protocol/and make them implement aBroadcasterinterface. - Inject
ConnectionServiceandMouseServiceinto the protocol handlers. - Replace direct calls to
device.Managerwith calls toConnectionServiceandClientRepository. - Refactor the UI to use the new services (this is a bigger effort).
- Move all protocol servers to
- Delete all duplicate/ignored files to reduce confusion.
- Write comprehensive unit and integration tests for the critical paths.
7. Summary
The cleanest, most maintainable structure is one where:
- UI depends only on application services.
- Services depend on repository interfaces and infrastructure adapters.
- Repositories and protocol servers are pluggable and testable.
- There are no duplicate implementations and no ignored files in the main build.
I have provided the full file layout and the reasoning. If you need more detail on any specific file (e.g., the exact implementation of mouse_repository_impl.go that calls the OS APIs), I can provide that too. Let me know which part you want to tackle first.
Xet Storage Details
- Size:
- 15.6 kB
- Xet hash:
- 2e369d634e03c4b13b359ea22d7c86f33bb0191fb3e7f9e65f4b7a5b71f0d419
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.