Skip to content

Update AHN endpoint and improve caching stability#395

Merged
SvenVw merged 2 commits into
mainfrom
hotfix/FDM394
Dec 23, 2025
Merged

Update AHN endpoint and improve caching stability#395
SvenVw merged 2 commits into
mainfrom
hotfix/FDM394

Conversation

@SvenVw
Copy link
Copy Markdown
Collaborator

@SvenVw SvenVw commented Dec 23, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved elevation map stability and performance on mobile devices
    • Corrected cache endpoint path configuration
    • Enhanced error handling for offline scenarios
  • Improvements

    • Better offline support with automatic fallback to cached data
    • Strengthened data validation for elevation map features

✏️ Tip: You can customize this high-level summary in your review settings.

Closes #394

…path, implementing robust localStorage error handling, and adding a 'fallback-to-stale' strategy for offline resilience
@SvenVw SvenVw self-assigned this Dec 23, 2025
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Dec 23, 2025

⚠️ No Changeset found

Latest commit: dfbefd6

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

@github-actions
Copy link
Copy Markdown
Contributor

👋 Hotfix Branch PR Detected!

Before merging this Pull Request into main, please ensure you have finalized the hotfix by manually running the 'Release' workflow on this hotfix/FDM394 branch.

This will:

  1. Bump package versions.
  2. Generate changelogs.
  3. Create Git tags.

You can trigger the workflow from the 'Actions' tab, selecting the 'Release' workflow, and choosing this hotfix/FDM394 branch.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 23, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This PR enhances the elevation map's cache handling and network resilience by implementing a "fallback-to-stale" pattern. It adds robust localStorage validation with 24-hour TTL, corrects the AHN index endpoint path, and introduces comprehensive error handling for offline scenarios.

Changes

Cohort / File(s) Summary
Elevation Map Cache & Fetch Logic
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx
Refactored AHN index fetching with multi-layer resilience: localStorage cache validation (features presence, 24hr freshness), wrapped cache access in try-catch, corrected endpoint to "/atlas/ahn-index", added data validation post-fetch, and implemented fallback to expired cache on network failure.
Version & Documentation
fdm-app/package.json, fdm-app/CHANGELOG.md
Bumped version from 0.26.1 to 0.26.2; added changelog entry documenting mobile elevation stability fixes, cache endpoint correction, robust localStorage handling, and offline resilience improvements.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Cache as localStorage Cache
    participant Server as AHN API
    
    Client->>Cache: Check for cached index
    alt Cache Accessible & Valid
        Cache-->>Client: Return fresh cached data
    else Cache Missing or Expired
        Client->>Server: Fetch fresh AHN index from /atlas/ahn-index
        alt Fetch Successful
            Server-->>Client: Return index with features
            rect rgba(76, 175, 80, 0.1)
                note right of Client: Validate features & store<br/>with timestamp in cache
            end
            Client->>Cache: Store fresh data + timestamp
            Cache-->>Client: ✓ Cached
        else Fetch Failed (Network Error)
            rect rgba(244, 67, 54, 0.1)
                note right of Client: Network unavailable
            end
            Client->>Cache: Attempt fallback to stale data
            alt Stale Cache Available
                Cache-->>Client: Return expired cached data
                note right of Client: Use stale data for rendering
            else No Cache Available
                Client-->>Client: Signal error — no data available
            end
        end
    else Cache Access Error (e.g., Private Mode)
        Client->>Server: Proceed to fetch (skip cache)
        Server-->>Client: Return index
        Client->>Cache: Attempt to store (logged if fails)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • SvenVw/fdm#376 — Modifies the same elevation route file and overlaps on AHN index fetching and caching logic changes.
  • SvenVw/fdm#393 — Alters elevation atlas flow and AHN index endpoint path configuration.

Suggested reviewers

  • BoraIneviNMI
  • gerardhros

Poem

🐰 Whiskers twitching with delight,
The cache now holds through day and night,
When networks fail on mobile ground,
Stale data keeps us safe and sound!
No more maps that disappear—
Elevation's here, elevation's here! 🗻

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code changes fully address all requirements from issue #394: safe localStorage error handling, 24-hour cache TTL validation, and fallback-to-stale strategy for offline resilience.
Out of Scope Changes check ✅ Passed All changes are scoped to the elevation map cache stability fix described in issue #394; no unrelated modifications were introduced.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: updating the AHN endpoint path and improving caching stability with localStorage error handling and fallback-to-stale strategy.

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a30b7b and dfbefd6.

