Add 2025 Dutch fertilization norms with backend, frontend, and API updates#156
Conversation
🦋 Changeset detectedLatest commit: ca2b011 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
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 |
WalkthroughThis update introduces a comprehensive feature set for calculating and displaying Dutch agricultural fertilization norms for 2025. It adds new database schema, backend logic, and API endpoints for managing derogations, as well as frontend components and routes for visualizing farm and field-level norms. Extensive documentation and test coverage are also included. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant WebApp
participant Backend
participant DB
participant Calculator
User->>WebApp: Navigate to Farm Norms page
WebApp->>Backend: Request farm and field norms (with farm, calendar)
Backend->>DB: Fetch farm, fields, derogations, soil, cultivations
Backend->>Calculator: Calculate norms for fields (manure, phosphate, nitrogen)
Calculator-->>Backend: Return norms per field
Backend->>Calculator: Aggregate field norms to farm level
Calculator-->>Backend: Return farm-level norms
Backend-->>WebApp: Return norms data (farm, fields)
WebApp-->>User: Render farm and field norms UI
sequenceDiagram
participant User
participant WebApp
participant Backend
participant DB
User->>WebApp: Toggle derogation for year in settings
WebApp->>Backend: Submit derogation add/remove request
Backend->>DB: Add or remove derogation record
DB-->>Backend: Confirm operation
Backend-->>WebApp: Return success/error
WebApp-->>User: Update derogation UI
Estimated code review effort5 (>120 minutes) Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## development #156 +/- ##
===============================================
+ Coverage 93.55% 94.04% +0.49%
===============================================
Files 74 85 +11
Lines 9043 12628 +3585
Branches 1141 1290 +149
===============================================
+ Hits 8460 11876 +3416
- Misses 581 750 +169
Partials 2 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:
|
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
fdm-docs/docs/norms/nl/01-2025.md (1)
12-14: Nice catch on “effective nitrogen” translation.Using “effective nitrogen” instead of the earlier “workable” translation resolves the previous terminology issue.
🧹 Nitpick comments (2)
fdm-docs/docs/norms/nl/01-2025.md (2)
26-39: Fix nested-list indentation to satisfy markdownlint (MD007).Indentation for the second-level bullets is 4 spaces; markdownlint (and most renderers) expect 2 spaces to keep hierarchy clear. Adjusting prevents future CI lint failures.
Example:
-* **Derogation Status**: ... + * **Derogation Status**: ...
55-56: Tighten wording around “overig” & add English gloss.The Dutch term overig may be opaque to non-Dutch readers. Suggest adding an English explanation and dropping the inner quotes.
-... the standard norm is used as "overig". +... the standard norm classified as *overig* (“other”).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.norm.tsx(0 hunks)fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.tsx(0 hunks)fdm-app/package.json(1 hunks)fdm-calculator/package.json(1 hunks)fdm-calculator/src/norms/nl/2025/fosfaatgebruiksnorm.ts(1 hunks)fdm-docs/docs/norms/nl/01-2025.md(1 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-docs/docs/norms/nl/01-2025.md (2)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: #88
File: fdm-calculator/src/doses/calculate-dose.ts:18-18
Timestamp: 2025-03-04T10:56:35.540Z
Learning: In the FDM calculator, fertilizer nutrient rates (p_n_rt, p_p_rt, p_k_rt) are measured in g/kg, and are converted to fractions by dividing by 10 during dose calculations.
🪛 LanguageTool
fdm-docs/docs/norms/nl/01-2025.md
[grammar] ~55-~55: Ensure spelling is correct
Context: ...ty is unknown or not on the list of RVO Tabel 2c, the standard norm is used as "overi...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 markdownlint-cli2 (0.17.2)
fdm-docs/docs/norms/nl/01-2025.md
27-27: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
30-30: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
33-33: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
34-34: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
35-35: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
38-38: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
💤 Files with no reviewable changes (2)
- fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.norm.tsx
- fdm-app/app/routes/farm.$b_id_farm.$calendar.field.$b_id.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- fdm-app/package.json
- fdm-calculator/package.json
- fdm-calculator/src/norms/nl/2025/fosfaatgebruiksnorm.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-docs/docs/norms/nl/01-2025.md (2)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: #88
File: fdm-calculator/src/doses/calculate-dose.ts:18-18
Timestamp: 2025-03-04T10:56:35.540Z
Learning: In the FDM calculator, fertilizer nutrient rates (p_n_rt, p_p_rt, p_k_rt) are measured in g/kg, and are converted to fractions by dividing by 10 during dose calculations.
🪛 LanguageTool
fdm-docs/docs/norms/nl/01-2025.md
[grammar] ~55-~55: Ensure spelling is correct
Context: ...ty is unknown or not on the list of RVO Tabel 2c, the standard norm is used as "overi...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 markdownlint-cli2 (0.17.2)
fdm-docs/docs/norms/nl/01-2025.md
27-27: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
30-30: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
33-33: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
34-34: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
35-35: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
38-38: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
Add norms for winterteelt and vanggewas
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
fdm-calculator/src/norms/nl/2025/input.test.ts(1 hunks)fdm-calculator/src/norms/nl/2025/input.ts(1 hunks)fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm-data.ts(1 hunks)fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.test.ts(1 hunks)fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts(1 hunks)fdm-calculator/src/norms/nl/2025/types.d.ts(1 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.test.ts (4)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
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.
Learnt from: SvenVw
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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (7)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.$b_id_farm.field.$b_id.cultivation.$b_lu.harvest.$b_id_harvesting.tsx:114-124
Timestamp: 2025-02-13T08:35:59.306Z
Learning: The HarvestForm component in fdm-app expects undefined (not 0) for b_lu_yield when no yield information is available, as 0 would incorrectly imply that yield data exists.
Learnt from: SvenVw
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.
Learnt from: SvenVw
PR: #6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: #6
File: fdm-app/vite.config.ts:5-9
Timestamp: 2024-11-25T12:42:32.783Z
Learning: In the fdm-app project, SvenVw is preparing for migration to Remix v3 and may include type declarations or configurations for v3 features in advance, such as in vite.config.ts.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.create.$b_id_farm.cultivations.$b_lu_catalogue.crop.harvest._index.tsx:111-135
Timestamp: 2025-02-13T09:03:11.890Z
Learning: When adding multiple harvests in fdm-app, use Promise.all instead of Promise.allSettled to ensure atomic behavior - if one harvest addition fails, all should fail and rollback to maintain data consistency.
✅ Files skipped from review due to trivial changes (2)
- fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm-data.ts
- fdm-calculator/src/norms/nl/2025/types.d.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- fdm-calculator/src/norms/nl/2025/input.test.ts
- fdm-calculator/src/norms/nl/2025/input.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.test.ts (4)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
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.
Learnt from: SvenVw
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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (7)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.$b_id_farm.field.$b_id.cultivation.$b_lu.harvest.$b_id_harvesting.tsx:114-124
Timestamp: 2025-02-13T08:35:59.306Z
Learning: The HarvestForm component in fdm-app expects undefined (not 0) for b_lu_yield when no yield information is available, as 0 would incorrectly imply that yield data exists.
Learnt from: SvenVw
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.
Learnt from: SvenVw
PR: #6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: #6
File: fdm-app/vite.config.ts:5-9
Timestamp: 2024-11-25T12:42:32.783Z
Learning: In the fdm-app project, SvenVw is preparing for migration to Remix v3 and may include type declarations or configurations for v3 features in advance, such as in vite.config.ts.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.create.$b_id_farm.cultivations.$b_lu_catalogue.crop.harvest._index.tsx:111-135
Timestamp: 2025-02-13T09:03:11.890Z
Learning: When adding multiple harvests in fdm-app, use Promise.all instead of Promise.allSettled to ensure atomic behavior - if one harvest addition fails, all should fail and rollback to maintain data consistency.
🔇 Additional comments (9)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.test.ts (4)
1-29: LGTM! Well-structured test imports and helper function tests.The imports are clean and the helper function tests appropriately verify the spatial API functionality for NV gebied detection and region classification with realistic coordinate data.
31-52: Good test coverage for grassland norm calculation.The test properly mocks input data and verifies expected norm values and sources. The test data structure follows the expected interface patterns.
54-75: Excellent potato variety-specific norm test.This test correctly validates variety-specific norm calculation for potatoes ("Adora" variety) and confirms the expected norm value (140) and source description.
77-282: Comprehensive korting calculation test suite.The test suite thoroughly covers all korting scenarios:
- Winterteelt exception (0 korting)
- Vanggewas timing-based korting (0, 5, 10, 20 kg N/ha based on sowing dates)
- No winterteelt/vanggewas scenario (20 kg N/ha korting)
- Regional exceptions (no korting for non-sandy/loess regions)
The test data properly simulates different cultivation periods and the assertions validate both norm values and descriptive text.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (5)
1-49: Well-implemented NV gebied detection function.The function properly handles the spatial API call with appropriate error handling and clear documentation. The coordinate extraction and API parameter formatting are correct.
51-94: Robust region determination with proper error handling.The function correctly implements spatial querying for soil region classification with comprehensive error handling for both API failures and missing region data.
96-210: Excellent hierarchical norm selection logic.The
getNormsForCultivationfunction implements a well-designed hierarchy for norm selection:
- Sub-type norms (temporal periods for grasslands)
- Variety-specific norms (potato varieties)
- Derogation-specific norms (maize)
- Default norms
The logic properly handles edge cases and provides appropriate fallbacks.
212-326: Comprehensive korting calculation implementation.The korting calculation properly implements the complex business rules for nitrogen reductions based on:
- Regional applicability (sandy/loess regions only)
- Winterteelt exceptions
- Vanggewas presence and timing
- Proper date-based logic for different reduction levels
The logic correctly handles edge cases and provides descriptive feedback.
328-559: Excellent main calculation function with comprehensive logic.The
getNL2025StikstofGebruiksNormfunction provides a well-orchestrated calculation process:
- Proper hoofdteelt determination
- Geographical context assessment
- Sophisticated standard matching with variety and derogation handling
- Appropriate korting application
- Comprehensive error handling throughout
The function correctly handles the braak cultivation special case and provides detailed error messages for debugging.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
fdm-docs/docs/norms/nl/01-2025.md (1)
27-38: Fix markdown list indentation for consistencyThe nested list items use 4-space indentation when 2-space indentation is expected. Consider updating for better consistency with markdown standards.
- * **Derogation Status**: Does the farm have a derogation permit for 2025? This is a critical factor for nitrogen and animal manure norms. + * **Derogation Status**: Does the farm have a derogation permit for 2025? This is a critical factor for nitrogen and animal manure norms. - * **Field Location**: The precise geographical coordinates of the field are used to determine if it falls within special regulatory zones, such as Nutrient-Polluted Areas (`NV-gebieden`), Groundwater Protection Areas (`GWBG-gebieden`), or specific soil regions (sand, clay, peat, loess). + * **Field Location**: The precise geographical coordinates of the field are used to determine if it falls within special regulatory zones, such as Nutrient-Polluted Areas (`NV-gebieden`), Groundwater Protection Areas (`GWBG-gebieden`), or specific soil regions (sand, clay, peat, loess). - * **Main Crop (`hoofdteelt`)**: The primary crop grown on the field. The calculator identifies the main crop as the one with the longest cultivation period between May 15th and July 15th. - * **Crop Variety**: For certain crops like potatoes and flowers, the specific variety can result in a higher or lower nitrogen norm. - * **Cultivation Dates**: The start and end dates of cultivation are crucial for time-sensitive norms, such as those for temporary grassland. + * **Main Crop (`hoofdteelt`)**: The primary crop grown on the field. The calculator identifies the main crop as the one with the longest cultivation period between May 15th and July 15th. + * **Crop Variety**: For certain crops like potatoes and flowers, the specific variety can result in a higher or lower nitrogen norm. + * **Cultivation Dates**: The start and end dates of cultivation are crucial for time-sensitive norms, such as those for temporary grassland. - * **Phosphate Levels**: The P-CaCl2 (or P-PAE) and P-Al values from your most recent soil test are used to classify the soil's phosphate status, which directly determines the phosphate usage norm. + * **Phosphate Levels**: The P-CaCl2 (or P-PAE) and P-Al values from your most recent soil test are used to classify the soil's phosphate status, which directly determines the phosphate usage norm.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts(1 hunks)fdm-docs/docs/norms/nl/01-2025.md(1 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (7)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.$b_id_farm.field.$b_id.cultivation.$b_lu.harvest.$b_id_harvesting.tsx:114-124
Timestamp: 2025-02-13T08:35:59.306Z
Learning: The HarvestForm component in fdm-app expects undefined (not 0) for b_lu_yield when no yield information is available, as 0 would incorrectly imply that yield data exists.
Learnt from: SvenVw
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.
Learnt from: SvenVw
PR: #6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: #6
File: fdm-app/vite.config.ts:5-9
Timestamp: 2024-11-25T12:42:32.783Z
Learning: In the fdm-app project, SvenVw is preparing for migration to Remix v3 and may include type declarations or configurations for v3 features in advance, such as in vite.config.ts.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.create.$b_id_farm.cultivations.$b_lu_catalogue.crop.harvest._index.tsx:111-135
Timestamp: 2025-02-13T09:03:11.890Z
Learning: When adding multiple harvests in fdm-app, use Promise.all instead of Promise.allSettled to ensure atomic behavior - if one harvest addition fails, all should fail and rollback to maintain data consistency.
fdm-docs/docs/norms/nl/01-2025.md (2)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: #88
File: fdm-calculator/src/doses/calculate-dose.ts:18-18
Timestamp: 2025-03-04T10:56:35.540Z
Learning: In the FDM calculator, fertilizer nutrient rates (p_n_rt, p_p_rt, p_k_rt) are measured in g/kg, and are converted to fractions by dividing by 10 during dose calculations.
🪛 markdownlint-cli2 (0.17.2)
fdm-docs/docs/norms/nl/01-2025.md
27-27: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
30-30: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
33-33: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
34-34: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
35-35: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
38-38: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: SvenVw/fdm#6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (7)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
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();.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.$b_id_farm.field.$b_id.cultivation.$b_lu.harvest.$b_id_harvesting.tsx:114-124
Timestamp: 2025-02-13T08:35:59.306Z
Learning: The HarvestForm component in fdm-app expects undefined (not 0) for b_lu_yield when no yield information is available, as 0 would incorrectly imply that yield data exists.
Learnt from: SvenVw
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.
Learnt from: SvenVw
PR: #6
File: fdm-app/app/routes/app.addfarm.$b_id_farm.fields.tsx:63-99
Timestamp: 2024-11-25T14:50:16.074Z
Learning: i18n will be added in future PRs; for now, hardcoded Dutch text is acceptable until a translation system is implemented.
Learnt from: SvenVw
PR: #6
File: fdm-app/vite.config.ts:5-9
Timestamp: 2024-11-25T12:42:32.783Z
Learning: In the fdm-app project, SvenVw is preparing for migration to Remix v3 and may include type declarations or configurations for v3 features in advance, such as in vite.config.ts.
Learnt from: SvenVw
PR: #71
File: fdm-app/app/routes/farm.create.$b_id_farm.cultivations.$b_lu_catalogue.crop.harvest._index.tsx:111-135
Timestamp: 2025-02-13T09:03:11.890Z
Learning: When adding multiple harvests in fdm-app, use Promise.all instead of Promise.allSettled to ensure atomic behavior - if one harvest addition fails, all should fail and rollback to maintain data consistency.
fdm-docs/docs/norms/nl/01-2025.md (2)
Learnt from: SvenVw
PR: #156
File: fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts:295-303
Timestamp: 2025-07-21T12:06:07.031Z
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.
Learnt from: SvenVw
PR: #88
File: fdm-calculator/src/doses/calculate-dose.ts:18-18
Timestamp: 2025-03-04T10:56:35.540Z
Learning: In the FDM calculator, fertilizer nutrient rates (p_n_rt, p_p_rt, p_k_rt) are measured in g/kg, and are converted to fractions by dividing by 10 during dose calculations.
🪛 markdownlint-cli2 (0.17.2)
fdm-docs/docs/norms/nl/01-2025.md
27-27: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
30-30: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
33-33: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
34-34: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
35-35: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
38-38: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
🔇 Additional comments (9)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (5)
25-49: LGTM: Well-implemented spatial query functionThe function correctly implements the spatial query logic with proper error handling, descriptive error messages, and appropriate return types. The API endpoint usage and coordinate handling are implemented correctly.
67-94: LGTM: Robust region determination logicThe function implements proper spatial querying with comprehensive error handling. The fallback error message includes coordinates for debugging, which is helpful for troubleshooting edge cases.
141-210: LGTM: Well-structured norm selection hierarchyThe function implements a clear and logical hierarchy for norm selection with proper handling of edge cases like year-spanning periods and case-insensitive variety matching. The extensive documentation makes the complex business logic easy to understand and maintain.
220-326: LGTM: Comprehensive korting calculation logicThe function correctly implements complex agricultural policy rules with proper date handling, array length checks, and tiered reduction calculations. The business logic is well-structured and the descriptive return values will be helpful for users understanding why specific reductions were applied.
405-559: LGTM: Comprehensive norm calculation implementationThe main function orchestrates a complex multi-step calculation process with excellent error handling and comprehensive business logic. The variety matching, standard selection, and final norm calculation are all implemented correctly with appropriate fallbacks and edge case handling.
fdm-docs/docs/norms/nl/01-2025.md (4)
1-25: LGTM: Clear and well-structured introductionThe document provides an excellent overview of the calculation methodology with appropriate disclaimers and clear explanations of the three key norms. The terminology correctly uses "effective nitrogen" as suggested in previous reviews.
40-75: LGTM: Accurate and comprehensive nitrogen norm documentationThe section provides an excellent technical explanation of the nitrogen usage norm calculation that accurately reflects the implementation logic. The step-by-step process, variety-specific rules, and korting calculations are all clearly documented with appropriate references to official RVO sources.
76-95: LGTM: Clear phosphate norm documentation with helpful reference tableThe section provides a concise and accurate explanation of phosphate norm determination. The inclusion of the reference table makes it easy to understand the relationship between soil status, land type, and applicable norms.
96-108: LGTM: Clear and accurate animal manure norm documentationThe section provides a straightforward explanation of the animal manure usage norm calculation with proper coverage of derogation status and geographical considerations.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests
Chores