Extensive refactor for typesafety - Mobile & RN-SDK need testing#15
Conversation
…nvex-wrapper-hooks
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Review Summary by QodoModularize backend code and enhance E2E test infrastructure
WalkthroughsDescription* **Modularize large monolithic Convex backend files** into organized domain-specific submodules: - testData.ts: Extracted mutations into separate files (seeds, cleanup, demoWorkspace, landing) - series.ts: Split into authoring, runtime, and telemetry submodules - visitors.ts: Separated into coreQueries, directoryQueries, and mutations submodules - testing/helpers.ts: Reorganized into domain-specific helper modules (series, workspace, conversations, notifications, content, email, tickets, ai, cleanup) * **Add comprehensive E2E test data seed mutations** in new testData/seeds.ts with environment guards and test data prefixes for easy identification * **Improve E2E test reliability and maintainability**: - Extract ticket conversion logic into reusable helper with retry logic and error handling - Simplify public pages test by removing conditional setup logic - Simplify carousel deletion test with explicit button clicks instead of dialog auto-acceptance - Add explicit waits for UI element visibility * **Add widget helper function** for human agent name resolution with normalization and default fallback * **Remove unused test utilities** and clean up redundant auth state refresh calls Diagramflowchart LR
A["Large Monolithic Files<br/>testData, series, visitors<br/>testing/helpers"] -->|"Extract & Reorganize"| B["Domain-Specific Submodules<br/>authoring, runtime, mutations<br/>coreQueries, directoryQueries"]
C["E2E Tests<br/>public-pages, inbox<br/>carousels"] -->|"Extract Helpers<br/>Improve Reliability"| D["Reusable Test Utilities<br/>Explicit Waits<br/>Error Handling"]
E["Test Data Seeds"] -->|"Add Environment Guards"| F["E2E Test Data<br/>with Prefixes"]
B --> G["Improved Maintainability<br/>& Type Safety"]
D --> G
F --> G
File Changes1. packages/convex/convex/testData.ts
|
Code Review by Qodo
1. Any-args gate ignored
|
CI Feedback 🧐A test triggered by this PR failed. Here is an AI-generated analysis of the failure:
|
| report_blocking "Lint (web + convex)" "${{ steps.lint.outcome }}" | ||
| report_blocking "Typecheck (web + convex)" "${{ steps.typecheck.outcome }}" | ||
| report_blocking "Convex raw auth guard" "${{ steps.convex_auth_guard.outcome }}" | ||
| report_warning "Convex validator any guard" "${{ steps.convex_any_guard.outcome }}" |
There was a problem hiding this comment.
1. Any-args gate ignored 🐞 Bug ⛨ Security
In .github/workflows/ci.yml, the summarizer reports the pnpm security:convex-any-args-gate step using report_warning, and report_warning never sets the failures flag, so the workflow can succeed even when the v.any() security gate fails. This disables a documented CI security gate intended to block unsafe Convex argument validators from merging.
Agent Prompt
## Issue description
The CI workflow currently treats the Convex `v.any()` argument gate (`pnpm security:convex-any-args-gate`) as warning-only. Because `report_warning` never sets the `failures` flag, the workflow can exit successfully even when this security gate fails.
## Issue Context
This gate is documented as part of the Checks job security gates, so it should be enforced as blocking.
## Fix Focus Areas
- .github/workflows/ci.yml[97-121]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
Pull request overview
This PR refactors Convex function reference usage (moving from generated api.* property access to explicit makeFunctionReference/web*Ref patterns) to mitigate deep TypeScript instantiation issues, while also expanding web admin features (inbox/outbound/articles), improving E2E stability, and enhancing CI reporting/docs.
Changes:
- Replaces direct generated Convex
api.*usage with explicit function references across web + mobile, and adds several web “Convex hook” wrappers (useWebQuery/useWebMutation/...). - Adds new web admin modules (inbox orchestration hooks, outbound editor hooks/UI, articles admin utils/hooks) with accompanying unit tests.
- Improves CI workflow result summarization and Playwright E2E robustness (selectors, auth/storage-state handling), plus roadmap/agent docs updates.
Reviewed changes
Copilot reviewed 118 out of 919 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/web/src/app/settings/MessengerSettingsSection.test.tsx | Adds regression tests for messenger settings error feedback. |
| apps/web/src/app/settings/MessengerSettingsPreview.tsx | Introduces a live preview component for messenger settings form state. |
| apps/web/src/app/settings/HelpCenterAccessSection.tsx | Adds UI to toggle help center access policy. |
| apps/web/src/app/settings/EmailChannelSection.tsx | Adds UI to configure the email support channel settings. |
| apps/web/src/app/settings/AutomationSettingsSection.tsx | Refactors Convex refs to makeFunctionReference for automation settings. |
| apps/web/src/app/settings/AIAgentSection.tsx | Refactors Convex refs and tweaks knowledge source labels. |
| apps/web/src/app/segments/page.tsx | Refactors segments page Convex refs to makeFunctionReference. |
| apps/web/src/app/reports/team/page.tsx | Refactors reporting queries to makeFunctionReference refs. |
| apps/web/src/app/reports/page.tsx | Refactors reporting queries to makeFunctionReference refs. |
| apps/web/src/app/reports/csat/page.tsx | Refactors CSAT reporting queries to makeFunctionReference refs. |
| apps/web/src/app/reports/conversations/page.tsx | Refactors conversation reporting queries to makeFunctionReference refs. |
| apps/web/src/app/reports/ai/page.tsx | Refactors AI reporting queries to makeFunctionReference refs and guards avgConfidence. |
| apps/web/src/app/outbound/outboundMessageUi.tsx | Adds outbound message UI constants + icon/badge helpers. |
| apps/web/src/app/outbound/hooks/useOutboundMessageEditorConvex.ts | Adds outbound editor Convex hook wrapper with typed refs. |
| apps/web/src/app/outbound/hooks/useOutboundMessageEditorController.ts | Adds outbound editor controller hook to manage editor state and persistence. |
| apps/web/src/app/outbound/[id]/editorState.test.ts | Adds unit tests for outbound editor state helpers. |
| apps/web/src/app/outbound/[id]/OutboundTriggerPanel.tsx | Adds trigger configuration panel UI for outbound messages. |
| apps/web/src/app/outbound/[id]/OutboundStatisticsPanel.tsx | Adds lightweight stats panel UI for outbound message performance. |
| apps/web/src/app/outbound/[id]/OutboundPreviewPanel.tsx | Adds a preview panel for outbound messages (chat/post/banner). |
| apps/web/src/app/outbound/[id]/OutboundFrequencyPanel.tsx | Adds frequency selection UI panel for outbound messages. |
| apps/web/src/app/outbound/[id]/OutboundFieldLabel.tsx | Adds small label helper component for outbound editor forms. |
| apps/web/src/app/outbound/[id]/OutboundEditorHeader.tsx | Adds outbound editor header with status controls and navigation. |
| apps/web/src/app/outbound/[id]/OutboundClickActionPanel.tsx | Adds click action configuration panel for outbound messages. |
| apps/web/src/app/onboarding/page.tsx | Refactors onboarding Convex refs to makeFunctionReference. |
| apps/web/src/app/knowledge/internal/new/page.tsx | Replaces internal article creation page with a redirect to new articles flow. |
| apps/web/src/app/inbox/inboxRenderTypes.ts | Adds typed inbox render payload shapes for the refactor. |
| apps/web/src/app/inbox/hooks/useInboxSuggestionsCount.ts | Adds hook to fetch and track suggestions count async state. |
| apps/web/src/app/inbox/hooks/useInboxSelectionSync.ts | Adds hook to sync selected conversation to URL query params. |
| apps/web/src/app/inbox/hooks/useInboxSelectionSync.test.tsx | Adds tests for selection sync URL/query semantics. |
| apps/web/src/app/inbox/hooks/useInboxConvex.ts | Adds inbox Convex wrapper hook using typed web*Ref refs. |
| apps/web/src/app/inbox/hooks/useInboxCompactPanels.ts | Adds hook to manage compact auxiliary panel behavior. |
| apps/web/src/app/inbox/hooks/useInboxCompactPanels.test.tsx | Adds tests for compact panel reset/toggle semantics. |
| apps/web/src/app/inbox/hooks/useInboxAttentionCues.ts | Adds hook for unread attention cues + document title updates. |
| apps/web/src/app/inbox/hooks/useInboxAttentionCues.test.tsx | Adds tests for title and cue suppression behavior. |
| apps/web/src/app/inbox/README.md | Documents ownership boundaries and extension points for inbox hooks. |
| apps/web/src/app/inbox/InboxThreadPane.test.tsx | Adds tests for consolidated knowledge/snippet picker behaviors. |
| apps/web/src/app/help/page.tsx | Refactors help center queries to makeFunctionReference and enforces public visibility params. |
| apps/web/src/app/help/helpCenterLinks.ts | Adds helpers for building help center URLs and reading/persisting workspace IDs. |
| apps/web/src/app/help/[slug]/page.tsx | Refactors article page Convex refs and blocks feedback for internal articles. |
| apps/web/src/app/checklists/page.tsx | Refactors page to use a dedicated Convex hook + shared types. |
| apps/web/src/app/checklists/hooks/useChecklistsPageConvex.ts | Adds checklists page Convex hook wrapper. |
| apps/web/src/app/checklists/hooks/useChecklistBuilderConvex.ts | Adds checklist builder Convex hook wrapper. |
| apps/web/src/app/checklists/checklistTypes.ts | Extracts checklist domain types into a shared module. |
| apps/web/src/app/checklists/[id]/page.tsx | Refactors checklist builder to use shared types and Convex hook wrapper. |
| apps/web/src/app/campaigns/series/[id]/seriesEditorTypes.ts | Adds series editor types + utility helpers. |
| apps/web/src/app/campaigns/series/[id]/seriesBlockUi.tsx | Adds series block icon/color helpers. |
| apps/web/src/app/campaigns/series/[id]/SeriesEditorCanvas.tsx | Adds series editor canvas rendering blocks/connections. |
| apps/web/src/app/campaigns/push/[id]/page.tsx | Refactors push campaign editor to use Convex hook wrapper and safer stats rendering. |
| apps/web/src/app/campaigns/page.tsx | Refactors campaigns page to use Convex hook wrapper consolidated in one module. |
| apps/web/src/app/campaigns/hooks/useSeriesEditorConvex.ts | Adds series editor Convex hook wrapper with typed refs. |
| apps/web/src/app/campaigns/hooks/usePushCampaignEditorConvex.ts | Adds push campaign editor Convex hook wrapper with typed refs. |
| apps/web/src/app/campaigns/hooks/useCarouselEditorConvex.ts | Adds carousel editor Convex hook wrapper with typed refs. |
| apps/web/src/app/campaigns/hooks/useCampaignsPageConvex.ts | Adds campaigns page Convex hook wrapper with typed refs. |
| apps/web/src/app/campaigns/email/[id]/page.tsx | Refactors email campaign editor to makeFunctionReference and safer stats rendering. |
| apps/web/src/app/campaigns/carousels/[id]/page.tsx | Refactors carousel editor to use Convex hook wrapper and typed screen records. |
| apps/web/src/app/audit-logs/page.tsx | Updates import path for AuditLogViewer. |
| apps/web/src/app/articles/hooks/useArticlesAdminConvex.ts | Adds articles admin Convex hook wrapper for list/import/export/publish flows. |
| apps/web/src/app/articles/hooks/useArticleEditorConvex.ts | Adds article editor Convex hook wrapper for assets and publish state. |
| apps/web/src/app/articles/hooks/useArticleCollectionsConvex.ts | Adds collections management Convex hook wrapper. |
| apps/web/src/app/articles/collections/page.tsx | Refactors collections page to use hook wrapper and hardens articleCount handling. |
| apps/web/src/app/articles/articlesAdminUtils.ts | Adds articles admin utility helpers (filtering/signature/formatting). |
| apps/web/src/app/articles/articlesAdminUtils.test.ts | Adds unit tests for articles admin filtering utilities. |
| apps/web/src/app/articles/articlesAdminTypes.ts | Adds shared client-side types/constants for articles admin UI. |
| apps/web/src/app/articles/DeleteArticleDialog.tsx | Adds delete confirmation dialog component for articles admin UI. |
| apps/web/package.json | Updates lint command, bumps convex, and adds @opencom/web-shared. |
| apps/web/next.config.js | Adds @opencom/web-shared to transpilePackages. |
| apps/web/e2e/widget.spec.ts | Stabilizes widget E2E selectors/timeouts and resets volatile storage keys. |
| apps/web/e2e/tooltips.spec.ts | Improves determinism (workspace id selection + explicit confirm button). |
| apps/web/e2e/snippets.spec.ts | Converts auth bootstrap skip into a hard assertion for consistency. |
| apps/web/e2e/reports.spec.ts | Simplifies auth-refresh usage (relies on global setup/fixtures). |
| apps/web/e2e/public-pages.spec.ts | Removes nondeterministic “restricted boundary” test and documents why. |
| apps/web/e2e/outbound.spec.ts | Replaces dialog auto-accept with explicit confirm button clicks. |
| apps/web/e2e/inbox.spec.ts | Adds retry/error handling for convert-to-ticket and ensures suggestions sidecar opens. |
| apps/web/e2e/helpers/widget-helpers.ts | Adds new helper waiters and improves survey/tour visibility utilities. |
| apps/web/e2e/helpers/storage-state.ts | Adds storage-state sanitization + helpers to clear volatile widget state. |
| apps/web/e2e/fixtures.ts | Refreshes auth and sanitizes storage state at worker boundaries. |
| apps/web/e2e/csat.spec.ts | Makes CSAT tests deterministic per visitor via visitorKey. |
| apps/web/e2e/carousels.spec.ts | Removes redundant auth refresh and uses explicit confirm button. |
| apps/web/e2e/auth.spec.ts | Improves signup selectors for UI variants (“Password” / “Create Account”). |
| apps/web/e2e/ai-agent-settings.spec.ts | Makes AI section opening deterministic via section toggle/content selectors. |
| apps/web/e2e/SKIP_REGISTRY.md | Updates skip registry to reflect removed/changed skip conditions. |
| apps/mobile/src/contexts/NotificationContext.tsx | Refactors push token mutations to makeFunctionReference. |
| apps/mobile/src/contexts/AuthContext.tsx | Refactors auth/workspace/onboarding refs to makeFunctionReference and adds local shallow types. |
| apps/mobile/package.json | Bumps convex to match web. |
| apps/mobile/app/_layout.tsx | Simplifies route detection logic using segments.at(1) and removes index special-case. |
| apps/mobile/app/(app)/settings.tsx | Refactors settings Convex hooks to typed makeFunctionReference refs. |
| apps/mobile/app/(app)/onboarding.tsx | Refactors onboarding Convex refs and adds local types. |
| apps/mobile/app/(app)/index.tsx | Refactors inbox list/presence queries to makeFunctionReference refs and handles legacy payload shapes. |
| apps/mobile/app/(app)/conversation/[id].tsx | Refactors conversation page Convex refs to makeFunctionReference refs and adds local record types. |
| ROADMAP.md | Expands/reorganizes roadmap items including RN/native SDK docs topics. |
| AGENTS.md | Documents Convex TS deep-instantiation mitigation patterns and when to localize workarounds. |
| .github/workflows/ci.yml | Adds continue-on-error gates + a final summary step that fails only when blocking checks failed. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const hostedOnboardingStateQuery = makeFunctionReference< | ||
| "query", | ||
| { workspaceId: Id<"workspaces"> }, | ||
| { | ||
| status?: string; | ||
| verificationToken?: string | null; | ||
| isWidgetVerified?: boolean; | ||
| } | null | ||
| >("workspaces:getHostedOnboardingState"); | ||
|
|
||
| const onboardingIntegrationSignalsQuery = makeFunctionReference< | ||
| "query", | ||
| { workspaceId: Id<"workspaces"> }, | ||
| { | ||
| integrations?: Array<{ | ||
| id: string; | ||
| clientType: string; | ||
| clientVersion?: string; | ||
| detectedAt?: number | null; | ||
| isActiveNow?: boolean; | ||
| matchesCurrentVerificationWindow?: boolean; | ||
| origin?: string; | ||
| currentUrl?: string; | ||
| clientIdentifier?: string; | ||
| lastSeenAt?: number | null; | ||
| activeSessionCount?: number; | ||
| }>; | ||
| } | null | ||
| >("workspaces:getHostedOnboardingIntegrationSignals"); | ||
|
|
||
| const startHostedOnboardingRef = makeFunctionReference< | ||
| "mutation", | ||
| { workspaceId: Id<"workspaces"> }, | ||
| unknown | ||
| >("workspaces:startHostedOnboarding"); | ||
|
|
||
| const issueVerificationTokenRef = makeFunctionReference< | ||
| "mutation", | ||
| { workspaceId: Id<"workspaces"> }, | ||
| { token: string } | ||
| >("workspaces:issueHostedOnboardingVerificationToken"); | ||
|
|
||
| const completeWidgetStepRef = makeFunctionReference< | ||
| "mutation", | ||
| { workspaceId: Id<"workspaces">; token?: string }, | ||
| { success: boolean } | ||
| >("workspaces:completeHostedOnboardingWidgetStep"); |
There was a problem hiding this comment.
These Convex function references are created inside the component, which means they are re-instantiated every render. Move them to module scope (or memoize them) so useQuery/useMutation receive stable references and don’t risk unnecessary resubscribe/re-render churn.
| const campaignQuery = makeFunctionReference< | ||
| "query", | ||
| { id: Id<"emailCampaigns"> }, | ||
| EmailCampaignRecord | null | ||
| >("emailCampaigns:get"); | ||
|
|
||
| const campaignStatsQuery = makeFunctionReference< | ||
| "query", | ||
| { id: Id<"emailCampaigns"> }, | ||
| EmailCampaignStats | ||
| >("emailCampaigns:getStats"); | ||
|
|
||
| const eventNamesQuery = makeFunctionReference< | ||
| "query", | ||
| { workspaceId: Id<"workspaces"> }, | ||
| string[] | ||
| >("events:getDistinctNames"); | ||
|
|
||
| const updateCampaignRef = makeFunctionReference<"mutation", UpdateCampaignArgs, Id<"emailCampaigns">>( | ||
| "emailCampaigns:update" | ||
| ); | ||
| const updateCampaign = useMutation(api.emailCampaigns.update); | ||
| const sendCampaign = useMutation(api.emailCampaigns.send); | ||
|
|
||
| const sendCampaignRef = makeFunctionReference<"mutation", SendCampaignArgs, SendCampaignResult>( | ||
| "emailCampaigns:send" | ||
| ); |
There was a problem hiding this comment.
Same pattern as above: creating makeFunctionReference(...) values inside a React component produces new reference objects on every render. Define these refs at module scope (recommended for consistency with the other refactors in this PR) so query/mutation hooks can rely on referential stability.
| <Input | ||
| type="number" | ||
| value={value.delaySeconds || 5} | ||
| onChange={(e) => | ||
| onChange({ ...value, delaySeconds: Number.parseInt(e.target.value, 10) }) | ||
| } | ||
| min={1} | ||
| /> |
There was a problem hiding this comment.
Parsing numeric inputs with Number.parseInt can yield NaN (e.g., user clears the input), which will push an invalid value into state. Consider normalizing to undefined (or a safe default) when parsing fails, so downstream trigger evaluation doesn’t receive NaN.
| <Input | ||
| type="number" | ||
| value={value.scrollPercent || 50} | ||
| onChange={(e) => | ||
| onChange({ ...value, scrollPercent: Number.parseInt(e.target.value, 10) }) | ||
| } | ||
| min={1} | ||
| max={100} | ||
| /> |
There was a problem hiding this comment.
Parsing numeric inputs with Number.parseInt can yield NaN (e.g., user clears the input), which will push an invalid value into state. Consider normalizing to undefined (or a safe default) when parsing fails, so downstream trigger evaluation doesn’t receive NaN.
| > | ||
| <p className="text-sm font-medium">{content.text || "Your banner text..."}</p> | ||
| {content.dismissible !== false && ( | ||
| <button className="text-white/80 hover:text-white">x</button> |
There was a problem hiding this comment.
The dismiss button uses a single-character label (“x”) without an accessible name. Add an explicit aria-label (e.g., “Dismiss banner”) or render a visually-hidden label so screen readers announce the action correctly.
| <button className="text-white/80 hover:text-white">x</button> | |
| <button | |
| type="button" | |
| className="text-white/80 hover:text-white" | |
| aria-label="Dismiss banner" | |
| > | |
| x | |
| </button> |
| export function getOutboundMessageStatusBadgeClass(status: OutboundMessageStatus): string { | ||
| switch (status) { | ||
| case "active": | ||
| return "bg-green-100 text-green-800"; | ||
| case "draft": | ||
| return "bg-gray-100 text-gray-800"; | ||
| case "paused": | ||
| return "bg-yellow-100 text-yellow-800"; | ||
| case "archived": | ||
| return "bg-red-100 text-red-800"; | ||
| } | ||
| } |
There was a problem hiding this comment.
Both switches rely on union exhaustiveness, but have no default/assert-never path, so a future union expansion can silently return undefined at runtime. Add an explicit default (or an assertNever) so behavior is predictable and TypeScript will enforce exhaustiveness.
| export function OutboundMessageTypeIcon({ | ||
| type, | ||
| className = "h-4 w-4", | ||
| }: OutboundMessageTypeIconProps) { | ||
| switch (type) { | ||
| case "chat": | ||
| return <MessageSquare className={className} />; | ||
| case "post": | ||
| return <Bell className={className} />; | ||
| case "banner": | ||
| return <Flag className={className} />; | ||
| } | ||
| } |
There was a problem hiding this comment.
Both switches rely on union exhaustiveness, but have no default/assert-never path, so a future union expansion can silently return undefined at runtime. Add an explicit default (or an assertNever) so behavior is predictable and TypeScript will enforce exhaustiveness.
| "use client"; | ||
|
|
||
| import type { Id } from "@opencom/convex/dataModel"; | ||
|
|
||
| export type ArticleEditorId = Id<"articles"> | Id<"internalArticles">; | ||
|
|
There was a problem hiding this comment.
This file is a types/constants module (no React hooks/components) but is marked "use client", which can unnecessarily force client-module boundaries and increase bundling constraints in Next.js. Remove "use client" here (and in similar pure-type modules) unless there’s a concrete need for client-only semantics.
| "use client"; | |
| import type { Id } from "@opencom/convex/dataModel"; | |
| export type ArticleEditorId = Id<"articles"> | Id<"internalArticles">; | |
| import type { Id } from "@opencom/convex/dataModel"; | |
| export type ArticleEditorId = Id<"articles"> | Id<"internalArticles">; |
| export function buildHelpCenterHref(options?: { | ||
| workspaceId?: WorkspaceIdLike; | ||
| collectionSlug?: string | null; | ||
| }): string { | ||
| const params = new URLSearchParams(); | ||
| if (options?.collectionSlug) { | ||
| params.set("collection", options.collectionSlug); | ||
| } | ||
| if (options?.workspaceId) { | ||
| params.set("workspaceId", options.workspaceId); | ||
| } | ||
| return buildHelpHref("/help", params); | ||
| } |
There was a problem hiding this comment.
This new module introduces routing/localStorage logic that can be unit-tested deterministically (URL building + storage fallback behavior). Consider adding a small vitest suite for these helpers to lock in query param behavior and storage parsing fallbacks.
| export function readStoredPublicWorkspaceId(): string | null { | ||
| if (typeof window === "undefined") { | ||
| return null; | ||
| } | ||
|
|
||
| const rawValue = window.localStorage.getItem(PUBLIC_WORKSPACE_STORAGE_KEY); | ||
| if (rawValue && rawValue.length > 0) { | ||
| return rawValue; | ||
| } | ||
|
|
||
| return readStoredActiveWorkspaceId(); | ||
| } |
There was a problem hiding this comment.
This new module introduces routing/localStorage logic that can be unit-tested deterministically (URL building + storage fallback behavior). Consider adding a small vitest suite for these helpers to lock in query param behavior and storage parsing fallbacks.
There was a problem hiding this comment.
Why do we use local storage for this? @copilot
For help center links, why do we need to read active workspaceID from local storage?
Dont the public links have the specific workspace ID in the URLs, and if we are linking to helpcenter in the widget, why do we need to pull active workspace id?
This pull request primarily refactors how Convex backend function references are used in the mobile app codebase, moving from direct usage of generated
apireferences to explicitmakeFunctionReferencecalls. This change addresses deep TypeScript instantiation issues and improves type safety and maintainability. Additionally, the CI workflow is enhanced to better summarize and control job outcomes, and the documentation and roadmap are updated for clarity and future planning.Refactor: Convex Function References in Mobile App
apireferences with explicitmakeFunctionReferencecalls in mobile app files ([id].tsx,index.tsx,onboarding.tsx,settings.tsx), defining local types for query and mutation results to avoid deep TypeScript instantiation errors. (apps/mobile/app/(app)/conversation/[id].tsxL15-R15, apps/mobile/app/(app)/conversation/[id].tsxR26-R76, apps/mobile/app/(app)/conversation/[id].tsxL40-R107, [1] [2] [3] [4] [5] F78a3a4dL15R15)Developer Experience & Documentation
AGENTS.mdexplaining the workaround for Convex TypeScript deep-instantiation errors, recommending the use ofmakeFunctionReferenceat problematic sites and keeping workarounds localized.CI/CD Improvements
.github/workflows/ci.ymlto use newpnpm quality:lintandpnpm quality:typecheckscripts, addscontinue-on-errorfor quality and security steps, and introduces a new step to summarize check results and fail the workflow if blocking steps fail.Roadmap & Planning
ROADMAP.mdto clarify, reorganize, and expand on P0 tasks, including new items for deployment dependencies, AI features, mobile parity, and documentation structure. Also adds a section for RN & Native SDKs documentation topics. [1] [2]