Release v2.0.17#2004
Conversation
Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
…tem quantity adjustment Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
… through guard Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
- Clear searchValue in handleAddSelected so search resets after adding items - Wrap addItemsToPack in try/catch with Alert feedback on failure - Remove redundant `packId as string` cast (already typed as string) - Remove unused i18n keys: catalog.quickAdd, catalog.adjustQuantity, catalog.tapToAdjust
…oose-from-catalog-option-again # Conflicts: # apps/expo/features/catalog/components/CatalogBrowserModal.tsx # apps/expo/features/packs/components/AddPackItemActions.tsx
Add Share to the react-native import to resolve the TS2304 "Cannot find name 'Share'" type-check error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… performed via the Web UI
chore(wrangler): add migrations for TikTokContainer to match deletion…
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
chore(api): refactor container name to AppContainer
…template-generation fix(api): address memory limit issue in video to pack template genera…
…from-youtube feat: support generating of pack template from youtube videos
Fix/Bug Fixes 26.03.26
📝 WalkthroughWalkthroughThis PR bundles version 2.0.17 with multiple features: a weather alerts system (new screens, preferences, dynamic data from API), catalog improvements (recently-used item tracking, popular items hook, quantity selection in browser modal), safe-area inset handling across multiple screens, pack template import refactored from TikTok-only to generalized online content (supporting YouTube + TikTok via transcript fetching), Google Genai video upload integration in the backend, container/environment variable renaming (TikTokContainer → AppContainer), and localization updates. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
apps/expo/app/(app)/(tabs)/profile/index.tsx (3)
33-33:⚠️ Potential issue | 🔴 CriticalMissing
Linkingimport causes an unresolved identifier.Line 158 calls
Linking.openSettings()butLinkingis not imported in Line 33, causing TS2304.🔧 Suggested fix
-import { Alert, Platform, TouchableOpacity, View } from 'react-native'; +import { Alert, Linking, Platform, TouchableOpacity, View } from 'react-native';Also applies to: 158-158
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/(tabs)/profile/index.tsx at line 33, The code calls Linking.openSettings() in the Profile component but Linking is not imported, causing an unresolved identifier; fix by adding Linking to the React Native imports so the symbol Linking is available (update the import statement that currently imports Alert, Platform, TouchableOpacity, View to also import Linking) and ensure any other usages of Linking in this file reference the same imported symbol.
213-213:⚠️ Potential issue | 🔴 CriticalUse a typed color token for the success icon.
Line 213 uses
colors.green, which is not on the current theme type and triggers TS2339. Please switch to a valid token from your theme contract (for examplecolors.primaryor another existing success token).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/(tabs)/profile/index.tsx at line 213, The success icon currently uses an untyped color token (materialIcon: { name: 'check-circle-outline', color: colors.green }), which causes TS2339; update the color to a valid theme token (for example colors.primary or your theme's success token) so it matches the theme contract. Locate the materialIcon declaration in the profile component (the object with name 'check-circle-outline') and replace colors.green with an existing typed token (e.g., colors.primary or colors.success) ensuring the imported colors type includes that token. Run TypeScript to confirm the error is resolved.
140-142:⚠️ Potential issue | 🔴 CriticalRemove the
{ size: true }option fromgetInfoAsync()—it's unsupported and unnecessary.The
sizefield is always included in the returnedFileInfoobject inexpo-file-system/legacy(v19.0.21). TheInfoOptionstype only supports{ md5?: boolean }, making{ size: true }a TypeScript error. Simply callFileSystem.getInfoAsync(image.uri)without options; the size will still be available on the result.🔧 Suggested fix
- const info = await FileSystem.getInfoAsync(image.uri, { size: true }); + const info = await FileSystem.getInfoAsync(image.uri); if (info.exists && info.size > AVATAR_MAX_BYTES) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/(tabs)/profile/index.tsx around lines 140 - 142, The call to FileSystem.getInfoAsync in the profile screen passes an unsupported options object ({ size: true }); remove the options so call FileSystem.getInfoAsync(image.uri) instead — the returned FileInfo already includes size. Update the check that uses info.size (and AVATAR_MAX_BYTES) to remain the same and ensure TypeScript no longer errors; no other logic changes are needed where info and image.uri are referenced.apps/expo/features/weather/screens/LocationsScreen.tsx (1)
122-143:⚠️ Potential issue | 🟠 MajorDouble
paddingTop: insets.topcauses excessive top spacing.Both
SafeAreaView(line 122) and the search containerView(line 143) applypaddingTop: insets.top. This pushes the search input down by 2× the safe area inset.🐛 Proposed fix: Remove duplicate padding from search container
- <View className="p-4" style={{ paddingTop: insets.top }}> + <View className="p-4">🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/weather/screens/LocationsScreen.tsx` around lines 122 - 143, The search container View (the <View className="p-4" style={{ paddingTop: insets.top }}>) is redundantly applying paddingTop already set on the SafeAreaView; remove the duplicate by deleting the style paddingTop from that inner View (leave className="p-4" intact) so only SafeAreaView provides insets.top, ensuring LargeTitleHeader and the search input are not pushed down twice.packages/api/container_src/server.ts (1)
36-55:⚠️ Potential issue | 🟡 MinorPotential issue: GoogleGenAI client initialized before environment validation.
The
googleAiclient is initialized at line 37-39 usingprocess.env.GOOGLE_GENAI_API_KEYdirectly, but environment validation viavalidateEnv()happens later (line 42). IfGOOGLE_GENAI_API_KEYis missing, the client will be created with an undefined API key, and the error will only surface later when upload is attempted.Consider deferring initialization or validating the key exists first.
Proposed fix: Defer GoogleGenAI initialization
-// GoogleGenAI client (for video upload) -const googleAi = new GoogleGenAI({ - apiKey: process.env.GOOGLE_GENAI_API_KEY, -}); +// GoogleGenAI client (for video upload) - initialized after env validation +let googleAi: GoogleGenAI | null = null; try { env = validateEnv(); s3Client = new S3Client({ region: 'auto', endpoint: `https://${env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`, credentials: { accessKeyId: env.R2_ACCESS_KEY_ID, secretAccessKey: env.R2_SECRET_ACCESS_KEY, }, }); console.log('R2 client initialized successfully'); + googleAi = new GoogleGenAI({ apiKey: env.GOOGLE_GENAI_API_KEY }); + console.log('GoogleGenAI client initialized successfully'); } catch (error) { console.warn('R2 client initialization failed:', error); - console.warn('Image rehosting will be disabled'); + console.warn('Image rehosting and video upload will be disabled'); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/container_src/server.ts` around lines 36 - 55, The GoogleGenAI client (googleAi) is being constructed before environment validation; move or defer initialization until after validateEnv() returns so the API key is validated, or explicitly check env.GOOGLE_GENAI_API_KEY before creating the GoogleGenAI instance; update the code to call validateEnv() first, then create new GoogleGenAI({ apiKey: env.GOOGLE_GENAI_API_KEY }) (or guard creation with a conditional and handle the missing-key case) so GoogleGenAI is never instantiated with an undefined key.packages/api/src/routes/packTemplates/generateFromOnlineContent.ts (1)
296-308:⚠️ Potential issue | 🔴 CriticalTypeScript error: Invalid type for Sentry
captureExceptionsecond argument.The pipeline reports
TS2345: Argument of type 'unknown' is not assignable to parameter of type 'EventHint | undefined'at line 298. Theas unknowncast is incorrect.Proposed fix
} catch (apiError) { console.error('TikTok service call failed:', apiError); c.get('sentry').captureException(apiError, { extra: { tiktokUrl: contentUrl, errorType: 'tiktok_service_error' }, - } as unknown); + }); return c.json(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts` around lines 296 - 308, The Sentry capture call is being passed an invalid cast (as unknown); instead construct a properly typed EventHint and pass it to c.get('sentry').captureException: import the EventHint type from Sentry (e.g., '@sentry/types' or '@sentry/node'), create const hint: EventHint = { extra: { tiktokUrl: contentUrl, errorType: 'tiktok_service_error' } }, and call c.get('sentry').captureException(apiError, hint). This keeps the additional context while satisfying TypeScript for captureException.
🟡 Minor comments (9)
apps/expo/features/ai-packs/screens/AIPacksScreen.tsx-80-80 (1)
80-80:⚠️ Potential issue | 🟡 MinorTop inset is applied twice.
Line 80 and Line 83 both add
paddingTop: insets.top, which likely creates extra vertical spacing. Keeping it on the outerSafeAreaViewonly should avoid the double offset.🔧 Suggested fix
- <View className="px-4 py-6 space-y-6" style={{ paddingTop: insets.top }}> + <View className="px-4 py-6 space-y-6">Also applies to: 83-83
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/ai-packs/screens/AIPacksScreen.tsx` at line 80, The outer SafeAreaView (the one with className="flex-1" and style={{ paddingTop: insets.top }}) already applies the top inset, so remove the duplicate paddingTop: insets.top from the inner SafeAreaView in AIPacksScreen.tsx (leave any other styles on the inner SafeAreaView intact); ensure only the outer SafeAreaView uses paddingTop to avoid double vertical offset.apps/expo/features/weather/screens/LocationsScreen.tsx-14-14 (1)
14-14:⚠️ Potential issue | 🟡 MinorUnused
Platformimport andheaderPaddingTopvariable.
Platformis imported (line 14) and used to computeheaderPaddingTop(line 119), but this value is never applied anywhere in the component's render output. This appears to be leftover code from an incomplete implementation.🧹 Proposed fix: Remove unused code
Keyboard, - Platform, Pressable,const showLocationsList = filteredLocations.length > 0; - const headerPaddingTop = Platform.OS === 'ios' ? 80 : 24;Also applies to: 119-119
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/weather/screens/LocationsScreen.tsx` at line 14, Remove the unused Platform import and the unused headerPaddingTop calculation inside the LocationsScreen component: delete the Platform import near the top and remove the headerPaddingTop constant (and any related Platform.OS checks) around where headerPaddingTop is defined so there is no dead code left; ensure LocationsScreen compiles and no other references to headerPaddingTop remain.apps/expo/features/weather/hooks/useWeatherAlert.ts-126-152 (1)
126-152:⚠️ Potential issue | 🟡 MinorInner callbacks also use
anytype.The forecast hour iteration callbacks at lines 129 and 142 use
anytyping for the hour objects. These should be typed according to the weather API response structure.🔧 Proposed fix
- const willRain = todayHours.some((h: any) => h.condition?.text?.toLowerCase().includes('rain')); + const willRain = todayHours.some((h: ForecastHour) => h.condition?.text?.toLowerCase().includes('rain')); - const highWindComing = todayHours.some((h: any) => h.wind_kph >= 30); + const highWindComing = todayHours.some((h: ForecastHour) => h.wind_kph >= 30);As per coding guidelines: "Never use
anyin TypeScript — use proper types orunknown"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/weather/hooks/useWeatherAlert.ts` around lines 126 - 152, The callbacks use (h: any) for forecast hour objects (used in todayHours, willRain and highWindComing) which violates the no-any rule; define a proper Hour type/interface matching the API (e.g., Hour { condition?: { text?: string }; wind_kph?: number }) and type forecastDays/todayHours accordingly (e.g., todayHours: Hour[] = forecastDays[0]?.hour || []). Then replace (h: any) with (h: Hour) and add lightweight runtime guards where needed (optional chaining and typeof checks) in willRain and highWindComing to safely access condition.text and wind_kph.apps/expo/features/weather/screens/LocationSearchScreen.tsx-35-35 (1)
35-35:⚠️ Potential issue | 🟡 MinorFix incorrect ref type annotation.
The ref should use explicit generic typing:
useRef<SearchInputRef>(null)instead ofconst searchInputRef: SearchInputRef = useRef(null). The latter creates a type mismatch sinceuseRef(null)returns aRefObject, not the component instance type directly.🐛 Proposed fix
- const searchInputRef: SearchInputRef = useRef(null); + const searchInputRef = useRef<SearchInputRef>(null);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/weather/screens/LocationSearchScreen.tsx` at line 35, The ref declaration for searchInputRef is typed incorrectly; change the declaration to use React's generic useRef typing so the variable is a RefObject instead of the raw instance type — replace the current line that declares searchInputRef with a generic useRef usage: useRef<SearchInputRef>(null), referencing the SearchInputRef type and the useRef hook to ensure the ref has the correct RefObject type.apps/expo/features/packs/components/AddPackItemActions.tsx-108-113 (1)
108-113:⚠️ Potential issue | 🟡 MinorMove recently-used tracking after a successful add.
Right now failures still persist items to “recently used” because tracking happens before the API call. Reorder it inside the
tryblock afterawait addItemsToPack(...).Suggested fix
if (catalogItems.length > 0) { - trackRecentlyUsed(catalogItems); try { await addItemsToPack(packId, catalogItems as CatalogItemWithPackItemFields[]); + trackRecentlyUsed(catalogItems); } catch (error) { console.error('Error adding catalog items to pack:', error); Alert.alert(t('common.error'), t('catalog.somethingWentWrong')); } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/packs/components/AddPackItemActions.tsx` around lines 108 - 113, The call to trackRecentlyUsed currently runs before the API call so failures still mark items as recently used; move the trackRecentlyUsed(catalogItems) invocation into the try block immediately after await addItemsToPack(packId, catalogItems as CatalogItemWithPackItemFields[]) so it only runs on success, and remove the earlier pre-call invocation; keep the existing catch behavior that logs the error and shows Alert.alert.apps/expo/features/pack-templates/screens/PackTemplateListScreen.tsx-114-114 (1)
114-114:⚠️ Potential issue | 🟡 MinorRemove double top inset padding from SafeAreaView and child View.
SafeAreaViewfrom react-native-safe-area-context automatically applies safe area insets as padding on all edges (including top) by default. The explicitpaddingTop: insets.topon line 114 is added to (not replacing) this automatic padding, creating a double-padding effect that pushes content down unnecessarily. The same issue applies to the View at line 131, which should only add the 22px spacing without the redundantinsets.top.Suggested fix
-<SafeAreaView className="flex-1 " style={{ paddingTop: insets.top }}> +<SafeAreaView className="flex-1"> @@ -<View className="bg-background gap-2 px-4 pb-2" style={{ paddingTop: insets.top + 22 }}> +<View className="bg-background gap-2 px-4 pb-2" style={{ paddingTop: 22 }}>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/pack-templates/screens/PackTemplateListScreen.tsx` at line 114, The SafeAreaView in PackTemplateListScreen currently adds explicit paddingTop: insets.top on top of the SafeAreaView's own automatic insets, causing double top padding; remove the inline style paddingTop: insets.top from the SafeAreaView and update the child View (the one adding spacing at the top) to only add the fixed 22px (e.g., marginTop or paddingTop: 22) without referencing insets.top so the safe-area padding is applied once by SafeAreaView.apps/expo/app/(app)/weather-alerts.tsx-160-160 (1)
160-160:⚠️ Potential issue | 🟡 MinorUse i18n for user-facing strings.
The loading and empty-state messages are hardcoded in English. Use the translation hook for consistency.
🌐 Proposed fix
- {loading && <Text className="mx-4">Loading alerts...</Text>} + {loading && <Text className="mx-4">{t('common.loading')}</Text>} {error && <Text className="mx-4 text-red-500">{error}</Text>} {!loading && alerts.length === 0 && ( <Text className="mx-4 text-muted-foreground"> - No active alerts for {activeLocation?.name ?? 'this location'} + {t('weather.noActiveAlerts', { location: activeLocation?.name ?? t('weather.thisLocation') })} </Text> )}You may need to add the corresponding translation keys.
Also applies to: 165-167
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/weather-alerts.tsx at line 160, The hardcoded user-facing strings in the WeatherAlerts component (the loading text rendered when loading is true and the empty-state messages around lines where alerts are rendered) must use the app i18n hook instead of literal English; import and call the translation hook (e.g., useTranslation or t from your i18n util) at the top of the weather-alerts component, replace "Loading alerts..." and any empty-state Text values with t('weatherAlerts.loading') / t('weatherAlerts.empty') (or chosen keys), and add those keys to the translation files for all locales; update the JSX that checks the loading and alerts variables so it renders the translated strings via the translation function.apps/expo/app/(app)/weather-alerts.tsx-152-152 (1)
152-152:⚠️ Potential issue | 🟡 MinorReplace invalid icon name
'tune-vertical-variant'— this icon does not exist inMaterialCommunityIconsfrom@expo/vector-icons. Either use a valid icon name from the MaterialCommunityIcons set (check https://icons.expo.fyi/), switch to a different icon library that includes this icon, or use an alternative icon name that matches your UI requirements.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/weather-alerts.tsx at line 152, The JSX uses <MaterialCommunityIcons name="tune-vertical-variant" ... /> which is an invalid icon name; update the MaterialCommunityIcons usage in weather-alerts.tsx to a valid icon name from the MaterialCommunityIcons set (check https://icons.expo.fyi/) or switch to a different icon component/library that contains the desired glyph, e.g., replace "tune-vertical-variant" with a confirmed name like "tune" or another matching icon, and ensure the import of MaterialCommunityIcons remains correct.packages/api/src/routes/packTemplates/generateFromOnlineContent.ts-449-453 (1)
449-453:⚠️ Potential issue | 🟡 MinorAvoid using
as anyper coding guidelines.Line 453 uses
as anywhich violates the coding guideline "Never useanyin TypeScript". The SentrycaptureExceptionextra parameter should be properly typed.Proposed fix
console.error('Error generating pack template:', error); c.get('sentry').captureException(error, { extra: { contentUrl, errorType: 'template_generation_error' }, - } as any); + });As per coding guidelines: "Never use
anyin TypeScript — use proper types orunknown"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts` around lines 449 - 453, The current catch block uses an unsafe "as any" cast when calling c.get('sentry').captureException(error, { extra: ... } as any); replace that with a properly typed Sentry hint by importing the correct Sentry type (e.g., Sentry.EventHint or Sentry.CaptureContext from the Sentry package you use) and creating a typed variable for the second argument (e.g., const hint: Sentry.EventHint = { extra: { contentUrl, errorType: 'template_generation_error' } }) then pass that typed variable to c.get('sentry').captureException(error, hint) so there is no use of any and the extra payload is correctly typed.
🧹 Nitpick comments (8)
apps/expo/features/weather/hooks/useWeatherAlert.ts (1)
184-216: Consider using React Query instead of manual useEffect/useState for data fetching.Per coding guidelines for
apps/expo/features/*/hooks/**/*.ts{,x}: "Use React Query hooks (useQuery,useMutation,useInfiniteQuery) for data fetching."Using React Query would provide built-in caching, deduplication, refetching, and better loading/error state management.
♻️ Suggested refactor using React Query
import { useQuery } from '@tanstack/react-query'; export function useWeatherAlerts() { const activeLocation = useAtomValue(activeLocationAtom); const { data: alerts = [], isLoading: loading, error } = useQuery({ queryKey: ['weatherAlerts', activeLocation?.id], queryFn: async () => { const data = await getWeatherData(activeLocation!.id); return generateAlerts(data, activeLocation); }, enabled: !!activeLocation?.id, }); return { alerts, loading, error: error?.message ?? null, activeLocation, }; }As per coding guidelines: "Use React Query hooks for data fetching in Expo feature hooks"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/weather/hooks/useWeatherAlert.ts` around lines 184 - 216, Replace the manual useEffect/useState fetch in useWeatherAlerts with a React Query useQuery-based implementation: use the activeLocationAtom value for the query key (e.g., ['weatherAlerts', activeLocation?.id]) and set enabled to !!activeLocation?.id, call getWeatherData(activeLocation!.id) in the queryFn and transform the result with generateAlerts before returning; map useQuery's data/isLoading/error to alerts/loading/error and return activeLocation as before. Ensure you import useQuery from `@tanstack/react-query` and convert error to a string (error?.message ?? null).apps/expo/app/(app)/weather-alert-preferences.tsx (1)
137-137: Avoidas nevertype casts; define proper types instead.Using
as neverbypasses TypeScript's type checking entirely, which defeats the purpose of type safety. This pattern is fragile and will hide errors if icon names or translation keys become invalid.♻️ Suggested approach for icon names
Import the icon type and use it in
AlertTypeConfig:+import type { MaterialCommunityIcons } from '@expo/vector-icons'; + type AlertTypeConfig = { key: keyof Omit<AlertPreferences, 'weatherNotifications' | 'locationMonitoring'>; - iconName: string; + iconName: keyof typeof MaterialCommunityIcons.glyphMap; iconColor: string; };Then remove the
as nevercast on line 137:- <Icon name={iconName as never} size={18} color="white" /> + <Icon name={iconName} size={18} color="white" />For translation keys (lines 145, 148), consider defining a union type of valid weather translation keys.
Also applies to: 145-145, 148-148
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/app/`(app)/weather-alert-preferences.tsx at line 137, Replace the unsafe "as never" cast by giving iconName a proper type: import the icon name type used by the Icon component (or define a union of allowed icon string literals) and use that type in AlertTypeConfig so iconName is typed correctly; update usages of Icon to accept iconName with the correct type instead of casting. Likewise, replace the loose translation key usage by defining a union type of valid weather translation keys (used where you build titles/subtitles) and use it in AlertTypeConfig so the translation function receives a properly typed key. Ensure AlertTypeConfig references these new types and remove all "as never" casts (including the Icon invocation and translation key usages).apps/expo/features/pack-templates/components/TemplateCreationOptions.tsx (1)
83-101: Stale comment: update to reflect the new functionality.The comment on line 83 still references TikTok, but the code now handles generic online content import.
📝 Suggested fix
- {/* Import from TikTok option (only for admins) */} + {/* Import from online content option (only for admins) */} {isAdmin && isAuthenticated && (🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/pack-templates/components/TemplateCreationOptions.tsx` around lines 83 - 101, Update the stale inline comment that mentions "Import from TikTok" to reflect the new generic online content import behavior; locate the JSX block that renders the import option (the TouchableOpacity using handleImportFromOnlineContent inside TemplateCreationOptions.tsx) and replace or remove the outdated comment so it accurately describes the "Import from online content" option for admins who are authenticated.packages/api/src/routes/packTemplates/generateFromOnlineContent.ts (1)
362-364: Error message still references "TikTok post" but this endpoint now handles YouTube content too.Consider updating the error message to be generic.
Proposed fix
} else { - throw new Error('No content found in TikTok post (no images or video)'); + throw new Error('No content found (no images, video, or transcript)'); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts` around lines 362 - 364, The error thrown in the else branch of generateFromOnlineContent still says "No content found in TikTok post (no images or video)"; change that message to a generic one that covers YouTube and other sources (e.g., "No content found in online post (no images or video)") by updating the throw new Error(...) statement inside the else block of the generateFromOnlineContent handler so it no longer references TikTok specifically.apps/expo/features/pack-templates/components/OnlineContentImportModal.tsx (1)
19-22: Interface name is inconsistent with the renamed component.The interface is still named
TikTokImportModalPropsbut the component was renamed toOnlineContentImportModal. Consider renaming for consistency.Proposed fix
-interface TikTokImportModalProps { +interface OnlineContentImportModalProps { visible: boolean; onClose: () => void; } -export function OnlineContentImportModal({ visible, onClose }: TikTokImportModalProps) { +export function OnlineContentImportModal({ visible, onClose }: OnlineContentImportModalProps) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/pack-templates/components/OnlineContentImportModal.tsx` around lines 19 - 22, Rename the mismatched props interface to match the component: change TikTokImportModalProps to OnlineContentImportModalProps and update all references (the component declaration OnlineContentImportModal, any prop annotations, and any exports/imports) to use the new name so the props type and component name are consistent; search for occurrences of TikTokImportModalProps and replace them with OnlineContentImportModalProps and adjust any tests/types that reference the old name.apps/expo/features/catalog/components/CatalogBrowserModal.tsx (1)
231-240: Type inconsistency: Returns items withquantityproperty but signature expectsCatalogItem[].The
handleAddSelectedfunction adds aquantityproperty to items at line 235, butonItemsSelectedexpectsCatalogItem[]which doesn't includequantity(perapps/expo/features/catalog/types.ts:23-37). While this works at runtime because downstream code casts toCatalogItemWithPackItemFields[], it's not type-safe.Consider using the existing
CatalogItemWithQuantitytype from the types file for the callback signature.Proposed fix
// In types.ts or at the top of this file import type { CatalogItem, CatalogItemWithQuantity } from '../types'; type CatalogBrowserModalProps = { visible: boolean; onClose: () => void; - onItemsSelected: (items: CatalogItem[]) => void; + onItemsSelected: (items: CatalogItemWithQuantity[]) => void; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/expo/features/catalog/components/CatalogBrowserModal.tsx` around lines 231 - 240, The handler handleAddSelected builds items with a quantity field but calls onItemsSelected typed as CatalogItem[], causing a type mismatch; update the onItemsSelected callback signature (and any related uses) to accept CatalogItemWithQuantity[] (the type defined in features/catalog/types.ts) and ensure handleAddSelected returns that type by mapping to CatalogItemWithQuantity (use itemQuantities.get(item.id) ?? 1 for quantity). Also update any upstream prop types or callers of CatalogBrowserModal that provide onItemsSelected to match the new CatalogItemWithQuantity[] signature.packages/api/src/containers/AppContainer.ts (1)
9-15: Update the lifecycle log labels toAppContainertoo.The class rename stops at the declaration;
onStart,onStop, andonErrorstill emitTikTok container…, which makes log filtering and troubleshooting inconsistent with the new binding name.🪵 Suggested log cleanup
override onStart() { - console.log('TikTok container successfully started'); + console.log('AppContainer successfully started'); } override onStop() { - console.log('TikTok container successfully shut down'); + console.log('AppContainer successfully shut down'); } override onError(error: unknown) { - console.log('TikTok container error:', error); + console.log('AppContainer error:', error); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/src/containers/AppContainer.ts` around lines 9 - 15, The lifecycle log messages still use the old "TikTok container…" label; update them to "AppContainer" for consistency. In the AppContainer class, modify the logging calls inside onStart, onStop, and onError to replace any "TikTok container" text with "AppContainer" (or an equivalent exact label), and ensure any processLogger or logger.error/info usages include the new label so log filtering works consistently across those methods.packages/api/test/generate-from-tiktok.test.ts (1)
41-47: Make the mock fail when the binding isn't passed.
getContainerignores its first argument right now, so this suite still passes ifAPP_CONTAINERisundefinedor the rename is miswired. That leaves thegetEnv()→getContainer()handoff inpackages/api/src/routes/packTemplates/generateFromOnlineContent.ts:55-105effectively untested.🧪 Suggested assertion
vi.mock('@cloudflare/containers', () => ({ Container: class MockContainer {}, - getContainer: vi.fn(() => ({ - fetch: (...args: Parameters<typeof mockContainerFetch>) => mockContainerFetch(...args), - })), + getContainer: vi.fn((binding: unknown) => { + if (!binding) { + throw new Error('APP_CONTAINER binding was not provided'); + } + return { + fetch: (...args: Parameters<typeof mockContainerFetch>) => mockContainerFetch(...args), + }; + }), }));🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/api/test/generate-from-tiktok.test.ts` around lines 41 - 47, The mock for getContainer currently ignores its first argument so tests don't verify the binding is passed; update the vi.mock implementation for '@cloudflare/containers' so getContainer examines its first parameter (the binding name/identifier used by getEnv() → getContainer()) and throws or returns a rejected promise when that argument is undefined or not the expected binding (e.g., "APP_CONTAINER"), ensuring tests fail if the binding is missing or misnamed; reference getContainer, MockContainer and mockContainerFetch in the mock and then adjust the test to call getContainer with the correct binding name so the suite verifies the handoff.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/expo/app/`(app)/(tabs)/profile/notifications.tsx:
- Around line 74-77: FormSection is being passed an invalid title prop causing
TS2322; remove the title prop from the FormSection instance (the one using
materialIconProps={{ name: 'weather-cloudy-alert' }}). If a visible heading is
required, render a separate Text (or Heading) component immediately above this
FormSection or move title-like content into an allowed prop such as footnote or
platform-specific ios={{ title: '...' }} consistent with how
weather-alert-preferences.tsx handles titles. Ensure only allowed props (e.g.,
materialIconProps, footnote, ios) are used on FormSection.
- Around line 100-107: Replace the invalid Icon name in the Notifications UI:
inside the Pressable block in notifications.tsx where Icon is rendered (the Icon
usage with name="tune-vertical-variant"), change the name to a valid
`@roninoss/icons` value such as "cog-outline" (the same icon used elsewhere) so
the prop matches the library's allowed union; note that "tune-vertical-variant"
is from MaterialCommunityIcons (used in weather-alerts.tsx) and should not be
used with this Icon component.
In `@apps/expo/app/`(app)/current-pack/[id].tsx:
- Around line 138-145: The inner View that renders the avatar row (the element
with className "flex-row items-center p-4") duplicates the safe-area padding
already applied to SafeAreaView; remove the duplicate paddingTop by deleting the
style entry or setting paddingTop to 0 on that View so only SafeAreaView applies
insets.top. Keep the SafeAreaView style={{ paddingTop: insets.top }} and ensure
no other parent/content containers also add insets.top.
In `@apps/expo/app/`(app)/weather-alert-preferences.tsx:
- Around line 51-62: Preferences in local state (preferences, setPreferences of
type AlertPreferences) are not persisted and will be lost on navigation;
implement persistence by creating a persisted atom (pattern like
recentlyUsedCatalogItemsAtom) or by reading/writing to AsyncStorage in this
component: load stored AlertPreferences into preferences on mount and save on
change/unmount (or when navigating away). Specifically, add a persisted atom or
utility that exposes get/set for AlertPreferences, replace the local
React.useState with that atom (or wrap setPreferences to also write to
AsyncStorage), and ensure you reference AlertPreferences, preferences,
setPreferences, and recentlyUsedCatalogItemsAtom pattern to locate where to
apply the fix. Ensure reads handle missing data (use the current defaults) and
writes debounce or batch updates to avoid excessive I/O.
- Around line 87-88: The Icon component is using an invalid name prop
'bell-ring-outline' causing a pipeline/type error; update the Icon usage (Icon
name="bell-ring-outline" ...) to use the valid icon name 'bell-outline' instead
so the component (Icon) renders a supported glyph and the TypeScript error
TS2820 is resolved.
In `@apps/expo/app/`(app)/weather-alerts.tsx:
- Around line 11-18: Remove the duplicate WeatherAlert type definition from
weather-alerts.tsx and import the exported WeatherAlert type from
expo-app/features/weather/hooks/useWeatherAlert instead; update the top of
weather-alerts.tsx to remove the local type block (the lines defining
WeatherAlert) and add an import for WeatherAlert from the hook module so all
references in this file use the single shared type.
In `@apps/expo/app/`(app)/weight-analysis/[id].tsx:
- Around line 51-58: The inner grid View and the SafeAreaView both apply
paddingTop: insets.top causing double top-padding; remove the duplicate by
deleting or setting paddingTop to 0 on the inner View (the <View className="grid
grid-cols-2 gap-3 p-4" ...> in weight-analysis/[id].tsx) so only SafeAreaView
applies insets.top; keep the rest of the View styling intact and ensure no other
nested element repeats insets.top.
In `@apps/expo/features/pack-templates/components/AddPackTemplateItemActions.tsx`:
- Around line 121-122: The code currently calls trackRecentlyUsed(catalogItems)
before the API write addItemsToPackTemplate(packTemplateId, catalogItems),
causing stale state if the add fails; change the flow so you await
addItemsToPackTemplate(...) first and only call trackRecentlyUsed(catalogItems)
after that promise resolves successfully, wrapping the operation in a try/catch
in the AddPackTemplateItemActions handler to prevent tracking on error and to
handle or rethrow the error (e.g., show a user-facing error) for consistent
client state.
In `@apps/expo/features/packs/components/HorizontalCatalogItemCard.tsx`:
- Around line 38-43: Remove the leftover debug class "bg-red" from the className
in the HorizontalCatalogItemCard component so it no longer forces a red
background; update the className expression that currently starts with
`rounded-lg flex-row gap-3 border p-4 bg-red` to match the pattern used in
PackItemCard.tsx (i.e., start without the unconditional bg class and rely solely
on the conditional expression using `isSelectable` and `restProps.selected` to
apply `border-primary bg-primary/5` or `border-border bg-card`).
In `@apps/expo/features/weather/hooks/useWeatherAlert.ts`:
- Around line 15-31: Change the function signature and map callback to use real
types: update generateAlerts to accept data: WeatherApiForecastResponse and
activeLocation: { name?: string } | undefined (instead of any), and when mapping
use the precise alert element type by declaring the mapper param as a:
WeatherApiForecastResponse["alerts"]["alert"][number], index: number; keep the
return type WeatherAlert[] unchanged and adjust any property accesses
accordingly so TypeScript type-checks the alert fields
(id/type/location/dates/severity/details) against the declared
WeatherApiForecastResponse shape.
In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts`:
- Around line 267-295: When handling the YouTube branch in the
generateFromOnlineContent flow, initialize the variables that the rest of the
pipeline expects (notably imageUrls, and optionally videoUrl and caption) so
they are defined for downstream usage; inside the isYouTubeUrl branch (after
setting contentId and youtubeVideoTranscript) set imageUrls = [] (and videoUrl =
undefined, caption = undefined if you want explicitness) and ensure
contentSource = 'youtube' remains. This ensures references to imageUrls later in
the code (and any use of videoUrl/caption) won't cause TypeScript or runtime
errors.
In `@packages/api/test/setup.ts`:
- Line 425: Remove the problematic cast to unknown when assigning testDb from
drizzle; call drizzle(testClient, { schema }) without casting so TypeScript can
infer the correct NodePgDatabase type for testDb, or if inference still fails
explicitly cast to the correct generic NodePgDatabase<typeof schema> type
(importing NodePgDatabase from 'drizzle-orm/node-postgres') and use that instead
of unknown; update the assignment where testDb = drizzle(testClient, { schema })
as unknown to one of these two safe approaches.
In `@packages/api/wrangler.jsonc`:
- Around line 180-186: The dev migration uses "new_sqlite_classes":
["AppContainer"] plus "deleted_classes": ["TikTokContainer"] which diverges from
production’s rename path and can drop existing Durable Object state; change the
dev migration to use a "renamed_classes" mapping from "TikTokContainer" to
"AppContainer" (replace the new_sqlite_classes/deleted_classes entries with a
single renamed_classes object) so the Durable Object rename preserves instances
and matches production behavior.
---
Outside diff comments:
In `@apps/expo/app/`(app)/(tabs)/profile/index.tsx:
- Line 33: The code calls Linking.openSettings() in the Profile component but
Linking is not imported, causing an unresolved identifier; fix by adding Linking
to the React Native imports so the symbol Linking is available (update the
import statement that currently imports Alert, Platform, TouchableOpacity, View
to also import Linking) and ensure any other usages of Linking in this file
reference the same imported symbol.
- Line 213: The success icon currently uses an untyped color token
(materialIcon: { name: 'check-circle-outline', color: colors.green }), which
causes TS2339; update the color to a valid theme token (for example
colors.primary or your theme's success token) so it matches the theme contract.
Locate the materialIcon declaration in the profile component (the object with
name 'check-circle-outline') and replace colors.green with an existing typed
token (e.g., colors.primary or colors.success) ensuring the imported colors type
includes that token. Run TypeScript to confirm the error is resolved.
- Around line 140-142: The call to FileSystem.getInfoAsync in the profile screen
passes an unsupported options object ({ size: true }); remove the options so
call FileSystem.getInfoAsync(image.uri) instead — the returned FileInfo already
includes size. Update the check that uses info.size (and AVATAR_MAX_BYTES) to
remain the same and ensure TypeScript no longer errors; no other logic changes
are needed where info and image.uri are referenced.
In `@apps/expo/features/weather/screens/LocationsScreen.tsx`:
- Around line 122-143: The search container View (the <View className="p-4"
style={{ paddingTop: insets.top }}>) is redundantly applying paddingTop already
set on the SafeAreaView; remove the duplicate by deleting the style paddingTop
from that inner View (leave className="p-4" intact) so only SafeAreaView
provides insets.top, ensuring LargeTitleHeader and the search input are not
pushed down twice.
In `@packages/api/container_src/server.ts`:
- Around line 36-55: The GoogleGenAI client (googleAi) is being constructed
before environment validation; move or defer initialization until after
validateEnv() returns so the API key is validated, or explicitly check
env.GOOGLE_GENAI_API_KEY before creating the GoogleGenAI instance; update the
code to call validateEnv() first, then create new GoogleGenAI({ apiKey:
env.GOOGLE_GENAI_API_KEY }) (or guard creation with a conditional and handle the
missing-key case) so GoogleGenAI is never instantiated with an undefined key.
In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts`:
- Around line 296-308: The Sentry capture call is being passed an invalid cast
(as unknown); instead construct a properly typed EventHint and pass it to
c.get('sentry').captureException: import the EventHint type from Sentry (e.g.,
'@sentry/types' or '@sentry/node'), create const hint: EventHint = { extra: {
tiktokUrl: contentUrl, errorType: 'tiktok_service_error' } }, and call
c.get('sentry').captureException(apiError, hint). This keeps the additional
context while satisfying TypeScript for captureException.
---
Minor comments:
In `@apps/expo/app/`(app)/weather-alerts.tsx:
- Line 160: The hardcoded user-facing strings in the WeatherAlerts component
(the loading text rendered when loading is true and the empty-state messages
around lines where alerts are rendered) must use the app i18n hook instead of
literal English; import and call the translation hook (e.g., useTranslation or t
from your i18n util) at the top of the weather-alerts component, replace
"Loading alerts..." and any empty-state Text values with
t('weatherAlerts.loading') / t('weatherAlerts.empty') (or chosen keys), and add
those keys to the translation files for all locales; update the JSX that checks
the loading and alerts variables so it renders the translated strings via the
translation function.
- Line 152: The JSX uses <MaterialCommunityIcons name="tune-vertical-variant"
... /> which is an invalid icon name; update the MaterialCommunityIcons usage in
weather-alerts.tsx to a valid icon name from the MaterialCommunityIcons set
(check https://icons.expo.fyi/) or switch to a different icon component/library
that contains the desired glyph, e.g., replace "tune-vertical-variant" with a
confirmed name like "tune" or another matching icon, and ensure the import of
MaterialCommunityIcons remains correct.
In `@apps/expo/features/ai-packs/screens/AIPacksScreen.tsx`:
- Line 80: The outer SafeAreaView (the one with className="flex-1" and style={{
paddingTop: insets.top }}) already applies the top inset, so remove the
duplicate paddingTop: insets.top from the inner SafeAreaView in
AIPacksScreen.tsx (leave any other styles on the inner SafeAreaView intact);
ensure only the outer SafeAreaView uses paddingTop to avoid double vertical
offset.
In `@apps/expo/features/pack-templates/screens/PackTemplateListScreen.tsx`:
- Line 114: The SafeAreaView in PackTemplateListScreen currently adds explicit
paddingTop: insets.top on top of the SafeAreaView's own automatic insets,
causing double top padding; remove the inline style paddingTop: insets.top from
the SafeAreaView and update the child View (the one adding spacing at the top)
to only add the fixed 22px (e.g., marginTop or paddingTop: 22) without
referencing insets.top so the safe-area padding is applied once by SafeAreaView.
In `@apps/expo/features/packs/components/AddPackItemActions.tsx`:
- Around line 108-113: The call to trackRecentlyUsed currently runs before the
API call so failures still mark items as recently used; move the
trackRecentlyUsed(catalogItems) invocation into the try block immediately after
await addItemsToPack(packId, catalogItems as CatalogItemWithPackItemFields[]) so
it only runs on success, and remove the earlier pre-call invocation; keep the
existing catch behavior that logs the error and shows Alert.alert.
In `@apps/expo/features/weather/hooks/useWeatherAlert.ts`:
- Around line 126-152: The callbacks use (h: any) for forecast hour objects
(used in todayHours, willRain and highWindComing) which violates the no-any
rule; define a proper Hour type/interface matching the API (e.g., Hour {
condition?: { text?: string }; wind_kph?: number }) and type
forecastDays/todayHours accordingly (e.g., todayHours: Hour[] =
forecastDays[0]?.hour || []). Then replace (h: any) with (h: Hour) and add
lightweight runtime guards where needed (optional chaining and typeof checks) in
willRain and highWindComing to safely access condition.text and wind_kph.
In `@apps/expo/features/weather/screens/LocationSearchScreen.tsx`:
- Line 35: The ref declaration for searchInputRef is typed incorrectly; change
the declaration to use React's generic useRef typing so the variable is a
RefObject instead of the raw instance type — replace the current line that
declares searchInputRef with a generic useRef usage:
useRef<SearchInputRef>(null), referencing the SearchInputRef type and the useRef
hook to ensure the ref has the correct RefObject type.
In `@apps/expo/features/weather/screens/LocationsScreen.tsx`:
- Line 14: Remove the unused Platform import and the unused headerPaddingTop
calculation inside the LocationsScreen component: delete the Platform import
near the top and remove the headerPaddingTop constant (and any related
Platform.OS checks) around where headerPaddingTop is defined so there is no dead
code left; ensure LocationsScreen compiles and no other references to
headerPaddingTop remain.
In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts`:
- Around line 449-453: The current catch block uses an unsafe "as any" cast when
calling c.get('sentry').captureException(error, { extra: ... } as any); replace
that with a properly typed Sentry hint by importing the correct Sentry type
(e.g., Sentry.EventHint or Sentry.CaptureContext from the Sentry package you
use) and creating a typed variable for the second argument (e.g., const hint:
Sentry.EventHint = { extra: { contentUrl, errorType: 'template_generation_error'
} }) then pass that typed variable to c.get('sentry').captureException(error,
hint) so there is no use of any and the extra payload is correctly typed.
---
Nitpick comments:
In `@apps/expo/app/`(app)/weather-alert-preferences.tsx:
- Line 137: Replace the unsafe "as never" cast by giving iconName a proper type:
import the icon name type used by the Icon component (or define a union of
allowed icon string literals) and use that type in AlertTypeConfig so iconName
is typed correctly; update usages of Icon to accept iconName with the correct
type instead of casting. Likewise, replace the loose translation key usage by
defining a union type of valid weather translation keys (used where you build
titles/subtitles) and use it in AlertTypeConfig so the translation function
receives a properly typed key. Ensure AlertTypeConfig references these new types
and remove all "as never" casts (including the Icon invocation and translation
key usages).
In `@apps/expo/features/catalog/components/CatalogBrowserModal.tsx`:
- Around line 231-240: The handler handleAddSelected builds items with a
quantity field but calls onItemsSelected typed as CatalogItem[], causing a type
mismatch; update the onItemsSelected callback signature (and any related uses)
to accept CatalogItemWithQuantity[] (the type defined in
features/catalog/types.ts) and ensure handleAddSelected returns that type by
mapping to CatalogItemWithQuantity (use itemQuantities.get(item.id) ?? 1 for
quantity). Also update any upstream prop types or callers of CatalogBrowserModal
that provide onItemsSelected to match the new CatalogItemWithQuantity[]
signature.
In `@apps/expo/features/pack-templates/components/OnlineContentImportModal.tsx`:
- Around line 19-22: Rename the mismatched props interface to match the
component: change TikTokImportModalProps to OnlineContentImportModalProps and
update all references (the component declaration OnlineContentImportModal, any
prop annotations, and any exports/imports) to use the new name so the props type
and component name are consistent; search for occurrences of
TikTokImportModalProps and replace them with OnlineContentImportModalProps and
adjust any tests/types that reference the old name.
In `@apps/expo/features/pack-templates/components/TemplateCreationOptions.tsx`:
- Around line 83-101: Update the stale inline comment that mentions "Import from
TikTok" to reflect the new generic online content import behavior; locate the
JSX block that renders the import option (the TouchableOpacity using
handleImportFromOnlineContent inside TemplateCreationOptions.tsx) and replace or
remove the outdated comment so it accurately describes the "Import from online
content" option for admins who are authenticated.
In `@apps/expo/features/weather/hooks/useWeatherAlert.ts`:
- Around line 184-216: Replace the manual useEffect/useState fetch in
useWeatherAlerts with a React Query useQuery-based implementation: use the
activeLocationAtom value for the query key (e.g., ['weatherAlerts',
activeLocation?.id]) and set enabled to !!activeLocation?.id, call
getWeatherData(activeLocation!.id) in the queryFn and transform the result with
generateAlerts before returning; map useQuery's data/isLoading/error to
alerts/loading/error and return activeLocation as before. Ensure you import
useQuery from `@tanstack/react-query` and convert error to a string
(error?.message ?? null).
In `@packages/api/src/containers/AppContainer.ts`:
- Around line 9-15: The lifecycle log messages still use the old "TikTok
container…" label; update them to "AppContainer" for consistency. In the
AppContainer class, modify the logging calls inside onStart, onStop, and onError
to replace any "TikTok container" text with "AppContainer" (or an equivalent
exact label), and ensure any processLogger or logger.error/info usages include
the new label so log filtering works consistently across those methods.
In `@packages/api/src/routes/packTemplates/generateFromOnlineContent.ts`:
- Around line 362-364: The error thrown in the else branch of
generateFromOnlineContent still says "No content found in TikTok post (no images
or video)"; change that message to a generic one that covers YouTube and other
sources (e.g., "No content found in online post (no images or video)") by
updating the throw new Error(...) statement inside the else block of the
generateFromOnlineContent handler so it no longer references TikTok
specifically.
In `@packages/api/test/generate-from-tiktok.test.ts`:
- Around line 41-47: The mock for getContainer currently ignores its first
argument so tests don't verify the binding is passed; update the vi.mock
implementation for '@cloudflare/containers' so getContainer examines its first
parameter (the binding name/identifier used by getEnv() → getContainer()) and
throws or returns a rejected promise when that argument is undefined or not the
expected binding (e.g., "APP_CONTAINER"), ensuring tests fail if the binding is
missing or misnamed; reference getContainer, MockContainer and
mockContainerFetch in the mock and then adjust the test to call getContainer
with the correct binding name so the suite verifies the handoff.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f5c5c8ab-158d-4269-809d-6c240e486f7e
⛔ Files ignored due to path filters (2)
bun.lockis excluded by!**/*.lockpackages/api/container_src/bun.lockis excluded by!**/*.lock
📒 Files selected for processing (47)
apps/expo/app.config.tsapps/expo/app/(app)/(tabs)/profile/index.tsxapps/expo/app/(app)/(tabs)/profile/notifications.tsxapps/expo/app/(app)/_layout.tsxapps/expo/app/(app)/current-pack/[id].tsxapps/expo/app/(app)/pack-categories/[id].tsxapps/expo/app/(app)/weather-alert-preferences.tsxapps/expo/app/(app)/weather-alerts.tsxapps/expo/app/(app)/weight-analysis/[id].tsxapps/expo/atoms/recentlyUsedCatalogItemsAtom.tsapps/expo/features/ai-packs/screens/AIPacksScreen.tsxapps/expo/features/catalog/components/CatalogBrowserModal.tsxapps/expo/features/catalog/hooks/index.tsapps/expo/features/catalog/hooks/usePopularCatalogItems.tsapps/expo/features/catalog/hooks/useRecentlyUsedCatalogItems.tsapps/expo/features/pack-templates/components/AddPackTemplateItemActions.tsxapps/expo/features/pack-templates/components/OnlineContentImportModal.tsxapps/expo/features/pack-templates/components/TemplateCreationOptions.tsxapps/expo/features/pack-templates/hooks/index.tsapps/expo/features/pack-templates/hooks/useGenerateTemplateFromOnlineContent.tsapps/expo/features/pack-templates/screens/PackTemplateListScreen.tsxapps/expo/features/packs/components/AddPackItemActions.tsxapps/expo/features/packs/components/HorizontalCatalogItemCard.tsxapps/expo/features/weather/components/LocationPicker.tsxapps/expo/features/weather/components/WeatherAlertsTile.tsxapps/expo/features/weather/hooks/useWeatherAlert.tsapps/expo/features/weather/screens/LocationSearchScreen.tsxapps/expo/features/weather/screens/LocationsScreen.tsxapps/expo/lib/i18n/locales/en.jsonapps/expo/package.jsonapps/guides/package.jsonapps/landing/package.jsonpackage.jsonpackages/api/container_src/package.jsonpackages/api/container_src/server.tspackages/api/package.jsonpackages/api/src/containers/AppContainer.tspackages/api/src/containers/index.tspackages/api/src/index.tspackages/api/src/routes/packTemplates/generateFromOnlineContent.tspackages/api/src/routes/packTemplates/index.tspackages/api/src/schemas/packTemplates.tspackages/api/src/utils/env-validation.tspackages/api/test/generate-from-tiktok.test.tspackages/api/test/setup.tspackages/api/wrangler.jsoncpackages/ui/package.json
This pull request introduces a new weather alert preferences feature and improves the weather alerts experience in the Expo app. It adds a dedicated screen for configuring weather alert types, integrates live weather alert data, and updates the notification settings to support weather alerts. There are also several minor improvements and bug fixes for safe area handling and UI consistency.
Weather Alerts and Preferences Improvements:
weather-alert-preferencesscreen (weather-alert-preferences.tsx) allowing users to customize which types of weather alerts they receive, with toggles for various alert categories and location monitoring.weather-alertsscreen to fetch real weather alert data, display loading and error states, and allow navigation to the new preferences screen. Mock data was replaced, and alert icons/colors are now determined dynamically. [1] [2] [3]Notification Settings Enhancements:
Safe Area and UI Consistency:
current-pack/[id].tsxandweight-analysis/[id].tsxto useuseSafeAreaInsetsfor proper padding, ensuring content is displayed correctly on all devices. (apps/expo/app/(app)/current-pack/[id].tsxL19-R19, apps/expo/app/(app)/current-pack/[id].tsxR135-R145, apps/expo/app/(app)/weight-analysis/[id].tsxL10-R10)Dependency and Version Updates:
expo-file-systemto use the legacy version for compatibility.2.0.17.Summary by CodeRabbit
Release Notes – Version 2.0.17
New Features
Improvements