11 Commits
Author SHA1 Message Date
vinihcrosaandClaude Opus 4.8 d86116e33f fix(sim): address review round 1 (6 issues)
- manager: surface worker_thread errors/exit to clients and tear the sim
  down (issue 001); cache last status/state and replay on attach so a
  reconnecting client sees current state even when paused (issue 002)
- web socket: capped exponential reconnect backoff + bounded command queue
  (issue 003); derive ws/wss URL from page origin (issue 004)
- runner: build replacement engine before freeing the old one (issue 005)
- remove dead VesselConfig message path across types/api/web (issue 006)

Tests added for each fix. Full monorepo suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 12:05:05 -03:00
vinihcrosaandClaude Opus 4.8 ff2e3db3bb refactor(web): remove client-side physics engine
Single engine now lives on the server. Delete the simulation Web Worker,
the JS mock (mock-wasm), apps/web/public/wasm, and retire WorkerMessageDTO
and the wasm|mock SimulationEngine union from @ymir/types. Drop the
COOP/COEP headers and worker.format from vite config (were only for
in-browser WASM).

Task: task_08. Verified: web typecheck + unit suite green (83%), types
100%, api build clean, no dangling references. E2E against a live server
is validated separately (requires the running apps/api + web).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 20:43:38 -03:00
vinihcrosaandClaude Opus 4.8 8a21003c37 feat(wasm): add @ymir/wasm package with Node-target Emscripten build
Package the physics engine as an internal @ymir/wasm workspace package
that runs in Node (worker_threads). Parametrize the Emscripten build
(YMIR_WASM_ENVIRONMENT=node, output dir override) so the same C++ core
builds for the server. Expose SimulationEngine interface +
createSimulationEngine() loader mirroring YmirBindings.cpp.

Task: task_01. Tests: 8 passing against the real WASM engine, 100% coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 19:58:08 -03:00
vinihcrosaandClaude Opus 4.8 c54a73080c feat(types): add ClientMessage/ServerMessage network protocol DTOs
Add-only network contract for the server-side simulation: ClientMessage
(commands) and ServerMessage (events) TypeBox unions, reusing
SimulationStateDTO/VesselConfigDTO. Adds ScenarioDraftVesselDTO and
ScenarioInputDTO. WorkerMessageDTO left intact (removed in a later task).

