Skip to content

RU-T51 Checkin fixes, status fix#254

Merged
ucswift merged 1 commit into
masterfrom
develop
Jul 23, 2026
Merged

RU-T51 Checkin fixes, status fix#254
ucswift merged 1 commit into
masterfrom
develop

Conversation

@ucswift

@ucswift ucswift commented Jul 23, 2026

Copy link
Copy Markdown
Member

Description

This PR addresses multiple fixes and improvements related to check-in functionality, status workflows, weather alerts, and UI polish.

Check-in Fixes

  • Eligibility filtering: Check-in timers and the bottom sheet now filter targets based on the current user's active unit type and personnel identity. Timers for other unit types and personnel are no longer shown.
  • IC exclusion: Incident Commander (IC) check-in type is now blocked from both the UI and the API layer, as it is not supported in the Unit app.
  • Quick check-in accuracy: Quick check-in now respects the preferred eligible check-in type and no longer attaches the active unit ID to Personnel check-ins.
  • Status normalization: Timer status values (including the misspelled "Critial" and the API's "Green") are now normalized to consistent display states with correct colors, translations, and pulse animations.
  • Tab badge: The check-in tab badge now accurately counts critical and overdue timers scoped to the matching unit type, with warning/critical color variants.

Status Bottom Sheet Fixes

  • Deduplication: The StatusBottomSheet is now mounted once at the app root level instead of being duplicated across call detail, POI detail, and sidebar screens, eliminating stacked Actionsheet backdrops and redundant data fetches.
  • Smart step routing: When a status is preselected (from a button or screen), the initial step now reflects whether that status actually requires a destination or note, instead of always landing on the destination step.
  • Cancel vs. Previous: The note step shows "Cancel" instead of "Previous" when there is no prior step to return to.
  • Backdrop guard: Actionsheet overlay-click dismissal is now delayed shortly after opening to prevent the opening tap from immediately closing the sheet.

Weather Alert Fixes

  • Date parsing: Weather alert dates in department-local formats (e.g., 07/23/2026 4:15:30 PM) from the Core API are now parsed correctly instead of showing "Invalid Date".
  • Banner dismiss logic: Dismissed alerts are now tracked by ID, so newly received alerts re-show the banner instead of resetting the entire dismissed state whenever the alert count changes.
  • Detail map: The weather alert detail map now properly fits polygon bounds across MultiPolygons, falls back to center coordinates, and shows a "no location" state instead of defaulting to a US map when no geometry exists.

UI Improvements

  • Shared tabs: Tab titles are kept on a single line, overflow scroll indicators (chevrons) were added to signal when more tabs are available, and badge color variants (warning/critical) are now supported.
  • Routes tab: The FocusAwareStatusBar is now included on the Routes tab screen to maintain consistent system bar behavior.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 131 files, which is 31 over the limit of 100.

To get a review, narrow the scope:
• coderabbit review --committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 96cf3d59-7446-4b21-b71a-8e8824fd1895

📥 Commits

Reviewing files that changed from the base of the PR and between 15ae7f1 and 9554f9c.

⛔ Files ignored due to path filters (25)
  • .DS_Store is excluded by !**/.DS_Store
  • .agent/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/devtools-flamegraph.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/emerge-xray-ios.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/expo-atlas-treemap.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/fps-drop-graph.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/memory-heap-snapshot.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/xcode-instruments-templates.png is excluded by !**/*.png
  • .agent/skills/react-native-best-practices/references/images/xcode-thread-view.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/devtools-flamegraph.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/emerge-xray-ios.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/expo-atlas-treemap.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/fps-drop-graph.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/memory-heap-snapshot.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/xcode-instruments-templates.png is excluded by !**/*.png
  • .claude/skills/react-native-best-practices/references/images/xcode-thread-view.png is excluded by !**/*.png
📒 Files selected for processing (131)
  • .agent/skills/react-native-best-practices/POWER.md
  • .agent/skills/react-native-best-practices/SKILL.md
  • .agent/skills/react-native-best-practices/agents/openai.yaml
  • .agent/skills/react-native-best-practices/references/bundle-analyze-app.md
  • .agent/skills/react-native-best-practices/references/bundle-analyze-js.md
  • .agent/skills/react-native-best-practices/references/bundle-barrel-exports.md
  • .agent/skills/react-native-best-practices/references/bundle-code-splitting.md
  • .agent/skills/react-native-best-practices/references/bundle-hermes-mmap.md
  • .agent/skills/react-native-best-practices/references/bundle-library-size.md
  • .agent/skills/react-native-best-practices/references/bundle-native-assets.md
  • .agent/skills/react-native-best-practices/references/bundle-r8-android.md
  • .agent/skills/react-native-best-practices/references/bundle-tree-shaking.md
  • .agent/skills/react-native-best-practices/references/js-animations-reanimated.md
  • .agent/skills/react-native-best-practices/references/js-atomic-state.md
  • .agent/skills/react-native-best-practices/references/js-bottomsheet.md
  • .agent/skills/react-native-best-practices/references/js-concurrent-react.md
  • .agent/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md
  • .agent/skills/react-native-best-practices/references/js-measure-fps.md
  • .agent/skills/react-native-best-practices/references/js-memory-leaks.md
  • .agent/skills/react-native-best-practices/references/js-profile-react.md
  • .agent/skills/react-native-best-practices/references/js-react-compiler.md
  • .agent/skills/react-native-best-practices/references/js-uncontrolled-components.md
  • .agent/skills/react-native-best-practices/references/native-android-16kb-alignment.md
  • .agent/skills/react-native-best-practices/references/native-measure-tti.md
  • .agent/skills/react-native-best-practices/references/native-memory-leaks.md
  • .agent/skills/react-native-best-practices/references/native-memory-patterns.md
  • .agent/skills/react-native-best-practices/references/native-platform-setup.md
  • .agent/skills/react-native-best-practices/references/native-profiling.md
  • .agent/skills/react-native-best-practices/references/native-sdks-over-polyfills.md
  • .agent/skills/react-native-best-practices/references/native-threading-model.md
  • .agent/skills/react-native-best-practices/references/native-turbo-modules.md
  • .agent/skills/react-native-best-practices/references/native-view-flattening.md
  • .agent/skills/upgrading-react-native/SKILL.md
  • .agent/skills/upgrading-react-native/agents/openai.yaml
  • .agent/skills/upgrading-react-native/references/expo-sdk-upgrade.md
  • .agent/skills/upgrading-react-native/references/monorepo-singlerepo-targeting.md
  • .agent/skills/upgrading-react-native/references/react.md
  • .agent/skills/upgrading-react-native/references/upgrade-helper-core.md
  • .agent/skills/upgrading-react-native/references/upgrade-verification.md
  • .agent/skills/upgrading-react-native/references/upgrading-dependencies.md
  • .agent/skills/upgrading-react-native/references/upgrading-react-native.md
  • .claude/skills/react-native-best-practices/POWER.md
  • .claude/skills/react-native-best-practices/SKILL.md
  • .claude/skills/react-native-best-practices/agents/openai.yaml
  • .claude/skills/react-native-best-practices/references/bundle-analyze-app.md
  • .claude/skills/react-native-best-practices/references/bundle-analyze-js.md
  • .claude/skills/react-native-best-practices/references/bundle-barrel-exports.md
  • .claude/skills/react-native-best-practices/references/bundle-code-splitting.md
  • .claude/skills/react-native-best-practices/references/bundle-hermes-mmap.md
  • .claude/skills/react-native-best-practices/references/bundle-library-size.md
  • .claude/skills/react-native-best-practices/references/bundle-native-assets.md
  • .claude/skills/react-native-best-practices/references/bundle-r8-android.md
  • .claude/skills/react-native-best-practices/references/bundle-tree-shaking.md
  • .claude/skills/react-native-best-practices/references/js-animations-reanimated.md
  • .claude/skills/react-native-best-practices/references/js-atomic-state.md
  • .claude/skills/react-native-best-practices/references/js-bottomsheet.md
  • .claude/skills/react-native-best-practices/references/js-concurrent-react.md
  • .claude/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md
  • .claude/skills/react-native-best-practices/references/js-measure-fps.md
  • .claude/skills/react-native-best-practices/references/js-memory-leaks.md
  • .claude/skills/react-native-best-practices/references/js-profile-react.md
  • .claude/skills/react-native-best-practices/references/js-react-compiler.md
  • .claude/skills/react-native-best-practices/references/js-uncontrolled-components.md
  • .claude/skills/react-native-best-practices/references/native-android-16kb-alignment.md
  • .claude/skills/react-native-best-practices/references/native-measure-tti.md
  • .claude/skills/react-native-best-practices/references/native-memory-leaks.md
  • .claude/skills/react-native-best-practices/references/native-memory-patterns.md
  • .claude/skills/react-native-best-practices/references/native-platform-setup.md
  • .claude/skills/react-native-best-practices/references/native-profiling.md
  • .claude/skills/react-native-best-practices/references/native-sdks-over-polyfills.md
  • .claude/skills/react-native-best-practices/references/native-threading-model.md
  • .claude/skills/react-native-best-practices/references/native-turbo-modules.md
  • .claude/skills/react-native-best-practices/references/native-view-flattening.md
  • .claude/skills/upgrading-react-native/SKILL.md
  • .claude/skills/upgrading-react-native/agents/openai.yaml
  • .claude/skills/upgrading-react-native/references/expo-sdk-upgrade.md
  • .claude/skills/upgrading-react-native/references/monorepo-singlerepo-targeting.md
  • .claude/skills/upgrading-react-native/references/react.md
  • .claude/skills/upgrading-react-native/references/upgrade-helper-core.md
  • .claude/skills/upgrading-react-native/references/upgrade-verification.md
  • .claude/skills/upgrading-react-native/references/upgrading-dependencies.md
  • .claude/skills/upgrading-react-native/references/upgrading-react-native.md
  • .gitignore
  • src/app/(app)/__tests__/routes.test.tsx
  • src/app/(app)/index.tsx
  • src/app/(app)/routes.tsx
  • src/app/_layout.tsx
  • src/app/call/[id].tsx
  • src/app/routes/poi/[id].tsx
  • src/app/weather-alert/[id].tsx
  • src/components/check-in-timers/__tests__/check-in-bottom-sheet.test.tsx
  • src/components/check-in-timers/__tests__/check-in-tab-content.test.tsx
  • src/components/check-in-timers/__tests__/check-in-timer-card.test.tsx
  • src/components/check-in-timers/check-in-bottom-sheet.tsx
  • src/components/check-in-timers/check-in-tab-content.tsx
  • src/components/check-in-timers/check-in-timer-card.tsx
  • src/components/sidebar/sidebar-content.tsx
  • src/components/status/__tests__/status-bottom-sheet.test.tsx
  • src/components/status/status-bottom-sheet.tsx
  • src/components/ui/__tests__/actionsheet.test.tsx
  • src/components/ui/__tests__/shared-tabs.test.tsx
  • src/components/ui/actionsheet/index.tsx
  • src/components/ui/shared-tabs.tsx
  • src/components/weather-alerts/__tests__/weather-alert-card.test.tsx
  • src/components/weather-alerts/__tests__/weather-alert-detail-map.test.tsx
  • src/components/weather-alerts/weather-alert-card.tsx
  • src/components/weather-alerts/weather-alert-detail-map.tsx
  • src/hooks/__tests__/use-quick-check-in.test.ts
  • src/hooks/__tests__/use-weather-alert-banner.test.ts
  • src/hooks/use-quick-check-in.ts
  • src/hooks/use-weather-alert-banner.ts
  • src/lib/__tests__/check-in-eligibility.test.ts
  • src/lib/__tests__/check-in-timer-utils.test.ts
  • src/lib/__tests__/weather-alert-utils.test.ts
  • src/lib/check-in-eligibility.ts
  • src/lib/check-in-timer-utils.ts
  • src/lib/weather-alert-utils.ts
  • src/models/v4/checkIn/resolvedCheckInTimerResultData.ts
  • src/stores/check-in-timers/__tests__/store.test.ts
  • src/stores/check-in-timers/store.ts
  • src/stores/status/__tests__/store.test.ts
  • src/stores/status/store.ts
  • src/translations/ar.json
  • src/translations/de.json
  • src/translations/en.json
  • src/translations/es.json
  • src/translations/fr.json
  • src/translations/it.json
  • src/translations/pl.json
  • src/translations/sv.json
  • src/translations/uk.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Resgrid-Bot

Resgrid-Bot commented Jul 23, 2026

Copy link
Copy Markdown

Code Review Could Not Complete ⚠️

The review failed before suggestions could be generated.

Reason: Transient error reaching the provider (openai_compatible). Try again.

After fixing the issue, comment @kody review on this PR to re-run the review.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the @kody start-review command at the root of your PR.

  • Validate Business Logic: Ask Kody to validate your code against business rules by adding a comment with the @kody -v business-logic command.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Business Logic

Access your configuration settings here.

<View>
<Button
title="Load Feature"
onPress={() => setShowFeature(true)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Inline arrow functions inside JSX props create new function instances on every render, degrading performance. Move the function definitions outside the render method.

Kody rule violation: Avoid using .bind() or arrow functions in JSX props

Prompt for LLM

File .claude/skills/react-native-best-practices/references/bundle-code-splitting.md:

Line 150:

Inline arrow functions inside JSX props create new function instances on every render, degrading performance. Move the function definitions outside the render method.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

});

ScriptManager.shared.on('error', (scriptId, error) => {
console.error(`Failed: ${scriptId}`, error);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Unstructured error logging via console.error with a template string reduces searchability and violates Rule [3]. Replace this call with a structured logger such as logger.error('chunk_load_failed', { scriptId, err: error }).

Kody rule violation: Include error context in structured logs

Prompt for LLM

File .claude/skills/react-native-best-practices/references/bundle-code-splitting.md:

Line 231:

Unstructured error logging via `console.error` with a template string reduces searchability and violates Rule [3]. Replace this call with a structured logger such as `logger.error('chunk_load_failed', { scriptId, err: error })`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.


```tsx
// Check if chunk loaded correctly
ScriptManager.shared.on('loading', (scriptId) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Memory leak risk identified where an event listener registered on ScriptManager lacks a corresponding removal path, violating Rule [57]. Store the unsubscribe handle and invoke it during cleanup using const off = ScriptManager.shared.on('loading', handler); /* in cleanup */ off();.

Kody rule violation: Proper memory management in event listeners

Prompt for LLM

File .claude/skills/react-native-best-practices/references/bundle-code-splitting.md:

Line 222:

Memory leak risk identified where an event listener registered on `ScriptManager` lacks a corresponding removal path, violating Rule [57]. Store the unsubscribe handle and invoke it during cleanup using `const off = ScriptManager.shared.on('loading', handler); /* in cleanup */ off();`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

<FlatList
data={items}
renderItem={renderItem}
keyExtractor={(item, index) => index.toString()}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Use of an array index as a key in the 'BetterList' keyExtractor causes reordering issues when items are mutated, violating Rule [56] and the document's own guidance at line 237. Use keyExtractor={(item) => item.id} as correctly demonstrated in lines 26 and 153.

Kody rule violation: Avoid array indexes as keys in React lists

Prompt for LLM

File .claude/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md:

Line 94:

Use of an array index as a key in the 'BetterList' `keyExtractor` causes reordering issues when items are mutated, violating Rule [56] and the document's own guidance at line 237. Use `keyExtractor={(item) => item.id}` as correctly demonstrated in lines 26 and 153.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.


```jsx
useEffect(() => {
const sub = EventEmitter.addListener('event', handler);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Unhandled subscription error path identified in EventEmitter.addListener. Provide error handlers to the subscription API and define a deterministic cleanup path.

Kody rule violation: Provide error handlers to subscription/listener APIs

Prompt for LLM

File .claude/skills/react-native-best-practices/references/js-memory-leaks.md:

Line 17:

Unhandled subscription error path identified in `EventEmitter.addListener`. Provide error handlers to the subscription API and define a deterministic cleanup path.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

// BAD: Memory leak
const BadTimerComponent = () => {
useEffect(() => {
const timer = setInterval(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Resource leak identified in setInterval without a deterministic cleanup path. Return a cleanup function that clears the timer, e.g., return () => clearInterval(timer);.

Kody rule violation: Clear timers on teardown/unmount

Prompt for LLM

File .claude/skills/react-native-best-practices/references/js-memory-leaks.md:

Line 126:

Resource leak identified in `setInterval` without a deterministic cleanup path. Return a cleanup function that clears the timer, e.g., `return () => clearInterval(timer);`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.


const handleChange = (text) => {
setQuery(text);
fetchResults(text).then(setResults);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Missing debounce mechanism in the recommended handleChange example triggers fetchResults on every keystroke, violating Rule [53] for rapid input network calls. Apply debounce to the fetch call using const debouncedSearch = debounce((text) => fetchResults(text).then(setResults).catch(...), 300);.

Kody rule violation: Debounce or throttle user input that triggers work

Prompt for LLM

File .claude/skills/react-native-best-practices/references/js-uncontrolled-components.md:

Line 153:

Missing debounce mechanism in the recommended `handleChange` example triggers `fetchResults` on every keystroke, violating Rule [53] for rapid input network calls. Apply debounce to the fetch call using `const debouncedSearch = debounce((text) => fetchResults(text).then(setResults).catch(...), 300);`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

```tsx
import performance from 'react-native-performance';

export default function HomeScreen() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Default export used for the HomeScreen component introduces naming inconsistencies and complicates refactoring. Change this to a named export using export function HomeScreen() or function HomeScreen() {} with export { HomeScreen };.

Kody rule violation: Avoid default exports

Prompt for LLM

File .claude/skills/react-native-best-practices/references/native-measure-tti.md:

Line 173:

Default export used for the `HomeScreen` component introduces naming inconsistencies and complicates refactoring. Change this to a named export using `export function HomeScreen()` or `function HomeScreen() {}` with `export { HomeScreen };`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Comment on lines +162 to +168
override fun heavyOperation(input: Double, promise: Promise?) {
moduleScope.launch {
// Heavy work on coroutine
val result = expensiveComputation(input)
promise?.resolve(result)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Unhandled promise rejection identified in the Android coroutine implementation where expensiveComputation lacks a try/catch block, causing the JS promise to hang indefinitely if an exception occurs. Wrap the body in try { val result = ...; promise?.resolve(result) } catch (e: Exception) { promise?.reject("ERROR", e.message, e) }, mirroring the example at lines 251-263.

Kody rule violation: Handle async operations with proper error handling

Prompt for LLM

File .claude/skills/react-native-best-practices/references/native-turbo-modules.md:

Line 162 to 168:

Unhandled promise rejection identified in the Android coroutine implementation where `expensiveComputation` lacks a `try/catch` block, causing the JS promise to hang indefinitely if an exception occurs. Wrap the body in `try { val result = ...; promise?.resolve(result) } catch (e: Exception) { promise?.reject("ERROR", e.message, e) }`, mirroring the example at lines 251-263.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Comment thread src/app/(app)/index.tsx
}, [extremeAlerts.length]);
const handleWeatherAlertBannerPress = useCallback(() => {
dismissBanner();
router.push('/(app)/weather-alerts');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Hardcoded route string literal identified in router.push, violating Rule [7] for centralized, reusable string constants. Define a route constant such as const WEATHER_ALERTS_ROUTE = '/(app)/weather-alerts' and reference it in the router call.

Kody rule violation: Centralize string constants

Prompt for LLM

File src/app/(app)/index.tsx:

Line 77:

Hardcoded route string literal identified in `router.push`, violating Rule [7] for centralized, reusable string constants. Define a route constant such as `const WEATHER_ALERTS_ROUTE = '/(app)/weather-alerts'` and reference it in the router call.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.


import { Actionsheet } from '../actionsheet';

const lastCloseOnOverlayClick = () => mockUIActionsheet.mock.calls[mockUIActionsheet.mock.calls.length - 1][0].closeOnOverlayClick;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Potential TypeError identified where array index access on mock.calls lacks bounds verification, throwing if the collection is empty. Use optional chaining (?.) when accessing indices: mock.calls[...]?.[0]?.closeOnOverlayClick.

Kody rule violation: Add null checks before accessing properties

Prompt for LLM

File src/components/ui/__tests__/actionsheet.test.tsx:

Line 41:

Potential `TypeError` identified where array index access on `mock.calls` lacks bounds verification, throwing if the collection is empty. Use optional chaining (`?.`) when accessing indices: `mock.calls[...]?.[0]?.closeOnOverlayClick`.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.


import { Actionsheet } from '../actionsheet';

const lastCloseOnOverlayClick = () => mockUIActionsheet.mock.calls[mockUIActionsheet.mock.calls.length - 1][0].closeOnOverlayClick;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Unsecured array indexing on mock.calls[...][0] can cause exceptions when the collection is empty. Use safer accessors or verify mock.calls is populated before accessing indices.

Kody rule violation: Check query results before accessing indices

Prompt for LLM

File src/components/ui/__tests__/actionsheet.test.tsx:

Line 41:

Unsecured array indexing on `mock.calls[...][0]` can cause exceptions when the collection is empty. Use safer accessors or verify `mock.calls` is populated before accessing indices.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

}, [polygonGeoJSON]);
cameraRef.current.setCamera({
centerCoordinate: [mapCenter.longitude, mapCenter.latitude],
zoomLevel: 8,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Magic number identified where the numeric literal 8 represents a zoom level without a named constant, unlike MAP_PADDING on line 15. Extract this value into a named constant such as const DEFAULT_ZOOM_LEVEL = 8; and reference it in both the setCamera call and the Camera component props, including its duplicate on line 64.

Kody rule violation: Replace magic numbers with named constants

Prompt for LLM

File src/components/weather-alerts/weather-alert-detail-map.tsx:

Line 47:

Magic number identified where the numeric literal `8` represents a zoom level without a named constant, unlike `MAP_PADDING` on line 15. Extract this value into a named constant such as `const DEFAULT_ZOOM_LEVEL = 8;` and reference it in both the `setCamera` call and the `Camera` component props, including its duplicate on line 64.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

@@ -0,0 +1,93 @@
import { CHECK_IN_TARGET_TYPE, type CheckInEligibilityContext, isCheckInTargetEligible } from '@/lib/check-in-eligibility';

export type CheckInTimerStatus = 'critical' | 'ok' | 'overdue' | 'unknown' | 'warning';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Type duplication risk identified where CheckInTimerStatus is manually maintained alongside STATUS_COLORS (line 18) and STATUS_SEVERITY (line 26). Declare STATUS_COLORS with as const first, then derive the type using type CheckInTimerStatus = keyof typeof STATUS_COLORS to prevent drift.

Kody rule violation: Derive TypeScript types from validation schemas

Prompt for LLM

File src/lib/check-in-timer-utils.ts:

Line 3:

Type duplication risk identified where `CheckInTimerStatus` is manually maintained alongside `STATUS_COLORS` (line 18) and `STATUS_SEVERITY` (line 26). Declare `STATUS_COLORS` with `as const` first, then derive the type using `type CheckInTimerStatus = keyof typeof STATUS_COLORS` to prevent drift.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

// A status with no destination (Detail 0) must not land on 'select-destination'.
const getInitialStepForStatus = (status: StatusType): StatusStep => {
if (toStatusNumber(status.Detail) > 0) {
return 'select-destination';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules low

Magic string identified where a bare literal 'select-destination' represents a StatusStep value, creating refactoring risks and duplication. Define StatusStep values as named constants using const STATUS_STEPS = { SELECT_DESTINATION: 'select-destination', ADD_NOTE: 'add-note' } as const or a string enum, and return the constant reference.

Kody rule violation: Use enums instead of magic strings

Prompt for LLM

File src/stores/status/store.ts:

Line 68:

Magic string identified where a bare literal `'select-destination'` represents a `StatusStep` value, creating refactoring risks and duplication. Define `StatusStep` values as named constants using `const STATUS_STEPS = { SELECT_DESTINATION: 'select-destination', ADD_NOTE: 'add-note' } as const` or a string enum, and return the constant reference.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

@ucswift

ucswift commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

Approve

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This PR is approved.

@ucswift
ucswift merged commit 8243113 into master Jul 23, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants