-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature - protected areas backend #194
base: develop
Are you sure you want to change the base?
Conversation
sentry upgrade (since older profiling setup has changed recently) ignored locally added .prettierignore (prevents local file formatting)
Trigger Commit
…b.com/rupamkairi/FireAlert into feature/vercel-development-deployment
This reverts commit 2632958.
+ different directUrl & shadowDatabaseUrl. + develop_baseline migration added.
+ model UserSiteRelation + enum SiteKind, UserSiteRealtionRole + columns Site.kind, Site.userId
…tected-areas--develop-fix
+ model UserSiteRelation + enum SiteKind, UserSiteRealtionRole + columns Site.kind, Site.userId
This reverts commit db454aa.
…siteRelation.user
Along goes some queries with it.
Update env.mjs for protected_planet apis envs made optional.
Preventing duplication on joinProtectedSite Join by (siteId or externalId i.e., WDPA_ID)
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe changes span across multiple parts of the project, including updates to ignore and configuration files, formatting and dependency upgrades in the React Native application, revisions to Android build settings, and significant server-side enhancements. Notable modifications include migration of main activity files from Java to Kotlin, adjustments in module import paths, new authentication hook logic in AppNavigator, updates to Prisma schema and migrations, and revised Sentry and environment configurations on the server. Changes
Sequence Diagram(s)sequenceDiagram
participant A as AppNavigator
participant H as useAuth0 Hook
participant F as Token Validator
participant R as refreshUserToken
participant S as State Manager
A->>H: Initialize authentication state
H->>F: Check token expiry via hasTimestampExpiredOrCloseToExpiry
alt Token valid
F-->>H: Token is valid
else Token expired/close to expiry
F-->>A: Token expired condition
A->>R: Invoke refreshUserToken (after connectivity check)
R-->>A: Return new token (or error)
alt Refresh successful
A->>S: Update credentials/state with new token
else Refresh failed
A->>S: Clear credentials & session
end
end
Poem
✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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 (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 16
🧹 Nitpick comments (31)
apps/nativeapp/Gemfile (2)
6-7
: Grammar Suggestion for Cocoapods Comment.
The comment on Cocoapods contains a minor grammatical issue. Consider revising “which break the build” to “which breaks the build” for clarity.
8-9
: Gem Ordering Suggestion.
Based on our RuboCop guidelines, gems should be listed in alphabetical order. Currently,'cocoapods'
appears before'activesupport'
, but alphabetically,'activesupport'
should come first.Apply the following diff to reorder the gems:
-gem 'cocoapods', '>= 1.13', '< 1.15' -gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' +gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' +gem 'cocoapods', '>= 1.13', '< 1.15'🧰 Tools
🪛 RuboCop (1.69.1)
[convention] 9-9: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem
activesupport
should appear beforecocoapods
.(Bundler/OrderedGems)
apps/nativeapp/ios/FireAlert.xcodeproj/xcshareddata/xcschemes/FireAlert.xcscheme (1)
44-44
: Verify if changing launch configuration to Debug was intentional.This change switches the launch configuration from Release to Debug mode, which seems unrelated to the PR's objectives of implementing protected areas backend features. While Debug mode is useful during development, it has performance implications and should typically be a temporary local change.
Consider:
- Is this change intentional or accidentally committed?
- Should this be kept in Release mode for consistency across the team?
apps/server/package.json (1)
28-29
: Sentry Dependency Version Upgrade
Upgrading"@sentry/nextjs"
and"@sentry/profiling-node"
to version"^8.47.0"
aligns with the updated Sentry configurations (e.g., usingnodeProfilingIntegration
in your config files). Ensure that all breaking changes introduced in Sentry v8 are accounted for in the existing error tracking and profiling setup.apps/nativeapp/.gitignore (2)
71-73
: Review the Turbo ignore rules for consistency.
The file now lists both.turbo
and/turbo/
. While this may be intentional (ignoring a file and a directory separately), consider if a recursive pattern (e.g.,**/turbo/
) might better cover cases where a Turbo folder appears at various levels.
77-83
: Yarn directory ignore with selective tracking.
Ignoring all.yarn/*
while explicitly unignoringpatches
,plugins
,releases
,sdks
, andversions
provides a granular approach to managing Yarn files. This configuration seems well thought out; please confirm that these exceptions cover all the necessary artifacts you intend to track.apps/nativeapp/app/screens/CreatePolygon/CreatePolygon.tsx (1)
30-30
: Naming Concern: Potential Shadowing of the Global "Map" ObjectThe import on line 30 now reads:
import Map from './MapMarking/Map';This name “Map” might shadow the global JavaScript
Map
object, which could lead to confusion or unintended behavior in certain contexts. Consider renaming the imported component to something likeCustomMap
or another descriptive name. Note that if you rename it, you'll need to update all its usages in the component accordingly.[static_analysis]
🧰 Tools
🪛 Biome (1.9.4)
[error] 30-30: Do not shadow the global "Map" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
apps/nativeapp/ios/Podfile (1)
38-44
: Consider enabling ccache for faster builds.The post_install configuration is well-structured. Consider uncommenting the
ccache_enabled
option to improve build times, especially in CI/CD pipelines.react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, - # :ccache_enabled => true + :ccache_enabled => true )🧰 Tools
🪛 RuboCop (1.69.1)
[convention] 42-42: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
apps/nativeapp/app/components/layerModal/LayerModal.tsx (1)
16-19
: Improve type safety and accessibility.Consider the following improvements:
- Replace
any
type with proper function type foronRequestClose
- Remove unnecessary optional chaining on static array items
- Add accessibility properties for better screen reader support
Apply these changes:
interface ILayerModalProps { visible: boolean; - onRequestClose?: any; + onRequestClose?: () => void; } // ... - <View key={item?.title}> + <View key={item.title}> <TouchableOpacity - onPress={() => selectMapLayer(item?.value)} + onPress={() => selectMapLayer(item.value)} + accessibilityRole="radio" + accessibilityState={{ selected: item.value === state }} + accessibilityLabel={`Select ${item.title} map layer`} style={styles.layerTextContainer}> <Text style={[ styles.layerText, - item?.value === state && { + item.value === state && { fontFamily: Typography.FONT_FAMILY_BOLD, color: Colors.GRADIENT_PRIMARY, }, ]}> - {item?.title} + {item.title} </Text> - {item?.value === state && <LayerCheck />} + {item.value === state && <LayerCheck />} </TouchableOpacity>Also applies to: 43-59
apps/server/src/server/api/routers/sample.json (1)
1-258
: Consider enhancing the test data and adding schema validation.The test data structure looks good but could benefit from:
- Schema validation using JSON Schema
- Additional test cases:
- Invalid geometries
- Edge cases (e.g., polygons crossing the international date line)
- Different polygon types (e.g., polygons with holes)
- Validation of coordinate ranges:
- Longitude: -180 to 180
- Latitude: -90 to 90
Consider adding a JSON Schema file to validate the data structure:
// sample.schema.json { "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "required": ["name", "country", "externalId", "geometry"], "properties": { "name": { "type": "string", "minLength": 1 }, "country": { "type": "string", "minLength": 1 }, "externalId": { "type": "string", "pattern": "^[A-Z]{2}[0-9]+$" }, "geometry": { "type": "object", "required": ["coordinates", "type"], "properties": { "type": { "const": "Polygon" }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "items": { "type": "number", "minimum": -180, "maximum": 180 }, "minItems": 2, "maxItems": 2 }, "minItems": 4 }, "minItems": 1 } } } } } }apps/server/src/server/api/routers/site.ts (5)
2-2
: Consider removing unused imports.
It appearsjoinProtectedSiteParams
is imported but only used in commented-out code. If it's not needed in the final implementation, removing it helps keep the import list clean.
12-13
: Enforce environment variable checks.
Before referencingNEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT
orNEXT_PUBLIC_PROTECTED_PLANET_API_KEY
, consider verifying that these env variables exist to avoid runtime issues.
112-156
: Clarify the DB query vs. placeholder usage.
Currently,findProtectedSites
returns results fromfilterByName(query)
while a DB retrieval is commented out. If this is a placeholder, encourage removing or refactoring the commented code to keep the codebase clean.
347-431
: Remove or document commented-out procedure.
The entirejoinProtectedSite
procedure is commented out. Keeping large commented blocks around can confuse future maintainers. If it's no longer needed, remove it; otherwise, add clear documentation explaining its future use.
439-439
: Implement or remove TODO.
A TODO remains to test the scenario when the returned array is empty or errors. This can be forgotten over time; consider proactively addressing it or opening an issue.apps/server/instrumentation.ts (1)
1-9
: Provide fallback or error handling for unrecognized runtimes.
Current logic only conditionally imports Sentry configs for"nodejs"
or"edge"
. Ifprocess.env.NEXT_RUNTIME
is missing or not set to these values, the function will silently do nothing. Consider handling or logging such cases.apps/server/src/pages/api/migrations/site_userId-to-siterelations.ts (1)
4-5
: Consider making batch parameters configurable.The hard-coded values for
BATCH_SIZE
andDELAY
should be configurable through environment variables to allow tuning based on the deployment environment.-const BATCH_SIZE = 2; -const DELAY = 1000; +const BATCH_SIZE = Number(process.env.MIGRATION_BATCH_SIZE ?? 2); +const DELAY = Number(process.env.MIGRATION_DELAY ?? 1000);apps/server/src/server/api/zodSchemas/site.schema.ts (2)
62-62
: Remove commented code.Remove the commented-out schema definition as it's no longer needed and could cause confusion.
-// export const createProtectedSiteSchema = protectedSiteSchema;
41-51
: Consider reusing the base site schema.The
protectedSiteSchema
largely duplicates the structure ofcreateSiteSchema
. Consider creating a base schema and extending it for specific use cases.+const baseSiteSchema = z.object({ + type: z.enum(["Point", "Polygon", "MultiPolygon"]), + name: nameSchema.optional(), + geometry: z.union([PointSchema, PolygonSchema, MultiPolygonSchema]), + radius: z.number().optional().default(0), +}).refine((obj) => obj.type === obj.geometry.type, { + message: "geometry type does not match the specified type", + path: ["geometry.type", "type"], +}); -export const protectedSiteSchema = z.object({ - type: z.enum(["Point", "Polygon", "MultiPolygon"]), - name: nameSchema.optional(), - geometry: z.union([PointSchema, PolygonSchema, MultiPolygonSchema]), - radius: z.number().optional().default(0), +export const protectedSiteSchema = baseSiteSchema.extend({ externalId: z.string().optional(), isActive: z.boolean().optional(), -}).refine((obj) => obj.type === obj.geometry.type, { - message: "geometry type does not match the specified type", - path: ["geometry.type", "type"], });apps/server/prisma/migrations/20250107025619_protected_areas_02/migration.sql (1)
1-2
: Consider adding an index for the externalId column.If this column will be used in queries (e.g., looking up sites by externalId), consider adding an index to improve query performance. Additionally, if the externalId is meant to be unique, consider adding a unique constraint.
-- AlterTable ALTER TABLE "Site" ADD COLUMN "externalId" TEXT; +-- CreateIndex +CREATE INDEX "Site_externalId_idx" ON "Site"("externalId");apps/server/src/Services/Notifications/CreateNotifications.ts (1)
211-257
: Consider pagination for large result sets.The query fetches all unprocessed alerts without pagination, which could lead to memory issues with large datasets.
Consider implementing cursor-based pagination:
const unprocessedAlerts = await prisma.siteAlert.findMany({ where: { isProcessed: false, deletedAt: null, eventDate: { gte: new Date(new Date().getTime() - 24 * 60 * 60 * 1000), }, }, + take: 100, // Process in smaller batches + cursor: cursor ? { id: cursor } : undefined, select: { // ... existing select }, orderBy: [{ siteId: 'asc' }, { eventDate: 'asc' }] });apps/nativeapp/ios/FireAlert/PrivacyInfo.xcprivacy (1)
41-44
: Consider documenting data collection practices.While tracking is disabled and no data types are collected, it's good practice to document this decision for future reference.
apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainApplication.kt (1)
13-13
: Remove unused import and consider package autolink.The
SplashScreenReactPackage
is imported but not used in the package list. Also, the comment about manual package addition could be enhanced with autolink instructions.-import org.devio.rn.splashscreen.SplashScreenReactPackage; override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply { - // Packages that cannot be autolinked yet can be added manually here, for example: + // Packages that cannot be autolinked should be added here after following + // the autolinking guide at: https://rnfirebase.io/ }Also applies to: 20-22
apps/nativeapp/app/routes/AppNavigator.tsx (4)
3-3
: Remove unused default import.
If you're only using theuseAuth0
hook, you could remove the defaultAuth0
import to keep imports concise.-import Auth0, { useAuth0 } from 'react-native-auth0'; +import { useAuth0 } from 'react-native-auth0';
60-61
: Enhance error handling in callbacks.
Currently,onSuccess
andonFail
are empty. Consider adding logging or logic to handle success/failure for configuration data calls.
72-84
: Make token expiry threshold configurable.
Hardcoding 5 hours inhasTimestampExpiredOrCloseToExpiry
may reduce flexibility during testing or in different environments. Extract the 5-hour threshold into a constant or configuration value.
103-160
: Improve error messages & unify final steps.
Youthrow 'error'
multiple times when unexpected conditions arise. Using more descriptive error messages would aid debugging. For example:-throw 'error' +throw new Error('Missing refreshToken or invalid token details')Additionally, you may unify
SplashScreen.hide()
calls and ensure the final state gets set just once to avoid unexpected states if multiple conditions trigger consecutive calls.apps/nativeapp/app/screens/Login/Login.tsx (1)
18-25
: Consistent hook-based approach.
These imports reflect a clear transition to the hooks approach. Ensure any old Auth0 constructor usage is fully removed throughout the app to avoid confusion.apps/nativeapp/app/screens/Home/Home.tsx (3)
221-230
: Error handling in TRPC query.
You display'something went wrong'
as a toast on error. Consider including more details (likeerror.message
) for quicker triage without exposing sensitive data.
257-299
: Cache updates are done well.
Manually updatingsite
andalert
data after delete avoids a full refetch, improving performance. Just be cautious if the site or alert has untracked side effects in other queries.
483-495
: Asynchronous logout approach.
ChainingclearCredentials()
andclearSession()
is correct, but consider a more descriptive error log message. Also note thatconsole.log("Error ocurred")
is misspelled.-console.log("Error ocurred", error) +console.log("Error occurred", error)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
apps/nativeapp/Gemfile.lock
is excluded by!**/*.lock
apps/nativeapp/android/gradle/wrapper/gradle-wrapper.jar
is excluded by!**/*.jar
apps/nativeapp/ios/Podfile.lock
is excluded by!**/*.lock
apps/nativeapp/package-lock.json
is excluded by!**/package-lock.json
package-lock.json
is excluded by!**/package-lock.json
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
📒 Files selected for processing (70)
.gitignore
(1 hunks)Readme.MD
(2 hunks)apps/nativeapp/.eslintrc.js
(1 hunks)apps/nativeapp/.gitignore
(3 hunks)apps/nativeapp/.node-version
(0 hunks)apps/nativeapp/.ruby-version
(0 hunks)apps/nativeapp/Gemfile
(1 hunks)apps/nativeapp/__tests__/App-test.tsx
(1 hunks)apps/nativeapp/android/app/build.gradle
(3 hunks)apps/nativeapp/android/app/src/debug/AndroidManifest.xml
(1 hunks)apps/nativeapp/android/app/src/debug/java/eco/pp/firealert/ReactNativeFlipper.java
(0 hunks)apps/nativeapp/android/app/src/debug/res/values/strings.xml
(1 hunks)apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainActivity.java
(0 hunks)apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainActivity.kt
(1 hunks)apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainApplication.java
(0 hunks)apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainApplication.kt
(1 hunks)apps/nativeapp/android/app/src/main/res/drawable/rn_edit_text_material.xml
(1 hunks)apps/nativeapp/android/app/src/main/res/values/strings.xml
(1 hunks)apps/nativeapp/android/app/src/release/java/eco/pp/firealert/ReactNativeFlipper.java
(0 hunks)apps/nativeapp/android/app/src/release/java/eco/pp/firealert/res/values/strings.xml
(1 hunks)apps/nativeapp/android/build.gradle
(3 hunks)apps/nativeapp/android/gradle.properties
(1 hunks)apps/nativeapp/android/gradle/wrapper/gradle-wrapper.properties
(1 hunks)apps/nativeapp/android/gradlew
(4 hunks)apps/nativeapp/android/gradlew.bat
(4 hunks)apps/nativeapp/android/settings.gradle
(1 hunks)apps/nativeapp/app/App.tsx
(1 hunks)apps/nativeapp/app/components/index.tsx
(1 hunks)apps/nativeapp/app/components/layerModal/LayerModal.tsx
(1 hunks)apps/nativeapp/app/global/reducers/mapLayers.tsx
(1 hunks)apps/nativeapp/app/routes/AppNavigator.tsx
(2 hunks)apps/nativeapp/app/routes/stack/CommonStack.tsx
(1 hunks)apps/nativeapp/app/routes/stack/index.tsx
(1 hunks)apps/nativeapp/app/screens/CreatePolygon/CreatePolygon.tsx
(1 hunks)apps/nativeapp/app/screens/CreatePolygon/MapMarking/Map.tsx
(1 hunks)apps/nativeapp/app/screens/CreatePolygon/Markers/index.tsx
(1 hunks)apps/nativeapp/app/screens/Home/Home.tsx
(27 hunks)apps/nativeapp/app/screens/Login/Login.tsx
(3 hunks)apps/nativeapp/app/screens/Settings/Settings.tsx
(2 hunks)apps/nativeapp/app/screens/index.tsx
(1 hunks)apps/nativeapp/app/screens/selectLocation/SelectLocation.tsx
(1 hunks)apps/nativeapp/babel.config.js
(1 hunks)apps/nativeapp/index.js
(1 hunks)apps/nativeapp/ios/FireAlert.xcodeproj/project.pbxproj
(27 hunks)apps/nativeapp/ios/FireAlert.xcodeproj/xcshareddata/xcschemes/FireAlert.xcscheme
(1 hunks)apps/nativeapp/ios/FireAlert/AppDelegate.mm
(1 hunks)apps/nativeapp/ios/FireAlert/Info.plist
(3 hunks)apps/nativeapp/ios/FireAlert/PrivacyInfo.xcprivacy
(1 hunks)apps/nativeapp/ios/FireAlertTests/Info.plist
(1 hunks)apps/nativeapp/ios/Podfile
(2 hunks)apps/nativeapp/jest.config.js
(1 hunks)apps/nativeapp/metro.config.js
(1 hunks)apps/nativeapp/package.json
(3 hunks)apps/nativeapp/tsconfig.json
(1 hunks)apps/server/instrumentation.ts
(1 hunks)apps/server/package.json
(1 hunks)apps/server/prisma/migrations/20250103065810_develop_baseline/migration.sql
(1 hunks)apps/server/prisma/migrations/20250105034127_protected_areas_01/migration.sql
(1 hunks)apps/server/prisma/migrations/20250107025619_protected_areas_02/migration.sql
(1 hunks)apps/server/prisma/schema.prisma
(5 hunks)apps/server/sentry.edge.config.ts
(2 hunks)apps/server/sentry.server.config.ts
(2 hunks)apps/server/src/Services/Notifications/CreateNotifications.ts
(1 hunks)apps/server/src/env.mjs
(1 hunks)apps/server/src/pages/api/migrations/site_userId-to-siterelations.ts
(1 hunks)apps/server/src/server/api/routers/sample-utils.ts
(1 hunks)apps/server/src/server/api/routers/sample.json
(1 hunks)apps/server/src/server/api/routers/site.ts
(6 hunks)apps/server/src/server/api/trpc.ts
(1 hunks)apps/server/src/server/api/zodSchemas/site.schema.ts
(2 hunks)
💤 Files with no reviewable changes (6)
- apps/nativeapp/.node-version
- apps/nativeapp/.ruby-version
- apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainActivity.java
- apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainApplication.java
- apps/nativeapp/android/app/src/debug/java/eco/pp/firealert/ReactNativeFlipper.java
- apps/nativeapp/android/app/src/release/java/eco/pp/firealert/ReactNativeFlipper.java
✅ Files skipped from review due to trivial changes (20)
- apps/nativeapp/jest.config.js
- apps/nativeapp/android/app/src/main/res/values/strings.xml
- apps/nativeapp/tsconfig.json
- apps/nativeapp/app/screens/selectLocation/SelectLocation.tsx
- Readme.MD
- .gitignore
- apps/nativeapp/app/routes/stack/CommonStack.tsx
- apps/nativeapp/index.js
- apps/nativeapp/.eslintrc.js
- apps/nativeapp/android/app/src/release/java/eco/pp/firealert/res/values/strings.xml
- apps/nativeapp/app/global/reducers/mapLayers.tsx
- apps/nativeapp/app/App.tsx
- apps/nativeapp/android/app/src/main/res/drawable/rn_edit_text_material.xml
- apps/nativeapp/android/app/src/debug/res/values/strings.xml
- apps/nativeapp/app/screens/CreatePolygon/Markers/index.tsx
- apps/nativeapp/app/routes/stack/index.tsx
- apps/nativeapp/app/screens/CreatePolygon/MapMarking/Map.tsx
- apps/nativeapp/app/screens/index.tsx
- apps/nativeapp/app/components/index.tsx
- apps/nativeapp/app/screens/Settings/Settings.tsx
🧰 Additional context used
🪛 RuboCop (1.69.1)
apps/nativeapp/Gemfile
[convention] 9-9: Gems should be sorted in an alphabetical order within their section of the Gemfile. Gem activesupport
should appear before cocoapods
.
(Bundler/OrderedGems)
apps/nativeapp/ios/Podfile
[convention] 6-6: Put a comma after the last item of a multiline array.
(Style/TrailingCommaInArrayLiteral)
[convention] 42-42: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
🪛 Biome (1.9.4)
apps/nativeapp/app/screens/Home/Home.tsx
[error] 319-319: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
apps/nativeapp/app/screens/CreatePolygon/CreatePolygon.tsx
[error] 30-30: Do not shadow the global "Map" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
🔇 Additional comments (83)
apps/nativeapp/Gemfile (1)
4-4
: Ruby Version Specification Clear.
Specifying the Ruby version directly as">= 2.6.10"
in the Gemfile ensures consistency in development environments.apps/server/package.json (1)
20-21
: New Prisma Studio and DB Generate Scripts
The addition of the"db:generate": "dotenv -e ../../.env npx prisma generate"
and"db:studio": "dotenv -e ../../.env npx prisma studio"
scripts is a useful enhancement for managing Prisma operations. Please verify that the relative path../../.env
correctly points to your environment file in all deployment environments and doesn’t conflict with other configurations.apps/nativeapp/.gitignore (3)
23-23
: Enhance recursive Xcode env file ignore.
Changing the rule to**/.xcode.env.local
broadens the ignore to capture this file in any subdirectory, which is useful if multiple Xcode projects or configurations exist under different folders.
60-60
: Apply recursive pattern for Pods directories.
The updated pattern**/Pods/
ensures that Pods folders are ignored regardless of their location in the repository tree. This is especially beneficial in projects where iOS modules may be nested.
74-76
: Clarify testing coverage ignore rule.
The addition of the# testing
block with/coverage
is clear and helps segregate test report files. Just verify that the/coverage
path correctly targets the intended coverage reports relative to this directory structure.apps/nativeapp/app/screens/CreatePolygon/CreatePolygon.tsx (1)
36-38
: Import Path Update for Permission AlertsThe import statement now uses updated casing:
import {PermissionBlockedAlert, PermissionDeniedAlert} from '../Home/PermissionAlert/LocationPermissionAlerts';This change aligns the file structure with standardized naming conventions. Please verify that the new path matches the actual file locations within your project.
apps/nativeapp/ios/Podfile (2)
1-6
: LGTM! Improved dependency resolution.The new Node-based resolution for react_native_pods.rb is a better approach that supports monorepo setups with dependency hoisting.
🧰 Tools
🪛 RuboCop (1.69.1)
[convention] 6-6: Put a comma after the last item of a multiline array.
(Style/TrailingCommaInArrayLiteral)
23-23
: LGTM! Robust path resolution.Using
Pod::Config.instance.installation_root
provides a more reliable way to resolve the app path.apps/nativeapp/android/settings.gradle (1)
28-28
: Plugin Include Path Update VerificationThe update of the React Native Gradle plugin inclusion from
react-native-gradle-plugin
to@react-native/gradle-plugin
aligns with the namespace changes noted in the migration efforts. Please verify that all downstream configurations and dependencies are compatible with this new path.apps/nativeapp/app/components/layerModal/LayerModal.tsx (1)
13-13
:✅ Verification successful
Verify import path casing change across the codebase.
The change from
types
toTypes
in the import path could break imports on case-sensitive systems.Let's verify the consistency of this change across the codebase:
🏁 Script executed:
#!/bin/bash # Search for any remaining imports from the old path rg "from ['\"].*actions/types['\"]" # Search for imports using the new path to confirm adoption rg "from ['\"].*actions/Types['\"]"Length of output: 300
Confirmed import path update across the codebase.
The change from using
actions/types
toactions/Types
has been consistently applied:
- In
apps/nativeapp/app/components/layerModal/LayerModal.tsx
, the import now correctly uses../../global/actions/Types
.- In
apps/nativeapp/app/global/reducers/mapLayers.tsx
, the import has been updated to../actions/Types
.This should prevent issues on case-sensitive systems. No further changes related to the import path are required at this time.
apps/nativeapp/metro.config.js (2)
1-5
: LGTM! Well-structured Metro setup for monorepo.The imports and initial setup follow best practices for configuring Metro in a monorepo environment.
32-32
: LGTM! Proper configuration export using recommended pattern.The configuration is correctly exported using
mergeConfig
to combine default Metro settings with custom overrides.apps/nativeapp/babel.config.js (2)
3-20
: LGTM! Comprehensive module resolution configuration.The module-resolver plugin configuration is well-structured with:
- Appropriate root directory setting for monorepo setup
- Complete coverage of file extensions including platform-specific files
2-2
:✅ Verification successful
Verify the React Native Babel preset version.
The change to
@react-native/babel-preset
aligns with React Native's move to scoped packages.
🌐 Web query:
What is the latest recommended Babel preset for React Native? Is @react-native/babel-preset the current standard?
💡 Result:
The latest recommended Babel preset for React Native is
@react-native/babel-preset
, which has become the standard since React Native v0.76 and later[4][6]. This preset replaces older packages likebabel-preset-react-native
(deprecated since 2018)[1] andmetro-react-native-babel-preset
[9].Key Details:
Current Standard:
@react-native/babel-preset
(v0.77.1 as of February 2025)[4]
- Used by default in React Native projects
- Handles JSX transformation, Flow/TypeScript syntax stripping, and other React Native-specific optimizations[4][7]
Configuration:
Add to yourbabel.config.js
:module.exports = { presets: ['module:@react-native/babel-preset'], };This replaces older formats like
.babelrc
[4][6].Expo Compatibility:
Expo projects usebabel-preset-expo
, which extends@react-native/babel-preset
while adding web/tree-shaking support[2].Deprecated Presets:
Package Replacement Status babel-preset-react-native
@react-native/babel-preset
Deprecated[1] metro-react-native-babel-preset
@react-native/babel-preset
Merged[4][9] For new projects, use
@react-native/babel-preset
unless using Expo (wherebabel-preset-expo
is preferred)[2][4]. Existing projects should migrate to avoid compatibility issues with newer React Native versions[1][8].Citations:
- 1: https://www.npmjs.com/package/babel-preset-react-native
- 2: https://docs.expo.dev/versions/latest/config/babel/
- 3: https://babeljs.io/docs/v7-migration
- 4: https://www.npmjs.com/package/@react-native/babel-preset
- 5: https://classic.yarnpkg.com/en/package/metro-react-native-babel-preset
- 6: https://reactnative.dev/docs/typescript
- 7: https://babeljs.io/docs/babel-preset-react
- 8: cannot find module babel-preset-react-native facebook/metro#431
- 9: Update new project template to metro-react-native-babel-preset facebook/react-native#20327
- 10: https://github.com/skevy/babel-preset-react-native-stage-0
PRESET Update Verified
The change in
apps/nativeapp/babel.config.js
on line 2 to use['module:@react-native/babel-preset']
is correct. This preset is confirmed as the current standard for React Native (adopted since v0.76) and aligns with the latest recommendations.
- The configuration now aligns with React Native’s move to scoped packages.
- No further modifications are required based on this update.
apps/server/src/server/api/routers/sample.json (1)
1-258
: Verify the coordinate system and projection.The coordinates appear to be in decimal degrees, but it's important to:
- Document the coordinate reference system (CRS) being used
- Ensure consistency with the frontend mapping library
- Consider adding a
crs
property to the GeoJSON structureRun this script to validate coordinate ranges and detect potential issues:
#!/usr/bin/env python3 import json import sys def validate_coordinates(coords): for ring in coords: for point in ring: lon, lat = point if not (-180 <= lon <= 180): print(f"Invalid longitude: {lon}") if not (-90 <= lat <= 90): print(f"Invalid latitude: {lat}") def main(): with open('apps/server/src/server/api/routers/sample.json') as f: data = json.load(f) for feature in data: coords = feature['geometry']['coordinates'] print(f"Validating {feature['name']}...") validate_coordinates(coords) # Verify polygon closure for ring in coords: if ring[0] != ring[-1]: print(f"Polygon not closed in {feature['name']}") if __name__ == '__main__': main()apps/nativeapp/__tests__/App-test.tsx (1)
7-9
: LGTM! Import updates align with project restructuring.The changes improve type safety by explicitly importing Jest's
it
function and maintain consistency with the project's directory restructuring.apps/nativeapp/package.json (4)
6-6
: Android build command syntax updated.The change from
--variant
to--mode
reflects updates in React Native CLI. This is the correct syntax for React Native 0.74.x.Also applies to: 12-12
90-92
: Node.js version requirement added.The addition of the engines field ensures compatibility with React Native 0.74.x which requires Node.js >= 18.
45-47
:❓ Verification inconclusive
Verify compatibility with React Native 0.74.3 upgrade.
Major version upgrade from 0.71.1 to 0.74.3 requires careful testing. Please ensure:
- All native modules are compatible
- Breaking changes are addressed
- Deprecated APIs are updated
Run this script to check for potential compatibility issues:
🏁 Script executed:
#!/bin/bash # Description: Check for compatibility issues with React Native 0.74.3 # Check for outdated native dependencies npm outdated | grep "react-native" # Look for potential breaking changes in native code rg -l "import.*react.native" | grep -E "\.(java|kt|m|mm|h)$"Length of output: 97
Manual Compatibility Check Needed for React Native 0.74.3 Upgrade
The automated check returned no output, which might indicate no immediate issues were detected. However, given the major version upgrade from React Native 0.71.1 to 0.74.3, please perform a thorough manual review to ensure:
- All native modules are confirmed to be compatible.
- Any breaking changes in native code have been addressed.
- All deprecated APIs have been updated accordingly.
Please verify these aspects carefully across the codebase before finalizing the upgrade.
71-74
:✅ Verification successful
Migration to new React Native tooling packages.
The switch from @react-native-community to @react-native packages aligns with React Native's new tooling structure.
Please verify the migration by checking the official React Native 0.74 upgrade guide:
🌐 Web query:
What are the breaking changes in React Native 0.74 regarding tooling packages?
💡 Result:
React Native 0.74 introduces several significant breaking changes regarding tooling packages:
1. Removal of Flipper React Native Plugin
- The native Flipper libraries and setup code have been completely removed from new React Native projects[1][2][3]
- This eliminates ~4MB of dependencies and simplifies local setup[1][3]
- Impact: Existing debugging workflows using Flipper will break unless manually re-integrated
- Migration:
Developers must follow Flipper's Android and iOS integration guides manually[1]# To preserve Flipper in existing apps: # Ignore relevant diff lines when upgrading via Upgrade Helper2. Recommended Debugging Tool Changes
- New Defaults: Hermes Debugger remains primary recommendation[1]
- Experimental Debugger: Now default in Expo (early preview)[1]
- Native Alternatives:
| Feature | Android Studio Tools | Xcode Tools | |------------------|----------------------|-------------------| | Layout Inspection| Layout Inspector | Xcode View Debugger | | Network | Profiler | Instruments | ```[1]3. Yarn 3 as Default Package Manager
- New projects now use Yarn 3 instead of Yarn Classic[1][2][4]
- Key Differences:
- Zero-install architecture
- Improved workspace management
- Strict dependency resolution[4]
- Existing projects remain unaffected unless explicitly migrated[4]
These changes aim to reduce app size (13% smaller initial builds)[1], improve debugging performance, and modernize dependency management. Developers relying on Flipper should plan for manual re-integration or transition to recommended alternatives[1][3].
Citations:
- 1: https://reactnative.dev/blog/2024/04/22/release-0.74
- 2: https://javascript.plainenglish.io/react-native-0-74-what-is-new-and-what-does-that-mean-6705fbba4167
- 3: https://dev.to/sathishskdev/unveiling-react-native-074-whats-inside-the-latest-release-1nn3
- 4: https://writtify.com/upgrade-react-native-to-0-74-benefits/
- 5: https://github.com/facebook/react-native/blob/main/CHANGELOG.md
- 6: https://reactnativeexpert.com/blog/react-native-0-72-vs-0-73-vs-0-74/
- 7: https://react-native-community.github.io/upgrade-helper/?from=0.73.7&to=0.74.0
- 8: https://react-native-community.github.io/upgrade-helper/?from=0.73.8&to=0.74.2
- 9: https://reactnative.dev/versions
Migration Verified: React Native 0.74 Tooling Packages
The tooling packages in
apps/nativeapp/package.json
have been correctly updated from the legacy@react-native-community
versions to the new@react-native
packages, in line with the React Native 0.74 upgrade guide. Note that React Native 0.74 also introduces notable changes—such as the removal of native Flipper integration and a shift to Yarn 3 by default—which may affect debugging or dependency management setups if your project relies on those features. Overall, the migration regarding these packages is correct, but please ensure any additional configurations (e.g., for custom Flipper setups) are verified as needed.apps/server/src/server/api/routers/site.ts (2)
8-9
: Validate the utility functions' behavior.
While importingfilterByName
andgetByExternalId
, ensure these functions handle edge cases and large inputs gracefully, especially if they're critical for site lookups.
517-552
: Check for soft-deletions and unify naming.
getProtectedSites
currently does not filter out sites withdeletedAt
set. If that is a requirement, update the query accordingly. Also, consider renaming_siteRelation
tositeRelations
for clarity.apps/server/sentry.server.config.ts (1)
7-7
: Confirm correct profiling integration usage.
UsingnodeProfilingIntegration
replaces the olderProfilingIntegration
. Verify that this integration provides the expected performance metrics in the server-based environment.Also applies to: 21-21
apps/server/sentry.edge.config.ts (1)
8-8
:✅ Verification successful
Verify Sentry profiling package version compatibility.
The change from
ProfilingIntegration
class tonodeProfilingIntegration
function suggests an API update. Let's verify the compatibility with the current Sentry package version.Also applies to: 22-22
🌐 Web query:
What is the latest version of @sentry/profiling-node and when was ProfilingIntegration deprecated in favor of nodeProfilingIntegration?
💡 Result:
The latest version of
@sentry/profiling-node
is 9.1.0 as of February 13, 2025[4][7].The
ProfilingIntegration
class was deprecated in Sentry JavaScript SDK v8 and replaced with the functionalnodeProfilingIntegration()
[3][6]. This change was part of a broader migration from class-based integrations to function-based ones in Sentry's v8 release[3][5][6].Key details:
- Deprecation timeline:
- Class-based integrations like
new ProfilingIntegration()
were deprecated starting in v7.100.0[5][6]- Fully removed in v8 with replacement by
nodeProfilingIntegration()
[3][4]- Migration example:
// v7 integrations: [new ProfilingIntegration()] // v8+ integrations: [nodeProfilingIntegration()]- Compatibility: Requires
@sentry/[email protected]
or newer[1][9]The change aligns with Sentry's effort to simplify integration APIs and improve tree-shaking capabilities in modern JavaScript environments[3][5]. Developers using profiling must now use the functional integration format with Sentry v8+[4][10].
Citations:
- 1: https://docs.sentry.io/platforms/javascript/guides/node/profiling/node-profiling/
- 2: https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md
- 3: https://github.com/getsentry/sentry-javascript/blob/develop/docs/migration/v7-to-v8.md
- 4: https://www.npmjs.com/package/@sentry/profiling-node
- 5: https://docs.sentry.io/platforms/javascript/migration/v7-to-v8/v7-deprecations/
- 6: https://docs.sentry.io/platforms/javascript/guides/node/migration/v7-to-v8/v7-deprecations/
- 7: https://www.npmjs.com/package/@sentry/profiling-node/v/0.0.0-alpha.2
- 8: https://gitlab.com/gitlab-org/gitlab/-/issues/435791
- 9: https://docs.sentry.io/platforms/javascript/guides/node/profiling/node-profiling
- 10: https://docs.sentry.io/platforms/javascript/guides/node/profiling/
Sentry Profiling Integration Verified
- The use of
nodeProfilingIntegration
inapps/server/sentry.edge.config.ts
is consistent with Sentry's migration in SDK v8, where the class-basedProfilingIntegration
was replaced by the function-based API.- The current implementation aligns with the latest @sentry/profiling-node version (9.1.0 as of February 13, 2025) and its requirements.
- Ensure that the corresponding
@sentry/node
dependency is at least version 7.44.1 to maintain overall compatibility.No further changes are needed in lines 8 or 22.
apps/server/src/Services/Notifications/CreateNotifications.ts (1)
237-252
: LGTM: Good addition of siteRelations query.The inclusion of siteRelations in the query ensures we can access alert methods for protected sites.
apps/server/prisma/migrations/20250105034127_protected_areas_01/migration.sql (5)
1-3
: Enum Creation for SiteKind is Correct
The new enumSiteKind
is defined with appropriate values. No issues found here.
4-6
: Enum Creation for SiteRelationRole is Correct
The new enumSiteRelationRole
correctly includes the values'ROLE_ADMIN'
and'ROLE_VIEWER'
.
7-10
: Validate Table Alterations on "Site" Table
The alteration correctly adds the"kind"
column with a default value and drops the NOT NULL constraint on"userId"
. Please ensure that the application logic gracefully handles potential nulls foruserId
now, especially where it might have been assumed to always contain a value.
11-23
: New Table "SiteRelation" is Well-Structured
The creation of theSiteRelation
table is consistent with the intended data relationships. Note that theupdatedAt
column relies on application/trigger logic for automatic updates, so verify that such behavior is in place if required.
24-29
: Foreign Key Constraints Added Appropriately
The foreign keys linkingSiteRelation.siteId
toSite.id
andSiteRelation.userId
toUser.id
with cascading actions are correctly defined, ensuring referential integrity.apps/server/prisma/schema.prisma (6)
5-10
: Datasource Update for Shadow Database
The new line settingshadowDatabaseUrl = env("DATABASE_URL_NON_POOLING_SHADOW")correctly configures the shadow database. Please double-check that the environment variable is defined correctly in all deployment contexts.
12-33
: Enhancement in the User Model: Addition ofsiteRelations
Adding the fieldsiteRelations SiteRelation[]in the
User
model properly reflects the new relationship. This change will enable queries on all site relations associated with a user.
66-92
: Modifications in the Site Model for Protected Areas
Several important changes include:
- Making
userId
optional (line 80) and updating the corresponding relation (line 87) to be optional.- Introducing new fields
kind
(line 88) with a default ofUSER_SITE
andexternalId
(line 90).- Adding the relation
siteRelations
(line 91).These modifications are in line with supporting protected site functionalities. However, ensure that all business logic references are updated to handle cases where a site may not have an associated user, and that the
kind
field is consistently interpreted across the application.
160-165
: Minor Formatting Adjustments in the Stats Model
The changes in theStats
model appear to be formatting-related with no impact on functionality.
167-177
: New Model "SiteRelation" is Consistent with the Migration
TheSiteRelation
model aligns well with the migration script. It defines all necessary fields and relationships betweenSite
andUser
. Consider verifying if the handling of theupdatedAt
field (via Prisma’s@updatedAt
or external logic) meets your requirements for timestamp updates on modifications.
197-205
: New Enums for SiteKind and SiteRelationRole in Prisma Schema
The enumsSiteKind
andSiteRelationRole
are correctly defined in the Prisma schema and match the corresponding SQL definitions.apps/nativeapp/ios/FireAlert.xcodeproj/project.pbxproj (6)
15-16
: NewPrivacyInfo.xcprivacy
references.Multiple entries were added to reference
PrivacyInfo.xcprivacy
. This file typically stores app privacy configuration and usage descriptions. Please ensure:
- The file is correctly placed under the project's structure.
- The app's Info.plist also references or describes all new privacy usage keys if they are required by Apple guidelines.
- You have verified the final build includes the file properly in the resulting bundle.
Also applies to: 75-75, 79-79, 161-162, 384-384
26-26
: New or updated framework references.These references add or update linkage for
libPods-FireAlert-FireAlertTests.a
,libPods-FireAlert.a
, andlibPods-OneSignalNotificationServiceExtension.a
. Ensure your Pod install process is up to date and that all required frameworks are correctly included in test and app targets. Missing or incorrect linkages can lead to linker errors or runtime crashes.Also applies to: 30-30, 106-106, 111-111, 119-119, 127-127, 171-173
243-248
: New Pod configuration file references.Several lines reference newly added or updated xcconfig files:
Pods-FireAlert.debug.xcconfig
Pods-FireAlert.release.xcconfig
Pods-FireAlert-FireAlertTests.debug.xcconfig
Pods-FireAlert-FireAlertTests.release.xcconfig
Pods-OneSignalNotificationServiceExtension.debug.xcconfig
Pods-OneSignalNotificationServiceExtension.release.xcconfig
Confirm that these files exist under the specified paths, especially within “Target Support Files/...”. If any are missing or incorrectly named, the build might fail.
Also applies to: 594-594, 621-621, 645-645, 681-681, 713-713
602-602
: Raised iOS deployment target to 13.4.The
IPHONEOS_DEPLOYMENT_TARGET
was updated to13.4
in multiple build configurations. This may exclude users on older iOS versions. Verify that dropping support for older iOS devices is intentional, and ensure your app’s user base is prepared.Also applies to: 626-626, 835-835, 917-917
653-653
: Version increments.
CURRENT_PROJECT_VERSION = 7
andMARKETING_VERSION = 1.3
suggest you are introducing a new app version. Ensure corresponding app metadata (App Store Connect release notes, marketing channels) also reflects these changes.Also applies to: 663-663, 688-688, 697-697
412-412
: Pod-related shell script updates.Lines referencing
[CP] Check Pods Manifest.lock
,[CP] Copy Pods Resources
, and[CP] Embed Pods Frameworks
have been updated. Verify these scripts run successfully within your CI/CD environment. If any environment variables (e.g.,PODS_ROOT
orPODS_PODFILE_DIR_PATH
) change, the scripts might fail.Also applies to: 414-414, 421-424, 427-427, 429-429, 442-442, 446-446, 450-450, 459-459, 463-463, 467-467, 470-470, 495-495, 498-498, 502-502, 506-506, 510-510, 515-515, 519-519, 523-523, 541-541
apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainActivity.kt (2)
1-9
: Successful Kotlin migration.Migrating
MainActivity
from Java to Kotlin is a good modernization step. The package declaration and imports look fine. Confirm you have the Kotlin Gradle plugin applied in yourbuild.gradle
and that your team is aligned on Kotlin usage for future Android development.
14-26
: Splash screen and React setup.
- The splash screen is shown before the call to
super.onCreate()
, which is recommended to display the splash instantly.getMainComponentName()
returning"FireAlert"
aligns with your JavaScript entry point.createReactActivityDelegate()
uses the Fabric architecture flag. Ensure that your React Native version supports the new architecture for a smooth upgrade experience.apps/nativeapp/ios/FireAlertTests/Info.plist (2)
11-23
: Added Auth0 URL scheme.The
CFBundleURLTypes
and associatedauth0
scheme indicate an integration with Auth0 or a similar authentication mechanism. Double-check that your AppDelegate or SceneDelegate (if using iOS 13+) properly handles URL callbacks to complete the authentication flow.
31-31
: Updated short version string and build number.
CFBundleShortVersionString
was bumped to1.3
andCFBundleVersion
to6
. Verify these updates match your app’s overall versioning strategy and that you keep them consistent across Android and iOS builds if needed.Also applies to: 35-35
apps/nativeapp/android/app/src/main/java/eco/pp/firealert/MainApplication.kt (1)
35-42
: LGTM! Proper initialization sequence.The
onCreate
implementation correctly initializes SoLoader and conditionally loads the new architecture.apps/nativeapp/ios/FireAlert/AppDelegate.mm (1)
31-43
: LGTM! Clean bundle URL handling.The implementation properly separates bundle URL logic and handles both debug and release paths correctly.
apps/nativeapp/android/gradlew.bat (2)
44-44
: LGTM! Improved error handling.The changes properly redirect error messages to stderr and use the correct numeric comparison operator.
Also applies to: 46-50
84-87
: LGTM! Enhanced exit code handling.The implementation properly sets and handles exit codes, improving script robustness.
apps/nativeapp/ios/FireAlert/Info.plist (4)
44-50
: Security enhancement: Restricted network access.Good security practice! The changes disable arbitrary loads and local networking, which enhances the app's security posture.
19-20
:❓ Verification inconclusive
Version update requires verification.
The app version has been updated to 1.3 (build 7). Please ensure this aligns with your versioning strategy and release plans.
Also applies to: 36-37
🏁 Script executed:
#!/bin/bash # Check if version numbers are consistent across the project echo "Checking version numbers in package.json..." find . -name "package.json" -type f -exec grep -l "version" {} \;Length of output: 268
Ensure Consistency of Version Bump and Associated Changes
The Info.plist now shows the version updated to 1.3 (build 7). Please verify that this version bump is consistent across the project by confirming that the version numbers in the various package.json files (e.g., in the project root, apps/nativeapp, and packages/tsconfig) adhere to the intended versioning strategy. Also, double-check that the additional changes—network security adjustments, the shift to arm64 architecture (dropping armv7), and the minimum iOS version bump to 12.0—are in line with the planned release. Note that similar version-related adjustments appear on lines 36–37 in the corresponding configuration.
79-82
:✅ Verification successful
Architecture change impacts device compatibility.
Switching from armv7 to arm64 drops support for 32-bit devices. This aligns with modern iOS development but verify if this matches your device support requirements.
🌐 Web query:
When did Apple stop supporting 32-bit (armv7) apps in iOS?
💡 Result:
Apple officially discontinued support for 32-bit (armv7) apps starting with iOS 11, released in September 2017[1][3][4][6]. This marked a full transition to a 64-bit-only architecture across all iPhones and iPads running iOS/iPadOS versions beyond iOS 10[3][4]. Here’s a breakdown of key milestones:
Key Events Leading to Deprecation
- June 2015: Apple mandated that all new App Store submissions include 64-bit compatibility alongside existing 32-bit code[6].
- January 2016: Updates to existing apps also required 64-bit support[6].
- iOS 10.3 (2017): Introduced warnings for users about incompatible legacy apps[1].
- iOS 11 (September 2017): Dropped all compatibility for launching or running preinstalled or sideloaded 32-bit apps[3][4][6]. Apps using armv7 architecture would crash immediately upon launch[4].
Impact on Devices
- Devices older than the iPhone 5s (released in September 2013) became obsolete as they lacked hardware support for a pure 64-bit environment[1][6].
- Users were directed to check incompatible apps via Settings > General > About > Applications and update or delete them[1].
Developer Requirements
- By mid-2015, developers were required to include 64-bit code in all App Store submissions[1][6].
- In June 2022, Xcode 14 removed the ability to build universal binaries containing both armv7 (32-bit) and arm64 (64-bit) code[3]. This aligned with Apple’s long-term goal of eliminating legacy code from development workflows[8].
macOS Parallel
- macOS phased out 32-bit app support starting with macOS Catalina (October 2019), mirroring iOS’s transition[5].
User Confusion Clarified
Some users mistakenly attributed the discontinuation of legacy app functionality to newer iOS versions like iOS/iPadOS 17, but this was due to developers dropping updates for outdated apps rather than OS-level changes[4][7].
Citations:
- 1: https://clearbridgemobile.com/apple-dropping-32-bit-app-support-will-impact-app/
- 2: https://community.adobe.com/t5/air/air-30-dropping-support-for-32-bit-in-ios-apps/m-p/9846405
- 3: https://developer.apple.com/news/upcoming-requirements/?id=06062022a
- 4: https://discussions.apple.com/thread/255263319
- 5: https://support.apple.com/en-us/103076
- 6: https://apple.slashdot.org/story/17/02/01/1215200/the-future-of-ios-is-64-bit-only----apple-to-stop-support-for-32-bit-apps
- 7: https://discussions.apple.com/thread/254494259
- 8: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html
- 9: https://forums.developer.apple.com/forums/thread/729029
- 10: https://forums.developer.apple.com/forums/thread/715496
Architecture Change – Confirm Device Support Requirements
The updated
Info.plist
now restricts the app to devices supporting arm64. Note that Apple officially dropped support for 32‑bit (armv7) apps with iOS 11 (released September 2017). This change is in line with modern iOS development, but please ensure that your minimum deployment target is iOS 11 or later. If you need to support legacy devices, you may need to revisit this configuration.
- File:
apps/nativeapp/ios/FireAlert/Info.plist
(lines 79–82)- Snippet:
<key>UIRequiredDeviceCapabilities</key> <array> <string>arm64</string> </array>
40-41
:✅ Verification successful
Verify minimum iOS version requirement.
Setting minimum iOS version to 12.0 will drop support for devices that can't upgrade beyond iOS 11. Please confirm this aligns with your user base requirements.
🌐 Web query:
What percentage of iOS devices are running iOS 12 or later in 2024?
💡 Result:
As of late December 2024, over 99% of active Apple mobile devices were running iOS 12 or later based on aggregated data from multiple sources:
1. Cumulative adoption trends
The latest available data shows:
- 98–99% compatibility with iOS 13 and later due to Apple’s strong update ecosystem [1][3][5].
- Older operating systems like iOS 11 accounted for <0.8% globally by October 2024 [5].
Key Data Points:
Source Date % Running iOS 13+ Notes Statcounter Oct 2024 96–97% Includes minor updates beyond base versions [5]. TelemetryDeck Apr 2024 ~97–99% Combined 83–85% for iOS 17, 14–16% for iOS 16, residual <3–5% [6]. Apple Developer Jan 2025 >95–96% Focused on active App Store users [10].
Context:
Apple’s consistent update push ensures rapid adoption:
- Devices unsupported by newer updates phase out naturally over time.
- By late 2024, only legacy hardware like iPhone 5s (last updated in 2019) remained limited to iOS 15, representing a negligible share [1][3][6].
Citations:
- 1: https://www.statista.com/statistics/1118925/mobile-apple-ios-version-share-worldwide/
- 2: https://www.coolest-gadgets.com/ios-statistics/
- 3: https://www.engadget.com/mobile/smartphones/apple-says-68-percent-of-all-iphones-are-running-ios-18-195956904.html
- 4: https://telemetrydeck.com/blog/ios-market-share-02-24/
- 5: https://iosref.com/ios-usage
- 6: https://telemetrydeck.com/blog/ios-market-share-04-24/
- 7: https://backlinko.com/iphone-users
- 8: https://en.wikipedia.org/wiki/IOS_version_history
- 9: https://www.mobiloud.com/blog/android-vs-ios-market-share
- 10: https://developer.apple.com/support/app-store/
Minimum iOS Version Confirmation
The web data confirms that over 99% of active devices are running iOS 12 or later. Setting the minimum system version to 12.0 is therefore appropriate. Please double-check that there are no critical requirements for supporting legacy devices (iOS 11) in your user base.
- File: apps/nativeapp/ios/FireAlert/Info.plist (Lines 40-41)
- Current Code:
<key>LSMinimumSystemVersion</key> <string>12.0</string>apps/nativeapp/android/gradlew (3)
83-88
: Improved error handling and output suppression.Good improvements:
- Added shellcheck directive for better script validation
- Suppressed cd output to handle CDPATH issues
134-142
: Enhanced Java command verification.Improved error handling for Java command verification using
command -v
instead ofwhich
. This is more POSIX-compliant.
217-221
: Added xargs availability check.Good defensive programming by verifying xargs availability before use.
apps/nativeapp/android/app/src/debug/AndroidManifest.xml (1)
6-9
:❓ Verification inconclusive
Verify debug configuration removal.
The removal of debug-specific configurations (SYSTEM_ALERT_WINDOW permission and DevSettingsActivity) appears intentional. Please confirm this won't impact development workflows.
🏁 Script executed:
#!/bin/bash # Check if there are any remaining references to removed debug features echo "Checking for SYSTEM_ALERT_WINDOW usage..." rg "SYSTEM_ALERT_WINDOW" -l echo "Checking for DevSettingsActivity references..." rg "DevSettingsActivity" -lLength of output: 251
Verify removal of debug-specific configurations.
The removal of the
SYSTEM_ALERT_WINDOW
permission andDevSettingsActivity
from the debug AndroidManifest (apps/nativeapp/android/app/src/debug/AndroidManifest.xml) appears intentional, and the updated application tag (showing onlyandroid:usesCleartextTraffic="true"
,tools:targetApi="28"
, andtools:ignore="GoogleAppIndexingWarning"
) aligns with this change. However, since the automated search produced no output while checking for references to these removed features, please manually verify that no lingering references exist in the repository to ensure this change won’t inadvertently affect development workflows.apps/nativeapp/android/build.gradle (3)
5-10
: Update of Android SDK and Toolchain Versions
The updates tobuildToolsVersion
,minSdkVersion
,compileSdkVersion
,targetSdkVersion
, and the addition ofkotlinVersion
are clear and help bring the project up-to-date with newer Android standards.
21-23
: Gradle Plugin Dependency Configuration
Switching the classpath for the Android Gradle plugin to a generalized declaration ("com.android.tools.build:gradle"
) and adding the Kotlin Gradle plugin are acceptable, but make sure that the resolution of the Android Gradle plugin version is well-controlled elsewhere (for example, via a consistent dependency constraint).
36-36
: Application of React Native Root Project Plugin
The addition ofapply plugin: "com.facebook.react.rootproject"
at the end of the file integrates the React Native project structure. Please confirm that this plugin’s version and compatibility align with your current React Native setup.apps/nativeapp/android/app/build.gradle (2)
2-2
: Kotlin Support Integration
The addition ofapply plugin: "org.jetbrains.kotlin.android"
is a positive step toward modernizing the codebase by enabling Kotlin for Android development. Ensure that the rest of the Kotlin migration (including dependency versions and project configuration) is consistent across the app.
96-97
: Version Update in Default Configuration
UpdatingversionCode
from 4 to 6 andversionName
from "1.2" to "1.3" reflects an important release version bump. Confirm that these changes align with your release management and store versioning strategy, and that no downstream integrations are adversely affected.apps/nativeapp/app/routes/AppNavigator.tsx (3)
69-70
: Verify dependencies for token refresh logic.
You are callinghandleRefreshToken
in auseEffect
with[dispatch, queryClient]
as dependencies. Make sure you include any other state or variable dependencies used withinhandleRefreshToken
so that re-renders do not skip necessary updates.
86-95
: Validate returned credentials.
InrefreshUserToken
, theresult
might not always include valid properties (e.g., a new refresh token). Consider adding more robust null or shape checks to ensure you only proceed with valid credentials.
97-100
: LGTM for connectivity check.
ThecheckInternetConnectivity
function is straightforward and readable.apps/nativeapp/app/screens/Login/Login.tsx (5)
10-10
: Imports look good.
TheuseState
anduseEffect
imports are standard and align with your usage.
32-33
: Slight caution for error state.
Double-check iferror
fromuseAuth0
might contain fields other thancode
, ensuring you handle all relevant error properties.
38-44
: Robust unauthorized flow.
YouruseEffect
triggersshowVerifyAccModal
on unauthorized. This approach is correct but verify if other error codes might need unique handling, such as “login_required” or “consent_required”.
49-79
: Approve the async login flow.
Usingasync/await
forauthorize
and handling the toast notifications is significantly more readable. Nice enhancement to user experience and error feedback.
109-114
: No issues with updated text.
Your updated text content and styling are clear.apps/nativeapp/app/screens/Home/Home.tsx (12)
20-20
: Hook-based Auth0 usage recognized.
Transitioning touseAuth0
is consistent with the rest of the refactor; looks good.
108-115
: Ensure consistent context usage.
You're pullingstate
fromuseMapLayers
and also usingBottomBarContext
plus Redux state. Double-check these contexts remain in sync for complex updates (e.g., changes toselectedSiteBar
orpassMapInfo
).
169-169
: Tidy passMapInfo usage.
CollectingcenterCoordinates
andcurrZoom
upon user action is neat. Confirm the downstream usage is updated correctly if these values can change frequently.
219-219
: Query usage looks fine.
useFetchSites
withenabled: true
is straightforward for controlling request triggers.
237-254
: User update mutation approach is clear.
Your success and error callbacks are properly handled, and the function dispatchesgetUserDetails
again. All good.
301-330
: Site update mutation coverage.
Similarly, your cache manipulation on update merges changes neatly. Good approach to keep the UI in sync without reloading all data.🧰 Tools
🪛 Biome (1.9.4)
[error] 319-319: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.(lint/suspicious/noPrototypeBuiltins)
332-343
: User deletion flow is straightforward.
softDeleteUser
approach plus clearing the cache is logically consistent.
947-947
: Spacing changes are minor.
Styling adjustments at line 947 appear consistent with your design approach.
1006-1006
: Conditional rendering is fine.
Rendering( selectedSite?.site?.project?.id && (...) )
is an acceptable pattern for optional site attributes.
1108-1108
: Minor styling change.
Your newtextTransform: 'lowercase'
is consistent with the required design.
1189-1189
: No issues with absolute positioning.
Maintaining consistent UI placement is presumably intentional.
1287-1287
: Consistent color usage.
The updated border color keeps your UI consistent with the brand style.
const config = { | ||
transformer: { | ||
getTransformOptions: async () => ({ | ||
transform: { | ||
experimentalImportSupport: false, | ||
inlineRequires: true, | ||
}, | ||
}), | ||
}, | ||
watchFolders: [ | ||
// Include monorepo root and node_modules | ||
path.resolve(__dirname, '../..'), | ||
path.resolve(__dirname, '../../node_modules'), | ||
], | ||
resolver: { | ||
nodeModulesPaths: [ | ||
path.resolve(__dirname, 'node_modules'), | ||
path.resolve(__dirname, '../../node_modules'), | ||
], | ||
extraNodeModules: { | ||
...monorepoMetroTools.extraNodeModules, | ||
}, | ||
}; | ||
})(); | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
LGTM! Comprehensive Metro configuration for monorepo.
The configuration is well-structured with appropriate settings for transformer, watch folders, and module resolution. The use of inlineRequires: true
will help with performance.
Verify that the node_modules paths exist and are correctly configured:
🏁 Script executed:
#!/bin/bash
# Check if the specified node_modules directories exist
echo "Checking node_modules paths..."
[ -d "apps/nativeapp/node_modules" ] && echo "✓ Local node_modules exists" || echo "✗ Local node_modules missing"
[ -d "node_modules" ] && echo "✓ Root node_modules exists" || echo "✗ Root node_modules missing"
Length of output: 269
Action Required: Verify Node Modules Directory Configuration
The Metro configuration is well-structured regarding transformer, watch folders, and resolver settings. However, our verification script shows that neither the local (apps/nativeapp/node_modules
) nor the root (node_modules
) directories are present. Please confirm whether this is expected due to a hoisted dependency setup common in monorepos, or if the configuration needs adjustments to account for the actual directory structure.
- File:
apps/nativeapp/metro.config.js
(Lines 7-30) - Action: Double-check the physical presence of the
node_modules
directories or update the configuration if the dependency management strategy differs from the expected layout.
export function filterByName(text: string) { | ||
return data.filter(item => { | ||
return item.name.toLowerCase().includes(text.toLowerCase()); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation and error handling to filterByName.
The function should handle edge cases and invalid inputs:
- Empty/null text parameter
- Non-string inputs
- Performance considerations for large datasets
Consider this implementation:
export function filterByName(text: string) {
+ if (!text) return [];
+ if (typeof text !== 'string') throw new Error('Input must be a string');
+
return data.filter(item => {
+ if (!item.name) return false;
return item.name.toLowerCase().includes(text.toLowerCase());
});
}
export function getByExternalId(externalId: string) { | ||
return data.find(item => item.externalId === externalId); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add input validation and error handling to getByExternalId.
The function should handle edge cases and invalid inputs:
- Empty/null externalId parameter
- Non-string inputs
- Case where no item is found
Consider this implementation:
export function getByExternalId(externalId: string) {
+ if (!externalId) throw new Error('External ID is required');
+ if (typeof externalId !== 'string') throw new Error('External ID must be a string');
+
return data.find(item => item.externalId === externalId);
}
Committable suggestion skipped: line range outside the PR's diff.
|
||
const foundSite = await ctx.prisma.site.findFirst({ | ||
where: {externalId: externalId}, | ||
}) | ||
|
||
let site: Partial<Site>, siteRelation: Partial<SiteRelation>; | ||
if(foundSite) { | ||
const _foundSiteRelation = await ctx.prisma.siteRelation.findFirst({ | ||
where: { userId: userId, siteId: foundSite.id }, | ||
}) | ||
if (_foundSiteRelation) { | ||
site = foundSite; | ||
siteRelation = _foundSiteRelation | ||
} else { | ||
const _siteRelation = await ctx.prisma.siteRelation.create({ | ||
data: { | ||
role: "ROLE_VIEWER", | ||
userId: userId, | ||
siteId: foundSite.id, | ||
isActive: true | ||
}, | ||
select: { | ||
siteId: true, userId: true, role: true, | ||
site: { | ||
select: { | ||
id: true, | ||
type: true, | ||
name: true, | ||
radius: true, | ||
geometry: true, | ||
externalId: true, | ||
} | ||
} | ||
} | ||
}) | ||
const _site = await ctx.prisma.site.update({ | ||
where: {id: foundSite.id}, | ||
data: {isMonitored: true}, | ||
}) | ||
site = _site; | ||
siteRelation = _siteRelation | ||
} | ||
} else { | ||
const _site = await ctx.prisma.site.create({ | ||
data: { | ||
origin: origin, | ||
type: 'Polygon', | ||
name: ppSite.name, | ||
radius: 0, | ||
kind: 'PROTECTED_SITE', | ||
geometry: ppSite.geometry as unknown as Prisma.JsonObject, | ||
externalId: ppSite.externalId, | ||
lastUpdated: new Date(), | ||
siteRelations: { | ||
create: { | ||
user: { connect: { id: userId, } }, | ||
role: 'ROLE_VIEWER', | ||
} | ||
}, | ||
}, | ||
select: { | ||
id: true, | ||
type: true, | ||
name: true, | ||
radius: true, | ||
geometry: true, | ||
externalId: true, | ||
lastUpdated: true, | ||
project: { | ||
select: { id: true, name: true } | ||
}, | ||
siteRelations: { | ||
select: { siteId: true, userId: true, role: true } | ||
} | ||
}, | ||
}); | ||
site = _site; | ||
siteRelation = _site.siteRelations | ||
} | ||
|
||
return { | ||
status: "success", | ||
data: { | ||
site, | ||
siteRelation | ||
}, | ||
}; | ||
} catch (error) { | ||
console.log(error); | ||
if (error instanceof TRPCError) { | ||
// if the error is already a TRPCError, just re-throw it | ||
throw error; | ||
} | ||
// if it's a different type of error, throw a new TRPCError | ||
throw new TRPCError({ | ||
code: "INTERNAL_SERVER_ERROR", | ||
message: `Something Went Wrong`, | ||
}); | ||
} | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle concurrency and remove large commented sections.
This procedure creates or attaches a user to a protected site. Possible concurrency issues can arise if multiple users create the same externalId simultaneously. Consider using transactions or unique constraints to avoid duplicates. Large commented-out code blocks also make the code harder to read; consider removing them or moving them to documentation.
<key>NSPrivacyAccessedAPITypes</key> | ||
<array> | ||
<dict> | ||
<key>NSPrivacyAccessedAPIType</key> | ||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string> | ||
<key>NSPrivacyAccessedAPITypeReasons</key> | ||
<array> | ||
<string>CA92.1</string> | ||
</array> | ||
</dict> | ||
<dict> | ||
<key>NSPrivacyAccessedAPIType</key> | ||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string> | ||
<key>NSPrivacyAccessedAPITypeReasons</key> | ||
<array> | ||
<string>C617.1</string> | ||
<string>3B52.1</string> | ||
</array> | ||
</dict> | ||
<dict> | ||
<key>NSPrivacyAccessedAPIType</key> | ||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string> | ||
<key>NSPrivacyAccessedAPITypeReasons</key> | ||
<array> | ||
<string>35F9.1</string> | ||
</array> | ||
</dict> | ||
<dict> | ||
<key>NSPrivacyAccessedAPIType</key> | ||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string> | ||
<key>NSPrivacyAccessedAPITypeReasons</key> | ||
<array> | ||
<string>85F4.1</string> | ||
</array> | ||
</dict> | ||
</array> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify privacy reason codes with Apple's documentation.
The privacy manifest includes API access types with specific reason codes (CA92.1, C617.1, 3B52.1, 85F4.1). These codes should match Apple's documented privacy reasons.
🌐 Web query:
What are the valid reason codes for NSPrivacyAccessedAPITypes in iOS privacy manifest?
💡 Result:
To resolve errors related to NSPrivacyAccessedAPITypes
in your iOS app's privacy manifest, you must use valid reason codes corresponding to specific API categories as mandated by Apple[1][3][4]. Below are the required categories and their approved reason codes:
Valid Reason Codes by API Category
API Category | Reason Code | Approved Use Case |
---|---|---|
User Defaults | 1C8F.1 |
Accessing data within the same App Group[3][4]. |
(NSPrivacyAccessedAPICategoryUserDefaults ) |
CA92.1 |
General read/write operations (e.g., via .NET MAUI's Preferences API)[4][6]. |
File Timestamp | C617.1 |
Accessing file timestamps (required for .NET runtime/BCL)[4][7]. |
(NSPrivacyAccessedAPICategoryFileTimestamp ) |
||
System Boot Time | 35F9.1 |
Retrieving system boot time (common in diagnostics frameworks)[3][4][5]. |
(NSPrivacyAccessedAPICategorySystemBootTime ) |
||
Disk Space | E174.1 |
Checking available disk space[4][5]. |
(NSPrivacyAccessedAPICategoryDiskSpace ) |
Implementation Steps
-
Add a Privacy Manifest File:
CreatePrivacyInfo.xcprivacy
in Xcode (File → New → App Privacy File
)[3][4]. -
Declare API Categories and Reasons:
For each API category used, specify itsNSPrivacyAccessedAPIType
and correspondingNSPrivacyAccessedAPITypeReasons
in XML format:<key>NSPrivacyAccessedAPITypes</key> <array> <dict> <key>NSPrivacyAccessedAPIType</key> <string>NSPrivacyAccessedAPICategoryUserDefaults</string> <key>NSPrivacyAccessedAPITypeReasons</key> <array> <string>CA92.1</string> <!-- Example for UserDefaults --> </array> </dict> </array>
-
Third-Party Libraries:
Ensure dependencies include their ownPrivacyInfo.xcprivacy
files with valid reasons[3][6]. If they don’t, add required entries to your app’s manifest[6].
Common Pitfalls
- Using generic descriptions like "App Functionality" instead of approved codes[1].
- Omitting mandatory categories (e.g.,
.NET MAUI
apps require FileTimestamp, SystemBootTime, and DiskSpace declarations)[4]. - Failing to update manifests for app extensions or SDKs[3][6].
For full details, refer to Apple’s Required Reason API Documentation[9].
Citations:
- 1: https://forums.developer.apple.com/forums/thread/749940
- 2: https://blog.ostorlab.co/apple-privacy-manifest-file.html
- 3: https://www.avanderlee.com/xcode/missing-api-declaration-required-reason-itms-91053/
- 4: https://learn.microsoft.com/en-us/dotnet/maui/ios/privacy-manifest?view=net-maui-9.0
- 5: https://forum.juce.com/t/missing-api-declaration/60484
- 6: https://docs.expo.dev/guides/apple-privacy/
- 7: https://community.flutterflow.io/ask-the-community/post/appstore-connect-nsprivacyaccessedapitypes-error-DhAsaD26TEC8wRe
- 8: https://developer.apple.com/documentation/bundleresources/privacy-manifest-files
- 9: https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api
- 10: https://situm.com/docs/how-to-provide-your-ios-apps-privacy-manifest/
Action Required: Update Invalid Privacy Reason Codes
- For NSPrivacyAccessedAPICategoryFileTimestamp: Remove the extra reason code
"3B52.1"
so that only"C617.1"
remains. - For NSPrivacyAccessedAPICategoryDiskSpace: Change the reason code from
"85F4.1"
to"E174.1"
per Apple’s approved mapping.
Please update these entries in apps/nativeapp/ios/FireAlert/PrivacyInfo.xcprivacy
to ensure full compliance with Apple's documentation.
zipStoreBase=GRADLE_USER_HOME | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip | ||
networkTimeout=10000 | ||
validateDistributionUrl=truezipStoreBase=GRADLE_USER_HOME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix property formatting issue.
The line validateDistributionUrl=truezipStoreBase=GRADLE_USER_HOME
appears to be incorrectly merged. It should be split into separate properties.
-validateDistributionUrl=truezipStoreBase=GRADLE_USER_HOME
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
validateDistributionUrl=truezipStoreBase=GRADLE_USER_HOME | |
validateDistributionUrl=true | |
zipStoreBase=GRADLE_USER_HOME |
@@ -1,5 +1,6 @@ | |||
distributionBase=GRADLE_USER_HOME | |||
distributionPath=wrapper/dists | |||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip | |||
zipStoreBase=GRADLE_USER_HOME | |||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify Gradle version compatibility.
Upgrading to Gradle 8.6 is a major version jump. Please ensure compatibility with your Android build configuration and dependencies.
🌐 Web query:
What are the major changes and potential breaking changes in Gradle 8.6?
💡 Result:
Gradle 8.6 introduced several enhancements while maintaining backward compatibility, though one binary-breaking change was identified post-release:
Major Changes
- Custom Configuration Cache Encryption: Added support for custom encryption keys to secure cached configuration data[4][5][6].
- Build Init Improvements:
- Default package generation for new projects
- Non-interactive mode support
- Kotlin DSL assignment syntax adoption[4][5][6]
- Enhanced Dependency Management:
Provider
types can now be used with dependency capability declarations[6]
- Error Reporting:
- Improved clarity for dependency-locking failures
- Better circular reference detection in providers[6]
- IDE Integration: Enhanced Problems API reporting and stability fixes for IntelliJ/Android Studio[4][6].
Potential Breaking Change
- Binary Incompatibility: The
DependencyAdder
class was renamed toDependencyCollector
, causing compatibility issues for plugins using this API[10]. This affects builds relying on:dependencies { implementation(project(":lib")) }
While the official release notes state no intentional breaking changes[4][5], developers using affected plugins should check for updates or adjust their dependency declarations[10].
Citations:
- 1: https://docs.gradle.org/current/userguide/upgrading_version_8.html
- 2: https://docs.gradle.org/current/release-notes.html
- 3: https://docs.gradle.org/current/userguide/upgrading_version_7.html
- 4: https://newsletter.gradle.org/2024/02
- 5: https://docs.gradle.org/8.6/release-notes.html
- 6: https://www.youtube.com/watch?v=njwdner567g
- 7: https://github.com/gradle/gradle/releases
- 8: https://developer.android.com/build/releases/past-releases/agp-8-6-0-release-notes
- 9: https://youtrack.jetbrains.com/issue/KT-64600
- 10: Binary breaking change in 8.6 gradle/gradle#28113
Attention: Gradle 8.6 Upgrade & Formatting Correction Required
Your update to Gradle 8.6 introduces several new enhancements—such as improved configuration cache security and better dependency management—but note that a known binary incompatibility (the renaming of the DependencyAdder
class to DependencyCollector
) may affect plugins dependent on that API. Please verify that your Android build configuration, dependencies, and any custom plugins fully support Gradle 8.6.
Additionally, there is a formatting issue detected on line 5 of apps/nativeapp/android/gradle/wrapper/gradle-wrapper.properties
that needs correction.
- Confirm compatibility of all plugins (especially those interacting with dependency management APIs).
- Address the formatting issue on line 5.
MYAPP_RELEASE_STORE_FILE=my-release-key.keystore | ||
MYAPP_RELEASE_KEY_ALIAS=my-key-alias | ||
MYAPP_RELEASE_STORE_PASSWORD=fire-alert | ||
MYAPP_RELEASE_KEY_PASSWORD=fire-alert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduction of Signing Properties and Removal of Flipper Configuration
The added keystore and signing properties (MYAPP_RELEASE_STORE_FILE
, MYAPP_RELEASE_KEY_ALIAS
, MYAPP_RELEASE_STORE_PASSWORD
, and MYAPP_RELEASE_KEY_PASSWORD
) properly configure the release signing. However, hardcoding these credentials might expose sensitive data if committed to version control. Consider using environment variables or a secure secret management approach for production builds.
item.id === res?.json?.data?.id ? res?.json?.data : item, | ||
), | ||
}, | ||
} | ||
: null, | ||
); | ||
if (req?.json?.body.hasOwnProperty('isMonitored')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid prototype pollution vulnerabilities.
Replace .hasOwnProperty('isMonitored')
with a safer check:
-if (req?.json?.body.hasOwnProperty('isMonitored')) {
+if (Object.hasOwn(req?.json?.body, 'isMonitored')) {
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (req?.json?.body.hasOwnProperty('isMonitored')) { | |
if (Object.hasOwn(req?.json?.body, 'isMonitored')) { |
🧰 Tools
🪛 Biome (1.9.4)
[error] 319-319: Do not access Object.prototype method 'hasOwnProperty' from target object.
It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.
(lint/suspicious/noPrototypeBuiltins)
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/nativeapp/android/settings.gradle
(1 hunks)
🔇 Additional comments (1)
apps/nativeapp/android/settings.gradle (1)
28-28
: Approved: Updated Gradle Plugin Inclusion PathThe change from
react-native-gradle-plugin
to@react-native/gradle-plugin
is correctly updating the plugin inclusion path and aligns with the recent updates in the React Native ecosystem.
@@ -17,12 +17,12 @@ dependencyResolutionManagement { | |||
// This should always be `mapbox` (not your username). | |||
username = "mapbox" | |||
// Use the secret token you stored in gradle.properties as the password | |||
password = properties.getProperty('MAPBOX_DOWNLOADS_TOKEN') | |||
password = password = System.getenv("MAPBOXGL_ACCCESS_TOKEN") ?: properties.getProperty("mapboxgl_access_token") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical Issue: Duplicate Assignment and Typo in Environment Variable
The assignment on line 20 contains an inadvertent duplicate (password = password =
) and a likely typo in the environment variable name. The environment variable appears as MAPBOXGL_ACCCESS_TOKEN
(with an extra 'C') but should probably be MAPBOXGL_ACCESS_TOKEN
. Please remove the duplicate assignment and correct the variable name.
- password = password = System.getenv("MAPBOXGL_ACCCESS_TOKEN") ?: properties.getProperty("mapboxgl_access_token")
+ password = System.getenv("MAPBOXGL_ACCESS_TOKEN") ?: properties.getProperty("mapboxgl_access_token")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
password = password = System.getenv("MAPBOXGL_ACCCESS_TOKEN") ?: properties.getProperty("mapboxgl_access_token") | |
password = System.getenv("MAPBOXGL_ACCESS_TOKEN") ?: properties.getProperty("mapboxgl_access_token") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (2)
apps/server/src/server/api/routers/site.ts (2)
158-345
: 🛠️ Refactor suggestionHandle concurrency and remove large commented sections.
This procedure creates or attaches a user to a protected site. Possible concurrency issues can arise if multiple users create the same externalId simultaneously. Consider using transactions or unique constraints to avoid duplicates. Large commented-out code blocks also make the code harder to read; consider removing them or moving them to documentation.
createProtectedSite: protectedProcedure .input(createProtectedSiteSchema) .mutation(async ({ctx, input}) => { const userId = ctx.user!.id; try { const {externalId} = input const origin = 'firealert'; - // radius 0 on Point would generally not return any results - // So monitor 1km around the point by default - // if (input.type === 'Point' && input.radius === 0) { - // radius = 1000; - // } else { radius = input.radius; } const ppSite = getByExternalId(externalId) - // Any check by externalId? - // const protectedArea: {name: string, wdpa_id: string, geometry?: GeoJSON.Geometry} = { - // name: "", wdpa_id: "" - // }; - // [... many more commented lines removed ...] if(!ppSite) { throw new TRPCError({ code: "NOT_FOUND", message: `No protected area found with WDPA ID ${externalId}.` }) } // Use a transaction to ensure database consistency return await ctx.prisma.$transaction(async (tx) => { const foundSite = await tx.site.findFirst({ where: {externalId: externalId}, }) let site: Partial<Site>, siteRelation: Partial<SiteRelation>; if(foundSite) { const _foundSiteRelation = await tx.siteRelation.findFirst({ where: { userId: userId, siteId: foundSite.id }, }) if (_foundSiteRelation) { site = foundSite; siteRelation = _foundSiteRelation } else { const _siteRelation = await tx.siteRelation.create({ data: { role: "ROLE_VIEWER", userId: userId, siteId: foundSite.id, isActive: true }, select: { siteId: true, userId: true, role: true, site: { select: { id: true, type: true, name: true, radius: true, geometry: true, externalId: true, } } } }) const _site = await tx.site.update({ where: {id: foundSite.id}, data: {isMonitored: true}, }) site = _site; siteRelation = _siteRelation } } else { const _site = await tx.site.create({ data: { origin: origin, type: 'Polygon', name: ppSite.name, radius: 0, kind: 'PROTECTED_SITE', geometry: ppSite.geometry as unknown as Prisma.JsonObject, externalId: ppSite.externalId, lastUpdated: new Date(), siteRelations: { create: { user: { connect: { id: userId, } }, role: 'ROLE_VIEWER', } }, }, select: { id: true, type: true, name: true, radius: true, geometry: true, externalId: true, lastUpdated: true, project: { select: { id: true, name: true } }, siteRelations: { select: { siteId: true, userId: true, role: true } } }, }); site = _site; siteRelation = _site.siteRelations } return { status: "success", data: { site, siteRelation }, }; }); } catch (error) { console.log(error); if (error instanceof TRPCError) { // if the error is already a TRPCError, just re-throw it throw error; } // if it's a different type of error, throw a new TRPCError throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: `Something Went Wrong`, }); } }),
678-736
: 🛠️ Refactor suggestionConsider transaction for multi-step logic.
updateProtectedSite
updatessiteRelation
and then queries and possibly updates thesite
. Wrap these steps in a single database transaction to avoid partial updates if a failure occurs in between.updateProtectedSite: protectedProcedure .input(updateProtectedSiteSchema) .mutation(async ({ctx, input}) => { const userId = ctx.user!.id; const siteId = input.params.siteId; try { + return await ctx.prisma.$transaction(async (tx) => { const updatedSiteRelation = await ctx.prisma.siteRelation.updateMany({ where: { siteId: siteId, userId: userId }, data: { isActive: input.body.isActive }, }) if(updatedSiteRelation.count != 1) { return { status: 'failed' }; } const activeSiteRelations = await ctx.prisma.siteRelation.findMany({ where: { siteId: input.params.siteId, isActive:true } }) if(activeSiteRelations.length === 0) { await ctx.prisma.site.update({ where: {id: siteId}, data: {isMonitored: false} }) } const _siteRelation = await ctx.prisma.siteRelation.findFirst({ where: { siteId: siteId, userId: userId }, select: { siteId: true, isActive:true, site: { select: { id: true, name: true, type: true, isMonitored: true, userId: true, remoteId: true, project: true, geometry: true, } }} }) const updatedSite = { ..._siteRelation?.site, isActive: _siteRelation?.isActive, } return { status: 'success', data: updatedSite}; + }); } catch (error) { console.log(error); if (error instanceof TRPCError) { // if the error is already a TRPCError, just re-throw it throw error; } // if it's a different type of error, throw a new TRPCError throw new TRPCError({ code: "CONFLICT", message: `Error Updating Site.`, }); } }),
🧹 Nitpick comments (4)
apps/server/src/server/api/routers/site.ts (4)
517-552
: Improve error handling in getProtectedSites.The current error handling uses a generic "NOT_FOUND" code for all errors, which isn't always appropriate. Also, proper type definitions would help with type safety.
getProtectedSites: protectedProcedure.query(async ({ctx}) => { const userId = ctx.user!.id; try { - // console.log(userId) const _siteRelation = await ctx.prisma.siteRelation.findMany({ where: { userId: userId, }, select: { siteId: true, isActive:true, site: { select: { id: true, name: true, type: true, isMonitored: true, userId: true, remoteId: true, project: true, geometry: true, } } } }) const sites = _siteRelation.map(el => ({ ...el.site, isActive: el.isActive, })) return { status: 'success', data: sites, }; } catch (error) { console.log(error) throw new TRPCError({ - code: "NOT_FOUND", + code: "INTERNAL_SERVER_ERROR", message: `${error}`, }); } }),
347-430
: Cleanup commented code.Large blocks of commented code make the file harder to read and maintain. Consider removing this code or moving it to a separate file if it will be needed later.
251-251
: Improve type safety with non-partial types.Using
Partial<Site>
andPartial<SiteRelation>
allows for unexpected null or undefined values. Consider using more specific types or interfaces that match exactly what you need.-let site: Partial<Site>, siteRelation: Partial<SiteRelation>; +interface SiteData { + id: string; + name: string; + type: string; + // Add other required fields +} + +interface SiteRelationData { + siteId: string; + userId: string; + role: string; + // Add other required fields +} + +let site: SiteData, siteRelation: SiteRelationData;
691-691
: Improve error handling pattern.The code returns
{ status: 'failed' }
when the update doesn't affect exactly one row. This pattern is inconsistent with the rest of the codebase where errors are thrown using TRPCError.-if(updatedSiteRelation.count != 1) { return { status: 'failed' }; } +if(updatedSiteRelation.count != 1) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Site relation not found or multiple relations updated", + }); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/server/src/server/api/routers/site.ts
(6 hunks)
🔇 Additional comments (2)
apps/server/src/server/api/routers/site.ts (2)
439-439
: Address TODO comment.There's a TODO comment that needs to be addressed about testing error cases with the
getSitesForProject
procedure.
8-9
:❓ Verification inconclusive
Verify the imported utility functions.
The imported utility functions
filterByName
andgetByExternalId
from "./sample-utils" appear to be placeholder implementations rather than production-ready code. These functions likely return mock data rather than performing actual database or API operations.
🏁 Script executed:
#!/bin/bash # Check if these are sample/mock implementations cat apps/server/src/server/api/routers/sample-utils.ts || fd sample-utilsLength of output: 357
Action Required: Confirm the Implementation Approach for Utility Functions
The utility functions in
apps/server/src/server/api/routers/sample-utils.ts
have been verified to use data from./sample.json
. BothfilterByName()
andgetByExternalId()
operate on this sample data, acting as mock implementations rather than performing real database or API operations.
- Location:
apps/server/src/server/api/routers/sample-utils.ts
- Finding: The functions filter or search on static JSON data, confirming that they serve as placeholder implementations.
Please confirm whether these implementations are intentionally set as mocks for a demonstration environment or if production-ready implementations need to be provided.
const userId = ctx.user!.id; | ||
try { | ||
const {query} = input; | ||
const results = filterByName(query) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace mock implementation with real database queries.
The filterByName
function is likely a mock implementation. For production, this should be replaced with actual database queries that filter protected sites by name.
-const results = filterByName(query)
+const results = await ctx.prisma.site.findMany({
+ where: {
+ name: {
+ contains: query,
+ mode: 'insensitive'
+ },
+ kind: 'PROTECTED_SITE',
+ deletedAt: null,
+ },
+ select: {
+ id: true,
+ name: true,
+ type: true,
+ radius: true,
+ isMonitored: true,
+ lastUpdated: true,
+ externalId: true,
+ geometry: true,
+ }
+});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const results = filterByName(query) | |
const results = await ctx.prisma.site.findMany({ | |
where: { | |
name: { | |
contains: query, | |
mode: 'insensitive' | |
}, | |
kind: 'PROTECTED_SITE', | |
deletedAt: null, | |
}, | |
select: { | |
id: true, | |
name: true, | |
type: true, | |
radius: true, | |
isMonitored: true, | |
lastUpdated: true, | |
externalId: true, | |
geometry: true, | |
} | |
}); |
const pp_api = process.env.NEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT as string; | ||
const pp_api_key = process.env.NEXT_PUBLIC_PROTECTED_PLANET_API_KEY as string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Environment variables aren't being properly validated.
These environment variables are cast as string without proper checks. If they're missing, your application could silently fail with unexpected behavior.
-const pp_api = process.env.NEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT as string;
-const pp_api_key = process.env.NEXT_PUBLIC_PROTECTED_PLANET_API_KEY as string;
+const pp_api = process.env.NEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT;
+const pp_api_key = process.env.NEXT_PUBLIC_PROTECTED_PLANET_API_KEY;
+
+if (!pp_api || !pp_api_key) {
+ console.error('Missing required Protected Planet API configuration');
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const pp_api = process.env.NEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT as string; | |
const pp_api_key = process.env.NEXT_PUBLIC_PROTECTED_PLANET_API_KEY as string; | |
const pp_api = process.env.NEXT_PUBLIC_PROTECTED_PLANET_ENDPOINT; | |
const pp_api_key = process.env.NEXT_PUBLIC_PROTECTED_PLANET_API_KEY; | |
if (!pp_api || !pp_api_key) { | |
console.error('Missing required Protected Planet API configuration'); | |
} |
findProtectedSites: protectedProcedure | ||
.input(findProtectedSiteParams) | ||
.mutation(async ({ctx, input}) => { | ||
const userId = ctx.user!.id; | ||
try { | ||
const {query} = input; | ||
const results = filterByName(query) | ||
|
||
// const sites = await ctx.prisma.site.findMany({ | ||
// where: { | ||
// userId: userId, | ||
// deletedAt: null, | ||
// kind: 'PROTECTED_SITE', | ||
// }, | ||
// select: { | ||
// id: true, | ||
// name: true, | ||
// type: true, | ||
// radius: true, | ||
// isMonitored: true, | ||
// lastUpdated: true, | ||
// userId: true, | ||
// remoteId: true, | ||
// project: { | ||
// select: { | ||
// id: true, | ||
// name: true | ||
// } | ||
// }, | ||
// geometry: true, | ||
// } | ||
// }) | ||
|
||
return { | ||
status: 'success', | ||
data: results, | ||
}; | ||
} catch (error) { | ||
console.log(error) | ||
throw new TRPCError({ | ||
code: "NOT_FOUND", | ||
message: `${error}`, | ||
}); | ||
} | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove commented code and use proper error handling.
The current implementation relies on a sample function but includes a large commented-out block. Additionally, the error handling uses a generic "NOT_FOUND" code for all errors, regardless of their nature.
findProtectedSites: protectedProcedure
.input(findProtectedSiteParams)
.mutation(async ({ctx, input}) => {
const userId = ctx.user!.id;
try {
const {query} = input;
const results = filterByName(query)
- // const sites = await ctx.prisma.site.findMany({
- // where: {
- // userId: userId,
- // deletedAt: null,
- // kind: 'PROTECTED_SITE',
- // },
- // select: {
- // id: true,
- // name: true,
- // type: true,
- // radius: true,
- // isMonitored: true,
- // lastUpdated: true,
- // userId: true,
- // remoteId: true,
- // project: {
- // select: {
- // id: true,
- // name: true
- // }
- // },
- // geometry: true,
- // }
- // })
return {
status: 'success',
data: results,
};
} catch (error) {
console.log(error)
throw new TRPCError({
- code: "NOT_FOUND",
+ code: "INTERNAL_SERVER_ERROR",
message: `${error}`,
});
}
}),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
findProtectedSites: protectedProcedure | |
.input(findProtectedSiteParams) | |
.mutation(async ({ctx, input}) => { | |
const userId = ctx.user!.id; | |
try { | |
const {query} = input; | |
const results = filterByName(query) | |
// const sites = await ctx.prisma.site.findMany({ | |
// where: { | |
// userId: userId, | |
// deletedAt: null, | |
// kind: 'PROTECTED_SITE', | |
// }, | |
// select: { | |
// id: true, | |
// name: true, | |
// type: true, | |
// radius: true, | |
// isMonitored: true, | |
// lastUpdated: true, | |
// userId: true, | |
// remoteId: true, | |
// project: { | |
// select: { | |
// id: true, | |
// name: true | |
// } | |
// }, | |
// geometry: true, | |
// } | |
// }) | |
return { | |
status: 'success', | |
data: results, | |
}; | |
} catch (error) { | |
console.log(error) | |
throw new TRPCError({ | |
code: "NOT_FOUND", | |
message: `${error}`, | |
}); | |
} | |
}), | |
findProtectedSites: protectedProcedure | |
.input(findProtectedSiteParams) | |
.mutation(async ({ctx, input}) => { | |
const userId = ctx.user!.id; | |
try { | |
const {query} = input; | |
const results = filterByName(query) | |
return { | |
status: 'success', | |
data: results, | |
}; | |
} catch (error) { | |
console.log(error) | |
throw new TRPCError({ | |
code: "INTERNAL_SERVER_ERROR", | |
message: `${error}`, | |
}); | |
} | |
}), |
// radius = 1000; | ||
// } else { radius = input.radius; } | ||
|
||
const ppSite = getByExternalId(externalId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace mock implementation with real API calls.
The getByExternalId
function is likely a mock implementation. For production, this should be replaced with actual API calls to the Protected Planet API.
-const ppSite = getByExternalId(externalId)
+// Fetch the protected area data from the Protected Planet API
+const qs = new URLSearchParams();
+qs.append("token", pp_api_key);
+qs.append("with_geometry", "true");
+const pp_url = `${pp_api}/protected_areas/${externalId}?${qs.toString()}`;
+
+const res = await fetch(pp_url);
+if (!res.ok) {
+ throw new TRPCError({
+ code: 'INTERNAL_SERVER_ERROR',
+ message: `Failed to fetch protected area data: ${res.statusText}`,
+ });
+}
+
+const data = await res.json();
+const protectedArea = data?.protected_area;
+
+if (!protectedArea) {
+ throw new TRPCError({
+ code: "NOT_FOUND",
+ message: `No protected area found with WDPA ID ${externalId}.`
+ });
+}
+
+const ppSite = {
+ name: protectedArea.name,
+ externalId: protectedArea.wdpa_id.toString(),
+ geometry: protectedArea.geojson.geometry
+};
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const ppSite = getByExternalId(externalId) | |
// Fetch the protected area data from the Protected Planet API | |
const qs = new URLSearchParams(); | |
qs.append("token", pp_api_key); | |
qs.append("with_geometry", "true"); | |
const pp_url = `${pp_api}/protected_areas/${externalId}?${qs.toString()}`; | |
const res = await fetch(pp_url); | |
if (!res.ok) { | |
throw new TRPCError({ | |
code: 'INTERNAL_SERVER_ERROR', | |
message: `Failed to fetch protected area data: ${res.statusText}`, | |
}); | |
} | |
const data = await res.json(); | |
const protectedArea = data?.protected_area; | |
if (!protectedArea) { | |
throw new TRPCError({ | |
code: "NOT_FOUND", | |
message: `No protected area found with WDPA ID ${externalId}.` | |
}); | |
} | |
const ppSite = { | |
name: protectedArea.name, | |
externalId: protectedArea.wdpa_id.toString(), | |
geometry: protectedArea.geojson.geometry | |
}; |
Caution: Do not Directly Merge -
Changes in this pull request:
@
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Improvements
These changes deliver a more reliable and responsive experience while ensuring enhanced security and better handling of site-related updates.