📒 Files selected for processing (2)
  • fdm-app/CHANGELOG.md
  • fdm-app/package.json

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 23, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.47%. Comparing base (a440436) to head (2a30b7b).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #395   +/-   ##
=======================================
  Coverage   87.47%   87.47%           
=======================================
  Files          91       91           
  Lines        4559     4559           
  Branches     1391     1391           
=======================================
  Hits         3988     3988           
  Misses        571      571           
Flag Coverage Δ
fdm-calculator 86.98% <ø> (ø)
fdm-core 87.66% <ø> (ø)
fdm-data 92.12% <ø> (ø)

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.

@coderabbitai coderabbitai Bot changed the title @coderabbitai Update AHN endpoint and improve caching stability Dec 23, 2025
@coderabbitai coderabbitai Bot added branch:main An issue, affecting the main branch, that requires an hotfix bug Something isn't working fdm-app labels Dec 23, 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: 0

🧹 Nitpick comments (1)
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx (1)

277-296: Solid fallback-to-stale implementation for offline resilience.

The strategy correctly prioritizes: fresh cache → network fetch → expired cache → error state. This aligns well with the PR objectives.

One consideration: setting networkStatus to "idle" when serving stale data (line 289) means users won't know they're viewing potentially outdated information. The console warning is helpful for debugging, but you might consider adding a "stale" status or displaying a subtle UI indicator. This is optional if the UX decision is to silently degrade.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a440436 and 2a30b7b.

📒 Files selected for processing (2)
  • .changeset/fix-mobile-elevation-fallback.md
  • fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx
🧰 Additional context used
🧠 Learnings (6)
📚 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.atlas.elevation.tsx
  • .changeset/fix-mobile-elevation-fallback.md
📚 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/routes/farm.$b_id_farm.$calendar.atlas.elevation.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.atlas.elevation.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.atlas.elevation.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/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx
📚 Learning: 2025-09-25T15:10:59.708Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 272
File: fdm-app/app/store/field-fertilizer-form.tsx:45-47
Timestamp: 2025-09-25T15:10:59.708Z
Learning: In the FDM application, Zustand stores with persist middleware using sessionStorage/localStorage don't require SSR hardening guards. The existing store patterns in fdm-app work without typeof window checks or memory storage fallbacks.

Applied to files:

  • .changeset/fix-mobile-elevation-fallback.md
🔇 Additional comments (4)
.changeset/fix-mobile-elevation-fallback.md (1)

1-5: LGTM!

The changeset accurately describes the fix with appropriate patch-level versioning. The description aligns well with the PR objectives and the actual code changes.

fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx (3)

224-250: Robust cache lookup with proper error handling.

The implementation correctly:

  • Guards localStorage access with typeof check for SSR compatibility
  • Wraps parsing in try-catch to handle malformed cache entries
  • Validates both freshness (24h TTL) and data integrity before using cache
  • Clears corrupted cache entries on failure

The empty catch on line 249 is acceptable here—localStorage cleanup is best-effort and shouldn't block the fetch fallback.


220-300: Well-structured caching strategy addressing mobile stability concerns.

The fetchIndex implementation correctly addresses the issue requirements:

  • ✅ localStorage access wrapped in try-catch to prevent crashes
  • ✅ 24-hour cache TTL aligned with server
  • ✅ Fresh cache → network → stale fallback flow
  • ✅ Guards for undefined localStorage (SSR/mobile edge cases)

The double localStorage read (lines 228 and 281) is intentional and appropriate since the first block may clear corrupted entries before the fallback block runs.


252-274: Good fetch logic with proper validation and caching.

The implementation correctly validates the response structure before using/caching it, preventing invalid data from propagating. Storage failures are gracefully handled. The /atlas/ahn-index endpoint is properly configured in fdm-app/app/routes/atlas.ahn-index.tsx with appropriate caching headers (86400 seconds) and server-side in-memory caching with a 24-hour TTL.

@SvenVw SvenVw merged commit ede0376 into main Dec 23, 2025
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

branch:main An issue, affecting the main branch, that requires an hotfix bug Something isn't working fdm-app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant