Season view: filter the editor to a year #54

Closed
opened 2026-07-21 04:18:54 +00:00 by steve · 0 comments
Owner

Design: DESIGN.md

Context

"Change the garlic bed to cucumbers this year" has a year in it, and right now pansy has no notion of one — the editor shows whatever is currently planted, full stop.

The good news is the data already supports seasons and always has: plantings carry planted_at and removed_at, and "clear bed" soft-removes rather than deleting. A season is a date range over data that already exists. No schema change, and specifically no seasons table — v1's parking lot listed a "season/year scenario layer", but a table would duplicate what the dates already say and create a second source of truth about when something was in the ground.

Worth noting the copy feature from #46 is the other half of this: copy last year's layout, edit it, keep both. Scenario planning is a garden copy; season viewing is a filter.

Scope

  • GET /gardens/:id/full?year=YYYY — include plantings whose [planted_at, removed_at) interval overlaps that calendar year. Absent param keeps today's behaviour (active plantings only), so nothing existing changes.
  • Undated plantings are always included. Every planting today has a null planted_at, so a rule that excludes them would empty every garden the moment a year is selected. Document it in the handler.
  • Year selector in the editor chrome; default to the current year. Persist the choice per garden in the editor store (ephemeral state, not server-side).
  • Historical years render read-only, or at minimum make it unmistakable that you're not looking at now. Editing the past by accident is the failure mode.
  • Offer only years that actually have data, plus the current one — a free-numeric year field invites typos and empty views.

Out of scope

  • A seasons table, per above.
  • Crop rotation warnings ("nightshades here three years running"). Genuinely useful, genuinely a later thing, and it becomes easy once this lands.
  • Comparing two years side by side.

Key files

internal/api/objects.go (getGardenFull) · internal/service/objects.go (assembleFull) · internal/store/plantings.go (ListActivePlantingsForGarden — needs a dated sibling) · web/src/editor/store.ts · web/src/pages/GardenEditorPage.tsx

Dependencies

None. Pairs naturally with #52/#53 — a year's plantings plus that year's notes is the season record.

Acceptance criteria

  • Selecting a past year shows what was planted then, including plops since removed.
  • A planting spanning a year boundary (garlic in October, harvested in July) appears in both years.
  • Undated plantings appear in every year.
  • Without the param, /full behaves exactly as it does today — verified by the existing tests still passing unchanged.
Design: [DESIGN.md](https://gitea.stevedudenhoeffer.com/steve/pansy/src/branch/main/DESIGN.md) ## Context "Change the garlic bed to cucumbers **this year**" has a year in it, and right now pansy has no notion of one — the editor shows whatever is currently planted, full stop. The good news is the data already supports seasons and always has: plantings carry `planted_at` and `removed_at`, and "clear bed" soft-removes rather than deleting. A season is a date range over data that already exists. **No schema change, and specifically no `seasons` table** — v1's parking lot listed a "season/year scenario layer", but a table would duplicate what the dates already say and create a second source of truth about when something was in the ground. Worth noting the copy feature from #46 is the other half of this: copy last year's layout, edit it, keep both. Scenario planning is a garden copy; season *viewing* is a filter. ## Scope - [ ] `GET /gardens/:id/full?year=YYYY` — include plantings whose `[planted_at, removed_at)` interval overlaps that calendar year. Absent param keeps today's behaviour (active plantings only), so nothing existing changes. - [ ] **Undated plantings are always included.** Every planting today has a null `planted_at`, so a rule that excludes them would empty every garden the moment a year is selected. Document it in the handler. - [ ] Year selector in the editor chrome; default to the current year. Persist the choice per garden in the editor store (ephemeral state, not server-side). - [ ] Historical years render read-only, or at minimum make it unmistakable that you're not looking at now. Editing the past by accident is the failure mode. - [ ] Offer only years that actually have data, plus the current one — a free-numeric year field invites typos and empty views. ## Out of scope - A `seasons` table, per above. - Crop rotation warnings ("nightshades here three years running"). Genuinely useful, genuinely a later thing, and it becomes easy once this lands. - Comparing two years side by side. ## Key files `internal/api/objects.go` (`getGardenFull`) · `internal/service/objects.go` (`assembleFull`) · `internal/store/plantings.go` (`ListActivePlantingsForGarden` — needs a dated sibling) · `web/src/editor/store.ts` · `web/src/pages/GardenEditorPage.tsx` ## Dependencies None. Pairs naturally with #52/#53 — a year's plantings plus that year's notes is the season record. ## Acceptance criteria - Selecting a past year shows what was planted then, including plops since removed. - A planting spanning a year boundary (garlic in October, harvested in July) appears in both years. - Undated plantings appear in every year. - Without the param, `/full` behaves exactly as it does today — verified by the existing tests still passing unchanged.
steve added the frontenddrawing labels 2026-07-21 04:18:54 +00:00
steve closed this issue 2026-07-21 05:47:35 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: steve/pansy#54