Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
WalkthroughThis change set implements a comprehensive refactor and redesign of the activity, moderation, and submission APIs and their related data schemas. It transitions validation and typing to a new shared types package, updates database schemas (especially moderation history), and removes all backend test code and related seed/config files. The update also streamlines internal logic, enhances type safety, and standardizes API responses. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API_Route
participant Service
participant Repository
participant TypesPkg
Client->>API_Route: Request (e.g., GET /api/activity/user/:accountId)
API_Route->>TypesPkg: Validate params/query with Zod schemas
API_Route->>Service: Call getUserActivities(accountId, options)
Service->>Repository: Fetch user, activities, moderation history
Repository-->>Service: Return typed and validated data
Service->>TypesPkg: Parse/validate results with shared schemas
Service-->>API_Route: Return standardized response object
API_Route->>TypesPkg: Wrap response in ActivityListResponseSchema
API_Route-->>Client: JSON response { statusCode, success, data }
Possibly related PRs
Poem
✨ Finishing Touches
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 (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/shared-db/src/repositories/submission.repository.ts (1)
372-379: Fix formatting issue in pagination object.While the logic is correct, there's a Prettier formatting failure that needs to be addressed. The pagination object formatting should be standardized.
#!/bin/bash # Description: Fix formatting issues in the file # Expected: Clean formatting after running prettier npx prettier --write packages/shared-db/src/repositories/submission.repository.tsapps/api/src/routes/api/activity.ts (1)
46-76: Consider extracting error handling into a helper function.The error handling pattern is repeated multiple times throughout the file with similar logic for parsing
ActivityServiceErrorvs validation errors vs generic errors.Consider creating a helper function to reduce duplication:
+function handleActivityError(error: unknown, operation: string) { + if (error instanceof ActivityServiceError) { + return { + schema: ApiErrorResponseSchema.parse({ + statusCode: error.statusCode as ContentfulStatusCode, + success: false, + error: { message: error.message }, + }), + statusCode: error.statusCode as ContentfulStatusCode, + }; + } + + const isValidationError = error instanceof Error && error.name === "ValidationError"; + const message = isValidationError ? "Invalid query parameters" : `Failed to ${operation}`; + const statusCode = isValidationError ? 400 : 500; + + return { + schema: ApiErrorResponseSchema.parse({ + statusCode, + success: false, + error: { message }, + }), + statusCode, + }; +}apps/app/src/lib/api/activity.ts (1)
40-71: Comprehensive query parameter support with minor optimization opportunityThe enhanced
useUserActivityhook now supports rich filtering options. The parameter building logic is thorough and handles all the query options fromGetUserActivitiesApiQuery.Consider extracting the parameter building logic into a helper function for better readability:
+function buildUserActivityParams(options?: Partial<GetUserActivitiesApiQuery>): string { + const params = new URLSearchParams(); + + if (options?.types) + params.append( + "types", + Array.isArray(options.types) ? options.types.join(",") : options.types, + ); + if (options?.feed_id) params.append("feed_id", options.feed_id); + if (options?.from_date) params.append("from_date", options.from_date); + if (options?.to_date) params.append("to_date", options.to_date); + if (options?.limit) params.append("limit", options.limit.toString()); + if (options?.offset) params.append("offset", options.offset.toString()); + if (options?.sortBy) params.append("sortBy", options.sortBy); + if (options?.sortOrder) params.append("sortOrder", options.sortOrder); + + return params.toString(); +} export function useUserActivity( userId: string | number, options?: Partial<GetUserActivitiesApiQuery>, ) { - const params = new URLSearchParams(); - - if (options?.types) - params.append( - "types", - Array.isArray(options.types) ? options.types.join(",") : options.types, - ); - if (options?.feed_id) params.append("feed_id", options.feed_id); - if (options?.from_date) params.append("from_date", options.from_date); - if (options?.to_date) params.append("to_date", options.to_date); - - if (options?.limit) params.append("limit", options.limit.toString()); - if (options?.offset) params.append("offset", options.offset.toString()); - if (options?.sortBy) params.append("sortBy", options.sortBy); - if (options?.sortOrder) params.append("sortOrder", options.sortOrder); - - const queryString = params.toString(); + const queryString = buildUserActivityParams(options); const path = `/activity/user/${userId}${queryString ? `?${queryString}` : ""}`;apps/api/src/services/moderation.service.ts (1)
149-223: Improved variable naming and moderation source trackingThe changes to use
moderatorNearIdandmoderatorAccountIdfor clarity are good. The addition ofmoderationSourcelogic properly distinguishes between super admin direct actions and UI-driven actions.Consider making the platform determination more dynamic as noted in the TODO:
- const submissionPlatform = "twitter"; // TODO: dynamic, tied to source + const submissionPlatform = submission.platform || "twitter"; // Default to twitter for backward compatibility
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (37)
apps/api/package.json(0 hunks)apps/api/src/routes/api/activity.ts(13 hunks)apps/api/src/routes/api/submission.ts(3 hunks)apps/api/src/services/activity.service.ts(9 hunks)apps/api/src/services/moderation.service.ts(11 hunks)apps/api/src/services/submission.service.ts(0 hunks)apps/api/src/validation/activity.validation.ts(0 hunks)apps/api/test/README.md(0 hunks)apps/api/test/component/approval-flow.test.ts(0 hunks)apps/api/test/component/submission-flow.test.ts(0 hunks)apps/api/test/curate.config.test.json(0 hunks)apps/api/test/e2e/full-flow.test.ts(0 hunks)apps/api/test/integration/database.test.ts(0 hunks)apps/api/test/setup/seed-test.ts(0 hunks)apps/api/test/setup/seed.sql(0 hunks)apps/api/test/unit/sanitize.test.ts(0 hunks)apps/api/test/unit/services/scheduler/scheduler.service.test.ts(0 hunks)apps/api/test/utils/test-client.ts(0 hunks)apps/api/test/utils/test-data.ts(0 hunks)apps/api/test/utils/test-helpers.ts(0 hunks)apps/api/test/utils/test-server.ts(0 hunks)apps/app/src/lib/api/activity.ts(1 hunks)packages/shared-db/migrations/0015_ambiguous_the_watchers.sql(1 hunks)packages/shared-db/migrations/meta/0015_snapshot.json(1 hunks)packages/shared-db/migrations/meta/_journal.json(1 hunks)packages/shared-db/src/repositories/activity.repository.ts(2 hunks)packages/shared-db/src/repositories/moderation.repository.ts(6 hunks)packages/shared-db/src/repositories/submission.repository.ts(4 hunks)packages/shared-db/src/schema/activity.ts(2 hunks)packages/shared-db/src/schema/moderation.ts(4 hunks)packages/shared-db/src/validators.ts(0 hunks)packages/types/src/api/activity.ts(1 hunks)packages/types/src/api/common.ts(1 hunks)packages/types/src/api/moderation.ts(2 hunks)packages/types/src/domain/submission.ts(3 hunks)packages/types/src/dtos/activity.dto.ts(0 hunks)packages/types/src/index.ts(1 hunks)
💤 Files with no reviewable changes (19)
- apps/api/package.json
- apps/api/src/services/submission.service.ts
- apps/api/test/setup/seed-test.ts
- apps/api/test/utils/test-client.ts
- apps/api/test/utils/test-server.ts
- apps/api/test/component/submission-flow.test.ts
- apps/api/test/README.md
- apps/api/test/unit/sanitize.test.ts
- apps/api/test/setup/seed.sql
- packages/shared-db/src/validators.ts
- apps/api/test/curate.config.test.json
- apps/api/test/utils/test-helpers.ts
- apps/api/test/integration/database.test.ts
- apps/api/test/unit/services/scheduler/scheduler.service.test.ts
- apps/api/test/component/approval-flow.test.ts
- apps/api/test/e2e/full-flow.test.ts
- apps/api/src/validation/activity.validation.ts
- apps/api/test/utils/test-data.ts
- packages/types/src/dtos/activity.dto.ts
🧰 Additional context used
🪛 GitHub Actions: CI
packages/shared-db/src/repositories/submission.repository.ts
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues.
packages/shared-db/src/repositories/activity.repository.ts
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues.
🔇 Additional comments (48)
packages/shared-db/migrations/meta/_journal.json (1)
110-116: LGTM! Migration journal entry is properly formatted.The new migration entry follows the expected format and corresponds to the moderation history schema changes mentioned in the AI summary.
packages/types/src/index.ts (1)
4-4: ```shell
#!/bin/bash
set -eRe-verify that no files still import from the old DTO path in .ts and .tsx sources
rg "dtos/activity.dto" --glob ".ts" --glob ".tsx"
</details> <details> <summary>packages/shared-db/src/repositories/activity.repository.ts (2)</summary> `3-11`: **Good practice: Separating type-only imports from runtime imports.** The separation of type-only imports (`ActivityType`, `InsertActivity`, `UpdateFeedUserStats`, `UpdateUserStats`) from runtime value imports (`activityTypeZodEnum`) improves clarity and potentially helps with tree-shaking. --- `757-764`: **Fix formatting issues to resolve pipeline failure.** The formatting changes look fine functionally, but there's a Prettier formatting check failure in the pipeline that needs to be addressed. ```shell #!/bin/bash # Description: Check and fix Prettier formatting issues # Expected: No formatting errors after running prettier --write # Check current formatting npx prettier --check packages/shared-db/src/repositories/activity.repository.ts # Show what prettier would change npx prettier packages/shared-db/src/repositories/activity.repository.tspackages/shared-db/src/repositories/submission.repository.ts (1)
124-133: LGTM! Consistent update to moderation history mapping.The changes correctly update the moderation history mapping from the old structure (
tweetId,adminId) to the new enriched structure (submissionId,moderatorAccountId,moderatorAccountIdType,source). The pattern is consistently applied across all three methods.Also applies to: 201-210, 325-334
packages/types/src/domain/submission.ts (2)
1-1: Good practice: Consolidating moderation types.Importing
ModerationActionfrom the shared API module instead of maintaining a localModerationinterface promotes type consistency and reduces duplication across the codebase.
32-32: ```shell
#!/bin/bashLocate any local
Moderationtype/interface in the types packagerg -n "export (type|interface) Moderation" packages/types/src
Dump the
ModerationActionSchemadefinition to review its fieldsrg -n -A20 "export const ModerationActionSchema" packages/types/src/api/moderation.ts
</details> <details> <summary>packages/shared-db/migrations/0015_ambiguous_the_watchers.sql (4)</summary> `1-3`: **Verify column renaming order and constraint handling.** The migration renames columns before dropping constraints, which is correct. However, ensure that the constraint drop on line 3 references the original column name before the rename. --- `26-27`: **Ensure data integrity before setting NOT NULL constraints.** Setting columns to NOT NULL after data population is correct. The migration populates both new columns for all existing records, so this should be safe. --- `29-31`: **Verify foreign key and index recreation.** The new foreign key constraint correctly references the renamed column `submission_id` and maintains cascade deletion. The indexes are properly recreated with updated column names. --- `15-24`: ```shell #!/bin/bash # Locate the creation of the moderation_history table and any FK on submission_id echo "=== moderation_history table definition ===" rg -n 'create table "moderation_history"' -A 20 packages/shared-db/migrations echo echo "=== FOREIGN KEY constraints involving submission_id ===" rg -n 'foreign key.*submission_id' -A 5 packages/shared-db/migrationsapps/api/src/routes/api/submission.ts (4)
88-101: Excellent expansion of moderation history mapping.The mapping correctly includes all new fields from the updated moderation schema:
moderatorAccountId,moderatorAccountIdType,source(new fields)- Proper date formatting with ISO strings
- Safe handling of optional
updatedAtfieldThe addition of null safety with
(rs.moderationHistory ?? [])is a good defensive programming practice.
102-102: Good defensive programming with null safety.Adding
(rs.feeds ?? [])prevents potential runtime errors when feeds is null or undefined.
175-188: Consistent mapping implementation across endpoints.The single submission endpoint uses identical mapping logic to the list endpoint, ensuring API consistency.
256-269: Feed-specific endpoint maintains consistency.The feed submissions endpoint also implements the same expanded moderation history mapping, maintaining consistent API responses across all submission endpoints.
packages/types/src/api/common.ts (2)
46-60: Well-designed query options schema with proper validation.The
QueryOptionsSchemaimplementation is excellent:
- String-to-number transformation handles HTTP query parameters correctly
- Proper validation with min/max constraints
- Optional parameters allow flexible API usage
- Enum validation for
sortOrderprevents invalid values
62-74: Comprehensive pagination schema design.The
PaginatedDataSchemaprovides a robust foundation for paginated API responses:
- Generic item schema allows reuse across different data types
- Includes all necessary pagination metadata
- Optional convenience fields (
totalPages,hasNextPage,hasPrevPage) enhance client-side experiencepackages/types/src/api/moderation.ts (3)
12-21: Well-defined enums for moderation metadata.The new enums are comprehensive and align with the PR objectives:
ModeratorAccountIdTypeEnumsupports both "near" and "platform_username" as requiredModerationSourceEnumcovers various moderation sources including UI, platform comments, auto-approval, and admin actionsThese enums provide clear type safety and validation for moderation workflows.
27-29: Schema correctly updated to match database changes.The
ModerationActionSchemaproperly replacesadminIdwith the new moderation fields:
moderatorAccountId(string) - the identifier valuemoderatorAccountIdType(enum) - specifies whether it's a NEAR account or platform usernamesource(enum) - tracks how the moderation action was initiatedThis matches the database migration exactly.
46-46: Consistent schema updates for request types.The
CreateModerationRequestSchemais properly updated to usemoderatorAccountIdinstead ofadminId, maintaining consistency across the API contract.packages/shared-db/migrations/meta/0015_snapshot.json (2)
1264-1403: Database schema snapshot correctly reflects migration changes.The
moderation_historytable schema properly shows:
- Column renames:
submission_id(line 1274-1279) andmoderator_account_id(line 1286-1291)- New columns:
moderator_account_id_type(line 1292-1297) andsource(line 1298-1303)- Updated indexes:
moderation_history_submission_idxandmoderation_history_moderator_account_idx- Correct foreign key:
moderation_history_submission_id_submissions_tweet_id_fkThe schema snapshot accurately captures the migration results.
1405-1428: Enums properly defined in schema.The database enums are correctly defined:
activity_typeincludes all expected activity typessubmission_statusmaintains the standard pending/approved/rejected valuesplugin_typecovers all plugin categoriesThese align with the application type definitions.
apps/api/src/routes/api/activity.ts (3)
8-19: LGTM: Good refactoring to use shared types.The transition from local validation schemas to the centralized
@curatedotfun/typespackage improves consistency and type safety across the codebase.
179-184: Good change: Standardized NEAR account ID parameters.The update from generic user ID to explicit NEAR account ID in the path parameter improves API clarity and aligns with the system's account model.
124-126: Verify authentication middleware sets accountId correctly.The code assumes
c.get("accountId")is always properly set by authentication middleware. Ensure the middleware consistently populates this value for all authenticated routes.#!/bin/bash # Description: Verify authentication middleware sets accountId in context # Expected: Find middleware that sets accountId in context rg -A 10 -B 5 "\.set.*accountId" --type tspackages/shared-db/src/repositories/moderation.repository.ts (3)
1-6: LGTM: Good addition of schema validation.The import of
selectModerationHistorySchemaand theor/inArrayoperators enables proper validation and the new flexible querying capabilities.
40-40: Excellent: Consistent schema validation across all methods.Adding schema parsing to all return values ensures data integrity and proper type validation throughout the moderation operations.
Also applies to: 66-68, 95-95, 126-126
136-185: Well-implemented: New method supports PR objective.The
getModerationsLinkedToNearAccountmethod effectively addresses the requirement to enable moderation queries by either platform username or NEAR account ID. The logic correctly handles:
- Direct NEAR account ID matching
- Platform username array matching (when provided)
- Proper conditional query construction with
orOne minor suggestion for clarity:
+ /** + * Retrieves all moderation entries linked to a specific NEAR account, + * either directly or through their connected platform usernames. + * @param nearAccountId The NEAR account ID. + * @param platformUsernameStrings An array of formatted platform username strings (e.g., ["twitter:userA", "mastodon:userB@social.com"]). + * @returns Promise<SelectModerationHistory[]> Array of moderation entries, empty if none found. + */packages/shared-db/src/schema/moderation.ts (3)
13-27: Well-designed: Comprehensive enum definitions.The new enums
moderatorAccountIdTypeSchemaandmoderationSourceSchemaprovide good type safety and cover the expected use cases:
- Account ID types:
"near"and"platform_username"- Sources: UI, platform comments, auto-approval, and super admin actions
33-42: Consistent field updates align with PR objectives.The replacement of
tweetIdwithsubmissionIdandadminIdwithmoderatorAccountId, plus the addition ofmoderatorAccountIdTypeandsourcefields, properly supports the enhanced moderation capabilities.
74-81: Proper schema validation for new fields.The insert and select schemas correctly validate the new enum fields, ensuring data integrity at the application level.
Also applies to: 93-96
packages/shared-db/src/schema/activity.ts (2)
26-26: Good addition: CONTENT_REJECTION activity type.Adding
"CONTENT_REJECTION"to the activity types properly supports tracking rejection actions in the moderation workflow.
129-161: Excellent: Comprehensive schema validation.The addition of Zod insert/update/select schemas for all activity-related tables provides:
- Runtime validation for database operations
- Type safety with proper TypeScript inference
- Consistent handling of auto-generated fields (id, timestamps)
This follows best practices for schema-driven development.
packages/types/src/api/activity.ts (3)
1-187: Excellent: Comprehensive API schema design.This new file provides a well-structured foundation for activity-related API validation and typing:
- Clear separation of concerns (enums, core schemas, request params, responses)
- Proper date handling with preprocessing for ISO string conversion
- Comprehensive validation for query parameters with transformation
- Standardized response schemas for consistent API contracts
The design follows Zod best practices and provides strong type safety.
132-158: Robust query parameter transformation.The transform function for
GetUserActivitiesApiQuerySchemahandles edge cases well:
- Proper string splitting and trimming for activity types
- Validation against allowed enum values
- Graceful handling of empty or invalid types
- Sensible defaults for pagination parameters
31-46: Good date handling with preprocessing.The use of
z.preprocessto handle both Date objects and ISO strings ensures flexibility while maintaining strict datetime validation in the final schema.apps/app/src/lib/api/activity.ts (3)
1-11: LGTM: Clean import structure with shared typesThe migration to
@curatedotfun/typesimproves type consistency across the codebase and centralizes type definitions.
28-37: Good authentication integrationProperly integrates
isSignedInstate to conditionally enable user-specific queries, preventing unnecessary API calls when unauthenticated.
73-95: Consistent authentication pattern across user-specific hooksBoth
useMyCuratedFeedsanduseMyApprovedFeedsfollow the same authentication pattern, which is good for consistency.apps/api/src/services/moderation.service.ts (4)
47-68: Good simplification of authorization return typeChanging from an object with
{ isAuthorized: boolean; adminIdForHistory: string }to a simple boolean makes the method easier to use and understand. ThemoderatorNearIdis now tracked directly in the calling method.
218-226: Enhanced moderation data structure with proper metadataThe addition of
moderatorAccountIdType: "near"andsource: moderationSourcefields provides better tracking of moderation actions. The rename fromtweetIdtosubmissionIdis more generic and appropriate.
486-508: Solid implementation of moderation lookup by NEAR accountThe new
getModerationsByNearAccountmethod properly integrates connected accounts to find all moderation actions linked to a NEAR account. The error handling for connected accounts lookup is appropriate.
510-533: Good encapsulation of connected accounts logicMaking
getConnectedAccountsprivate and renaming it fromgetConnectedAccountsForUserimproves encapsulation and clarity.apps/api/src/services/activity.service.ts (5)
32-46: Good dependency injection and logging setupThe addition of
ModerationServiceandUserServicedependencies enables the enhanced functionality, and the child logger provides proper service-scoped logging.
90-115: Excellent moderation integration with proper error handlingThe integration of moderation data is well-implemented:
- Uses a Map for efficient lookup by submission ID
- Includes comprehensive error handling that logs failures without interrupting the main flow
- Properly handles the case where moderation data might not be available
112-115: Consistent schema parsing patternThe two-step parsing approach (
selectActivitySchema.parse()followed byActivitySchema.parse()) ensures data consistency and type safety throughout the transformation pipeline.
127-135: Good type safety improvements across leaderboard methodsThe updates to use
GetLeaderboardApiQueryand return properly typedUserRankingLeaderboardEntry[]improve type safety and API consistency.
274-294: Consistent typing pattern for feed-related methodsBoth
getFeedsCuratedByUserandgetFeedsApprovedByUsernow return properly typedFeedInfo[]arrays with schema parsing, maintaining consistency with the broader type safety improvements.
There was a problem hiding this comment.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
packages/shared-db/src/repositories/activity.repository.ts (1)
214-214: Fix unsafe IN clause construction.The current implementation directly interpolates the array into SQL, which could lead to SQL injection if the types array contains malicious input.
Use Drizzle's
inArrayoperator for safe parameterization:-conditions.push(sql`${schema.activities.type} IN ${options.types}`); +conditions.push(inArray(schema.activities.type, options.types));Don't forget to import
inArrayfrom drizzle-orm.
🧹 Nitpick comments (1)
packages/shared-db/src/repositories/leaderboard.repository.ts (1)
47-72: Extract date range calculation to shared utility.The date range calculation logic is duplicated between this file and
activity.repository.ts. Consider extracting this to a shared utility function to follow the DRY principle.Create a shared utility:
// In packages/shared-db/src/utils/dateRange.ts export function getStartDateForTimeRange(timeRange: string): Date | null { const now = new Date(); switch (timeRange) { case "day": case "today": return new Date( Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()) ); case "week": const startDate = new Date(now); const dayOfWeek = startDate.getUTCDay(); const diff = startDate.getUTCDate() - dayOfWeek; startDate.setUTCDate(diff); startDate.setUTCHours(0, 0, 0, 0); return startDate; case "month": return new Date( Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1) ); case "year": return new Date(Date.UTC(now.getUTCFullYear(), 0, 1)); default: // "all" return null; } }Then use it in both repositories:
import { getStartDateForTimeRange } from "../utils/dateRange"; // Replace the switch statement with: const startDate = getStartDateForTimeRange(timeRange);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/shared-db/migrations/0016_ambitious_blazing_skull.sql(1 hunks)packages/shared-db/migrations/meta/0016_snapshot.json(1 hunks)packages/shared-db/migrations/meta/_journal.json(1 hunks)packages/shared-db/src/repositories/activity.repository.ts(5 hunks)packages/shared-db/src/repositories/leaderboard.repository.ts(2 hunks)packages/shared-db/src/repositories/submission.repository.ts(3 hunks)packages/shared-db/src/schema/activity.ts(4 hunks)packages/shared-db/src/schema/users.ts(2 hunks)
✅ Files skipped from review due to trivial changes (3)
- packages/shared-db/src/schema/users.ts
- packages/shared-db/migrations/meta/0016_snapshot.json
- packages/shared-db/migrations/0016_ambitious_blazing_skull.sql
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/shared-db/migrations/meta/_journal.json
- packages/shared-db/src/repositories/submission.repository.ts
- packages/shared-db/src/schema/activity.ts
🔇 Additional comments (5)
packages/shared-db/src/repositories/activity.repository.ts (4)
3-11: Good separation of type-only imports from value imports.This improves code clarity and can help with tree-shaking in the build process.
72-122: Excellent refactor to atomic upsert operations.The change from manual existence checks to
INSERT ... ON CONFLICT DO UPDATEprovides several benefits:
- Eliminates race conditions in concurrent environments
- Reduces database round trips from 2 to 1
- Simplifies the code and improves maintainability
- Ensures atomic operations for counter increments
133-192: Well-structured refactor using query builder CTEs.The conversion from raw SQL to typed query builder improves:
- Type safety with schema references
- Maintainability through clearer structure
- Readability with named CTEs
The ranking logic correctly uses
ROW_NUMBER()window functions ordered by counts.
318-377: Clean refactor with improved type safety.The conversion to query builder with CTEs provides better type safety while maintaining the original logic. The date filtering and aggregation calculations are correctly preserved.
packages/shared-db/src/repositories/leaderboard.repository.ts (1)
74-193: Verify date filtering behavior for moderation counts.The refactor looks great with improved type safety and maintainability. However, I notice that the date filter is only applied to
submissions.createdAtbut not to moderation history records. This means approvals/rejections that happened outside the date range will be counted if they're for submissions within the range.Is this intentional behavior (counting all moderation actions on submissions from the time period) or should moderation actions also be filtered by date?
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/api/src/services/activity.service.ts (1)
77-83: Excellent! NotFoundError implementation addresses previous feedback.The implementation properly throws a NotFoundError when the user is not found, which addresses the previous review comment and improves API consistency.
🧹 Nitpick comments (1)
apps/api/src/services/activity.service.ts (1)
112-115: Consider if double schema parsing is necessary.The code applies both
selectActivitySchema.parse()andActivitySchema.parse()to each activity. This double parsing may be redundant unless there's a specific transformation needed between the database schema and API schema.If the schemas are compatible, consider simplifying to:
- return activities.map((activity) => { - const parsedActivity = selectActivitySchema.parse(activity); - return ActivitySchema.parse(parsedActivity); - }); + return activities.map((activity) => + ActivitySchema.parse(activity) + );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/api/src/services/activity.service.ts(9 hunks)
🔇 Additional comments (9)
apps/api/src/services/activity.service.ts (9)
16-33: LGTM! Well-structured import refactoring.The import changes properly support the transition to the shared types package and new service dependencies for enhanced moderation integration.
41-46: LGTM! Constructor properly supports new service dependencies.The addition of ModerationService and UserService dependencies and enhanced logger initialization align well with the service's expanded functionality.
128-132: LGTM! Improved type safety with GetLeaderboardApiQuery.The parameter type refinement enhances API consistency and type safety.
256-262: LGTM! Proper schema parsing implementation.The schema parsing with
UserRankingLeaderboardEntrySchema.parse()ensures data validation and type safety.
170-170: LGTM! Consistent schema parsing for type safety.The addition of
selectUserStatsSchema.parse()maintains consistency with the service's validation pattern.
216-216: LGTM! Consistent schema parsing for type safety.The addition of
selectFeedUserStatsSchema.parse()maintains consistency with the service's validation pattern.
274-277: LGTM! Enhanced type safety with FeedInfo schema.The return type change to
FeedInfo[]with proper schema parsing improves API consistency and type safety.
289-293: LGTM! Enhanced type safety with FeedInfo schema.The return type change to
FeedInfo[]with proper schema parsing improves API consistency and type safety.
308-314: LGTM! Enhanced type safety with UserFeedRanks schema.The return type change to
UserFeedRankswith proper schema parsing improves API consistency and type safety.
| let detailedModerationsMap = new Map(); | ||
|
|
||
| try { | ||
| const detailedModerations = | ||
| await this.moderationService.getModerationsByNearAccount(accountId); | ||
| detailedModerations.forEach((modAction) => { | ||
| if (modAction.submissionId) { | ||
| if (!detailedModerationsMap.has(modAction.submissionId)) { | ||
| detailedModerationsMap.set(modAction.submissionId, modAction); | ||
| } | ||
| } | ||
| }); | ||
| } catch (modError) { | ||
| this.logger.error( | ||
| { | ||
| accountId, | ||
| error: modError, | ||
| }, | ||
| "Failed to fetch detailed moderations for activity feed.", | ||
| ); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Unused moderation data - consider integrating or removing.
The detailed moderation data is fetched and stored in detailedModerationsMap but is never used in the activity processing or return statement. This creates unnecessary overhead and potentially confusing code.
Consider either:
- Integrating the moderation data into the returned activities
- Removing the unused moderation fetching logic
- let detailedModerationsMap = new Map();
-
- try {
- const detailedModerations =
- await this.moderationService.getModerationsByNearAccount(accountId);
- detailedModerations.forEach((modAction) => {
- if (modAction.submissionId) {
- if (!detailedModerationsMap.has(modAction.submissionId)) {
- detailedModerationsMap.set(modAction.submissionId, modAction);
- }
- }
- });
- } catch (modError) {
- this.logger.error(
- {
- accountId,
- error: modError,
- },
- "Failed to fetch detailed moderations for activity feed.",
- );
- }📝 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.
| let detailedModerationsMap = new Map(); | |
| try { | |
| const detailedModerations = | |
| await this.moderationService.getModerationsByNearAccount(accountId); | |
| detailedModerations.forEach((modAction) => { | |
| if (modAction.submissionId) { | |
| if (!detailedModerationsMap.has(modAction.submissionId)) { | |
| detailedModerationsMap.set(modAction.submissionId, modAction); | |
| } | |
| } | |
| }); | |
| } catch (modError) { | |
| this.logger.error( | |
| { | |
| accountId, | |
| error: modError, | |
| }, | |
| "Failed to fetch detailed moderations for activity feed.", | |
| ); | |
| } | |
| // ... previous activity fetching logic above | |
| // (Removed unused moderation fetching logic) | |
| // ... continue processing activities below |
🤖 Prompt for AI Agents
In apps/api/src/services/activity.service.ts around lines 90 to 110, the
detailedModerationsMap is populated but never used afterward, causing
unnecessary overhead. To fix this, either integrate the moderation data from
detailedModerationsMap into the activity processing or the return value where
relevant, or remove the entire try-catch block and related variables fetching
detailed moderation data if it is not needed.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
apps/app/src/components/profile/overview/CuratorFor.tsx (2)
16-18: Same commented code issue as ApproverFor.Consider removing this commented code or converting to a proper TODO if the points feature is planned.
9-9: Same TODO comment as ApproverFor.Consider addressing the default image fallback consistently across both components.
🧹 Nitpick comments (2)
apps/app/src/components/profile/overview/ApproverFor.tsx (2)
16-18: Remove commented code or track as proper TODO.The commented-out points rendering appears to be dead code. Either remove it completely or convert it to a proper TODO comment if the feature is planned for future implementation.
- {/* <h5 className="text-lg sm:text-xl font-[900] text-black shrink-0"> - {(feed as any).points} - </h5> */}
9-9: Address the TODO comment.The fallback image path suggests incomplete work. Consider using a more appropriate default image or tracking this as a proper issue.
Would you like me to help create a proper issue to track finding a better default image for feeds?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/api/src/utils/service-provider.ts(2 hunks)apps/app/src/components/profile/overview/ApproverFor.tsx(2 hunks)apps/app/src/components/profile/overview/CuratorFor.tsx(2 hunks)packages/shared-db/src/repositories/activity.repository.ts(7 hunks)packages/types/src/api/activity.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/shared-db/src/repositories/activity.repository.ts
- packages/types/src/api/activity.ts
🔇 Additional comments (7)
apps/api/src/utils/service-provider.ts (2)
2-2: LGTM! Repository imports added correctly.The new imports for
ActivityRepositoryandLeaderboardRepositoryare properly added to support the ActivityService initialization.Also applies to: 4-4
150-160: ActivityService initialization looks good.The service is properly initialized with all required dependencies (repositories, services, database, logger) and follows the established pattern used by other services in this provider. The service registration ensures it's available for dependency injection throughout the application.
apps/app/src/components/profile/overview/ApproverFor.tsx (3)
1-1: Good type safety improvement.Using
FeedInfofrom the shared types package improves type consistency across the application and aligns with the PR's goal of standardizing data schemas.
4-4: Component simplification improves maintainability.The refactored
Itemcomponent with a singledataprop reduces complexity and prop drilling while maintaining type safety with theFeedInfointerface.Also applies to: 9-9, 13-13
42-46: Good error handling addition.The error state provides users with clear feedback when feed fetching fails, improving the user experience.
apps/app/src/components/profile/overview/CuratorFor.tsx (2)
2-2: Consistent refactoring with ApproverFor component.The changes mirror the improvements in
ApproverFor.tsx, usingFeedInfotype for better type safety and simplifying the component structure. This consistency is good for maintainability.Also applies to: 4-4, 9-9, 13-13
42-46: Error handling implementation matches ApproverFor.The error state handling is consistent with the other component, providing a uniform user experience across both curator and approver views.
Also applies to: 47-47, 53-53
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Chores