chore: clear type-cast backlog and promote to hard gate#2317
chore: clear type-cast backlog and promote to hard gate#2317andrew-bierman wants to merge 9 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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 |
Coverage Report for Expo Unit Tests Coverage (./apps/expo)
File Coverage
|
||||||||||||||||||||||||||||||||||||||
Coverage Report for API Unit Tests Coverage (./packages/api)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
packrat-admin | 5636103 | Commit Preview URL Branch Preview URL |
Apr 26 2026, 09:41 PM |
Deploying packrat-landing with
|
| Latest commit: |
5636103
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5e696364.packrat-landing.pages.dev |
| Branch Preview URL: | https://feat-checks-backlog-casts.packrat-landing.pages.dev |
There was a problem hiding this comment.
Pull request overview
This PR clears the monorepo’s unsafe type-cast backlog and promotes check-type-casts from a soft signal to a hard CI + pre-push gate, primarily by tightening the cast-scanning script and annotating remaining unavoidable casts with // safe-cast:.
Changes:
- Improve
check-type-castsscanning (exclude tests, broaden safe-cast annotation lookback, reduce false positives, expand safe cast patterns). - Remove redundant casts / add
// safe-cast:annotations across apps and packages (API, Expo app, analytics, CLI, etc.). - Promote
bun check:casts:strictto a hard gate in CI and pre-push.
Reviewed changes
Copilot reviewed 68 out of 68 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/web-ui/src/components/form.tsx | Annotate React context sentinel casts with // safe-cast:. |
| packages/guards/src/narrow.ts | Annotate internal narrowing cast used for Object.entries. |
| packages/config/src/config.ts | Annotate deep-freeze Object.values cast. |
| packages/cli/src/shared.ts | Annotate DuckDB/DB “row as record” casts used for table output. |
| packages/checks/src/check-type-casts.ts | Expand exclusions/suppressions and patterns for the unsafe-cast scanner. |
| packages/api/src/utils/env-validation.ts | Annotate Cloudflare Workers runtime binding casts + global env stash. |
| packages/api/src/utils/csv-utils.ts | Annotate generic-boundary JSON.parse(...) as T. |
| packages/api/src/utils/compute-pack.ts | Remove redundant WeightUnit cast when converting weights. |
| packages/api/src/utils/auth.ts | Annotate JWT payload cast at verify boundary. |
| packages/api/src/services/refreshTokenService.ts | Annotate Drizzle and/or(...) as SQL casts. |
| packages/api/src/services/r2-bucket.ts | Annotate stream/ArrayBuffer/generic JSON parsing casts in R2 body helpers. |
| packages/api/src/services/etl/processValidItemsBatch.ts | Annotate cast from Partial<NewCatalogItem>[] to NewCatalogItem[] post-validation. |
| packages/api/src/routes/weather.ts | Annotate WeatherAPI JSON response casts. |
| packages/api/src/routes/packs/index.ts | Annotate NewPackItem cast during insert/returning flow. |
| packages/api/src/middleware/auth.ts | Annotate AuthUser cast in auth macro. |
| packages/api/src/index.ts | Annotate Cloudflare worker entrypoint casts (env + fetch signature + queue payload). |
| packages/api/src/containers/AppContainer.ts | Annotate cloudflare:workers env cast to typed Env. |
| packages/api-client/src/index.ts | Annotate error-body field access + generic return boundary cast. |
| packages/analytics/src/core/spec-parser.ts | Annotate DuckDB row-schema casts. |
| packages/analytics/src/core/local-cache.ts | Annotate generic “row object as T” boundary cast. |
| packages/analytics/src/core/entity-resolver.ts | Annotate DuckDB entity-row cast. |
| packages/analytics/src/core/enrichment.ts | Annotate DuckDB row-schema casts in enrichment pipeline. |
| lefthook.yml | Add bun check:casts:strict to pre-push clean-checks gate. |
| apps/landing/lib/icons.tsx | Annotate dynamic lucide icon lookup cast. |
| apps/guides/scripts/sync-to-r2.ts | Annotate SyncEnv → ValidatedEnv cast for R2 bucket service usage. |
| apps/guides/components/search.tsx | Annotate event.target as Node cast for click-outside handling. |
| apps/guides/app/dev/generate/page.tsx | Reduce casts by typing Object.entries and validate select value via assertEnum. |
| apps/expo/lib/store.ts | Annotate Legend-State proxy indexing cast in obs(). |
| apps/expo/features/wildlife/hooks/useWildlifeIdentification.ts | Annotate treaty response cast for online identification results. |
| apps/expo/features/weather/lib/weatherService.ts | Annotate treaty response casts for weather endpoints. |
| apps/expo/features/weather/hooks/useWeatherAlert.ts | Annotate structural subset cast used for alert generation. |
| apps/expo/features/trips/screens/TripDetailScreen.tsx | Annotate store-hydration cast for trip details. |
| apps/expo/features/trips/components/TripForm.tsx | Annotate defaultValues cast to form values type. |
| apps/expo/features/trail-conditions/hooks/useTrailConditionReports.ts | Annotate JSON.parse cache cast + treaty casts + Legend-State values cast. |
| apps/expo/features/trail-conditions/components/TrailConditionReportCard.tsx | Remove redundant enum casts for label lookup. |
| apps/expo/features/packs/utils/computePackWeights.ts | Remove redundant WeightUnit cast when converting weights. |
| apps/expo/features/packs/store/packItems.ts | Annotate treaty response cast + Legend-State object[] bridge. |
| apps/expo/features/packs/screens/PackDetailScreen.tsx | Annotate non-undefined pack cast tied to early-return guard. |
| apps/expo/features/packs/screens/ItemsScanScreen.tsx | Annotate expo-router params cast passed to image picker. |
| apps/expo/features/packs/hooks/useSeasonSuggestions.ts | Annotate treaty response cast for season suggestions. |
| apps/expo/features/packs/hooks/usePackItemDetailsFromApi.ts | Annotate treaty response cast for pack item fetch. |
| apps/expo/features/packs/hooks/usePackGapAnalysis.ts | Annotate treaty response cast for gap analysis. |
| apps/expo/features/packs/hooks/usePackDetailsFromApi.ts | Annotate treaty response cast for pack fetch. |
| apps/expo/features/packs/hooks/useImageDetection.ts | Annotate treaty response cast for image analysis. |
| apps/expo/features/packs/hooks/useDuplicatePack.ts | Annotate treaty response cast for duplication fetch step. |
| apps/expo/features/packs/components/SimilarItemsForPackItem.tsx | Annotate cast for untyped items field in similar-items response. |
| apps/expo/features/packs/components/PackCard.tsx | Update safe-cast annotation for `Pack |
| apps/expo/features/pack-templates/store/packTemplateItems.ts | Annotate treaty response casts for templates + items flattening. |
| apps/expo/features/pack-templates/screens/ItemsScanScreen.tsx | Annotate expo-router params cast passed to image picker. |
| apps/expo/features/pack-templates/hooks/usePackTemplateSummary.ts | Remove redundant WeightUnit casts in weight computations. |
| apps/expo/features/pack-templates/hooks/useGenerateTemplateFromOnlineContent.ts | Annotate treaty error-shape probing + augmented Error + response cast. |
| apps/expo/features/catalog/screens/CatalogItemsScreen.tsx | Annotate treaty response cast(s) for catalog search/pagination. |
| apps/expo/features/catalog/hooks/useSimilarItems.ts | Annotate treaty response cast for similar-items response. |
| apps/expo/features/catalog/hooks/useCatalogItems.ts | Annotate treaty response cast bridging Drizzle row shape to projection type. |
| apps/expo/features/catalog/components/SimilarItems.tsx | Remove redundant cast by relying on typed data.items. |
| apps/expo/features/catalog/components/CatalogBrowserModal.tsx | Annotate treaty response casts for popular/search/paginated items. |
| apps/expo/features/auth/hooks/useAuthActions.ts | Annotate Expo Router Href cast fallback for string route. |
| apps/expo/features/ai/hooks/useReportedContent.ts | Annotate treaty response cast for reported content. |
| apps/expo/features/ai/hooks/useReportContent.ts | Annotate treaty response cast for report content. |
| apps/expo/features/ai/components/ToolInvocationRenderer.tsx | Annotate discriminated-union switch arm casts for tool UI parts. |
| apps/expo/features/ai/components/ChatBubble.tsx | Annotate part as ToolUIPart cast after prefix guard. |
| apps/expo/features/ai-packs/hooks/useGeneratedPacks.ts | Annotate treaty response cast for generated packs. |
| apps/expo/components/Icon/get-icon-names.ts | Annotate casts bridging icon-name string unions and lookup tables. |
| apps/expo/components/Icon/Icon.tsx | Annotate icon-name union casts for Material icon components. |
| apps/expo/components/Icon/Icon.ios.tsx | Annotate icon-name union casts for iOS-specific icon component. |
| apps/expo/app/(app)/current-pack/[id].tsx | Remove redundant PackItem cast in list render. |
| apps/admin/lib/api.ts | Annotate res.json() as Promise<T> generic boundary cast. |
| .github/workflows/checks.yml | Remove continue-on-error from the unsafe-casts check step. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for (let j = i - 1; j >= 0 && j >= i - 10; j--) { | ||
| const prev = lines[j] ?? ''; | ||
| if (SAFE_CAST_ANNOTATION.test(prev)) { | ||
| annotated = true; | ||
| break; | ||
| } | ||
| if (!COMMENT_LINE.test(prev.trimStart())) break; | ||
| } |
| const EXCLUDED_FILE_PATTERNS = [ | ||
| /\.test\./, | ||
| /\.spec\./, | ||
| /\.stories\./, | ||
| /\.d\.ts$/, | ||
| /\/__tests__\//, // any file inside a __tests__ directory | ||
| /\/test\//, // any file inside a test directory | ||
| ]; |
| const { payload } = await jwtVerify(token, secretKey(JWT_SECRET), { | ||
| algorithms: ['HS256'], | ||
| }); | ||
| return payload as JWTPayload; | ||
| return payload as JWTPayload; // safe-cast: jose jwtVerify returns JWTPayload — our JWTPayload type extends the jose type with userId/role fields | ||
| } catch { |
| const payload = await verifyJWT({ token }); | ||
| if (!payload) return status(401, { error: 'Invalid token' }); | ||
|
|
||
| const { userId: _uid, role: _role, ...rest } = payload; | ||
| return { | ||
| user: { | ||
| userId: Number(payload.userId), | ||
| role: (payload.role as 'USER' | 'ADMIN') ?? 'USER', | ||
| ...rest, | ||
| } as AuthUser, | ||
| } as AuthUser, // safe-cast: JWT payload validated by auth middleware — userId and role fields are confirmed present |
| // safe-cast: when isOwnedByUser, packFromStore is a full Pack with computed weights; | ||
| // when not owned, packArg is also accepted as Pack (caller must supply the full shape). | ||
| const pack = (isOwnedByUser ? packFromStore : packArg) as Pack; |
a0f05f6 to
2fe85f1
Compare
1b404df to
8241453
Compare
2fe85f1 to
d443422
Compare
…e-positive fixes - Exclude test files (/__tests__/, /test/) from cast scanning - Extend safe-cast annotation lookback through consecutive comment lines (was 1 line; now scans the entire comment block preceding the cast) - Add NATURAL_LANGUAGE_CAST pattern to skip content-string false positives - Add ArrayBuffer, ReadableStream, SQL to SAFE_CAST_PATTERNS
…ditions - computePackWeights: remove redundant WeightUnit cast - PackDetailScreen/PackCard: annotation for Pack union narrowing - usePackTemplateSummary: remove redundant casts - TrailConditionReportCard: remove redundant casts - treaty hooks: annotate with safe-cast where response shape matches schema
…ps, components) - treaty response hooks: safe-cast annotations for shape-match casts - ToolInvocationRenderer: inline safe-cast on each discriminated case branch - Icon components: safe-cast for ComponentProps/SfSymbolName icon type coercions - store.ts obs(): safe-cast for Legend-State Proxy access pattern
- guides generate page: type ContentCategory at Object.entries; DifficultyLevel uses assertEnum - guides sync-to-r2: inline safe-cast for SyncEnv → ValidatedEnv subset - landing icons: safe-cast for Lucide icon type narrowing
…, config, web-ui) - env-validation: safe-cast annotations for Cloudflare Worker runtime bindings - api middleware/services: safe-cast for treaty/generic boundary casts - analytics: safe-cast for DuckDB row result types - guards narrow.ts: assertEnum helper for enum type narrowing - cli, config, web-ui: safe-cast for legitimate type boundary casts
Type-cast backlog cleared (130 → 0). Remove continue-on-error from CI and add bun check:casts:strict to the pre-push clean-checks gate.
8241453 to
5636103
Compare
Treaty response type has createdAt as string | undefined but the PackItem schema type requires string; the cast bridges this gap.
Summary
Chained off
feat/checks-backlog-2(PR #2313). Clears the 130-violation type-cast backlog and graduatescheck-type-castsfromcontinue-on-errorto a hard CI + pre-push gate.Changes
Script improvements (
packages/checks/src/check-type-casts.ts):/__tests__/,/test/)// safe-cast:lookback through entire preceding comment block (was 1 line)NATURAL_LANGUAGE_CASTpattern to skip content-string false positivesArrayBuffer,ReadableStream,SQLtoSAFE_CAST_PATTERNSCast fixes across the monorepo (130 → 0 violations):
WeightUnit,TrailSurface, etc.)// safe-cast: treaty response shape matches <Type>Gate promotion:
continue-on-errorfromcheck:casts:strictCI stepbun check:casts:strictto pre-pushclean-checksgateTest plan
bun check:casts:strictexits 0continue-on-erroron the cast step🤖 Generated with Claude Code