Hotfix/20251222#393
Conversation
…yer)` before the map is fully initialized
…rency for sampling requests to avoid exceeding HTTP/1.1 connection limits.
…nt chunked sampling concurrency, server-side AHN index caching, geometry simplification and WMS layer zoom constraints
|
|
👋 Hotfix Branch PR Detected! Before merging this Pull Request into This will:
You can trigger the workflow from the 'Actions' tab, selecting the 'Release' workflow, and choosing this |
|
Caution Review failedThe pull request is closed. WalkthroughThis pull request introduces performance and stability improvements to the Atlas module, including a map initialization guard fix, a new AHN index caching utility with 24-hour TTL, geometry simplification across multiple routes, and optimizations to the elevation atlas including concurrent batch sampling and WMS zoom-based visibility constraints. Changes
Sequence DiagramsequenceDiagram
participant Client
participant RouteLoader as Route Loader<br/>(atlas.ahn-index)
participant Cache as AHN Cache
participant PDOK as PDOK API
Client->>RouteLoader: Request /resources/ahn-index
RouteLoader->>Cache: getAhnIndex()
alt Cache Hit (not expired)
Cache-->>RouteLoader: Return cached data
else Cache Miss or Expired
Cache->>PDOK: Fetch AHN index GeoJSON
PDOK-->>Cache: Response
alt HTTP OK
Cache->>Cache: Validate & store<br/>(24hr TTL)
Cache-->>RouteLoader: Return data
else HTTP Error
Cache->>Cache: Log error
alt Stale cache available
Cache-->>RouteLoader: Serve stale data
else No stale cache
Cache-->>RouteLoader: Throw error
end
end
end
RouteLoader-->>Client: data() with Cache-Control headers
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 3 inconclusive)
✅ Passed checks (1 passed)
📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #393 +/- ##
=======================================
Coverage 87.47% 87.47%
=======================================
Files 91 91
Lines 4559 4559
Branches 1391 1391
=======================================
Hits 3988 3988
Misses 571 571
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: 1
🧹 Nitpick comments (6)
fdm-app/app/routes/atlas.ahn-index.tsx (1)
1-1: Remove unused import.
LoaderFunctionArgsis imported but not used in the loader function signature.🔎 Suggested cleanup
-import { type LoaderFunctionArgs, data } from "react-router" +import { data } from "react-router"fdm-app/app/integrations/ahn-cache.server.ts (2)
13-21: Consider adding a timeout to the fetch call.The
fetchcall has no timeout configured. If PDOK is slow or unresponsive, this could block the request indefinitely until the default TCP timeout (which can be several minutes).Proposed fix using AbortSignal.timeout
console.log("Fetching AHN index from PDOK...") const response = await fetch( "https://service.pdok.nl/rws/ahn/atom/downloads/dtm_05m/kaartbladindex.json", + { signal: AbortSignal.timeout(30000) } // 30 second timeout )
23-28: The JSON response is type-asserted without validation.The response is cast directly to
FeatureCollectionwithout validating the structure. If PDOK returns malformed data or an error page (with a 200 status), this could cache invalid data for 24 hours.Consider adding minimal validation before caching:
const data = (await response.json()) as FeatureCollection + if (!data.features || !Array.isArray(data.features)) { + throw new Error("Invalid AHN index format") + } cache = { data, expires: now + CACHE_TTL, }fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx (3)
222-263: Double caching may cause staleness.The client-side localStorage cache (7 days) is longer than the server-side cache (24 hours). This means clients could serve stale data even after the server cache has been refreshed.
Consider either:
- Reducing the client cache TTL to match or be shorter than the server cache, or
- Having the server endpoint return cache headers that the client respects.
The current setup isn't incorrect—it prioritizes availability over freshness—but be aware that index updates won't propagate to clients for up to 7 days.
316-324: Stale comment: update to reflect actual limit.The comment on line 316 still mentions "24 tiles" but the actual limit is now 12.
Proposed fix
// Find intersecting tiles - // Optimization: limit to e.g. 24 tiles to avoid overload + // Optimization: limit to 12 tiles to avoid overload const visibleFeatures = indexData.features
454-454: Minor: Consider ifactiveTilesdependency is necessary.The
updateVisibleTilescallback depends onactiveTiles, but it's only used for a length check on line 283. Since you're using theupdateRefpattern to ensure throttled calls use the latest callback, this works correctly, but includingactiveTilesin the dependency array causes the callback to be recreated on every tile update.You could use a ref for the activeTiles length check to avoid the dependency:
+ const activeTilesLengthRef = useRef(activeTiles.length) + useEffect(() => { + activeTilesLengthRef.current = activeTiles.length + }, [activeTiles]) // In updateVisibleTiles: - if (activeTiles.length > 0) { + if (activeTilesLengthRef.current > 0) { setActiveTiles([]) } -}, [indexData, activeTiles]) +}, [indexData])This is a minor optimization and the current implementation is correct.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
.changeset/silly-shoes-shake.md.changeset/witty-foxes-lose.md.changeset/yummy-wombats-live.mdfdm-app/app/components/blocks/atlas/atlas-panels.tsxfdm-app/app/integrations/ahn-cache.server.tsfdm-app/app/routes/atlas.ahn-index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsx
🧰 Additional context used
🧠 Learnings (25)
📚 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/atlas.ahn-index.tsx
📚 Learning: 2025-04-29T11:28:44.181Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 132
File: fdm-app/app/routes/farm.create.$b_id_farm.$calendar.access.tsx:54-68
Timestamp: 2025-04-29T11:28:44.181Z
Learning: In React Router v7, the `json()` function has been replaced with `data()` for creating responses in loaders and actions.
Applied to files:
fdm-app/app/routes/atlas.ahn-index.tsx
📚 Learning: 2025-07-24T08:29:44.044Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 198
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen.$b_id.tsx:146-148
Timestamp: 2025-07-24T08:29:44.044Z
Learning: React Router v7 supports Suspense patterns by returning promises directly from loaders. The pattern is: return { data: somePromise } from loader, then use <Suspense><Await resolve={loaderData.data}>{resolvedData => ...}</Await></Suspense> in components.
Applied to files:
fdm-app/app/routes/atlas.ahn-index.tsx
📚 Learning: 2025-04-29T11:28:44.181Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 132
File: fdm-app/app/routes/farm.create.$b_id_farm.$calendar.access.tsx:54-68
Timestamp: 2025-04-29T11:28:44.181Z
Learning: In React Router v7, the `json()` function has been deprecated and removed. Instead, either return plain JavaScript objects directly from loaders/actions, or use the `data()` function for responses with custom status codes and headers.
Applied to files:
fdm-app/app/routes/atlas.ahn-index.tsx
📚 Learning: 2025-07-24T08:29:44.044Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 198
File: fdm-app/app/routes/farm.$b_id_farm.$calendar.balance.nitrogen.$b_id.tsx:146-148
Timestamp: 2025-07-24T08:29:44.044Z
Learning: In React Router v7, the defer() function has been removed. Instead, loaders can return promises directly in the response object, and components use Suspense and Await to handle them without needing defer().
Applied to files:
fdm-app/app/routes/atlas.ahn-index.tsx
📚 Learning: 2025-01-09T16:07:36.741Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 42
File: fdm-app/app/routes.ts:81-81
Timestamp: 2025-01-09T16:07:36.741Z
Learning: The route pattern "api/auth/:" in React Router is required for better-auth's handler to function correctly. The auth.handler() method in the route's loader and action functions expects this exact pattern to handle various authentication endpoints including OAuth callbacks, session management, and rate limiting.
Applied to files:
fdm-app/app/routes/atlas.ahn-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/routes/atlas.ahn-index.tsxfdm-app/app/components/blocks/atlas/atlas-panels.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx
📚 Learning: 2025-01-31T14:29:37.599Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/components/custom/atlas/atlas.d.tsx:8-8
Timestamp: 2025-01-31T14:29:37.599Z
Learning: In the Atlas component's MapFieldsProps interface, mapStyle is intentionally restricted to "mapbox://styles/mapbox/satellite-streets-v12" as it's currently the only supported style option.
Applied to files:
fdm-app/app/components/blocks/atlas/atlas-panels.tsx
📚 Learning: 2024-11-25T14:42:26.660Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 6
File: fdm-app/app/components/blocks/field-map.tsx:0-0
Timestamp: 2024-11-25T14:42:26.660Z
Learning: In `fdm-app/app/components/blocks/field-map.tsx`, explicit cleanup of Mapbox GL resources is not necessary, as `react-map-gl` handles it automatically upon component unmount, and `MapRef` does not have a `remove` method.
Applied to files:
fdm-app/app/components/blocks/atlas/atlas-panels.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsx
📚 Learning: 2025-01-31T15:41:43.741Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/components/custom/atlas/atlas-panels.tsx:28-28
Timestamp: 2025-01-31T15:41:43.741Z
Learning: When handling different map event types in react-map-gl v7.1.8, use MapLayerMouseEvent for mouse events (which have the point property) and ViewStateChangeEvent for view state changes. Use a type guard like 'point' in evt to safely access event-specific properties.
Applied to files:
fdm-app/app/components/blocks/atlas/atlas-panels.tsx
📚 Learning: 2025-01-31T16:06:33.810Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/routes/farm.create.$b_id_farm.atlas.tsx:164-212
Timestamp: 2025-01-31T16:06:33.810Z
Learning: MapGL implementations should use the shared `useMapConfig` hook for configuration and `getLayerStyle` utility for consistent styling. The hook supports both interactive and non-interactive maps, handling bounds calculation and view state management.
Applied to files:
fdm-app/app/components/blocks/atlas/atlas-panels.tsx
📚 Learning: 2025-06-10T13:10:03.154Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 161
File: fdm-app/app/components/blocks/field-map.tsx:0-0
Timestamp: 2025-06-10T13:10:03.154Z
Learning: When facing prop name inconsistencies with react-map-gl (like mapboxAccessToken vs mapboxApiAccessToken), using different import statements can resolve the issue more elegantly than changing prop names across multiple files.
Applied to files:
fdm-app/app/components/blocks/atlas/atlas-panels.tsx
📚 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.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.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.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.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.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.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: 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-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.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.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsx
📚 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-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.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-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.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.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.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/routes/farm.$b_id_farm.$calendar.atlas.soil.tsxfdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsx
📚 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-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.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/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsxfdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsx
📚 Learning: 2025-01-31T15:06:35.764Z
Learnt from: SvenVw
Repo: SvenVw/fdm PR: 67
File: fdm-app/app/components/custom/atlas/atlas-sources.tsx:21-66
Timestamp: 2025-01-31T15:06:35.764Z
Learning: In react-map-gl components, when querying rendered features via map.queryRenderedFeatures(), the effect's dependency array must include any props that affect the map's rendered state (like source data) to ensure features are queried against the current map state.
Applied to files:
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._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 `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/routes/farm.create.$b_id_farm.$calendar.atlas.tsx
🧬 Code graph analysis (1)
fdm-app/app/routes/atlas.ahn-index.tsx (1)
fdm-app/app/integrations/ahn-cache.server.ts (1)
getAhnIndex(6-34)
🔇 Additional comments (17)
.changeset/silly-shoes-shake.md (1)
1-5: LGTM!The changeset correctly documents the TypeError fix as a patch release with a clear description of the issue being resolved.
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.soil.tsx (1)
2-2: LGTM!The import of
simplifyfrom @turf/turf is appropriate for geometry simplification to improve rendering performance..changeset/yummy-wombats-live.md (1)
1-5: LGTM!The changeset correctly documents the AggregateError fix with a clear explanation of the solution (chunked concurrency for HTTP/1.1 connection limits).
.changeset/witty-foxes-lose.md (1)
1-5: LGTM!The changeset correctly documents the comprehensive optimization work, covering chunked sampling concurrency, server-side caching, geometry simplification, and WMS zoom constraints.
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.fields._index.tsx (2)
2-2: LGTM!The import of
simplifyfrom @turf/turf is appropriate for geometry simplification.
87-90: Verify the necessity of the type assertion.The
as anytype assertion bypasses TypeScript's type safety. This is the same pattern observed in atlas.soil.tsx. Iffield.b_geometryis properly typed as a GeoJSON geometry, the assertion may be unnecessary.Please verify whether this type assertion is required. If it's due to a type incompatibility between fdm-core's geometry type and Turf.js expectations, consider adding proper type definitions instead of using
as any.fdm-app/app/routes/farm.create.$b_id_farm.$calendar.atlas.tsx (2)
10-10: LGTM!The import of
simplifyfrom @turf/turf is appropriate for geometry simplification.
152-155: Verify the necessity of the type assertion.The
as anytype assertion is used here as well. This pattern appears across all three atlas routes that were modified. Consider addressing this systematically across all affected files.Since this pattern appears in multiple files (soil.tsx, fields._index.tsx, and farm.create.tsx), please verify if there's a type incompatibility that can be resolved at the source (e.g., in fdm-core type definitions or by properly typing the simplify call).
fdm-app/app/components/blocks/atlas/atlas-panels.tsx (1)
42-42: Critical fix correctly implements the map style guard.The added check
!map.getStyle()ensures the map style is initialized before querying layers, preventing the TypeError described in issue #390. This guard correctly addresses the root cause wheremap.getLayer()internally accessesthis.style, which can be undefined during initialization.fdm-app/app/routes/atlas.ahn-index.tsx (2)
2-2: LGTM!The import correctly references the new AHN index caching utility.
4-11: Cache headers correctly align with server-side TTL.The 24-hour cache duration (
max-age=86400, s-maxage=86400) matches the server-side cache TTL defined inahn-cache.server.ts, ensuring consistent caching behavior across all layers. Thepublicdirective appropriately allows CDN caching for this static geospatial index data.fdm-app/app/integrations/ahn-cache.server.ts (2)
1-4: LGTM on the cache structure and TTL configuration.The module-scoped cache with 24-hour TTL is a reasonable choice for this use case. Note that this cache is instance-local, so in a multi-instance or serverless deployment, each instance will maintain its own cache. This is acceptable given the data is static and the TTL provides eventual consistency.
29-33: Good resilience pattern with stale cache fallback.Serving stale cache on fetch failure is a solid approach that prevents cascading failures when PDOK is unavailable. The error is logged appropriately before falling back.
fdm-app/app/routes/farm.$b_id_farm.$calendar.atlas.elevation.tsx (4)
7-7: LGTM on the simplify import.Using
@turf/turffor geometry simplification is appropriate and aligns with changes across other atlas routes mentioned in the summary.
340-393: LGTM on chunked concurrency implementation.The sequential chunk processing with
chunkSize = 4effectively mitigates the HTTP/1.1 connection limit issues mentioned in the PR objectives. Individual errors are caught and converted tonull, allowing the aggregation to proceed with partial results.
573-591: LGTM on WMS zoom constraints.The zoom-based rendering logic is consistent:
- WMS layer renders when
zoom < 13withmaxzoom={13}on the Source- COG tiles take over at
zoom >= 13- Legend and hover behavior align with this threshold
This provides a smooth transition between overview and detailed elevation data.
134-137: Geometry simplification looks reasonable.The tolerance of
0.00001(degrees, equivalent to approximately 1 meter at mid-latitudes) withhighQuality: trueis a good balance between reducing payload size and maintaining visual fidelity for field boundaries. This setting is consistently applied across all atlas routes.
Summary by CodeRabbit
Release Notes - Version 0.26.1
Bug Fixes
Performance & Stability
✏️ Tip: You can customize this high-level summary in your review settings.
Closes #390, #391 and #392