Skip to content

Add an interactive garden bed planner - #189

Merged
NetworkTheoryAppliedResearchInstitute merged 1 commit into
NTARI-RAND:mainfrom
nirmalhk7:nirmal/agrinet-garden-planner
Oct 28, 2026
Merged

NetworkTheoryAppliedResearchInstitute merged 1 commit into
NTARI-RAND:mainfrom
nirmalhk7:nirmal/agrinet-garden-planner

Conversation

@nirmalhk7

@nirmalhk7 nirmalhk7 commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Agrinet already has crop spacing, compatibility, and maturity calculations, but using them requires calling JavaScript utilities. This adds /garden-planner and a navigation link so growers can plan a bed directly in the existing Next.js site.

Choose a bed size and planting date, select a crop, and click a square to plant or replace it. The page shows plant counts, highlights incompatible adjacent crops, and lists estimated harvest dates. It reuses the existing tomato, lettuce, carrot, and basil rules. Estimates are explicitly limited: they do not account for variety, climate, soil, or the local growing season.

Saving is explicit and browser-local. JSON export/import lets a grower keep an editable copy elsewhere; invalid files leave the current bed intact. Shrinking a bed shows the number of planted squares that would be removed and requires confirmation. The planner runs without a backend server or external service, and adds no dependencies.

This is a local planning aid, not a federated Plan message or ledger implementation. CONFORMANCE.md records that boundary without changing existing in-review claims. The scope follows Jodson's local-growing description and Confluence's modular planting-coordination design; current repo invariants govern the implementation.

Validation

  • Frontend npm test: 10 planner tests and production build passed. Tests were added before implementation and observed failing, including separate save/restore and resize-impact cases.
  • Frontend npm run lint passed. Existing backend npm test passed: 37 Node tests and 46 Jest tests across 19 suites.
  • Browser checks covered editing, erasing, conflict detection/resolution, resizing and cancellation, save/reload, JSON download/reimport, and invalid-file rejection. The final production build also restored the saved example and displayed neighbor conflicts correctly.

One SSH-signed commit with DCO sign-off.

Screenshots

Editable bed with all four supported crops:

Garden planner showing a four-by-four-foot bed and crop palette

Neighbor conflicts and plant totals:

Garden planner showing incompatible adjacent crops and explanations

Expose existing crop spacing, compatibility, and maturity calculations
through an editable Next.js garden bed. Show crop totals, neighbor
conflicts, and estimated harvest dates without a backend service.

Keep saving explicit and browser-local, with validated JSON export and
import. Confirm resizes that remove plantings and label estimate limits.

Add test-first coverage for planning, validation, portability, storage
errors, and resize impact. Document NTARI scope and include UI screenshots.

Signed-off-by: Nirmal Khedkar <nirmalhk7@gmail.com>
@nirmalhk7
nirmalhk7 marked this pull request as ready for review October 25, 2026 19:21
@nirmalhk7

Copy link
Copy Markdown
Contributor Author

I've tried to be careful with these new feature PRs, but if I've missed anything, pls feel free to add anything here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Nirmal, thanks for the garden planner. It's a clean, well-scoped addition.

What I tested: commit 0382d5d, merged into current main (cf9299f) through GitHub's merge ref 31f25c5, on Node 24.

  • Backend: npm test 37/37 and Jest 46/46, unchanged from main.
  • Frontend: lint is clean, your new test:planner passes 10/10, and the Next.js build passes with the new static /garden-planner route (5.9 kB).
  • Chat-ui: 6/6, and its build output is unchanged.
  • CI: CodeQL, the URL scan and DCO are green.

No regressions.

What I liked:

  • The library never changes a plan in place, and the component is a thin layer over it.
  • It reuses the backend crop rules instead of copying them.
  • Import is strict: version, real calendar dates, a rectangular 1-8 ft grid, supported crops only, and a 32 KB limit. Save and export keep only version, startDate and layout.
  • Date math is UTC throughout, with a leap-day test.
  • Storage errors are shown to the user, not swallowed.
  • No new dependencies, and no env or network calls in the client bundle.
  • The CONFORMANCE note is honest.

To check the tests, I planted 34 small bugs in the code one at a time. Your tests caught 27, and production code handles all 7 missed cases correctly.

None of the points below block merging. Fixing them here or in a follow-up is fine:

  1. frontend/components/GardenPlanner.js:95. The replace-on-import confirmation checks analysis?.occupiedSquares. That value is undefined while the date field is empty or half-typed, because analyzePlan throws. Import stays enabled in that state (line 115), so a planted, unsaved bed gets replaced with no prompt. Suggested fix: use plan.layout.some(row => row.some(Boolean)) for the check, and optionally disable Import while !analysis.

  2. frontend/tests/gardenPlanner.test.cjs:21-24. Both expected conflicts are horizontal, and the diagonal pairs in the "without treating diagonals" test are compatible crops, so that test can't detect a diagonal bug. Removing the vertical [r+1, c] check in lib/gardenPlanner.js:74 still passes all 10 tests. Please add:

    • a vertical case: [['tomato'],['carrot']] expecting [{first:[0,0], second:[1,0], crops:['tomato','carrot']}]
    • two diagonal-only layouts, [['basil',null],[null,'lettuce']] and [[null,'basil'],['lettuce',null]], each expecting []
  3. frontend/tests/gardenPlanner.test.cjs:74. The "oversized" fixture (33,000 spaces) is also invalid JSON, so the test passes even with the 32 KB check at lib line 99 removed. No import fixture reaches the bed-dimension check either. Please use a valid-JSON oversized plan and assert /too large/, then add 9-row and [[]] imports that assert /dimensions/.

  4. backend/utils/squareFootGardening.js (imported at frontend/lib/gardenPlanner.js:1-3 and components/GardenPlanner.js:8). This module now ships to the browser. As a test, I added a server-only require to it: the build still passed, and the SDK ended up in the page bundle. A header comment saying the module must stay dependency-free and browser-safe would protect it.

  5. GardenPlanner.js:137-138. If the width or length is edited while the resize confirmation is showing, confirming applies the old size while the inputs show the new one. Calling setPendingResize(null) in both onChange handlers fixes it.

  6. GardenPlanner.js:160 and 163. The button's aria-label hides the "!" conflict span from screen readers. Add ", neighbor conflict" to the button's aria-label for conflicting squares, and mark the span aria-hidden="true".

  7. frontend/README.md:34-35. The design-context links go to a Slack thread and a Confluence page that need an NTARI login. Could you replace them with a short public summary or a link to a public issue?

On our side: no workflow in the repo runs tests or builds yet, so your planner tests won't run in CI. We'll handle that in a separate ticket; it's not on you.

Thanks again, nice work.

Approved at the tested commit 0382d5d on Jodson Graves's instruction.

@NetworkTheoryAppliedResearchInstitute
NetworkTheoryAppliedResearchInstitute merged commit 7524c48 into NTARI-RAND:main Oct 28, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants