Refactors create feed flow, steps use router#188
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
|
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 You can disable this status message by setting the WalkthroughThis update refactors the feed API, backend services, error handling, and frontend feed creation flow. It introduces Zod-based validation schemas, streamlines error classes, updates service and repository method signatures, and restructures the frontend feed creation process into a multi-step, form-driven workflow. Type safety and response consistency are enhanced throughout. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend (Multi-step Feed Creation)
participant API (feeds.ts)
participant FeedService
participant FeedRepository
participant Database
User->>Frontend (Multi-step Feed Creation): Fill out step forms (info, settings, review)
Frontend (Multi-step Feed Creation)->>API (feeds.ts): POST /feeds (validated with Zod)
API (feeds.ts)->>FeedService: createFeed(feedConfig, accountId)
FeedService->>FeedRepository: createFeed({config, created_by, ...})
FeedRepository->>Database: Insert feed record
Database-->>FeedRepository: Feed record
FeedRepository-->>FeedService: Feed record
FeedService-->>API (feeds.ts): Feed record
API (feeds.ts)-->>Frontend (Multi-step Feed Creation): JSON response (validated)
Frontend (Multi-step Feed Creation)-->>User: Show success, navigate to feed
Possibly related PRs
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 8
🔭 Outside diff range comments (1)
apps/app/src/lib/api/feeds.ts (1)
44-68: Consider adding query invalidation on successful mutations.The mutation hooks should invalidate related queries to ensure data consistency.
export function useCreateFeed() { + const queryClient = useQueryClient(); return useApiMutation<FeedResponse, Error, CreateFeedRequest>( { method: "POST", path: `/feeds`, message: "createFeed", }, { - // onSuccess logic can be added here if needed, using queryClient from useQueryClient() + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["feeds"] }); + }, }, ); } export function useUpdateFeed(feedId: string) { + const queryClient = useQueryClient(); return useApiMutation<FeedResponse, Error, UpdateFeedRequest>( { method: "PUT", path: `/feeds/${feedId}`, message: "updateFeed", }, { - // onSuccess logic + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["feeds"] }); + queryClient.invalidateQueries({ queryKey: ["feed-details", feedId] }); + }, }, ); }
🧹 Nitpick comments (11)
apps/app/src/components/FeedList.tsx (1)
7-7: Remove Debuggingconsole.log
Thisconsole.logappears to be left over from debugging. Please remove it or replace it with a structured logger for production readiness.apps/app/package.json (1)
43-44: Consider necessity of lodash dependency.While
immeris excellent for immutable state updates, consider whether the fulllodashlibrary is necessary or if specific utility functions could be implemented directly to reduce bundle size.apps/app/src/routes/_layout/create/feed.tsx (1)
37-52: Consider improving step navigation accessibility.The step titles could be made clickable to allow direct navigation to completed steps, improving user experience.
<div key={index} className="flex flex-col items-center min-w-[100px] px-2" + role="button" + tabIndex={index <= currentStep ? 0 : -1} >apps/app/src/routes/_layout/create/feed/review.tsx (1)
99-102: TODO: Implement user name resolutionThe TODO comment indicates missing functionality to display user names alongside handles.
Would you like me to help implement a solution to fetch and display user names from Twitter handles, or should I open an issue to track this enhancement?
apps/app/src/components/PublishIntegrations.tsx (1)
120-127: Incomplete save button implementationThe save button currently only logs to console without any actual save functionality. Since the form state is managed by react-hook-form, consider if this button is necessary or if it should trigger form validation/submission.
Should this button validate and save the Telegram settings, or can it be removed since the form context already manages the state?
apps/app/src/components/ContentApprovers.tsx (1)
174-179: Use camelCase for SVG attributes in ReactSVG attributes should use camelCase in React components.
Apply this diff:
<path d="M3 6.5H21M19 6.5V20.5C19 21.5 18 22.5 17 22.5H7C6 22.5 5 21.5 5 20.5V6.5M8 6.5V4.5C8 3.5 9 2.5 10 2.5H14C15 2.5 16 3.5 16 4.5V6.5M10 11.5V17.5M14 11.5V17.5" stroke="#020617" - stroke-linecap="round" - stroke-linejoin="round" + strokeLinecap="round" + strokeLinejoin="round" />apps/api/src/routes/api/feeds.ts (3)
173-175: Remove redundant null checkThe null check for
updatedFeedappears redundant. ThefeedService.updateFeedmethod should throw appropriate errors (NotFoundError or ForbiddenError) rather than returning null, maintaining consistent error handling patterns across the service layer.
283-283: Consider using validated response schemaThis endpoint returns an unvalidated object while all other endpoints use validated response schemas. Consider creating a schema for the moderation permission response to maintain consistency.
Define a response schema:
const CanModerateResponseSchema = z.object({ canModerate: z.boolean(), reason: z.string().optional(), error: z.string().optional(), });Also applies to: 297-297
288-291: Inconsistent service retrieval patternThis route uses a different pattern for service retrieval with generic type parameter while other routes use direct methods. Consider using
ServiceProvider.getInstance().getModerationService()for consistency.- const moderationService = - ServiceProvider.getInstance().getService<ModerationService>( - "moderationService", - ); + const moderationService = ServiceProvider.getInstance().getModerationService();apps/app/src/store/feed-creation-store.ts (2)
57-60: Consider making the AI prompt configurable.The AI transform prompt is hardcoded in the initial state. Consider moving this to a configuration constant or making it customizable, as different feeds might need different summarization approaches.
Would you like me to suggest a pattern for making the AI prompt configurable while maintaining sensible defaults?
86-90: Consider type-safe path updates.The
setValuemethod accepts a string path which isn't type-safe. Consider using a type-safe approach likets-toolbelt's Path type or creating specific update methods for commonly updated paths.- setValue: (path: string, value: unknown) => void; + setValue: <T extends keyof FeedConfig>(path: T | `${T}.${string}`, value: unknown) => void;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (28)
apps/api/src/routes/api/feeds.ts(2 hunks)apps/api/src/services/feed.service.ts(6 hunks)apps/api/src/types/errors.ts(1 hunks)apps/app/package.json(2 hunks)apps/app/rsbuild.config.ts(3 hunks)apps/app/src/components/ContentApprovers.tsx(2 hunks)apps/app/src/components/CurationFormSteps.tsx(0 hunks)apps/app/src/components/CurationSettingsForm.tsx(0 hunks)apps/app/src/components/FeedItem.tsx(1 hunks)apps/app/src/components/FeedList.tsx(1 hunks)apps/app/src/components/PublishIntegrations.tsx(3 hunks)apps/app/src/components/ui/tanstack-form.tsx(1 hunks)apps/app/src/lib/api/feed.ts(0 hunks)apps/app/src/lib/api/feeds.ts(4 hunks)apps/app/src/routeTree.gen.ts(14 hunks)apps/app/src/routes/_layout/create/feed.tsx(1 hunks)apps/app/src/routes/_layout/create/feed/index.tsx(1 hunks)apps/app/src/routes/_layout/create/feed/review.tsx(5 hunks)apps/app/src/routes/_layout/create/feed/settings.tsx(1 hunks)apps/app/src/store/feed-creation-store.ts(1 hunks)packages/shared-db/package.json(1 hunks)packages/shared-db/src/repositories/feed.repository.ts(4 hunks)packages/shared-db/src/schema/feeds.ts(3 hunks)packages/shared-db/src/validators.ts(0 hunks)packages/shared-db/tsconfig.json(1 hunks)packages/types/src/api/feeds.ts(1 hunks)packages/types/src/config.ts(2 hunks)packages/types/src/index.ts(1 hunks)
💤 Files with no reviewable changes (4)
- apps/app/src/lib/api/feed.ts
- packages/shared-db/src/validators.ts
- apps/app/src/components/CurationFormSteps.tsx
- apps/app/src/components/CurationSettingsForm.tsx
🔇 Additional comments (34)
apps/app/src/components/FeedItem.tsx (1)
7-7: Import path updated to newfeedsmodule
This aligns with the consolidation of your API hooks intofeeds.ts.packages/shared-db/package.json (1)
26-26: Add Workspace Dev Dependency for Shared Types
Introducing@curatedotfun/typesas a workspace devDependency ensures shared type definitions are accessible during development.packages/types/src/index.ts (1)
5-8: Export New Feeds API Types
Addingexport * from "./api/feeds"integrates the new feed schemas into the shared types package, enabling consistent typing across the codebase.apps/app/rsbuild.config.ts (3)
3-3: LGTM: Updated import to match new TanStack Router plugin API.The change from default import
TanStackRouterRspackto named importtanstackRouteraligns with the plugin API update.
27-27: Good addition: "@" alias improves import readability.Adding the "@" alias pointing to "./src" will make imports cleaner throughout the application.
49-51: LGTM: Plugin configuration updated correctly.The plugin invocation now uses the correct named import and enables route generation, which is essential for the new multi-step feed creation flow.
apps/app/package.json (2)
32-35: LGTM: Form handling dependencies added.The addition of
@tanstack/react-formand@tanstack/zod-form-adaptersupports the new form-driven approach in the multi-step feed creation flow.
34-34: LGTM: Router packages updated consistently.The router packages are updated to caret versions, which aligns with the routing refactor and ensures compatibility.
Also applies to: 67-67
packages/types/src/config.ts (3)
79-79: LGTM: Image field change improves UI flexibility.Allowing empty string in addition to URL for the image field provides better flexibility for forms where users might not provide an image initially.
81-81: LGTM: Admins field addition expands functionality.The optional
adminsarray field enhances feed configuration capabilities for permission management.
35-38: ```shell
#!/bin/bashShow the declaration and nearby context of RecapConfigSchema
rg -n "RecapConfigSchema" -C 5 packages/types/src/config.ts
Search for any usage of RecapConfig or RecapConfigSchema across .ts and .tsx files
rg -n "RecapConfig(Schema)?\b" -g "*.{ts,tsx}" -C 5
</details> <details> <summary>apps/app/src/routes/_layout/create/feed/settings.tsx (1)</summary> `58-63`: **LGTM: Proper form setup with global state.** The form is correctly initialized with default values from the global feed creation store and uses the FormProvider pattern for child components. </details> <details> <summary>apps/app/src/routes/_layout/create/feed.tsx (2)</summary> `12-22`: **LGTM: Well-implemented step tracking logic.** The step matching logic correctly identifies the current step using `useMatchRoute` and calculates progress percentage appropriately. --- `31-57`: **LGTM: Good responsive design and user experience.** The layout provides clear visual feedback with step indicators, progress bar, and responsive design considerations. The use of `Outlet` properly renders nested route content. </details> <details> <summary>apps/app/src/routes/_layout/create/feed/review.tsx (1)</summary> `22-23`: ```shell #!/bin/bash # Inspect the create feed API hook echo "===== apps/app/src/lib/api/feeds.ts =====" sed -n '1,200p' apps/app/src/lib/api/feeds.ts # Inspect the feed creation store definition echo "===== apps/app/src/store/feed-creation-store.ts =====" sed -n '1,200p' apps/app/src/store/feed-creation-store.tspackages/types/src/api/feeds.ts (1)
1-60: Well-structured type definitionsThe Zod schemas are properly organized with clear documentation and appropriate type exports. The date preprocessing ensures consistent serialization.
packages/shared-db/src/schema/feeds.ts (1)
102-116: Well-structured schema generation!Great use of
drizzle-zodfor automatic schema generation from the table definition. This approach reduces duplication and ensures consistency between database schema and validation schemas.packages/shared-db/src/repositories/feed.repository.ts (1)
110-132: Excellent cascading delete implementation!The explicit deletion of related records before deleting the main feed record is a robust approach that prevents foreign key constraint violations. Returning the deleted record is also useful for audit trails and confirmation.
apps/app/src/components/ui/tanstack-form.tsx (1)
92-109: Excellent accessibility implementation!Great use of ARIA attributes (
aria-describedby,aria-invalid) to ensure screen readers properly announce form field states and associated messages.apps/app/src/store/feed-creation-store.ts (4)
1-7: LGTM! Good choice of utilities for state management.Using Immer middleware with Zustand is an excellent choice for managing complex nested state immutably. The lodash utilities are appropriate for the nested object operations.
8-25: Well-structured type definitions.The type definitions are clear and appropriately typed. Using
Partial<FeedConfig>for the feedConfig state is a good choice for building the configuration incrementally during the creation flow.
96-123: Excellent implementation of Telegram config management.The
setTelegramConfigmethod correctly handles all scenarios: adding new config, updating existing config, and removing when disabled. Good use of array manipulation methods.
124-137: Well-implemented approver synchronization.The
setApproversmethod correctly maintains consistency between the flatapproversarray and the nestedmoderation.approversobject grouped by platform. The use of lodash'sgroupByand reduce pattern is appropriate.apps/api/src/services/feed.service.ts (3)
90-102: Clean implementation of feed creation.Good separation of concerns by accepting
FeedConfigand internally constructing the database insert object. Proper use of transactions.
104-110: Proper error handling for missing resources.Good use of the
NotFoundErrorwith clear resource identification. This provides consistent error responses across the API.
162-177: Well-implemented feed deletion with proper authorization.Good permission checks and error handling. The method properly returns the deleted feed data which can be useful for audit trails or undo functionality.
apps/app/src/lib/api/feeds.ts (2)
23-42: Clean implementation of data unwrapping.Good use of the
selectoption to unwrap the response data. The type transformations are clear and the fallback to empty array inuseAllFeedsis a good defensive practice.
135-141: Verify the response type matches the API.The TODO comment indicates uncertainty about the response type matching the API. This should be verified to ensure type safety.
#!/bin/bash # Search for the can-moderate endpoint definition in the API ast-grep --pattern 'router.$_("/feeds/:feedId/can-moderate"' # Also search for any response type definitions rg -A 10 "can-moderate" --glob "*.ts" --glob "!node_modules"apps/api/src/types/errors.ts (2)
3-61: Well-designed error class hierarchy.The simplified error hierarchy is clean and follows REST conventions. Good design choices:
- Fixed status codes for standard errors
- Optional details for additional context
- Service-specific errors with flexible status codes
- Consistent constructor patterns
62-70: Good error response schema definition.The Zod schema provides runtime validation for error responses and ensures consistent error structure across the API. The
success: falseliteral is useful for discriminating between success and error responses.apps/app/src/routeTree.gen.ts (4)
90-94: LGTM: Well-structured nested route hierarchy for multi-step flow.The route definitions correctly establish a parent-child relationship that supports the multi-step feed creation workflow. The nested structure allows for clean navigation between form steps while maintaining shared layout and state.
Also applies to: 127-137
454-468: LGTM: Consistent implementation of parent route with children.The
LayoutCreateFeedRouteChildreninterface and implementation follows the established pattern used by other parent routes in the application (likeLayoutFeedFeedIdRouteChildren). The structure properly defines the relationship between the parent feed creation route and its child steps.
154-168: ```shell
#!/bin/bash
echo "Re-running navigation reference search without --type flags and using globs..."
rg -i "navigate.create/feed" -n --glob '.tsx' --glob '.ts' --glob '.js' --glob '.jsx'
rg -i "href.create/feed" -n --glob '.tsx' --glob '.ts' --glob '.js' --glob '.jsx'
rg -i "/create/feed" -n --glob '.tsx' --glob '.ts' --glob '.js' --glob '.jsx' -A 2--- `23-23`: ```shell #!/bin/bash echo "Checking for named export 'Route' in new route components..." grep -R -n "export .*Route" apps/app/src/routes/_layout/create/feed/index.tsx || echo "No 'Route' export found in index.tsx" grep -R -n "export .*Route" apps/app/src/routes/_layout/create/feed/settings.tsx || echo "No 'Route' export found in settings.tsx" grep -R -n "export .*Route" apps/app/src/routes/_layout/create/feed/review.tsx || echo "No 'Route' export found in review.tsx"
apps/api/src/routes/api/feeds.ts
Outdated
| @@ -256,8 +297,8 @@ feedsRoutes.get( | |||
| return c.json({ canModerate }); | |||
| } catch (error: any) { | |||
There was a problem hiding this comment.
Use unknown instead of any for error type
- } catch (error: any) {
+ } catch (error: unknown) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| } catch (error: any) { | |
| } catch (error: unknown) { |
🤖 Prompt for AI Agents
In apps/api/src/routes/api/feeds.ts at line 298, the catch block currently types
the error as 'any', which is not recommended. Change the error type from 'any'
to 'unknown' to improve type safety and better handle unexpected error types.
| const feedConfig = (await this.feedRepository.getFeedConfig( | ||
| feedId, | ||
| )) as FeedConfig; // Get config from DB | ||
| if (!feedConfig) { |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid type assertion for feed config.
The type assertion as FeedConfig could hide type mismatches. Consider validating the config structure or updating the repository method to return the correct type.
- const feedConfig = (await this.feedRepository.getFeedConfig(
- feedId,
- )) as FeedConfig; // Get config from DB
+ const feedConfig = await this.feedRepository.getFeedConfig(feedId);
+ if (!feedConfig || !this.isValidFeedConfig(feedConfig)) {
+ throw new Error(`Invalid feed configuration for feedId: ${feedId}`);
+ }Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/api/src/services/feed.service.ts around lines 192 to 195, avoid using
the type assertion 'as FeedConfig' when retrieving the feedConfig from the
repository, as it can mask type mismatches. Instead, update the
feedRepository.getFeedConfig method to explicitly return a Promise of FeedConfig
or validate the returned data structure before assignment to ensure type safety
without forced casting.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt * feat: add settings page UI * feat: add route based tab navigation * feat: welcome route for new feed (#192) * feat: welcome route for new feed * fix: feed overflow in top feeds column of leaderboard * fix: coderabbit comments * moderate submissions * fmt * fmt --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* moderation handle platform_user_id and near account id * standardize activity * fmt * delete tests * fix shared types * activity leaderboard * throw not error * fix services * feat: use tanstack table for leaderboard (#183) * fix: mobile layout improvement feed page (#185) * Refactors create feed flow, steps use router (#188) * wip * feed types * better feed form * Update packages/shared-db/tsconfig.json Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/settings.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update apps/app/src/routes/_layout/create/feed/index.tsx Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * set lock * nitpicks * fmt --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Implements JWT auth flow with 7 day tokens (#187) * better auth services * nit picks * nonce validation * nitpicks * clean up * fix error types * import error * fix auth requests * fix: toast colors not correct (#189) * fix: toast colors not corrent * fmt * fix feed * fix zod type * fix @ and config * fmt * feat: add settings page UI * feat: add route based tab navigation * feat: welcome route for new feed (#192) * feat: welcome route for new feed * fix: feed overflow in top feeds column of leaderboard * fix: coderabbit comments * moderate submissions * fmt * fmt * adds auto approval * auto approval * upgrade fastintear * fix auth flow * upgrade packages * nitpicks * Introduces worker service w/ queues, enables auto-approval (#196) * init * clean up * fmt * build fixes * init * running * working auto approval * init * clean up * fmt * build fixes * init * running * working auto approval * clean up * nitpicks * update pnpm lock * add @roamhq/wrtc * docker and type module * agent-twitter-client * add rspack * REDIS_URL * bullmq workaround * clean config * fix auth flow * same flow * logger * better logger * railway logger --------- Co-authored-by: Zeeshan Ahmad <itexpert120@outlook.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Uses router for steps
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Chores
Refactor
Documentation