|
| 1 | +# ARCHITECTURE REFACTORING ROADMAP |
| 2 | + |
| 3 | +## OBJECTIVES |
| 4 | +- Stabilize domain logic so it can compile without Leptos, WebGPU, or WASM-only dependencies. |
| 5 | +- Introduce clear seams between user interface, rendering, data access, and core computations. |
| 6 | +- Prepare the repository for a multi-crate workspace without circular dependencies. |
| 7 | +- Reduce reliance on ad-hoc global state in favor of explicit application services and state containers. |
| 8 | +- Maintain current functionality (real-time stream, indicators, rendering) while refactoring incrementally with tests. |
| 9 | + |
| 10 | +## CURRENT COUPLING HOTSPOTS |
| 11 | +- `src/global_state.rs` stitches together Leptos UI types (`TooltipData`), renderer configuration (`LineVisibility`), and ECS accessors, so any change in UI or rendering cascades through the entire app. |
| 12 | +- ECS components (`src/ecs/components.rs`) embed `RwSignal<Chart>`, preventing the ECS layer from being reused without Leptos. |
| 13 | +- Rendering queue helpers (`src/app.rs` and `src/infrastructure/rendering`) pull values directly from global signals, hiding side effects and making it difficult to test rendering decisions. |
| 14 | +- Binance clients under `src/infrastructure` push updates straight into Leptos signals rather than exposing a domain-friendly API. |
| 15 | +- `DomainState` mixes historical candle storage with Leptos-driven refresh cadence, but lacks a dedicated repository service that other layers can depend on. |
| 16 | + |
| 17 | +## TARGET WORKSPACE LAYOUT |
| 18 | +| Crate | Responsibilities | Depends On | |
| 19 | +| --- | --- | --- | |
| 20 | +| `core` | Entities, value objects, indicators, pure services, deterministic tests. | — | |
| 21 | +| `data` | Binance REST/WebSocket clients, DTO translation, retry/backoff policies, mocked providers for tests. | `core` | |
| 22 | +| `rendering` | GPU primitives, buffer packing, line/tooltip layout independent from Leptos. | `core` | |
| 23 | +| `app-services` | Application state container, ECS orchestration, traits for streaming/backfill, adapter from Leptos signals to core models. | `core`, `rendering`, optionally `data` via traits | |
| 24 | +| `wasm-app` | Leptos components, hydration entry points, wiring between UI, `app-services`, and platform APIs. | `app-services` | |
| 25 | + |
| 26 | +The first four crates compile natively; only `wasm-app` requires the `wasm32` target. |
| 27 | + |
| 28 | +## ITERATIVE PLAN |
| 29 | +### ITERATION 0 – BASELINE AND SAFETY NETS |
| 30 | +- Document the current refactoring roadmap (this file) and list required invariants. |
| 31 | +- Add integration tests for indicator calculations and chart viewport math to guard key behaviors. |
| 32 | +- Introduce feature flags or conditional compilation hooks to run the app without WebGPU during tests. |
| 33 | + |
| 34 | +### ITERATION 1 – HARDEN DOMAIN AND ECS BOUNDARIES |
| 35 | +- Move `TooltipData`, `LineVisibility`, and similar UI concepts into a dedicated `app::ui_state` module so `global_state` depends only on that module instead of the entire `app.rs`. |
| 36 | +- Replace `RwSignal<Chart>` in ECS components with a small handle (`ChartHandle`) that hides Leptos behind trait bounds; provide a synchronous implementation for tests. |
| 37 | +- Extract `DomainState` and `ViewState` constructors into functions that do not require Leptos, and ensure no domain module imports anything from `app` or `infrastructure`. |
| 38 | + |
| 39 | +### ITERATION 2 – INTRODUCE APPLICATION SERVICES |
| 40 | +- Create an `AppContext` struct that owns all signals and exposes typed methods for updates (e.g., `set_streaming`, `update_tooltip`). |
| 41 | +- Move Binance websocket/rest callbacks to call through the new context instead of touching globals directly. |
| 42 | +- Define traits (`MarketStream`, `HistoryProvider`) that describe the data services. Provide adapters for current Binance implementations. |
| 43 | +- Cover the service layer with unit tests using fake implementations of the traits. |
| 44 | + |
| 45 | +### ITERATION 3 – ISOLATE RENDERING |
| 46 | +- Wrap the render queue helpers behind a `RenderScheduler` trait implemented by the WebGPU renderer. |
| 47 | +- Migrate `LineVisibility` and GPU configuration types into `rendering` so the UI layer only depends on traits. |
| 48 | +- Provide a dummy renderer used in tests to verify scheduling without invoking WebGPU. |
| 49 | +- Ensure rendering-specific state is no longer stored in `global_state`, but owned by the scheduler or renderer crate. |
| 50 | + |
| 51 | +### ITERATION 4 – PREPARE CRATE EXTRACTION |
| 52 | +- Split the repository into a Cargo workspace with `core`, `app-services`, and `wasm-app` crates; move source files accordingly while keeping `rendering` and `data` inside `app-services` temporarily via modules. |
| 53 | +- Fix imports, adjust `Cargo.toml` dependencies, and ensure `cargo check` succeeds for the new workspace. |
| 54 | +- Update documentation (`ARCHITECTURE.md`, `README.md`) to reflect the new structure. |
| 55 | + |
| 56 | +### ITERATION 5 – FINALIZE MULTI-CRATE STRUCTURE |
| 57 | +- Extract `data` and `rendering` as standalone crates consumed by `app-services`. |
| 58 | +- Provide integration tests that run the full pipeline using mock data streams to validate crate boundaries. |
| 59 | +- Audit for any remaining `OnceCell` globals; replace them with context-owned instances passed through dependency injection. |
| 60 | +- Conduct final cleanup: remove dead code, ensure all binaries and WASM entry points build, update CI workflows. |
| 61 | + |
| 62 | +## RISKS AND MITIGATIONS |
| 63 | +- **Risk:** Increased compilation times due to workspace split. **Mitigation:** Share features and enable incremental builds; start by creating crates without additional dependencies. |
| 64 | +- **Risk:** Hard-to-test asynchronous flows. **Mitigation:** Introduce trait-based abstractions and synchronous mocks in early iterations. |
| 65 | +- **Risk:** UI regressions caused by refactored state handling. **Mitigation:** Add snapshot tests for tooltip rendering and viewport calculations before moving logic. |
| 66 | + |
| 67 | +## DONE CRITERIA PER ITERATION |
| 68 | +- ✅ All commands `cargo fmt --all`, `cargo check --tests --benches`, `cargo clippy --tests --benches`, `cargo test`, and `cargo machete` (if available) succeed. |
| 69 | +- ✅ Documentation updated to mirror the new module ownership. |
| 70 | +- ✅ Tests cover new seams introduced in each iteration. |
| 71 | +- ✅ No module (or crate, once extracted) depends on layers above it. |
0 commit comments