Skip to content

Update derogation norm logic for Natura 2000 proximity and add tests#230

Merged
SvenVw merged 7 commits into
mainfrom
FDM229
Aug 8, 2025
Merged

Update derogation norm logic for Natura 2000 proximity and add tests#230
SvenVw merged 7 commits into
mainfrom
FDM229

Conversation

@SvenVw
Copy link
Copy Markdown
Collaborator

@SvenVw SvenVw commented Aug 8, 2025

Summary by CodeRabbit

  • New Features
    • Added Natura 2000 area checks for derogation farms, ensuring fields within or near these areas receive the correct norm.
  • Bug Fixes
    • Corrected derogation norm for groundwater protection areas to 170 kg N/ha.
  • Improvements
    • Enhanced error handling and reliability for area checks with standardized request timeouts and clearer error messages.
  • Chores
    • Updated version to 0.5.3 and documented changes in the changelog.

Closes @229

@SvenVw SvenVw self-assigned this Aug 8, 2025
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Aug 8, 2025

⚠️ No Changeset found

Latest commit: 60bb5c2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 8, 2025

Walkthrough

This update introduces a timeout mechanism and improved error handling for fetch requests in nitrogen norm calculations. It adds a new check for Natura 2000 areas affecting derogation norms, refines the norm determination logic to prioritize Natura 2000 areas, and updates related tests and documentation. Version numbers and changelogs are incremented accordingly.

Changes

Cohort / File(s) Change Summary
Norm Calculation Logic & Fetch Handling
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts, fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts
Added FETCH_TIMEOUT_MS constant and fetch timeout logic using AbortController; improved error messages and response parsing; added isFieldInNatura2000Gebied function; updated norm logic to prioritize Natura 2000 areas for derogation farms.
Norm Calculation Tests
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts
Updated existing test for derogation in groundwater protection area (GWBG); added new test for derogation in Natura 2000 area with expected norm and source.
Documentation & Versioning
fdm-calculator/CHANGELOG.md, fdm-calculator/package.json
Updated changelog and incremented package version to 0.5.3 to reflect changes in norm calculation prioritization and bug fixes.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant NormCalculator

    Client->>NormCalculator: getNL2025DierlijkeMestGebruiksNorm(input)
    par Parallel Checks
        NormCalculator->>NormCalculator: isFieldInNVGebied()
        NormCalculator->>NormCalculator: isFieldInGWGBGebied()
        NormCalculator->>NormCalculator: isFieldInNatura2000Gebied()
    end
    NormCalculator->>NormCalculator: Determine norm based on area checks (Natura 2000 > GWBG > NV > Default)
    NormCalculator-->>Client: Return norm value and source
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Possibly related PRs

Suggested reviewers

  • gerardhros

Poem

In fields where rabbits hop and roam,
New rules for nature claim their home.
With timeouts swift and logic neat,
Norms for every field complete!
Natura’s call now takes the lead—
A patch for every farmer’s need.
🐇✨

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch FDM229

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link
Copy Markdown

codecov Bot commented Aug 8, 2025

Codecov Report

❌ Patch coverage is 68.18182% with 35 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.88%. Comparing base (f8827d0) to head (60bb5c2).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
...r/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts 73.91% 18 Missing ⚠️
...lculator/src/norms/nl/2025/stikstofgebruiksnorm.ts 58.53% 17 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #230      +/-   ##
==========================================
- Coverage   93.02%   92.88%   -0.15%     
==========================================
  Files          85       85              
  Lines       12812    12885      +73     
  Branches     1293     1294       +1     
==========================================
+ Hits        11919    11968      +49     
- Misses        891      915      +24     
  Partials        2        2              
Flag Coverage Δ
fdm-calculator 94.61% <68.18%> (-0.39%) ⬇️
fdm-core 91.60% <ø> (ø)
fdm-data 94.21% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@SvenVw SvenVw linked an issue Aug 8, 2025 that may be closed by this pull request
@coderabbitai coderabbitai Bot changed the title @coderabbitai Update derogation norm logic for Natura 2000 proximity and add tests Aug 8, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
.changeset/warm-pants-rush.md (1)

5-5: Clarify wording & keep changeset titles consistent

“norm for derogation in GWGB should be 170” reads okay but differs from the style used in the two companion changesets. For easier changelog generation consider a short imperative sentence, e.g.

Fix derogation norm for GWBG: 170 kg N/ha

.changeset/shy-tools-matter.md (1)

5-5: Minor wording tweak

The sentence is a bit hard to parse. Something like

Add Natura 2000 proximity check to derogation norm calculation

is shorter and matches the other entries.

.changeset/angry-rings-punch.md (1)

5-5: Grammar / clarity

Maybe re-phrase to:

Give Natura 2000 and GWBG derogation norms priority over NV-gebied

(singular “has” → “give” / “has priority” → “priority over”).

Purely cosmetic, ignore if your changelog generator normalises text.

fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts (1)

66-81: Test name no longer matches behaviour