Task: task_02. Tests: 45 passing, 100% coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 19:53:51 -03:00
vinihcrosaandClaude Opus 4.8 0e28474b6b fix(types): carry both instanceId and vessel type id in scenario initial conditions
InitialCondition.vesselId held the per-scenario instance id, losing which vessel
TYPE each body was — so a saved scenario could not reload the right vessel config.
Add instanceId (engine body id) and keep vesselId as the type id; emit both from
the scenario store. (Resolves the flagged DTO ambiguity.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 22:14:02 -03:00
vinihcrosaandClaude Opus 4.8 c9e7fe1275 feat(web): instructor UI foundation — design system, app shell, real-physics surfacing
Phase 1 of the Figma "[INSTRUTOR]" port plus hardening found during testing.

Design system
- theme/tokens.ts + global.css: Figma palette, type scale, spacing, radii,
  shadows; injected as CSS vars at boot.
- ui/: 11 themed primitives (Button, IconButton, TopBar, Panel, Tabs, Card,
  Slider, Field, Modal/AlertDialog, SimulationControl, MapActions), each tested.

App shell (Layout do instrutor)
- features/shell/AppShell.tsx: TopBar (logo + breadcrumb, gated center actions,
  Sair/Salvar), full-bleed map, bottom-center Build/Play/Stop pill, bottom-right
  zoom, no-ownship AlertDialog. Replaces ScenarioCreatorPage.
- stores/mapStore.ts exposes the Leaflet instance so the zoom pill can drive it;
  AreaMapView registers it and drops Leaflet's default zoom control.

Physics truth
- Worker reports which engine loaded (real WASM vs JS mock); surfaced as a
  status badge/warning so the instructor never mistakes the mock for real
  dynamics. SimulationControls is now a status-only strip (actions moved to the
  pill).

Tests
- 229 passing, coverage gate green. New: tokens, all 11 primitives, AppShell,
  VesselPanel, vesselPanelStore. Fixed GeralTab to read draft by instanceId.

Docs
- docs/specs/features/instructor-ui/: extracted screen specs, reference maps,
  phased PLAN.md, and DYNAMICS-GAP.md (MATLAB↔Ymir physics parity).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 20:55:49 -03:00
vinihcrosaandClaude Sonnet 4.6 53ce4a91f6 feat: environmental conditions, vessel instanceId, panel stability, regression tests
Environmental Conditions feature:
- C++ EnvironmentTimeline: time-series current/wind data, JSON serialization
- WASM bindings: loadEnvironment(), World integration
- TypeScript types: CurrentSeries, WindSeries, EnvironmentPayload
- Zustand environmentStore with React panel (EnvironmentConditionPanel)
- Mock WASM current drift physics: nautical→body-frame velocity applied in step()

Bug fixes:
- Vessel instanceId: unique auto-increment ID per scenario instance prevents duplicate
  vesselId crash when adding two vessels of same type
- vesselPanelStore: separate vesselTypeId field so config fetch uses correct type ID
  (not instanceId) after the instanceId/vesselId split
- VesselMarker stable eventHandlers: useMemo + useRef pattern prevents react-leaflet
  from re-registering Leaflet listeners every 50ms tick, fixing panel clicks during
  active simulation

Tests:
- Playwright regression suite (e2e/regression.spec.ts): 8 tests covering panel open
  during simulation, multi-click consistency, two VLCC no error, dual marker render,
  individual panel open, remove-one behavior, current drift, no-drift baseline

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 11:29:16 -03:00
vinihcrosaandClaude Sonnet 4.6 a9061fbf2b feat(persistence): add simulation area model with geographic boundary
Introduces the Area entity: geographic origin (lat/lng = simulation 0,0),
GeoJSON polygon boundary, and environmental constants (gravity, water/air
density, magnetic correction). A simulation cannot run outside its area.

- areas table with origin, polygon (GeoJSON), and environment constants
- Auto-seed from area.json on startup (Baía de Guanabara)
- GET/POST/DELETE /areas endpoints (route → service → repository)
- scenarios.area_id FK — nullable for existing rows, idempotent ALTER migration
- AreaDTO + CreateAreaDTO in @ymir/types; ScenarioDTO gains optional areaId

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 02:52:23 -03:00
vinihcrosaandClaude Sonnet 4.6 5d937ca07b feat(persistence): store full vessel physics config from vessel1.json
Adds 6 supplementary SQLite tables (physical_props, current, connection_points,
rudders, thrusters, waves) to hold all hydrodynamic data for the VLCC
VLCC_L350_B63_T230 (L=350m, B=63m, T=23m).

- Auto-seed at startup: reads vessel1.json into all tables when DB is empty
- GET /vessels/:id/config endpoint returns full physics config for simulation
- Refactored vessels route to use service + repository layer pattern
- Expanded @ymir/types with VesselConfigDTO and all sub-component schemas
- Simulation worker fetches vessel config on init, passes to WASM loadConfig()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 02:06:56 -03:00
vinihcrosaandClaude Sonnet 4.6 3630507efa chore: remove build artifacts from tracking, update .gitignore
- Add dist/, *.profraw, .wasm-stage/ to .gitignore
- Remove apps/api/dist/, apps/web/dist/, packages/types/dist/ from git
  (generated on build, should not be versioned)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 00:41:24 -03:00
vinihcrosaandClaude Sonnet 4.6 6295d540a4 feat: migrate to monorepo with WASM core, Fastify API, and React frontend
- Move C++ sources to core/ subdirectory (T05)
- Add pnpm workspaces + Turborepo pipeline (T06)
- Add Emscripten CMake target and build-wasm.sh (T07)
- Implement Embind bindings via YmirBindings.cpp (T08)
- Add packages/types with TypeBox schemas for VesselDTO, ScenarioDTO, SimulationStateDTO (T09)
- Create apps/api: Fastify v4 + Drizzle ORM + SQLite with vessels/scenarios CRUD (T10-T13)
- Create apps/web: Vite + React 18 + COOP/COEP headers (T14)
- Add simulation.worker.ts for WASM loop in Web Worker (T15)
- Add Zustand simulationStore (T16)
- Add TelemetryPanel component (T17)
- Verified: pnpm build 3/3 tasks, 21ms cached; ctest 211/211 pass (T18-T19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 00:08:28 -03:00