# Step 3: node-and-domain-storage ## Read First Read these files before editing: - `/AGENTS.md` - `/docs/AGENT_RULES.md` - `/docs/ADR.md` - `/docs/ARCHITECTURE.md` - `/docs/implementation-plans/domain-model-foundation-implementation-plan.md` - `/include/fesa/core/ModelTypes.hpp` - `/CMakeLists.txt` ## Task Implement the first useful `Node` and `Domain` slice. Allowed files: - Create `/include/fesa/core/Node.hpp` - Create `/include/fesa/core/Domain.hpp` - Create `/src/core/Domain.cpp` - Create or modify `/tests/core/domain_storage_test.cpp` - Modify `/CMakeLists.txt` to compile the source and register the test Required behavior: - `Node` stores `NodeId` and three coordinates as `double`. - `Domain::addNode(Node)` inserts a node. - Duplicate node ids throw `std::invalid_argument`. - `Domain::findNode(NodeId)` returns a pointer or `nullptr`. - `Domain::node(NodeId)` returns a const reference or throws `std::out_of_range`. - `Domain::nodeCount()` returns the stored node count. - `Domain` must not expose mutable node references. ## Tests To Write First Write failing tests before creating production headers/sources: - Add and retrieve one node by id. - Missing node returns `nullptr` from `findNode`. - Missing node throws from `node`. - Duplicate node id throws. Run the targeted CTest and verify failure due to missing API. Then implement the minimal code. ## Acceptance Criteria Run: ```powershell cmake --build build/msvc-debug --config Debug ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain python scripts/validate_workspace.py ``` Update `/phases/domain-model-foundation/index.json` step 3 with `completed`, `error`, or `blocked`. ## Do Not - Do not add elements, materials, properties, sets, loads, or steps yet. - Do not store equation ids, displacement vectors, residuals, reactions, or solver state.