The test label still says “default norm value” but the expectation is the adjusted derogation value 170. Rename to avoid confusion when scanning results.

fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (2)

48-86: Duplicate helper – consider extracting a generic “geoContains” util

isFieldInNatura2000Gebied repeats the entire body of isFieldInGWGBGebied. Factor out a parametrised helper that takes the dataset URL to keep maintenance overhead low and reduce bundle size.


88-113: Doc-comment outdated

The remarks section still only mentions NV-gebied and 200 kg norms. Please update to include Natura 2000 & GWBG rules so generated docs stay trustworthy.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8827d0 and 9b71a8f.

📒 Files selected for processing (5)
  • .changeset/angry-rings-punch.md (1 hunks)
  • .changeset/shy-tools-matter.md (1 hunks)
  • .changeset/warm-pants-rush.md (1 hunks)
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts (2 hunks)
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: SvenVw
PR: SvenVw/fdm#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: SvenVw/fdm#194
File: fdm-core/src/harvest.ts:488-644
Timestamp: 2025-07-31T11:38:50.661Z
Learning: The validation logic in updateHarvest is intentionally different from checkHarvestDateCompability because updateHarvest is for updating existing harvests while checkHarvestDateCompability is for inserting new harvests. The insertion function includes checks that don't apply to updates, such as verifying no harvest already exists for "once" harvestable cultivations.
Learnt from: SvenVw
PR: SvenVw/fdm#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.
📚 Learning: 2025-07-21T12:06:07.070Z
Learnt from: SvenVw
PR: SvenVw/fdm#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:

  • .changeset/angry-rings-punch.md
  • .changeset/shy-tools-matter.md
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-02-14T09:56:37.606Z
Learnt from: SvenVw
PR: SvenVw/fdm#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:

  • .changeset/angry-rings-punch.md
  • .changeset/shy-tools-matter.md
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2024-11-25T12:42:32.783Z
Learnt from: SvenVw
PR: SvenVw/fdm#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`.

Applied to files:

  • .changeset/shy-tools-matter.md
📚 Learning: 2025-01-23T15:17:23.027Z
Learnt from: SvenVw
PR: SvenVw/fdm#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:

  • .changeset/shy-tools-matter.md
📚 Learning: 2025-01-23T15:17:23.028Z
Learnt from: SvenVw
PR: SvenVw/fdm#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:

  • .changeset/shy-tools-matter.md
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-31T15:34:20.850Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
🧬 Code Graph Analysis (2)
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts (2)
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (1)
  • getNL2025DierlijkeMestGebruiksNorm (114-149)
fdm-calculator/src/norms/nl/2025/types.d.ts (1)
  • NL2025NormsInput (14-25)
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (1)
fdm-core/src/index.ts (1)
  • Field (102-102)

Comment thread fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts Outdated
Comment thread fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts Outdated
@SvenVw SvenVw merged commit be9552f into main Aug 8, 2025
7 of 10 checks passed
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (1)

21-26: Naming inconsistency: “GWGB” vs “GWBG”

Domain term is “GWBG” (GrondWaterBeschermingsGebied). The exported function name uses “GWGB”, which can confuse usage/searches.

  • Prefer renaming to isFieldInGWBGGebied and keeping a deprecated alias to avoid breaking consumers.

As a non-breaking interim step, add an alias:

// Add near the bottom of this module
export function isFieldInGWBGGebied(
  b_centroid: Field["b_centroid"],
): Promise<boolean> {
  return isFieldInGWGBGebied(b_centroid)
}
🧹 Nitpick comments (4)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (1)

14-15: Avoid duplicating FETCH_TIMEOUT_MS across modules

This constant now exists in multiple modules. Consider centralizing (e.g., a small shared http/constants module) to keep timeout policy consistent across the calculator and avoid drift.

fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (3)

8-9: Avoid duplicating FETCH_TIMEOUT_MS across modules

Same note as in stikstofgebruiksnorm.ts: centralize the timeout constant to keep fetch behavior consistent.


30-40: Good: GWBG lookup hardened with Accept + timeout + cleanup

Consistent with the other module; this should mitigate flakiness and long-hanging requests. Consider preserving the original error as a cause for easier debugging.

Minimal tweak to retain the original error:

-throw new Error(`Error querying GWGB-Gebied : ${String(err)}`)
+throw new Error(`Error querying GWGB-Gebied : ${String(err)}`, { cause: err as any })

Also applies to: 42-49, 50-58


61-71: Doc typos and clarity in Natura 2000 helper

  • “natura200-gebieden” → “Natura 2000-gebieden”
  • “within 100m buffer” → “within a 100 m buffer”
  • Article/grammar tweaks for readability.

Apply this doc-only diff:

- * Determines if a field is located within a Natura 2000 in the Netherlands.
+ * Determines if a field is located within a Natura 2000 area in the Netherlands.
  * This is achieved by performing a spatial query against a vector file containing
