Introduce explicit buffer strip field handling#422
Conversation
…h the stored parameter `b_buffer` to allow users setting the value explicitly
…ic as in determineIfFieldIsBuffer
… screen design for the field pages
🦋 Changeset detectedLatest commit: e01ccdb The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## development #422 +/- ##
===============================================
+ Coverage 88.04% 88.07% +0.03%
===============================================
Files 91 91
Lines 4591 4620 +29
Branches 1468 1492 +24
===============================================
+ Hits 4042 4069 +27
- Misses 549 551 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the WalkthroughAdds a per-field boolean Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App as fdm-app (UI)
participant API as fdm-core (API)
participant DB as Database
participant Calc as fdm-calculator
participant NMI as External NMI
User->>App: toggle "Bufferstrook" on field
App->>API: updateField({ b_bufferstrip })
API->>DB: UPDATE fields SET b_bufferstrip=...
DB-->>API: OK
API-->>App: updated field (includes b_bufferstrip)
App->>API: request field list / fieldOptions
API->>DB: SELECT ... b_bufferstrip ...
DB-->>API: fields with b_bufferstrip
API-->>App: response
App->>Calc: getNutrientAdvice(..., b_bufferstrip)
alt b_bufferstrip == true
Calc-->>App: return zeroed nutrient advice (no NMI call)
else b_bufferstrip == false
Calc->>NMI: call external NMI API
NMI-->>Calc: results
Calc-->>App: nutrient advice data
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
fdm-app/app/components/blocks/farm/farm-title.tsx (1)
38-53: Skeleton layout doesn't match FarmTitle responsive behavior.
FarmTitleusesflex flex-col xl:flex-rowto stack vertically on smaller screens, butFarmTitleSkeletonalways usesflex items-center(horizontal). This causes a layout shift when content loads on mobile/tablet screens.🛠️ Suggested fix to align skeleton with component layout
export function FarmTitleSkeleton() { return ( <div className="space-y-6 p-4 md:px-6 md:py-8 pb-0"> - <div className="flex items-center gap-4"> - <div className="space-y-0.5 "> + <div className="flex flex-col xl:flex-row xl:items-center gap-4"> + <div className="space-y-0.5 min-w-0 flex-1"> <Skeleton className="h-8 w-[200px] md:w-64" /> <Skeleton className="h-5 w-[250px] md:w-96" /> </div> <div className="ml-auto"> <Skeleton className="h-10 w-24" /> </div> </div> <Separator className="my-6" /> </div> ) }fdm-app/app/integrations/calculator.ts (1)
167-190: Add missinggetFieldimport from@svenvw/fdm-core.
getFieldis invoked on line 167 but isn't imported, which will break the build. The function signature matches the call site:getField(fdm, principal_id, b_id)expects three arguments in that order, all of which are provided correctly.Proposed fix
import { type FdmType, type Field, type fdmSchema, getCultivations, getCurrentSoilData, + getField, type PrincipalId, type Timeframe, } from "@svenvw/fdm-core"fdm-calculator/src/balance/nitrogen/index.test.ts (2)
31-37: Fix pipeline failure: add missingb_bufferstripproperty.The TypeScript type check is failing because the
fieldobject is missing the requiredb_bufferstripproperty. Addb_bufferstrip: falseto the field definition to fix the build.🔧 Proposed fix
field: { b_id: "field1", b_centroid: [5.0, 52.0], b_area: 100, b_start: new Date("2023-01-01"), b_end: new Date("2023-12-31"), + b_bufferstrip: false, },
176-183: Fix pipeline failure: add missingb_bufferstripproperty to error handling test.This test also needs the
b_bufferstripproperty added to the field object to satisfy the updated type requirements.🔧 Proposed fix
field: { b_id: "field1", b_centroid: [5.0, 52.0], b_area: 100, b_start: new Date("2023-01-01"), b_end: new Date("2023-12-31"), + b_bufferstrip: false, },
🤖 Fix all issues with AI agents
In @.changeset/huge-cars-peel.md:
- Around line 1-5: Reword the changeset description to be clearer: replace the
awkward sentence about replacing "at field the derived parameter
`b_isproductive`" with a concise statement such as "Replace the derived
parameter `b_isproductive` with the stored parameter `b_bufferstrip` so users
can set it explicitly," and keep the existing metadata line for
"@svenvw/fdm-core": minor unchanged; ensure the parameter names `b_isproductive`
and `b_bufferstrip` remain exact.
In @.changeset/loud-yaks-repeat.md:
- Line 5: Fix the typo in the changeset sentence: change "bases" to "based" so
the note reads "Set for existing fields the b_bufferstrip based on the same
logic as in determineIfFieldIsBuffer"; ensure the identifier b_bufferstrip and
function name determineIfFieldIsBuffer remain unchanged.
In `@fdm-app/app/components/blocks/fertilizer-applications/form.tsx`:
- Around line 169-185: The container currently uses the utility "[&>*]:grow"
which makes both the Combobox wrapper and the button wrapper grow and lets the
button steal width; remove the "[&>*]:grow" from the parent div and ensure the
Combobox wrapper remains "flex-1" while the button wrapper (the div with class
"py-2 shrink-0") explicitly has "grow-0" so the Combobox (name="p_id", component
Combobox) keeps available space on small screens.
In `@fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx`:
- Around line 210-229: The Progress value and color calculations use divisions
like (resolvedNorms.filling.nitrogen / resolvedNorms.value.nitrogen) that can
divide by zero; update the component so before computing Progress value or
calling getNormsProgressColor you check resolvedNorms.value.nitrogen (and
similar for phosphorus/organic) and if it equals 0 return a safe fallback (e.g.
skip rendering Progress, use value 0, or use a neutral color) and also update
getNormsProgressColor to handle a zero denominator defensively; apply the same
guard at the other two places that compute Progress and alternatively you can
filter out BufferStrip inputs at the fertilizer route so resolvedNorms with
normValue: 0 never reach this component (but ensure both the Progress usage and
getNormsProgressColor are made zero-safe).
In `@fdm-app/app/components/blocks/header/atlas.tsx`:
- Around line 34-36: The DropdownMenuTrigger currently uses "outline-none" which
removes keyboard focus visibility; update the className on DropdownMenuTrigger
(the element that contains currentName and ChevronDown) to remove "outline-none"
and add appropriate focus-visible utility classes (e.g., focus-visible:ring,
focus-visible:ring-{color}, focus-visible:ring-offset) so a visible focus ring
appears when keyboard focusing the trigger; ensure the styling matches existing
theme tokens (ring color/offset) and preserves layout/truncation behavior for
currentName and the ChevronDown icon.
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.balance.nitrogen._index.tsx:
- Around line 194-195: Remove the stray debug console.log in the render path:
delete the console.log(hasErrors) call found in the
farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx render logic (where
hasErrors is referenced) so it doesn't spam client logs; if you need retained
debugging use a non-blocking approach (e.g., move logging into a useEffect and
use a proper logger/debug-level function) or remove entirely before release.
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.balance.nitrogen.tsx:
- Around line 96-107: The map that builds fieldOptions can produce NaN when
field.b_area is null; update the transformation in the fieldOptions creation
(the map over fields and the returned b_area) to guard b_area with a
null-coalescing or conditional fallback (e.g., use (field.b_area ?? 0) or
preserve null explicitly) before applying Math.round so Math.round is never
called with null; ensure you reference the fieldOptions variable and the b_area
property in the change and keep the existing validation on b_id/b_name.
In `@fdm-calculator/src/norms/nl/2025/value/dierlijke-mest-gebruiksnorm.test.ts`:
- Around line 116-130: Several tests use NL2025NormsInput mock objects but the
new required field field.b_bufferstrip is missing; update all mockInput objects
in this test file (used with calculateNL2025DierlijkeMestGebruiksNorm and other
NL2025-related tests) to include a boolean b_bufferstrip on the field object
(true/false as appropriate for each scenario) so they satisfy the type and
reflect the intended buffer-strip conditions; search for mockInput,
NL2025NormsInput, and any direct object literals passed to
calculateNL2025DierlijkeMestGebruiksNorm and add field: { ..., b_bufferstrip:
<boolean> } or merge b_bufferstrip into existing field objects.
♻️ Duplicate comments (2)
fdm-app/app/components/blocks/header/field.tsx (1)
42-50: Same focus-visible concern as in HeaderAtlas.
Please apply the same focus-visible fix here if the shared trigger doesn’t already provide one.fdm-app/app/components/blocks/header/balance.tsx (1)
40-88: Same focus-visible concern as in HeaderAtlas.
Both triggers remove the default outline; please ensure a focus-visible ring is present.
🧹 Nitpick comments (14)
fdm-app/app/components/blocks/farm/farm-title.tsx (1)
25-31: Redundantml-autoclass.The
ml-autois applied to both the outer<div>and the<NavLink>. Only the outer div needs it to push the action to the end.♻️ Suggested fix
{action && ( <div className="ml-auto"> - <NavLink to={action.to} className="ml-auto"> + <NavLink to={action.to}> <Button>{action.label}</Button> </NavLink> </div> )}fdm-calculator/src/balance/organic-matter/types.ts (1)
333-344: Consider addingb_bufferstripto the non-numericOrganicMatterBalanceFieldResulttype for consistency.The numeric result type now includes
b_bufferstrip, but the non-numericOrganicMatterBalanceFieldResult(lines 151-160) does not. If both types are used in similar contexts, this asymmetry could cause confusion or require conditional handling.Suggested addition to OrganicMatterBalanceFieldResult
export type OrganicMatterBalanceFieldResult = { /** The unique identifier of the field. */ b_id: string /** The area of the field in hectares. */ b_area: number + /** Whether the field is a buffer strip */ + b_bufferstrip: boolean /** The detailed organic matter balance for the field. Undefined if an error occurred. */ balance?: OrganicMatterBalanceField /** An error message if the calculation for this field failed. */ errorMessage?: string }fdm-app/app/components/blocks/header/farm.tsx (1)
39-52: Consider adding visible focus state for accessibility.The
outline-noneclass removes the default focus indicator. While this may be intentional for visual design, ensure there's a visible focus state for keyboard navigation users. Consider usingfocus-visible:ring-2 focus-visible:ring-offset-2or similar to maintain accessibility compliance.💡 Suggested improvement
- <DropdownMenuTrigger className="flex items-center gap-1 max-w-[120px] sm:max-w-[200px] md:max-w-none outline-none"> + <DropdownMenuTrigger className="flex items-center gap-1 max-w-[120px] sm:max-w-[200px] md:max-w-none outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">fdm-app/app/components/blocks/header/nutrient-advice.tsx (1)
44-52: Same accessibility consideration as infarm.tsx.The
outline-noneclass removes focus indicators. For consistency with the suggested improvement infarm.tsx, consider addingfocus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2to maintain keyboard accessibility.fdm-app/app/components/blocks/header/base.tsx (1)
23-29: Minor: Redundantml-autoclass.The
HeaderActioncomponent (per the relevant snippet ataction.tsx:11-30) already wraps itself in a<div className="ml-auto">. Havingml-autoon both the wrapper here and insideHeaderActionis redundant, though harmless.♻️ Optional cleanup
Either remove
ml-autofrom the wrapper here:- <div className="ml-auto flex-shrink-0"> + <div className="flex-shrink-0">Or remove it from
HeaderActionfor a cleaner separation of concerns where the parent controls positioning.fdm-calculator/src/balance/organic-matter/index.test.ts (1)
83-144: Consider addingb_bufferstrip: falseto existing aggregation tests for consistency.The existing tests at lines 84-144 don't include the
b_bufferstripfield in their test data. While the implementation likely defaults correctly, explicitly settingb_bufferstrip: falseon these test fields would improve test clarity and ensure consistent test data shapes across the suite.fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (1)
380-401: Good buffer strip handling with clear user messaging.The early return for buffer strips provides appropriate user feedback. The subsequent missing balance check with
CircleAlerticon improves error state visibility.Note:
b_bufferstripis accessed viafertilizerApplicationMetricsData.b_bufferstrip(line 381) while other properties are destructured at line 93-103. Consider destructuringb_bufferstripalong with the other properties for consistency.♻️ Optional: Destructure b_bufferstrip with other properties
const { norms, nitrogenBalance, nutrientAdvice, dose, b_id, b_id_farm, calendar, cultivations, activeCultivation, + b_bufferstrip, } = fertilizerApplicationMetricsDataThen use
b_bufferstripdirectly at line 381 instead offertilizerApplicationMetricsData.b_bufferstrip.fdm-core/src/cultivation.d.ts (1)
41-41: Use schema-derived type forb_bufferstripto avoid drift.♻️ Proposed change
- b_bufferstrip: boolean + b_bufferstrip: schema.fieldsTypeSelect["b_bufferstrip"]fdm-core/src/field.d.ts (1)
15-15: Use schema-derived type forb_bufferstriphere as well.♻️ Proposed change
- b_bufferstrip: boolean + b_bufferstrip: schema.fieldsTypeSelect["b_bufferstrip"]fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsx (1)
35-35: Unused import:useFieldFilterStore.This import appears to be unused after replacing
FieldFilterTogglewithBufferStripInfo. Consider removing it to keep the imports clean.🧹 Remove unused import
-import { useFieldFilterStore } from "~/store/field-filter"fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts (1)
3-12: Prefer fullNL2026NormsInputfixtures over type assertionsThe
as NL2026NormsInputhides missing required fields and can make tests brittle if the implementation starts usingfarm,cultivations, orsoilAnalysis. Consider a minimal complete input instead.♻️ Suggested fixture (apply similarly to the buffer-strip test)
- const input = { - field: { - b_bufferstrip: false, - }, - } as NL2026NormsInput + const input: NL2026NormsInput = { + farm: { has_grazing_intention: false }, + field: { + b_id: "field-1", + b_centroid: [0, 0], + b_bufferstrip: false, + }, + cultivations: [], + soilAnalysis: { a_p_al: 0, a_p_cc: 0 }, + }fdm-app/app/components/blocks/header/fertilizer.tsx (1)
40-49: Ensure keyboard focus remains visible on the dropdown trigger
outline-nonecan remove the only focus indicator. Please verify a visible focus style remains (or add one) for keyboard users.✅ Possible focus-visible styling
- <DropdownMenuTrigger className="flex items-center gap-1 max-w-[120px] sm:max-w-[200px] md:max-w-none outline-none"> + <DropdownMenuTrigger className="flex items-center gap-1 max-w-[120px] sm:max-w-[200px] md:max-w-none outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">fdm-calculator/src/balance/nitrogen/index.test.ts (1)
19-21: Avoid usingthenas a property name on objects.Static analysis flags this as suspicious because adding a
thenproperty makes the object "thenable", which can cause unexpected behavior when used withawaitor Promise chains. Consider using a different mock approach.♻️ Possible alternative
const mockFdm = { select: vi.fn().mockReturnThis(), from: vi.fn().mockReturnThis(), where: vi.fn().mockReturnThis(), limit: vi.fn().mockReturnThis(), - then: vi.fn((resolve) => - resolve ? Promise.resolve(resolve([])) : Promise.resolve([]), - ), // Simulate cache miss + execute: vi.fn().mockResolvedValue([]), // Simulate cache miss insert: vi.fn().mockReturnThis(), values: vi.fn().mockResolvedValue(undefined), } as unknown as FdmTypeAlternatively, if
thenis specifically required for the mock behavior, suppress the lint rule for this line with a comment explaining why.fdm-core/src/field.ts (1)
699-713: Confusing double-negation in buffer detection logic.The logic at lines 711 and 713 uses a confusing double-negation pattern that makes the code hard to understand, even though it produces the correct result.
♻️ Clearer implementation
// Check if name contains 'buffer' - const bufferAssumedByName = !b_name.toLowerCase().includes("buffer") + const bufferAssumedByName = b_name.toLowerCase().includes("buffer") - return bufferAssumedByShape || !bufferAssumedByName + return bufferAssumedByShape || bufferAssumedByNameThis reads more naturally: "A field is a buffer if it has buffer-like shape OR its name contains 'buffer'."
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (1)
86-92: Guard nutrient advice progress when requirements are 0.
Ifd_*_reqis 0 (e.g., buffer strips), the Progress value can becomeNaN/Infinity, leading to erratic UI. Consider mirroring the norms guard and handling the color function similarly.🐛 Suggested fix
const getAdviceProgressColor = (current: number, total: number) => { + if (total === 0) return "gray-500" const percentage = (current / total) * 100 if (percentage < 80) return "orange-500" if (percentage >= 80 && percentage <= 105) return "green-500" if (percentage > 105) return "orange-500" return "gray-500" // Default or error color } @@ <Progress key={`n-${dose.p_dose_n}`} value={ - (dose.p_dose_n / resolvedNutrientAdvice.d_n_req) * 100 + resolvedNutrientAdvice.d_n_req === 0 + ? 0 + : (dose.p_dose_n / resolvedNutrientAdvice.d_n_req) * 100 } @@ <Progress key={`p-${dose.p_dose_p}`} value={ - (dose.p_dose_p / resolvedNutrientAdvice.d_p_req) * 100 + resolvedNutrientAdvice.d_p_req === 0 + ? 0 + : (dose.p_dose_p / resolvedNutrientAdvice.d_p_req) * 100 } @@ <Progress key={`k-${dose.p_dose_k}`} value={ - (dose.p_dose_k / resolvedNutrientAdvice.d_k_req) * 100 + resolvedNutrientAdvice.d_k_req === 0 + ? 0 + : (dose.p_dose_k / resolvedNutrientAdvice.d_k_req) * 100 }Also applies to: 553-627
🤖 Fix all issues with AI agents
In `@fdm-app/app/components/blocks/farm/farm-title.tsx`:
- Around line 20-25: The paragraph element in the FarmTitle component uses a
non-existent utility class "wrap-break-word"; replace it with the correct
Tailwind utility "break-words" on the <p> element rendering {description} (look
for the <p className="text-muted-foreground wrap-break-word"> in farm-title.tsx)
so it matches other uses like breadcrumb.tsx and the farm overview route.
- Around line 27-31: The current markup nests Button (renders a <button>) inside
NavLink (<a>), which is invalid; change the structure so Button uses its asChild
prop and wrap NavLink with it (i.e., render <Button asChild> and place the
NavLink inside) so the NavLink becomes the rendered element with button styles;
update the JSX in farm-title.tsx where NavLink and Button are used (referencing
Button, NavLink, and the asChild prop) accordingly and remove the nested
<button> inside <a>.
In `@fdm-core/src/field.ts`:
- Around line 699-713: In determineIfFieldIsBuffer, guard against null/zero
inputs: normalize b_name with something like const name = (b_name ??
"").toString().toLowerCase() and use name.includes("buffer") for
bufferAssumedByName; for the shape heuristic only compute the ratio if
Number.isFinite(b_area) && Number.isFinite(b_perimeter) && b_area > 0 &&
b_perimeter > 0 (otherwise set bufferAssumedByShape = false) to avoid division
by zero/NaN/Infinity; keep BUFFERSTROKEN_CONSTANT and return
bufferAssumedByShape || bufferAssumedByName.
🧹 Nitpick comments (4)
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts (1)
22-31: Avoid type assertion; build a complete input for resilience.
as NL2026NormsInputsidesteps required fields and can hide failures if the implementation later relies on other properties. Consider constructing a full input (or reuse a base fixture) for stability.♻️ Suggested adjustment
- const input = { - field: { - b_bufferstrip: true, - }, - } as NL2026NormsInput + const input: NL2026NormsInput = { + farm: { has_grazing_intention: false }, + field: { + b_id: "field-1", + b_centroid: [0, 0], + b_bufferstrip: true, + }, + cultivations: [], + soilAnalysis: { a_p_al: 0, a_p_cc: 0 }, + }fdm-calculator/src/balance/nitrogen/index.test.ts (2)
1-22: Avoid Vitestvimocks for the FdmType stub.
Repo learnings indicatevimocking utilities have caused issues here; prefer plain function stubs and drop theviimport. Based on learnings, please align this mock with the project’s test guidance.♻️ Proposed refactor
-import { describe, expect, it, vi } from "vitest" +import { describe, expect, it } from "vitest" @@ -const mockFdm = { - select: vi.fn().mockReturnThis(), - from: vi.fn().mockReturnThis(), - where: vi.fn().mockReturnThis(), - limit: vi.fn().mockReturnThis(), - execute: vi.fn().mockResolvedValue([]), // Simulate cache miss - insert: vi.fn().mockReturnThis(), - values: vi.fn().mockResolvedValue(undefined), -} as unknown as FdmType +const mockFdm = { + select: () => mockFdm, + from: () => mockFdm, + where: () => mockFdm, + limit: () => mockFdm, + execute: async () => [], // Simulate cache miss + insert: () => mockFdm, + values: async () => undefined, +} as unknown as FdmType
210-248: Assert buffer strips don’t raise errors.
Right now the test would still pass ifhasErrorsstayed true. Add explicit assertions to keep the behavior locked.✅ Suggested assertion additions
const result = await calculateNitrogenBalance( mockFdm, mockNitrogenBalanceInput, ) + expect(result.hasErrors).toBe(false) + expect(result.fieldErrorMessages.length).toBe(0) expect(result.balance).toBe(0) expect(result.supply.total).toBe(0) expect(result.removal.total).toBe(0) expect(result.emission.total).toBe(0)fdm-app/app/components/blocks/farm/farm-title.tsx (1)
42-47: Align skeleton layout with the new responsive layout to reduce layout shift.The actual component now stacks on small screens, but the skeleton stays in a single row. Matching the flex behavior avoids jumpy transitions.
♻️ Suggested adjustment
- <div className="flex items-center gap-4"> - <div className="space-y-0.5 "> + <div className="flex flex-col xl:flex-row xl:items-center gap-4"> + <div className="space-y-0.5 min-w-0 flex-1">
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
.changeset/huge-cars-peel.md.changeset/loud-yaks-repeat.mdfdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/components/blocks/fertilizer-applications/form.tsxfdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/components/blocks/header/atlas.tsxfdm-app/app/components/blocks/header/base.tsxfdm-app/app/components/blocks/header/farm.tsxfdm-app/app/components/blocks/header/fertilizer.tsxfdm-app/app/components/blocks/header/nutrient-advice.tsxfdm-app/app/integrations/calculator.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-calculator/src/balance/nitrogen/index.test.tsfdm-calculator/src/balance/organic-matter/types.tsfdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.tsfdm-core/src/cultivation.d.tsfdm-core/src/field.d.tsfdm-core/src/field.ts
🚧 Files skipped from review as they are similar to previous changes (10)
- fdm-app/app/components/blocks/header/base.tsx
- fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen.tsx
- fdm-app/app/components/blocks/header/nutrient-advice.tsx
- fdm-app/app/components/blocks/fertilizer-applications/form.tsx
- fdm-core/src/cultivation.d.ts
- fdm-app/app/components/blocks/header/farm.tsx
- fdm-app/app/integrations/calculator.ts
- fdm-core/src/field.d.ts
- .changeset/huge-cars-peel.md
- fdm-app/app/components/blocks/header/fertilizer.tsx
🧰 Additional context used
🧠 Learnings (41)
📓 Common learnings
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 0
File: :0-0
Timestamp: 2025-08-13T10:33:05.313Z
Learning: In the fdm project, fdm-calculator integration for new features like b_lu_variety is handled in separate updates from the core data model changes. When fdm-core functions are updated to support new fields, fdm-calculator can consume these enhanced APIs without requiring changes in the same PR that introduces the core functionality.
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: .changeset/yellow-sheep-wash.md:1-5
Timestamp: 2025-01-09T16:06:08.547Z
Learning: The `b_sector` column has been removed from the farms table and replaced with `b_businessid_farm`, `b_address_farm`, and `b_postalcode_farm` columns for better business information management.
📚 Learning: 2025-08-11T11:55:26.053Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 233
File: fdm-app/app/integrations/nmi.ts:54-0
Timestamp: 2025-08-11T11:55:26.053Z
Learning: The NMI API Estimates endpoint (`https://api.nmi-agro.nl/estimates`) always returns the fields `b_gwl_ghg`, `b_gwl_glg`, and `cultivations` according to its specification. These fields should be kept as required (not optional) in the TypeScript return type and Zod validation schema in `fdm-app/app/integrations/nmi.ts`.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-calculator/src/balance/organic-matter/types.ts
📚 Learning: 2025-08-14T14:31:55.384Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 236
File: fdm-calculator/src/balance/nitrogen/index.ts:173-0
Timestamp: 2025-08-14T14:31:55.384Z
Learning: In nitrogen balance calculations for agricultural systems, the balance should only include ammonia emissions (emission.ammonia.total) and should not include nitrate leaching from the emission calculation. The nitrate component (emission.nitrate) should be excluded from the balance formula.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:23:48.352Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:134-170
Timestamp: 2025-03-06T15:23:48.352Z
Learning: When writing tests for fdm-core, avoid using Vitest's `vi` mocking utilities and prefer manual JavaScript mocks.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T14:58:48.603Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/cultivation.ts:67-73
Timestamp: 2025-03-06T14:58:48.603Z
Learning: When writing unit tests for the fdm project, avoid using Vitest's mocking utilities (vi) as it has caused problems in the past not related to the actual code. Instead, use simple object literals with methods that throw errors to test error handling.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:23:29.958Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:96-132
Timestamp: 2025-03-06T15:23:29.958Z
Learning: When writing tests for the FDM codebase, avoid using Vitest's `vi` mocking utilities (`vi.spyOn()`, etc.). Prefer using natural errors, real function behavior, and actual inputs that trigger expected failures.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T14:38:52.315Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/cultivation.ts:67-73
Timestamp: 2025-03-06T14:38:52.315Z
Learning: When writing unit tests for the fdm project, avoid using vi.mock() as it has caused implementation problems in the past. Use direct mock functions with vi.fn() instead.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:20:37.653Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:12-50
Timestamp: 2025-03-06T15:20:37.653Z
Learning: Do not use vi (Vitest) mocking utilities in unit tests for the fdm project.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-01-23T15:18:57.212Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-core/src/db/schema.ts:407-426
Timestamp: 2025-01-23T15:18:57.212Z
Learning: In the farm data model, each cultivation (b_lu) can have only one termination date but can have multiple harvest dates. This is enforced through the database schema where cultivationTerminating uses b_lu as primary key while cultivationHarvesting uses a composite primary key of b_id_harvestable and b_lu.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2024-11-27T12:15:36.425Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 9
File: fdm-data/src/cultivations/index.test.ts:57-59
Timestamp: 2024-11-27T12:15:36.425Z
Learning: In `fdm-data/src/cultivations/index.test.ts`, the `fdm` object created by `drizzle` does not have an `.end()` method. Cleanup code should not attempt to call `fdm.end();`.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-08-11T12:24:32.200Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 233
File: fdm-app/app/components/blocks/atlas-fields/cultivation-history.tsx:53-53
Timestamp: 2025-08-11T12:24:32.200Z
Learning: In `fdm-app/app/components/blocks/atlas-fields/cultivation-history.tsx`, the NMI API for cultivations guarantees that each year will be unique in the cultivation history data, so using `cultivation.year` as a React list key is safe and won't cause duplicate key warnings.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: The `FarmLayout` component in `components/custom/farm-layout.tsx` provides a reusable layout structure for farm-related pages, with support for farm selection dropdown, customizable breadcrumb titles, and flexible content rendering through either children or Outlet components.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/components/blocks/header/atlas.tsx
📚 Learning: 2025-09-23T10:02:32.123Z
Learnt from: BoraIneviNMI
Repo: SvenVw/fdm PR: 272
File: fdm-app/app/routes/farm.create.$b_id_farm.$calendar.fertilizers.$b_lu_catalogue.manage.$p_id.tsx:151-164
Timestamp: 2025-09-23T10:02:32.123Z
Learning: The getFertilizer function from svenvw/fdm-core throws an exception if the fertilizer doesn't exist, rather than returning null or undefined.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-04-18T13:49:17.029Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 124
File: fdm-app/app/components/custom/farm/farm-title.tsx:3-3
Timestamp: 2025-04-18T13:49:17.029Z
Learning: In the fdm project, NavLink and other routing components can be imported from either "react-router" or "react-router-dom" as react-router-dom is included in react-router.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-12-15T12:19:47.858Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 376
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx:187-213
Timestamp: 2025-12-15T12:19:47.858Z
Learning: When reviewing code, prefer storing only non-sensitive UI/state data in sessionStorage. For map viewState (e.g., longitude/latitude), ensure it represents non-personal business data and that persistence across sessions is justified, documented, and respects user privacy. If persisting, use a clearly scoped, namespaced key, guard access with try/catch, and avoid syncing with servers or exposing data to third-party scripts. Apply this guideline to all TSX files that manage client-side UI state.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-app/app/components/blocks/header/atlas.tsx
📚 Learning: 2026-01-15T09:39:38.225Z
Learnt from: BoraIneviNMI
Repo: SvenVw/fdm PR: 377
File: fdm-app/app/components/blocks/rotation/variety-selector.tsx:46-46
Timestamp: 2026-01-15T09:39:38.225Z
Learning: In fdm-app app/components/blocks/rotation/variety-selector.tsx, there is a custom Tailwind utility -translate-1/2 that sets --tw-translate-x and --tw-translate-y to calc(calc(1/2 * 100%) * -1) so translate uses centralized values. This is a project-specific utility; during reviews, do not flag usage as invalid if you encounter -translate-1/2. If adding similar utilities, document their intent in the Tailwind config or a style guide.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-app/app/components/blocks/header/atlas.tsx
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: A shared layout component `FarmLayoutBase` has been created in `components/custom/farm-layout-base.tsx` to maintain consistency across farm-related pages. The component handles farm selection dropdown, breadcrumb navigation, and provides a common layout structure.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-app/app/components/blocks/header/atlas.tsx
📚 Learning: 2025-09-23T12:27:07.391Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 274
File: fdm-app/app/routes/farm.$b_id_farm._index.tsx:151-204
Timestamp: 2025-09-23T12:27:07.391Z
Learning: In the FDM application, field overview functionality is implemented as a dedicated page accessible via `farm/{farmId}/{calendar}/field` rather than as a direct listing on the dashboard. The dashboard includes a "Perceelsoverzicht" quick action card that provides navigation to this comprehensive field management interface.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-09-26T08:34:50.413Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 279
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.norms.tsx:277-283
Timestamp: 2025-09-26T08:34:50.413Z
Learning: In the fdm project, fdm-core and fdm-app are updated together as part of a monorepo structure, which eliminates legacy data concerns when new fields like b_isproductive are introduced. Both packages are synchronized, so there's no need for defensive coding against undefined values for newly introduced database fields.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-core/src/field.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-09-23T12:29:34.184Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 274
File: fdm-app/app/routes/farm.$b_id_farm._index.tsx:160-163
Timestamp: 2025-09-23T12:29:34.184Z
Learning: In the FDM application, the fertilizer application route intentionally uses `${calendar}/field/fertilizer` instead of the originally planned `/farm/{farmId}/add/fertilizer` structure. This design decision prioritizes starting from the field list view to provide better field selection workflow before applying fertilizer, rather than direct dashboard-to-action navigation.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: The `updateField` function in fdm-core has optional parameters after `fdm` and `b_id`. The TypeScript definitions might show 8 required parameters due to a potential version mismatch.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-core/src/field.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-calculator/src/balance/organic-matter/types.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-05-09T14:53:44.578Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 138
File: fdm-app/app/components/custom/combobox.tsx:34-37
Timestamp: 2025-05-09T14:53:44.578Z
Learning: In the context of this React Router v7 project, it's important to follow the pattern of importing only the types (like UseFormReturn) from "react-hook-form" while importing the Form component from "react-router" to avoid naming conflicts.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-05-09T14:41:43.484Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 138
File: fdm-app/app/components/custom/fertilizer-applications/form.tsx:6-6
Timestamp: 2025-05-09T14:41:43.484Z
Learning: The project uses React Router v7 which exports a Form component directly from the "react-router" package, making importing from "remix-run/react" unnecessary.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-05-09T14:58:10.465Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 138
File: fdm-app/app/components/custom/combobox.tsx:34-37
Timestamp: 2025-05-09T14:58:10.465Z
Learning: When updating React components that use both react-hook-form and React Router v7, it's important to only import types (like UseFormReturn, FieldValues) from react-hook-form to avoid naming conflicts with React Router's Form component. Use `import type { ... } from 'react-hook-form'` syntax to ensure only types are imported.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-05-09T14:41:43.484Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 138
File: fdm-app/app/components/custom/fertilizer-applications/form.tsx:6-6
Timestamp: 2025-05-09T14:41:43.484Z
Learning: The project uses React Router v7 which exports a Form component directly from the "react-router" package, not from "remix-run/react".
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2024-12-16T10:56:07.561Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 16
File: fdm-app/app/routes/app.addfarm.$b_id_farm.cultivations.$b_lu_catalogue.fertilizers.tsx:1-1
Timestamp: 2024-12-16T10:56:07.561Z
Learning: The project uses `react-router` v7, and the `data` function is exported and used for error handling in loaders and actions.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: The farm layout system has been reorganized into separate components (`FarmHeader`, `ContentLayout`, `PaginationLayout`) to support different navigation patterns (sidebar, pagination) while maintaining consistent styling. Each layout component is designed to be used independently or combined as needed.
Applied to files:
fdm-app/app/components/blocks/farm/farm-title.tsx
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: A comprehensive farm layout system has been created in `components/custom/farm-layouts/` with `BaseFarmLayout` and `FarmSidebarLayout` components. The system supports both simple and sidebar-based layouts while maintaining consistent header and farm selection functionality across all farm routes.
Applied to files:
fdm-app/app/components/blocks/farm/farm-title.tsx
📚 Learning: 2025-01-31T15:34:20.850Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:34:20.850Z
Learning: The `updateField` function in fdm-core has optional parameters that don't need to be passed as undefined. Only `fdm` and `b_id` are required.
Applied to files:
fdm-core/src/field.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: The `updateField` function in fdm-core requires 8 parameters: fdm, b_id (required), and 6 optional parameters (b_name, b_id_source, b_geometry, b_acquiring_date, b_acquiring_method, b_discarding_date).
Applied to files:
fdm-core/src/field.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: When using `updateField` from fdm-core, all 8 parameters must be provided in order: fdm, b_id, b_name, b_geometry, b_area, b_id_source, b_id_farm, and b_id_farm_source.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-23T15:17:23.027Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-23T15:17:23.027Z
Learning: The `addField` function in fdm-core should verify field creation within the same transaction by checking the existence of the field and all its required relations (field data, acquiring info, geometry) before resolving its promise.
Applied to files:
fdm-core/src/field.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-01-23T15:17:23.028Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-23T15:17:23.028Z
Learning: The `addField` function in fdm-core should use database transactions and field verification to ensure field availability before resolving its promise, eliminating the need for sleep workarounds.
Applied to files:
fdm-core/src/field.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-08-13T10:33:05.313Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 0
File: :0-0
Timestamp: 2025-08-13T10:33:05.313Z
Learning: In the fdm project, fdm-calculator integration for new features like b_lu_variety is handled in separate updates from the core data model changes. When fdm-core functions are updated to support new fields, fdm-calculator can consume these enhanced APIs without requiring changes in the same PR that introduces the core functionality.
Applied to files:
fdm-core/src/field.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsxfdm-calculator/src/balance/organic-matter/types.ts.changeset/loud-yaks-repeat.md
📚 Learning: 2025-09-26T08:26:05.718Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 279
File: fdm-core/src/field.ts:169-169
Timestamp: 2025-09-26T08:26:05.718Z
Learning: In agricultural field management systems (fdm-core), when calculating field perimeter for productivity classification heuristics, holes inside polygons should be ignored. Use ST_ExteriorRing instead of ST_Perimeter to get only the outer boundary perimeter, as interior features like ponds or buildings should not affect the buffer strip vs productive field classification.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-24T11:28:01.882Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-24T11:28:01.882Z
Learning: The `addField` function in fdm-core should use database transactions to ensure atomicity, and since transactions provide ACID guarantees, awaiting the inserts is sufficient to ensure field availability - no additional verification queries are needed.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-09T16:06:08.547Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: .changeset/yellow-sheep-wash.md:1-5
Timestamp: 2025-01-09T16:06:08.547Z
Learning: The `b_sector` column has been removed from the farms table and replaced with `b_businessid_farm`, `b_address_farm`, and `b_postalcode_farm` columns for better business information management.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-07-21T12:06:07.070Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.070Z
Learning: Functions in the fdm-calculator with "NL2025" in their names are specifically designed for Netherlands 2025 agricultural norms calculation and hardcoded 2025 dates are appropriate in this context, as different years would have separate calculation modules.
Applied to files:
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.tsfdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-01-24T11:56:40.906Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-core/rollup.config.js:17-30
Timestamp: 2025-01-24T11:56:40.906Z
Learning: For the FDM project, keep error handling simple when basic error notification (console.error) is sufficient, avoiding unnecessary complexity in error handling mechanisms.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-02-14T09:56:37.606Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 75
File: fdm-app/app/routes/farm.$b_id_farm.field.$b_id.fertilizer.tsx:68-71
Timestamp: 2025-02-14T09:56:37.606Z
Learning: The `calculateDose` function in `svenvw/fdm-calculator` is a synchronous function that includes built-in validation for negative application amounts and nutrient rates.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
📚 Learning: 2025-09-23T12:37:58.711Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 274
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.field._index.tsx:113-148
Timestamp: 2025-09-23T12:37:58.711Z
Learning: In the FDM application, the current field data fetching implementation using Promise.all with individual API calls (getCultivations, getFertilizerApplications, getCurrentSoilData) performs acceptably even with farms containing 90+ fields. No performance issues have been observed in practice with this approach.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx
🧬 Code graph analysis (5)
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (2)
fdm-app/app/components/custom/cultivation-selector.tsx (1)
CultivationSelector(24-122)fdm-core/src/db/schema.ts (1)
cultivations(374-386)
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsx (1)
fdm-app/app/components/blocks/balance/buffer-strip-info.tsx (1)
BufferStripInfo(10-30)
fdm-core/src/field.ts (3)
fdm-core/src/db/schema.ts (2)
fieldsTypeInsert(112-112)fieldsTypeSelect(111-111)fdm-core/src/field.d.ts (1)
Field(3-16)fdm-core/src/index.ts (1)
Field(112-112)
fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx (1)
fdm-app/app/components/blocks/balance/buffer-strip-info.tsx (1)
BufferStripInfo(10-30)
fdm-calculator/src/balance/organic-matter/types.ts (1)
fdm-core/src/field.d.ts (1)
Field(3-16)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: core (24)
🔇 Additional comments (23)
fdm-app/app/components/blocks/header/atlas.tsx (2)
25-32: LGTM on the responsive breadcrumb visibility changes.Hiding the "Atlas" breadcrumb label on smaller viewports while keeping the functional dropdown visible is a sensible responsive design pattern consistent with other header components.
34-36: LGTM - Accessibility concern addressed and truncation handled correctly.The addition of
focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2resolves the previous accessibility concern about keyboard focus visibility. The truncation handling withtruncateon the text span andshrink-0on the chevron ensures graceful degradation on smaller viewports.fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts (2)
3-3: No issues.
6-20: Solid default-case coverage with explicit buffer strip flag.fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.organic-matter._index.tsx (2)
21-21: Nice UI affordance for buffer strips in the header.
BufferStripInfo placement here makes the exclusion behavior discoverable.Also applies to: 249-253
171-175: Filtering buffer strips from the per-field list looks correct.
This matches the updated balance semantics and keeps the list consistent.fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen._index.tsx (2)
23-23: Header update is clear and consistent with buffer-strip handling.
Good use of BufferStripInfo for quick context.Also applies to: 330-334
196-200: Buffer-strip filtering aligns with the new model.
Excluding buffer strips here keeps the field list coherent with calculations.fdm-calculator/src/balance/organic-matter/types.ts (3)
151-158: Type update correctly exposes buffer-strip status.
This ensures field results carry the flag for downstream consumers.
196-201: FieldInput now includes b_bufferstrip as expected.
Good propagation into calculator inputs.
334-345: Numeric result type mirrors the new buffer-strip flag.
Keeps numeric outputs aligned with the core result type.fdm-calculator/src/balance/nitrogen/index.test.ts (2)
26-37: Good: buffer-strip flag added to test fixtures.
This keeps fixtures aligned with the new schema and makes the intent explicit.Also applies to: 173-184
250-329: Aggregation test coverage looks solid.
This cleanly verifies that buffer strips are excluded from farm totals..changeset/loud-yaks-repeat.md (1)
1-5: Changelog entry aligns with the bufferstrip behavior.fdm-core/src/field.ts (2)
46-156: Good propagation ofb_bufferstripthrough addField creation path.
189-334: b_bufferstrip selection and update wiring looks solid.Also applies to: 360-470
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (7)
9-9: Status icon imports align with new balance indicators.
46-68: Buffer strip flag is correctly added to the metrics data shape.
This keeps the UI aligned with the new field-level state.
79-84: Zero-total guard in norms color calculation is a solid safety net.
94-105: b_bufferstrip is correctly plumbed into the component.
141-333: Norms progress rendering is now robust for zero norms.
The conditional progress value prevents divide-by-zero artifacts for buffer strips.
336-471: Buffer strip handling and balance status UI look good.
Clear messaging plus status icons make the balance state obvious.
645-761: Skeleton updates match the new layout nicely.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
fdm-core/src/field.ts (1)
432-458: Return type mismatch:updateFieldresult is missing requiredFieldproperties.The
Fieldinterface requiresb_centroid,b_area, andb_perimeter, but the select projection (lines 432-446) doesn't include these computed fields. The castas unknown as Fieldmasks this type inconsistency at compile time, but callers accessing these properties will getundefinedat runtime.Consider either:
- Adding the missing computed fields to the select (consistent with
getField), or- Defining a separate return type for
updateFieldthat reflects what's actually returned.💡 Suggested fix (option 1 - add missing fields)
const result = await tx .select({ b_id: schema.fields.b_id, b_name: schema.fields.b_name, b_id_farm: schema.fieldAcquiring.b_id_farm, b_id_source: schema.fields.b_id_source, b_geometry: schema.fields.b_geometry, b_bufferstrip: schema.fields.b_bufferstrip, + b_centroid_x: sql<number>`ST_X(ST_Centroid(b_geometry))`, + b_centroid_y: sql<number>`ST_Y(ST_Centroid(b_geometry))`, + b_area: sql<number>`ROUND((ST_Area(b_geometry::geography)/10000)::NUMERIC, 2)::FLOAT`, + b_perimeter: sql<number>`ROUND((ST_Length(ST_ExteriorRing(b_geometry)::geography))::NUMERIC, 2)::FLOAT`, b_start: schema.fieldAcquiring.b_start, b_acquiring_method: schema.fieldAcquiring.b_acquiring_method, b_end: schema.fieldDiscarding.b_end, - created: schema.fields.created, - updated: schema.fields.updated, }) // ... joins ... .limit(1) - const field = result[0] as unknown as Field + const field = result[0] + + // Process centroid into tuple + field.b_centroid = [field.b_centroid_x, field.b_centroid_y] + field.b_centroid_x = undefined + field.b_centroid_y = undefined
🤖 Fix all issues with AI agents
In `@fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts`:
- Around line 7-20: The test "should return the default norm value" uses
NL2026NormsInput with b_bufferstrip: true which causes
calculateNL2026DierlijkeMestGebruiksNorm to return 0; change the input in
dierlijke-mest-gebruiksnorm.test.ts so b_bufferstrip is false (or remove the
field) to align with the expected default normValue 170, keeping the rest of the
NL2026NormsInput and assertions unchanged.
♻️ Duplicate comments (1)
fdm-core/src/field.ts (1)
699-717: LGTM! Guard against null/zero values implemented.The guard at lines 704-706 correctly handles edge cases where
b_areaorb_perimeteris null/zero/invalid, falling back to name-based detection only. The nullish coalescing forb_name(line 705, 715) prevents potential errors from null names.
🧹 Nitpick comments (2)
fdm-core/src/field.ts (1)
470-479: Includeb_bufferstripin the error context for consistency.The
addFieldfunction includesb_bufferstripin its error payload (line 155), butupdateFieldomits it. For consistent debugging and error tracing, consider adding it here as well.💡 Suggested fix
} catch (err) { throw handleError(err, "Exception for updateField", { b_id, b_name, b_id_source, // b_geometry, b_start, b_acquiring_method, b_end, + b_bufferstrip, }) }fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (1)
386-512: Consider bypassing Suspense whenb_bufferstripis true.
Right now buffer strips still show the loading skeleton while the promise resolves, even though the UI always shows the static “Geen stikstofbalans” message. Skipping the await path for buffer strips avoids unnecessary loading states.♻️ Suggested refactor
- <ItemDescription className="line-clamp-none min-w-0 w-full"> - {isSubmitting ? ( - <NitrogenBalanceSkeleton /> - ) : ( - <Suspense - fallback={ - <NitrogenBalanceSkeleton /> - } - > - <Await - errorElement={ - <div className="text-destructive text-sm"> - Fout bij berekening - </div> - } - resolve={nitrogenBalance} - > - {(resolvedNitrogenBalance) => { - if (b_bufferstrip) { - return ( - <span className="text-xs text-muted-foreground"> - Geen - stikstofbalans - beschikbaar voor - bufferstrook. - </span> - ) - } + <ItemDescription className="line-clamp-none min-w-0 w-full"> + {b_bufferstrip ? ( + <span className="text-xs text-muted-foreground"> + Geen stikstofbalans beschikbaar voor bufferstrook. + </span> + ) : isSubmitting ? ( + <NitrogenBalanceSkeleton /> + ) : ( + <Suspense fallback={<NitrogenBalanceSkeleton />}> + <Await + errorElement={ + <div className="text-destructive text-sm"> + Fout bij berekening + </div> + } + resolve={nitrogenBalance} + > + {(resolvedNitrogenBalance) => { if ( !resolvedNitrogenBalance?.balance ) { return ( <div className="flex items-center gap-2 text-orange-500">
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
fdm-app/app/components/blocks/farm/farm-title.tsxfdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-calculator/src/balance/nitrogen/index.test.tsfdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.tsfdm-core/src/field.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- fdm-app/app/components/blocks/farm/farm-title.tsx
🧰 Additional context used
🧠 Learnings (30)
📓 Common learnings
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 0
File: :0-0
Timestamp: 2025-08-13T10:33:05.313Z
Learning: In the fdm project, fdm-calculator integration for new features like b_lu_variety is handled in separate updates from the core data model changes. When fdm-core functions are updated to support new fields, fdm-calculator can consume these enhanced APIs without requiring changes in the same PR that introduces the core functionality.
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: .changeset/yellow-sheep-wash.md:1-5
Timestamp: 2025-01-09T16:06:08.547Z
Learning: The `b_sector` column has been removed from the farms table and replaced with `b_businessid_farm`, `b_address_farm`, and `b_postalcode_farm` columns for better business information management.
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: A shared layout component `FarmLayoutBase` has been created in `components/custom/farm-layout-base.tsx` to maintain consistency across farm-related pages. The component handles farm selection dropdown, breadcrumb navigation, and provides a common layout structure.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-08-11T11:55:26.053Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 233
File: fdm-app/app/integrations/nmi.ts:54-0
Timestamp: 2025-08-11T11:55:26.053Z
Learning: The NMI API Estimates endpoint (`https://api.nmi-agro.nl/estimates`) always returns the fields `b_gwl_ghg`, `b_gwl_glg`, and `cultivations` according to its specification. These fields should be kept as required (not optional) in the TypeScript return type and Zod validation schema in `fdm-app/app/integrations/nmi.ts`.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsxfdm-calculator/src/balance/nitrogen/index.test.tsfdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts
📚 Learning: 2025-08-11T12:24:32.200Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 233
File: fdm-app/app/components/blocks/atlas-fields/cultivation-history.tsx:53-53
Timestamp: 2025-08-11T12:24:32.200Z
Learning: In `fdm-app/app/components/blocks/atlas-fields/cultivation-history.tsx`, the NMI API for cultivations guarantees that each year will be unique in the cultivation history data, so using `cultivation.year` as a React list key is safe and won't cause duplicate key warnings.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-01-09T16:03:37.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes/farm/_b_id_farm/layout.tsx:46-95
Timestamp: 2025-01-09T16:03:37.764Z
Learning: The `FarmLayout` component in `components/custom/farm-layout.tsx` provides a reusable layout structure for farm-related pages, with support for farm selection dropdown, customizable breadcrumb titles, and flexible content rendering through either children or Outlet components.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-09-23T10:02:32.123Z
Learnt from: BoraIneviNMI
Repo: SvenVw/fdm PR: 272
File: fdm-app/app/routes/farm.create.$b_id_farm.$calendar.fertilizers.$b_lu_catalogue.manage.$p_id.tsx:151-164
Timestamp: 2025-09-23T10:02:32.123Z
Learning: The getFertilizer function from svenvw/fdm-core throws an exception if the fertilizer doesn't exist, rather than returning null or undefined.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-04-18T13:49:17.029Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 124
File: fdm-app/app/components/custom/farm/farm-title.tsx:3-3
Timestamp: 2025-04-18T13:49:17.029Z
Learning: In the fdm project, NavLink and other routing components can be imported from either "react-router" or "react-router-dom" as react-router-dom is included in react-router.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-12-15T12:19:47.858Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 376
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx:187-213
Timestamp: 2025-12-15T12:19:47.858Z
Learning: When reviewing code, prefer storing only non-sensitive UI/state data in sessionStorage. For map viewState (e.g., longitude/latitude), ensure it represents non-personal business data and that persistence across sessions is justified, documented, and respects user privacy. If persisting, use a clearly scoped, namespaced key, guard access with try/catch, and avoid syncing with servers or exposing data to third-party scripts. Apply this guideline to all TSX files that manage client-side UI state.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2026-01-15T09:39:38.225Z
Learnt from: BoraIneviNMI
Repo: SvenVw/fdm PR: 377
File: fdm-app/app/components/blocks/rotation/variety-selector.tsx:46-46
Timestamp: 2026-01-15T09:39:38.225Z
Learning: In fdm-app app/components/blocks/rotation/variety-selector.tsx, there is a custom Tailwind utility -translate-1/2 that sets --tw-translate-x and --tw-translate-y to calc(calc(1/2 * 100%) * -1) so translate uses centralized values. This is a project-specific utility; during reviews, do not flag usage as invalid if you encounter -translate-1/2. If adding similar utilities, document their intent in the Tailwind config or a style guide.
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2026-01-16T12:55:46.704Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 422
File: fdm-app/app/components/blocks/farm/farm-title.tsx:20-25
Timestamp: 2026-01-16T12:55:46.704Z
Learning: In this repository, when editing Tailwind CSS in TSX files (e.g., fdm-app/app/components/.../*.tsx), prefer using the Tailwind v4 canonical class names. For word-wrapping, use 'wrap-break-word' instead of the v3 alias 'break-words'. If you encounter 'break-words', replace it with 'wrap-break-word' to align with Tailwind v4 conventions (Tailwind CSS v4.1.18 in this project).
Applied to files:
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx
📚 Learning: 2025-08-14T14:31:55.384Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 236
File: fdm-calculator/src/balance/nitrogen/index.ts:173-0
Timestamp: 2025-08-14T14:31:55.384Z
Learning: In nitrogen balance calculations for agricultural systems, the balance should only include ammonia emissions (emission.ammonia.total) and should not include nitrate leaching from the emission calculation. The nitrate component (emission.nitrate) should be excluded from the balance formula.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2024-11-27T12:15:36.425Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 9
File: fdm-data/src/cultivations/index.test.ts:57-59
Timestamp: 2024-11-27T12:15:36.425Z
Learning: In `fdm-data/src/cultivations/index.test.ts`, the `fdm` object created by `drizzle` does not have an `.end()` method. Cleanup code should not attempt to call `fdm.end();`.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:23:48.352Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:134-170
Timestamp: 2025-03-06T15:23:48.352Z
Learning: When writing tests for fdm-core, avoid using Vitest's `vi` mocking utilities and prefer manual JavaScript mocks.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T14:58:48.603Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/cultivation.ts:67-73
Timestamp: 2025-03-06T14:58:48.603Z
Learning: When writing unit tests for the fdm project, avoid using Vitest's mocking utilities (vi) as it has caused problems in the past not related to the actual code. Instead, use simple object literals with methods that throw errors to test error handling.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:23:29.958Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:96-132
Timestamp: 2025-03-06T15:23:29.958Z
Learning: When writing tests for the FDM codebase, avoid using Vitest's `vi` mocking utilities (`vi.spyOn()`, etc.). Prefer using natural errors, real function behavior, and actual inputs that trigger expected failures.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T14:38:52.315Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/cultivation.ts:67-73
Timestamp: 2025-03-06T14:38:52.315Z
Learning: When writing unit tests for the fdm project, avoid using vi.mock() as it has caused implementation problems in the past. Use direct mock functions with vi.fn() instead.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-03-06T15:20:37.653Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 95
File: fdm-core/src/catalogues.ts:12-50
Timestamp: 2025-03-06T15:20:37.653Z
Learning: Do not use vi (Vitest) mocking utilities in unit tests for the fdm project.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-01-23T15:18:57.212Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-core/src/db/schema.ts:407-426
Timestamp: 2025-01-23T15:18:57.212Z
Learning: In the farm data model, each cultivation (b_lu) can have only one termination date but can have multiple harvest dates. This is enforced through the database schema where cultivationTerminating uses b_lu as primary key while cultivationHarvesting uses a composite primary key of b_id_harvestable and b_lu.
Applied to files:
fdm-calculator/src/balance/nitrogen/index.test.ts
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: The `updateField` function in fdm-core has optional parameters after `fdm` and `b_id`. The TypeScript definitions might show 8 required parameters due to a potential version mismatch.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-31T15:34:20.850Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:34:20.850Z
Learning: The `updateField` function in fdm-core has optional parameters that don't need to be passed as undefined. Only `fdm` and `b_id` are required.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: The `updateField` function in fdm-core requires 8 parameters: fdm, b_id (required), and 6 optional parameters (b_name, b_id_source, b_geometry, b_acquiring_date, b_acquiring_method, b_discarding_date).
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-09-26T08:34:50.413Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 279
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.norms.tsx:277-283
Timestamp: 2025-09-26T08:34:50.413Z
Learning: In the fdm project, fdm-core and fdm-app are updated together as part of a monorepo structure, which eliminates legacy data concerns when new fields like b_isproductive are introduced. Both packages are synchronized, so there's no need for defensive coding against undefined values for newly introduced database fields.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-23T15:17:23.027Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-23T15:17:23.027Z
Learning: The `addField` function in fdm-core should verify field creation within the same transaction by checking the existence of the field and all its required relations (field data, acquiring info, geometry) before resolving its promise.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-08-13T10:33:05.313Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 0
File: :0-0
Timestamp: 2025-08-13T10:33:05.313Z
Learning: In the fdm project, fdm-calculator integration for new features like b_lu_variety is handled in separate updates from the core data model changes. When fdm-core functions are updated to support new fields, fdm-calculator can consume these enhanced APIs without requiring changes in the same PR that introduces the core functionality.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.fields.$b_id.tsx:601-610
Timestamp: 2025-01-31T15:05:14.310Z
Learning: When using `updateField` from fdm-core, all 8 parameters must be provided in order: fdm, b_id, b_name, b_geometry, b_area, b_id_source, b_id_farm, and b_id_farm_source.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-23T15:17:23.028Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-23T15:17:23.028Z
Learning: The `addField` function in fdm-core should use database transactions and field verification to ensure field availability before resolving its promise, eliminating the need for sleep workarounds.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-24T11:28:01.882Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 49
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:208-208
Timestamp: 2025-01-24T11:28:01.882Z
Learning: The `addField` function in fdm-core should use database transactions to ensure atomicity, and since transactions provide ACID guarantees, awaiting the inserts is sufficient to ensure field availability - no additional verification queries are needed.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-09-26T08:26:05.718Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 279
File: fdm-core/src/field.ts:169-169
Timestamp: 2025-09-26T08:26:05.718Z
Learning: In agricultural field management systems (fdm-core), when calculating field perimeter for productivity classification heuristics, holes inside polygons should be ignored. Use ST_ExteriorRing instead of ST_Perimeter to get only the outer boundary perimeter, as interior features like ponds or buildings should not affect the buffer strip vs productive field classification.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-01-09T16:06:08.547Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: .changeset/yellow-sheep-wash.md:1-5
Timestamp: 2025-01-09T16:06:08.547Z
Learning: The `b_sector` column has been removed from the farms table and replaced with `b_businessid_farm`, `b_address_farm`, and `b_postalcode_farm` columns for better business information management.
Applied to files:
fdm-core/src/field.ts
📚 Learning: 2025-07-21T12:06:07.070Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.070Z
Learning: Functions in the fdm-calculator with "NL2025" in their names are specifically designed for Netherlands 2025 agricultural norms calculation and hardcoded 2025 dates are appropriate in this context, as different years would have separate calculation modules.
Applied to files:
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts
🧬 Code graph analysis (4)
fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (1)
fdm-app/app/components/custom/cultivation-selector.tsx (1)
CultivationSelector(24-122)
fdm-calculator/src/balance/nitrogen/index.test.ts (2)
fdm-calculator/src/balance/nitrogen/types.d.ts (2)
NitrogenBalanceInput(535-543)NitrogenBalanceFieldResultNumeric(673-679)fdm-calculator/src/balance/nitrogen/index.ts (2)
calculateNitrogenBalance(32-87)calculateNitrogenBalancesFieldToFarm(302-538)
fdm-core/src/field.ts (3)
fdm-core/src/db/schema.ts (2)
fieldsTypeInsert(112-112)fieldsTypeSelect(111-111)fdm-core/src/field.d.ts (1)
Field(3-16)fdm-core/src/index.ts (1)
Field(112-112)
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts (2)
fdm-calculator/src/norms/nl/2026/value/types.d.ts (1)
NL2026NormsInput(14-25)fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.ts (1)
calculateNL2026DierlijkeMestGebruiksNorm(22-39)
🪛 GitHub Actions: Tests
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts
[error] 18-18: AssertionError: expected +0 to be 170 // Object.is equality
🪛 GitHub Actions: Type Check
fdm-calculator/src/balance/nitrogen/index.test.ts
[error] 1-1: TypeScript error TS6133: 'vi' is declared but its value is never read. (tsc --noEmit)
🪛 GitHub Check: calculator (24)
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts
[failure] 18-18: src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts > calculateNL2026DierlijkeMestGebruiksNorm > should return the default norm value
AssertionError: expected +0 to be 170 // Object.is equality
- Expected
- Received
- 170
- 0
❯ src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts:18:34
🔇 Additional comments (18)
fdm-calculator/src/norms/nl/2026/value/dierlijke-mest-gebruiksnorm.test.ts (1)
22-31: Buffer strip test looks correct.The test correctly verifies the zero-norm behavior for buffer strips. The type assertion (
as NL2026NormsInput) works here since the implementation only accessesfield.b_bufferstripin the early return path.fdm-core/src/field.ts (7)
56-79: LGTM!The optional
b_bufferstripparameter with a sensible default offalseis well implemented. The nullish coalescing ensures explicitfalsevalues are preserved while undefined falls back correctly.
116-142: LGTM!The automatic buffer detection is well-structured:
- Runs only when
b_bufferstripis not explicitly provided- Uses
ST_ExteriorRingfor perimeter calculation (correctly ignoring interior holes per the codebase conventions)- Executes within the same transaction for atomicity
- Guards against empty results before updating
197-197: LGTM!The
b_bufferstripfield is correctly added to the select projection, aligning with theFieldinterface definition.
306-306: LGTM!Consistent with
getField, theb_bufferstripfield is appropriately included in thegetFieldsprojection.
461-467: Good defensive addition.The
field.b_start &&guard correctly handles the case whereb_startcould be undefined, preventing a runtime error from calling.getTime()on undefined.
395-397: LGTM!The conditional update pattern is consistent with how other optional parameters (
b_name,b_id_source,b_geometry) are handled.
155-155: LGTM!Including
b_bufferstripin the error payload aids debugging when field creation fails.fdm-app/app/components/blocks/fertilizer-applications/metrics.tsx (5)
46-106: Nice propagation ofb_bufferstripinto the component props.
Keeps buffer-strip behavior explicit and type-safe in the UI layer.
79-93: Zero-total guard in progress color helpers looks solid.
Prevents divide-by-zero and yields a safe neutral color.
180-365: Norms progress rendering is now zero-safe.
The guards keep Progress values sane when norms are zeroed for buffer strips.
557-682: Nutrient advice progress is zero-safe and consistent.
Thed_*_req === 0guards prevent invalid percentages for buffer strips.
699-815: Skeleton updates align well with the new layout.
No issues here.fdm-calculator/src/balance/nitrogen/index.test.ts (5)
15-21: Mock execute flow looks consistent.The execute-based stub aligns with the new cache-miss path and keeps the mock chain intact.
29-36: Field inputs now includeb_bufferstrip—good coverage.This keeps the test inputs aligned with the new buffer-strip flag behavior.
Also applies to: 176-183
210-250: Buffer-strip zero-balance test is solid.Covers the expected short-circuit behavior and zeroed outputs.
252-331: Farm-level aggregation exclusion test looks good.Verifies that buffer-strip fields don’t affect farm totals.
1-5: Remove unusedviimport to fix the TS6133 typecheck failure.
viis imported but never used in the test file. Removing it resolves the TypeScript error and aligns with project guidance to avoid Vitest'svimocking utilities.Proposed fix
-import { describe, expect, it, vi } from "vitest" +import { describe, expect, it } from "vitest"
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
fdm-app/app/routes/farm.$b_id_farm.$calendar.rotation._index.tsx (1)
368-370: Critical:b_isproductiveshould beb_bufferstripto match the updatedCropRowtype.The
CropRowtype incolumns.tsxwas updated to useb_bufferstripinstead ofb_isproductive, but this loader still produces an object with the old field name. This type mismatch will cause TypeScript errors and the UI will not receive the expected buffer strip data for crop rows.🐛 Proposed fix
- b_isproductive: fieldsWithThisCultivation.some( - (field) => field.b_isproductive, - ), + b_bufferstrip: fieldsWithThisCultivation.some( + (field) => field.b_bufferstrip, + ),
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@fdm-app/app/routes/farm`.$b_id_farm.$calendar.rotation._index.tsx:
- Around line 224-225: The code calls Math.round(field.b_area * 10) / 10 but
Field.b_area can be number | null, causing NaN for null values; update the
mapping to guard b_area by using a nullish fallback like
Math.round((field.b_area ?? 0) * 10) / 10 (or return null explicitly with
field.b_area == null ? null : Math.round(field.b_area * 10) / 10) so b_area is
never NaN; change the expression where b_area is set in the mapping that
references field.b_area.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Sven Verweij <37927107+SvenVw@users.noreply.github.com>
| b_lu_end: Date[] | ||
| b_isproductive: boolean | ||
| b_bufferstrip: boolean | ||
| fields: FieldRow[] |
There was a problem hiding this comment.
for now its fine to replace. "isproductive" is still a property that might be used when Ecoregeling is implemented later. for now oke.
There was a problem hiding this comment.
Yes, we can reintroduce it later
| if (cleanedValue === "true" || cleanedValue === "on") { | ||
| formObject[key] = true | ||
| } else if (cleanedValue === "false") { | ||
| formObject[key] = false |
There was a problem hiding this comment.
to be consistent.. its not necessary to add "|| cleanedValue ===''off"?
There was a problem hiding this comment.
No, in case the checkbox is unchecked it will send undefined and not off. A bit confusing
| mineralisation: { total: 0 }, | ||
| }, | ||
| removal: { | ||
| total: 0, |
There was a problem hiding this comment.
so the baseline statement is that on a buffer strip there is no yield, isn't?
we might discuss and change that at a later moment
There was a problem hiding this comment.
As we discussed earlier, bufferstrips are excluded from balances, but if needed we can change it
| balance: { | ||
| supply: { total: 500 }, | ||
| degradation: { total: -200 }, | ||
| balance: 300, |
| } | ||
| return data | ||
| } | ||
|
|
There was a problem hiding this comment.
this function is not used anymore?
gerardhros
left a comment
There was a problem hiding this comment.
LGTM. few small questions.
Summary by CodeRabbit
New Features
Behavior Changes
UI / Improvements
Tests
✏️ Tip: You can customize this high-level summary in your review settings.
Closes #419