fix: include simulation index in RTDB writes to fix empty SimulationGrid#87
fix: include simulation index in RTDB writes to fix empty SimulationGrid#87TytaniumDev merged 2 commits intomainfrom
Conversation
The SimulationGrid was rendering zero cells in GCP mode because: 1. API PATCH handler built RTDB update objects from request body fields only, never including `index` (which lives in the stored simulation record) 2. Frontend RTDB listener received sims without `index`, called markSimsReceived(), cancelling REST polling (which had correct data) 3. SimulationGrid's simByIndex Map keyed by undefined index, causing all numeric get() lookups to miss Root cause fix: - Resolve sim index from getSimulationStatus() or parse from simId (e.g. "sim_003" → 3), include in RTDB write Defense-in-depth: - Extract parseRtdbSimulations() helper that falls back to parsing index from simId key when RTDB data lacks it - Only cancel REST polling when all sims have valid indices - Guard SimulationGrid against undefined index and NaN totalContainers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@claude do a code review |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical bug where the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Claude finished @TytaniumDev's task in 1m 53s —— View job Code Review
|
| Area | Status |
|---|---|
| Root cause fix | ✅ Correct |
API simIndex resolution |
✅ Clean, correct fallback chain |
parseRtdbSimulations extraction |
✅ Well-designed, testable |
markSimsReceived guard |
✅ Correct |
SimulationGrid NaN guard |
✅ Correct |
| simsRef listener length guard | |
| Test coverage | ✅ Solid, one gap noted |
| DATA_FLOW.md | ✅ Updated correctly |
The only actionable item is the missing if (sims.length > 0) guard in the simsRef listener at useJobProgress.ts:184. Everything else is sound.
There was a problem hiding this comment.
Code Review
This is a great pull request that addresses a critical bug causing the SimulationGrid to be empty. The fix is comprehensive, with changes in the API to include the simulation index in RTDB writes and defensive coding on the frontend to handle cases where the index might be missing.
I appreciate the thoroughness, including:
- Extracting
parseRtdbSimulationsfor better code structure and testability. - Adding resilience to the
SimulationGridcomponent for edge cases. - Writing extensive new tests to cover the new logic and prevent regressions.
- Updating the
DATA_FLOW.mddocumentation to reflect the changes.
I found one potential issue in the useJobProgress hook where the REST polling could be stopped prematurely, which is a valid code quality suggestion that should be addressed in this PR. My review comment includes a suggestion to fix it.
Overall, excellent work on this fix!
|
|
||
| markSimsReceived(); | ||
| const hasValidIndices = sims.every(s => typeof s.index === 'number' && s.index >= 0); | ||
| if (hasValidIndices) markSimsReceived(); |
There was a problem hiding this comment.
The current logic for deciding when to stop REST polling has a subtle bug. Array.prototype.every() returns true for an empty array. If the simsRef listener receives an empty simulations object from RTDB (e.g., before any sims have been written), parseRtdbSimulations will return an empty array []. This will cause hasValidIndices to be true on line 182, and markSimsReceived() will be called here, prematurely stopping the REST polling fallback. This could lead to the SimulationGrid remaining empty if the initial RTDB data is empty.
To fix this, you should also check that the sims array is not empty before marking sims as received. The logic in the jobRef listener (lines 152-157) correctly handles this by checking sims.length > 0.
| if (hasValidIndices) markSimsReceived(); | |
| if (sims.length > 0 && hasValidIndices) markSimsReceived(); |
References
- Address valid code quality suggestions immediately within the current pull request, even if it expands the scope. Do not defer them to a follow-up task.
Address review feedback from Gemini and Claude: - Array.every() returns true for empty arrays, which could prematurely cancel REST polling if parseRtdbSimulations returns [] - simsRef listener was missing the length guard that the parent listener already had, risking setSimulations([]) clearing valid data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Summary
Root cause: API PATCH handler for simulation status updates built RTDB update objects from request body fields only —
indexwas never included because it's a stored property, not sent by the worker. The frontend'sSimulationGridbuilds aMap<number, SimulationStatus>keyed byindex, soundefinedkeys caused all lookups to miss, rendering zero cells.API fix: Resolve sim
indexfromgetSimulationStatus()(already fetched for state-transition guard) or parse from simId (sim_003→3), include in the RTDB write object.Frontend defense-in-depth:
parseRtdbSimulations()helper that falls back to parsingindexfrom the simId key when RTDB data lacks itmarkSimsReceived) when all sims have valid indices, ensuring the fallback continues until usable data arrivesSimulationGridagainstundefinedindex entries andNaNtotalContainersTest plan
npm run lint --prefix api— type-check passesnpm run lint --prefix frontend— ESLint passes (zero warnings)npm run build --prefix frontend— production build succeedsnpx vitest run— all 78 tests pass (10 new)New tests
frontend/src/hooks/useJobProgress.test.tsparseRtdbSimulationsindex fallback, preservation, sorting, filtering, edge casesfrontend/src/components/SimulationGrid.test.tsxtotalSimulations=0,totalSimulations=undefined🤖 Generated with Claude Code