- * the boundaries of all natura200-gebieden, including the 100m buffer.
+ * the boundaries of all Natura 2000-gebieden, including a 100 m buffer.
@@
- * @returns A promise that resolves to `true` if the field's centroid is found within an natura2000-gebied or within 100m buffer,
+ * @returns A promise that resolves to `true` if the field's centroid is found within a Natura 2000-gebied or within the 100 m buffer,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b71a8f and 60bb5c2.

📒 Files selected for processing (5)
  • fdm-calculator/CHANGELOG.md (1 hunks)
  • fdm-calculator/package.json (1 hunks)
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts (2 hunks)
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (4 hunks)
  • fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (3 hunks)
✅ Files skipped from review due to trivial changes (2)
  • fdm-calculator/package.json
  • fdm-calculator/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.test.ts
🧰 Additional context used
🧠 Learnings (14)
📓 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.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.
📚 Learning: 2025-07-21T12:06:07.070Z
Learnt from: SvenVw
PR: SvenVw/fdm#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/2025/stikstofgebruiksnorm.ts
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-23T15:17:23.028Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-02-13T09:03:11.890Z
Learnt from: SvenVw
PR: SvenVw/fdm#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.

Applied to files:

  • fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts
  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2024-11-27T12:15:36.425Z
Learnt from: SvenVw
PR: SvenVw/fdm#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/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-23T15:17:23.027Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2024-11-25T12:42:32.783Z
Learnt from: SvenVw
PR: SvenVw/fdm#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`.

Applied to files:

  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-02-24T10:49:54.523Z
Learnt from: SvenVw
PR: SvenVw/fdm#84
File: fdm-app/app/root.tsx:89-145
Timestamp: 2025-02-24T10:49:54.523Z
Learning: In the ErrorBoundary component of fdm-app/app/root.tsx, all client errors (400, 401, 403, 404) are intentionally displayed with a 404 status code for security purposes.

Applied to files:

  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-31T15:34:20.850Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-24T11:28:01.882Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-04-18T14:20:40.975Z
Learnt from: SvenVw
PR: SvenVw/fdm#124
File: fdm-core/src/db/schema-authn.ts:70-76
Timestamp: 2025-04-18T14:20:40.975Z
Learning: The organization schema in fdm-core/src/db/schema-authn.ts is managed by better-auth, and modifications to field constraints (like making the slug field non-nullable) should maintain compatibility with better-auth's expectations, even if application code assumes non-null values.

Applied to files:

  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-01-31T15:05:14.310Z
Learnt from: SvenVw
PR: SvenVw/fdm#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-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
📚 Learning: 2025-03-04T10:56:35.540Z
Learnt from: SvenVw
PR: SvenVw/fdm#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.

Applied to files:

  • fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts
🧬 Code Graph Analysis (1)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (1)
fdm-calculator/src/norms/nl/2025/types.d.ts (1)
  • RegionKey (227-227)
🔇 Additional comments (4)
fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts (1)

36-46: Good: robust fetch with Accept header, AbortController, and timer cleanup

The NV-gebied lookup now has explicit content negotiation, timeout with abort, clearer error messages, and a finally cleanup. This matches prior guidance and will reduce flaky behavior and hangs.

Also applies to: 48-55, 56-64

fdm-calculator/src/norms/nl/2025/dierlijke-mest-gebruiksnorm.ts (3)

72-110: Good: Natura 2000 proximity check mirrors GWBG implementation

Timeout handling, Accept header, and feature parsing are consistent. LGTM.


148-153: Good: run NV/GWBG/Natura 2000 lookups in parallel

Using Promise.all here is the right choice and aligns with earlier suggestions to remove unnecessary latency.


159-168: Derogation prioritization logic looks correct

Priority order (Natura 2000 → GWBG → NV → default) with values 170/170/190/200 matches the PR intent and tests. Clear and readable.

Comment on lines +92 to +97
const params = new URLSearchParams()
params.append("locations", `[[${longitude}, ${latitude}]]`)

const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: getRegion may resolve undefined; throw when no feature/region

If no feature is returned, the function completes without returning/throwing even though it promises RegionKey. Downstream indexing with an undefined region will fail later and obscure the root cause. Throw a specific error when no region is found.

Apply this diff to ensure an explicit error is thrown when no region is found:

   const json = await response.json()
-  const feature = json?.[0]?.[0]
-  if (feature) {
-      return feature.region as RegionKey
-  }
+  const feature = json?.[0]?.[0]
+  if (feature?.region) {
+      return feature.region as RegionKey
+  }
+  throw new Error("No Table2 region found for provided location")

Also applies to: 99-107, 109-113, 114-121

🤖 Prompt for AI Agents
In fdm-calculator/src/norms/nl/2025/stikstofgebruiksnorm.ts around lines 92 to
97, the getRegion function may return undefined without throwing an error when
no feature or region is found, causing downstream failures. Modify the function
to explicitly check if the feature or region is undefined and throw a specific
error in that case. Apply similar checks and error throws in the code blocks
spanning lines 99-107, 109-113, and 114-121 to ensure consistent error handling
when no region is found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix derogation in 2025 for Natura2000 areas and GWGB areas

1 participant