Skip to content

Conversation

@3FE3LE
Copy link
Contributor

@3FE3LE 3FE3LE commented Apr 10, 2025

Summary by CodeRabbit

  • New Features

    • Introduced expense tracking for managing and sharing trip expenses.
    • Added new interfaces to create, update, and manage activities, budgets, and destinations.
    • Enhanced trip management with shareable links and QR codes for easier trip sharing.
  • Improvements

    • Strengthened authentication and logging for a smoother, more secure experience.
    • Optimized system performance and data handling to support these new capabilities.

3FE3LE added 30 commits August 21, 2024 13:31
…ce method/module & add new properties on create.dto file
@3FE3LE
Copy link
Contributor Author

3FE3LE commented Apr 10, 2025

Task linked: CU-86a47rg9a OPT Create Plan Flow

@coderabbitai
Copy link

coderabbitai bot commented Apr 10, 2025

Walkthrough

This pull request introduces a wide range of changes throughout the codebase. Version control settings and Docker configurations have been updated, and dependency versions in package.json have been bumped. Numerous Prisma migration scripts now modify table structures, constraints, enums, indexes, and relationships. The Prisma schema has been expanded with new models and fields, while the seeding script has been enhanced. Additionally, several new feature modules (Activity, Budget, Destiny, Trip) have been added with corresponding controllers, services, and DTOs. Authentication and middleware logic have been refined, and API documentation has been enriched with Swagger decorators.

Changes

File(s) Change Summary
.gitignore Added openapi.json; removed ignore for dbschema/edgeql-js.
Dockerfile Updated base image from node:20.15 to node:22.14.0-alpine3.20 and changed build/start commands from npm to direct Node.js invocations.
package.json Upgraded various dependencies and devDependencies (NestJS packages, Prisma, bcryptjs, ESLint, Jest, Prettier, etc.) to newer major versions.
prisma/migrations/.../*.sql and prisma/migrations/migration_lock.toml Multiple migration scripts adjust DB schema: adding/dropping columns, creating/dropping tables and indexes, updating foreign keys, modifying enums, adding composite primary keys, and revising unique constraints.
prisma/schema.prisma Revised and extended the data model: new models (Role, Trip, Expense, PaymentPlan, Payment, TripGroup, Activity, Destiny) and updates of existing models and enums with specific constraints.
prisma/seed.ts Added an upsert operation for the 'MXN' currency and a corresponding console log.
src/app.controller.ts Simplified: removed AppService dependency and endpoint logic.
src/auth/**/* Enhancements include updated method signatures, added Swagger decorators, new middleware integration in AuthModule, refined error handling in AuthService and AuthMiddleware, and removal of redundant interfaces.
src/database/prisma.module.ts and src/main.ts Added error handling for Prisma connection and a new file write to persist the OpenAPI JSON document.
src/opt/activity/**/* New Activity module with controller, service, and DTOs supporting CRUD operations for activities.
src/opt/budget/**/* New Budget module with controller, service, and DTOs for managing budgets and currencies.
src/opt/destiny/**/* New Destiny module with controller, service, and DTOs for managing destinies, including new fields like placeId and associated validations.
src/opt/trip/**/* Updated Trip controller, service, and DTOs with authentication and new fields (shareableLink, qrCode); added enhanced validation and relationship handling.
src/opt/group/dto/update-group.dto.ts Modified UpdateGroupDto to extend from CreateGroupDto via PartialType.
src/suite/user/dto/update-user.dto.ts Updated UpdateUserDto to extend the PartialType of CreateUserDto, removing individual property declarations.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant LM as LoggerMiddleware
    participant AM as AuthMiddleware
    participant CT as Controller
    participant SV as Service
    participant DB as Database
    C->>LM: Send HTTP Request
    LM->>AM: Forward logged request
    AM->>CT: Pass authenticated request
    CT->>SV: Invoke business logic
    SV->>DB: Query/modify data via Prisma
    DB-->>SV: Return result
    SV-->>CT: Send response
    CT-->>AM: Return formatted data
    AM-->>LM: Propagate response
    LM-->>C: Deliver HTTP Response
Loading
sequenceDiagram
    participant User
    participant AC as AuthController
    participant AS as AuthService
    participant JS as JwtService
    participant DB as Database
    User->>AC: Sends login/register request
    AC->>AS: Validate credentials
    AS->>DB: Retrieve user by ID
    DB-->>AS: Return user data / error
    AS->>JS: Generate token (expires in 30 days)
    JS-->>AS: Return token
    AS-->>AC: Return authentication result
    AC-->>User: Return token & status
Loading

Poem

I'm a happy little rabbit hopping through the code,
Each change a new carrot on a fresh, winding road.
From schema tweaks to API beats so neat,
I nibble all the updates – every line is a treat!
With Swagger and middleware in a dancing parade,
My code garden blooms in a joyful cascade.
Keep on hopping, keep on coding – hooray!

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 30

🧹 Nitpick comments (39)
src/app.service.ts (1)

3-4: AppService is now empty

The AppService class has been simplified by removing the getHello() method, leaving an empty class. This is likely part of refactoring to eliminate unused code.

Consider whether:

  1. This class is still needed if it has no methods
  2. Any components still depend on it
  3. It should be removed entirely if not required

Empty injectable services are generally unnecessary.

prisma/migrations/20240921180952_set_new_default_value_for_trip_satus_on_trip_table/migration.sql (1)

1-2: Consider typo in migration filename

The migration filename contains "satus" instead of "status" ("set_new_default_value_for_trip_satus_on_trip_table"). While this doesn't affect functionality, it's a best practice to use correct spelling in migration filenames for better maintainability.

prisma/migrations/20240902013014_fix_destination_table/migration.sql (1)

8-10: Consider adding NOT NULL constraints for new columns.

The new country and countryCode columns are added without NOT NULL constraints, making them nullable. If these fields are required for proper functionality, consider adding NOT NULL constraints or default values to maintain data integrity.

-- AlterTable
ALTER TABLE "Destination" DROP COLUMN "postalCode",
-ADD COLUMN     "country" TEXT,
-ADD COLUMN     "countryCode" TEXT;
+ADD COLUMN     "country" TEXT NOT NULL,
+ADD COLUMN     "countryCode" TEXT NOT NULL;
src/opt/budget/budget.module.ts (1)

16-22: Consider using more specific route paths for middleware.

While applying middleware to all 'budget' routes works, consider using more specific route paths if certain budget endpoints should be public or require different authentication levels.

configure(consumer: MiddlewareConsumer) {
  consumer
    .apply(LoggerMiddleware)
-   .forRoutes('budget')
+   .forRoutes({ path: 'budget', method: RequestMethod.ALL })
    .apply(AuthMiddleware)
-   .forRoutes('budget');
+   .forRoutes(
+     { path: 'budget', method: RequestMethod.GET },
+     { path: 'budget', method: RequestMethod.POST },
+     { path: 'budget/:id', method: RequestMethod.ALL }
+   );
}

Don't forget to import RequestMethod:

import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
src/opt/destiny/destiny.module.ts (1)

16-22: Consider simplifying middleware application.

The current approach applies middleware separately to the same route. For better readability, consider chaining middlewares in a single apply() call:

- consumer
-   .apply(LoggerMiddleware)
-   .forRoutes('destiny')
-   .apply(AuthMiddleware)
-   .forRoutes('destiny');
+ consumer
+   .apply(LoggerMiddleware, AuthMiddleware)
+   .forRoutes('destiny');

This change reduces repetition while maintaining the same functionality.

src/main.ts (1)

1-2: Consider using asynchronous file operations with error handling.

The current implementation uses synchronous file writing which could block the Node.js event loop. Consider using the asynchronous version with proper error handling.

- import * as fs from 'fs';
+ import * as fs from 'fs/promises';

- fs.writeFileSync('openapi.json', JSON.stringify(appDocument, null, 2));
+ try {
+   await fs.writeFile('openapi.json', JSON.stringify(appDocument, null, 2));
+   Logger.log('OpenAPI documentation generated successfully');
+ } catch (error) {
+   Logger.error('Failed to write OpenAPI documentation', error);
+ }

Also applies to: 24-24

src/auth/auth.service.ts (1)

49-49: Remove typo in error message

There's an unwanted "+" character at the end of the error message.

-throw new BadRequestException('Invalid email or password+');
+throw new BadRequestException('Invalid email or password');
src/auth/auth.module.ts (1)

1-4: Consider consolidating related imports together

Your import organization has separated related imports from the @nestjs/common package. Consider grouping them together for better readability.

-import { LoggerMiddleware } from 'src/middleware/logger/logger.middleware';
-import { UsersModule } from 'src/suite/user/user.module';
+import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
+import { JwtModule } from '@nestjs/jwt';
+import { LoggerMiddleware } from 'src/middleware/logger/logger.middleware';
+import { UsersModule } from 'src/suite/user/user.module';

-import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
-import { JwtModule } from '@nestjs/jwt';
src/opt/trip/dto/create-trip.dto.ts (2)

71-71: Consider keeping the default value for tripType

The default value for tripType has been removed. This might lead to inconsistencies if other parts of the code expect a default value.

-  tripType?: TripType;
+  tripType?: TripType = TripType.SOLO;

73-80: Maintain language consistency in property descriptions

The descriptions for new properties are in Spanish while existing properties use English descriptions. Consider keeping a consistent language throughout the codebase for better maintainability.

-  @ApiPropertyOptional({ description: 'El enlace compartible del viaje' })
+  @ApiPropertyOptional({ description: 'Shareable link for the trip' })
   @IsOptional()
   @IsUrl()
   shareableLink?: string;

-  @ApiPropertyOptional({ description: 'El código QR asociado al viaje' })
+  @ApiPropertyOptional({ description: 'QR code associated with the trip' })
   @IsOptional()
   qrCode?: string;
src/opt/activity/dto/create-activity.dto.ts (1)

6-48: Consider language consistency across DTOs

While the property descriptions in this DTO are consistently in Spanish, other DTOs in the project use English for descriptions. Consider adopting a consistent language approach across all DTOs to improve maintainability.

src/opt/destiny/destiny.controller.ts (1)

32-40: Consider adding pagination for the findAll endpoint.

The current implementation returns all destinations without pagination, which could lead to performance issues as the dataset grows.

Consider implementing pagination:

-  @Get()
-  @ApiOperation({ summary: 'Obtener todos los destinos' })
-  @ApiResponse({
-    status: 200,
-    description: 'Los destinos han sido obtenidos exitosamente.',
-  })
-  async findAll(): Promise<Destiny[]> {
-    return this.destinyService.findAll();
-  }
+  @Get()
+  @ApiOperation({ summary: 'Obtener todos los destinos' })
+  @ApiResponse({
+    status: 200,
+    description: 'Los destinos han sido obtenidos exitosamente.',
+  })
+  async findAll(
+    @Query('page') page = 1,
+    @Query('limit') limit = 10,
+  ): Promise<{ data: Destiny[]; total: number; page: number; limit: number }> {
+    return this.destinyService.findAll({ page, limit });
+  }

Don't forget to update the imports to include Query from '@nestjs/common'.

src/opt/destiny/dto/create-destiny.dto.ts (2)

10-57: Consider adding additional validation constraints.

While the basic type validation is in place, you might want to add more specific validation constraints for some fields.

For example:

  @ApiProperty({ description: 'The latitude of the destiny' })
  @IsNumber()
+ @Min(-90)
+ @Max(90)
  latitude: number;

  @ApiProperty({ description: 'The longitude of the destiny' })
  @IsNumber()
+ @Min(-180)
+ @Max(180)
  longitude: number;
  
  @ApiPropertyOptional({ description: 'The country code of the destiny' })
  @IsOptional()
  @IsString()
+ @MaxLength(2)
  countryCode?: string;

Don't forget to import Min, Max, and MaxLength from 'class-validator'.


1-57: Language inconsistency between DTO and controller.

The DTO documentation is in English while the controller endpoints are documented in Spanish. Consider standardizing the language used across the application for consistency.

src/opt/activity/activity.controller.ts (2)

34-42: Consider adding pagination for the findAll endpoint.

Similar to the DestinyController, this endpoint returns all activities without pagination, which could lead to performance issues with large datasets.

Consider implementing pagination:

-  @Get()
-  @ApiOperation({ summary: 'Obtener todas las actividades' })
-  @ApiResponse({
-    status: 200,
-    description: 'Las actividades han sido obtenidas exitosamente.',
-  })
-  async findAll(): Promise<Activity[]> {
-    return this.activityService.findAll();
-  }
+  @Get()
+  @ApiOperation({ summary: 'Obtener todas las actividades' })
+  @ApiResponse({
+    status: 200,
+    description: 'Las actividades han sido obtenidas exitosamente.',
+  })
+  async findAll(
+    @Query('page') page = 1,
+    @Query('limit') limit = 10,
+  ): Promise<{ data: Activity[]; total: number; page: number; limit: number }> {
+    return this.activityService.findAll({ page, limit });
+  }

Don't forget to update the imports to include Query from '@nestjs/common'.


1-79: Consider adding filtering options for the findAll endpoint.

For a more versatile API, consider adding filtering options to the findAll endpoint, such as filtering by tripId or destinyId.

  @Get()
  @ApiOperation({ summary: 'Obtener todas las actividades' })
  @ApiResponse({
    status: 200,
    description: 'Las actividades han sido obtenidas exitosamente.',
  })
-  async findAll(): Promise<Activity[]> {
-    return this.activityService.findAll();
+  async findAll(
+    @Query('tripId') tripId?: string,
+    @Query('destinyId') destinyId?: string,
+    @Query('page') page = 1,
+    @Query('limit') limit = 10,
+  ): Promise<{ data: Activity[]; total: number; page: number; limit: number }> {
+    return this.activityService.findAll({ 
+      where: { 
+        ...(tripId && { tripId }),
+        ...(destinyId && { destinyId }),
+      },
+      page, 
+      limit 
+    });
  }

This would allow clients to filter activities by trip or destination.

prisma/migrations/20241026162534_add_expenses_models_and_fix_enums/migration.sql (3)

10-17: Use a single transaction block.

Multiple short transactions carry a small risk of partial migration if a failure occurs midway between commits. Consider wrapping these enum updates into one transaction to ensure an atomic operation, preventing possible inconsistencies if an error happens.


62-66: Optimize indexing strategy.

While these indexes help, ensure queries on tripId, activityId, and destinyId commonly use all three columns together. If certain queries filter primarily by one or two columns, consider additional indexes or a composite index better aligned with typical query patterns.


69-84: Evaluate foreign key on-delete actions.

"RESTRICT" and "SET NULL" might be correct. However, if the business logic requires that related records be removed automatically, consider "ON DELETE CASCADE" for a more convenient cleanup and less orphaned data. Confirm with your product requirements before finalizing.

src/opt/trip/dto/update-trip.dto.ts (2)

13-13: Consider storing foreign key references.

Referencing Budget (from Prisma) directly here might be unclear if the update operation only needs a budget ID. If you intend to pass full Budget objects, confirm that nested updates are intended. If not, replace with an ID field or a partial object for safety and clarity.


25-26: Change property to optional if it can be omitted.

createdAt is marked @IsOptional(), yet it is declared as createdAt: Date;. Make it createdAt?: Date; to align with the optional decorator, avoiding potential validation or assignment conflicts.

- @IsOptional()
- createdAt: Date;
+ @IsOptional()
+ createdAt?: Date;
src/auth/auth.controller.ts (1)

28-30: Method name vs. returned data mismatch.

"Get a greeting message if authorized" may not reflect returning user validation data. Consider renaming the route or clarifying the endpoint's purpose in both the code and the OpenAPI description for better clarity.

src/opt/budget/budget.service.ts (4)

11-15: Consider adding error handling for data validation failures.

The create method directly passes the DTO to Prisma without additional validation. While the DTO likely contains decorators for validation, consider adding try/catch blocks to handle potential database errors gracefully.

  async create(createBudgetDto: CreateBudgetDto): Promise<Budget> {
+   try {
      return this.prisma.budget.create({
        data: createBudgetDto,
      });
+   } catch (error) {
+     // Handle specific errors (e.g., unique constraint violations)
+     throw error;
+   }
  }

17-19: Consider implementing pagination for the findAll method.

Returning all records without pagination could lead to performance issues as the dataset grows. Consider implementing pagination to improve scalability.

- async findAll(): Promise<Budget[]> {
-   return this.prisma.budget.findMany();
+ async findAll(page = 1, limit = 10): Promise<{ data: Budget[]; total: number; page: number; limit: number }> {
+   const skip = (page - 1) * limit;
+   const [data, total] = await Promise.all([
+     this.prisma.budget.findMany({ skip, take: limit }),
+     this.prisma.budget.count(),
+   ]);
+   return { data, total, page, limit };
  }

21-25: Consider adding a not found exception handler.

The current implementation returns null when a budget is not found. Consider throwing a NotFoundException for better RESTful API practices.

+ import { Injectable, Inject, NotFoundException } from '@nestjs/common';

  async findOne(id: number): Promise<Budget | null> {
-   return this.prisma.budget.findUnique({
+   const budget = await this.prisma.budget.findUnique({
      where: { id },
    });
+   if (!budget) {
+     throw new NotFoundException(`Budget with ID ${id} not found`);
+   }
+   return budget;
  }

40-42: Consider filtering or pagination for getCurrencies method.

Similar to findAll, returning all currency records without pagination might cause performance issues with large datasets.

- async getCurrencies(): Promise<Currency[]> {
-   return this.prisma.currency.findMany();
+ async getCurrencies(page = 1, limit = 20): Promise<{ data: Currency[]; total: number; page: number; limit: number }> {
+   const skip = (page - 1) * limit;
+   const [data, total] = await Promise.all([
+     this.prisma.currency.findMany({ skip, take: limit }),
+     this.prisma.currency.count(),
+   ]);
+   return { data, total, page, limit };
  }
src/opt/destiny/destiny.service.ts (1)

17-19: Implement pagination and filtering for findAll method.

Returning all records without pagination could lead to performance issues. Consider implementing pagination and optional filtering parameters.

- async findAll(): Promise<Destiny[]> {
-   return this.prisma.destiny.findMany();
+ async findAll(
+   page = 1, 
+   limit = 10, 
+   filters?: { country?: string; continent?: string }
+ ): Promise<{ data: Destiny[]; total: number; page: number; limit: number }> {
+   const where = {};
+   if (filters?.country) where['country'] = filters.country;
+   if (filters?.continent) where['continent'] = filters.continent;
+   
+   const skip = (page - 1) * limit;
+   const [data, total] = await Promise.all([
+     this.prisma.destiny.findMany({ 
+       where,
+       skip, 
+       take: limit 
+     }),
+     this.prisma.destiny.count({ where }),
+   ]);
+   return { data, total, page, limit };
  }
src/opt/activity/activity.service.ts (1)

17-19: Implement pagination and relation loading for findAll method.

Consider adding pagination and the ability to include related entities (like trip or destiny) when fetching activities.

- async findAll(): Promise<Activity[]> {
-   return this.prisma.activity.findMany();
+ async findAll(
+   page = 1, 
+   limit = 10,
+   includeRelations = false
+ ): Promise<{ data: Activity[]; total: number; page: number; limit: number }> {
+   const skip = (page - 1) * limit;
+   const include = includeRelations ? { trip: true, destiny: true } : undefined;
+   
+   const [data, total] = await Promise.all([
+     this.prisma.activity.findMany({ 
+       skip, 
+       take: limit,
+       include
+     }),
+     this.prisma.activity.count(),
+   ]);
+   return { data, total, page, limit };
  }
src/opt/budget/budget.controller.ts (4)

22-30: Add validation pipe for request body.

Consider adding a validation pipe to ensure the CreateBudgetDto is properly validated before being passed to the service.

+ import { Body, Controller, Delete, Get, Param, Post, Put, UsePipes, ValidationPipe } from '@nestjs/common';

  @Post()
  @ApiOperation({ summary: 'Crear un nuevo presupuesto' })
  @ApiResponse({
    status: 201,
    description: 'El presupuesto ha sido creado exitosamente.',
  })
+ @UsePipes(new ValidationPipe({ transform: true }))
  async create(@Body() createBudgetDto: CreateBudgetDto): Promise<Budget> {
    return this.budgetService.create(createBudgetDto);
  }

32-40: Add pagination support to findAll endpoint.

Consider adding pagination parameters to improve performance when dealing with large datasets.

+ import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common';

  @Get()
  @ApiOperation({ summary: 'Obtener todos los presupuestos' })
  @ApiResponse({
    status: 200,
    description: 'Los presupuestos han sido obtenidos exitosamente.',
  })
- async findAll(): Promise<Budget[]> {
+ @ApiQuery({ name: 'page', required: false, description: 'Page number' })
+ @ApiQuery({ name: 'limit', required: false, description: 'Items per page' })
+ async findAll(
+   @Query('page') page?: number,
+   @Query('limit') limit?: number,
+ ): Promise<{ data: Budget[]; total: number; page: number; limit: number }> {
    return this.budgetService.findAll(page, limit);
  }

41-49: Add pagination support to getCurrencies endpoint.

Similar to findAll, consider adding pagination parameters to the getCurrencies endpoint.

  @Get('/currencies')
  @ApiOperation({ summary: 'Obtener todas las monedas' })
  @ApiResponse({
    status: 200,
    description: 'Las monedas han sido obtenidas exitosamente.',
  })
+ @ApiQuery({ name: 'page', required: false, description: 'Page number' })
+ @ApiQuery({ name: 'limit', required: false, description: 'Items per page' })
- async getCurrencies(): Promise<Currency[]> {
+ async getCurrencies(
+   @Query('page') page?: number,
+   @Query('limit') limit?: number,
+ ): Promise<{ data: Currency[]; total: number; page: number; limit: number }> {
    return this.budgetService.getCurrencies(page, limit);
  }

1-86: Add error response documentation to Swagger decorators.

Enhance the API documentation by adding error response scenarios to each endpoint.

  @Post()
  @ApiOperation({ summary: 'Crear un nuevo presupuesto' })
  @ApiResponse({
    status: 201,
    description: 'El presupuesto ha sido creado exitosamente.',
  })
+ @ApiResponse({
+   status: 400,
+   description: 'Datos de entrada inválidos.',
+ })
+ @ApiResponse({
+   status: 500,
+   description: 'Error interno del servidor.',
+ })

Similar additions should be made to all other endpoint documentation.

prisma/migrations/20240901223710_new_relations/migration.sql (1)

32-91: Consider more descriptive column names instead of “A” and “B.”
Renaming those columns can improve maintainability and clarity.

-CREATE TABLE "_ActivityToTrip" (
-    "A" TEXT NOT NULL,
-    "B" TEXT NOT NULL
-);
+CREATE TABLE "_ActivityToTrip" (
+    "activityId" TEXT NOT NULL,
+    "tripId" TEXT NOT NULL
+);
# Similar changes for "_ActivityToDestination" and "_GroupMembers"
prisma/migrations/20240905124058_chande_name_from_destination_to_destiny/migration.sql (1)

36-44: Dropping tables might require data migration.
If Destination or _DestinationToTrip had essential data, confirm an alternative location or new table references are in place.

Do you want me to propose a data migration strategy?

src/opt/trip/trip.service.ts (2)

19-72: Consider modularizing repeated ID checks.
The block checking budgetId, tripGroupId, and userId is duplicated. A helper method could enhance readability.

- if (budgetId) {
-   ...
- }
- if (tripGroupId) {
-   ...
- }
- try {
-   this.prisma.user.findUniqueOrThrow({ ... });
- } catch ...
+ private async verifyReferences(budgetId?: number, tripGroupId?: number, userId?: string) {
+   // Reuse repeated findUniqueOrThrow logic here
+ }

74-93: Consider pagination or query limits for large trip lists.
Without pagination, user with many trips could cause slow queries and memory overhead.

prisma/schema.prisma (2)

27-30: Clarify Multiple TripGroup Relations in User Model

There are two fields—tripGroup (with an explicit relation alias "GroupMembers") and groups (without an explicit relation)—both of type TripGroup[]. Their intended semantics (e.g., group memberships vs. owned groups) should be clarified to avoid ambiguity. Consider renaming one of the fields or adding documentation.


185-195: TripGroup Model Refinement

The TripGroup model now defines the "name" field as VARCHAR(100) and maintains relationships with trips, members, and an owning user. As noted in the User model review, clarify the intended relationships between User and TripGroup to avoid potential ambiguity.

src/app.controller.ts (1)

1-4: Controller simplified but left empty.

The controller has been significantly simplified by removing the AppService dependency and getHello method. The explicit '/' route is more readable than an empty string.

Consider whether this empty controller is still needed in the application. If it serves no purpose, it might be cleaner to remove it entirely. If it's intended as a placeholder for future functionality, consider adding a TODO comment.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7871bcc and 9ae2f5d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (45)
  • .gitignore (1 hunks)
  • Dockerfile (2 hunks)
  • package.json (2 hunks)
  • prisma/migrations/20240901223710_new_relations/migration.sql (1 hunks)
  • prisma/migrations/20240902013014_fix_destination_table/migration.sql (1 hunks)
  • prisma/migrations/20240902020448_add_validations_and_qr_suport/migration.sql (1 hunks)
  • prisma/migrations/20240905124058_chande_name_from_destination_to_destiny/migration.sql (1 hunks)
  • prisma/migrations/20240915182741_add_place_id_property_on_destiny_table/migration.sql (1 hunks)
  • prisma/migrations/20240921180952_set_new_default_value_for_trip_satus_on_trip_table/migration.sql (1 hunks)
  • prisma/migrations/20241026145046_change_trip_relation_kind_to_many_to_many/migration.sql (1 hunks)
  • prisma/migrations/20241026162534_add_expenses_models_and_fix_enums/migration.sql (1 hunks)
  • prisma/schema.prisma (3 hunks)
  • prisma/seed.ts (1 hunks)
  • src/app.controller.ts (1 hunks)
  • src/app.service.ts (1 hunks)
  • src/auth/auth.controller.ts (4 hunks)
  • src/auth/auth.module.ts (2 hunks)
  • src/auth/auth.service.ts (4 hunks)
  • src/auth/dto/auth.interface.ts (0 hunks)
  • src/auth/guard/auth.guard.ts (1 hunks)
  • src/auth/middleware/auth.middleware.ts (2 hunks)
  • src/database/prisma.module.ts (2 hunks)
  • src/main.ts (2 hunks)
  • src/opt/activity/activity.controller.ts (1 hunks)
  • src/opt/activity/activity.module.ts (1 hunks)
  • src/opt/activity/activity.service.ts (1 hunks)
  • src/opt/activity/dto/create-activity.dto.ts (1 hunks)
  • src/opt/activity/dto/update-activity.dto.ts (1 hunks)
  • src/opt/budget/budget.controller.ts (1 hunks)
  • src/opt/budget/budget.module.ts (1 hunks)
  • src/opt/budget/budget.service.ts (1 hunks)
  • src/opt/budget/dto/create-budget.dto.ts (1 hunks)
  • src/opt/budget/dto/update-budget.dto.ts (1 hunks)
  • src/opt/destiny/destiny.controller.ts (1 hunks)
  • src/opt/destiny/destiny.module.ts (1 hunks)
  • src/opt/destiny/destiny.service.ts (1 hunks)
  • src/opt/destiny/dto/create-destiny.dto.ts (1 hunks)
  • src/opt/destiny/dto/update-destiny.dto.ts (1 hunks)
  • src/opt/group/dto/update-group.dto.ts (1 hunks)
  • src/opt/opt.module.ts (1 hunks)
  • src/opt/trip/dto/create-trip.dto.ts (3 hunks)
  • src/opt/trip/dto/update-trip.dto.ts (1 hunks)
  • src/opt/trip/trip.controller.ts (3 hunks)
  • src/opt/trip/trip.service.ts (2 hunks)
  • src/suite/user/dto/update-user.dto.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • src/auth/dto/auth.interface.ts
🧰 Additional context used
🧬 Code Graph Analysis (15)
src/opt/budget/dto/update-budget.dto.ts (1)
src/opt/budget/dto/create-budget.dto.ts (1)
  • CreateBudgetDto (5-25)
src/opt/activity/dto/update-activity.dto.ts (1)
src/opt/activity/dto/create-activity.dto.ts (1)
  • CreateActivityDto (6-48)
src/opt/budget/budget.module.ts (2)
src/opt/opt.module.ts (1)
  • Module (11-22)
src/opt/activity/activity.module.ts (1)
  • Module (10-23)
src/suite/user/dto/update-user.dto.ts (1)
src/suite/user/dto/create-user.dto.ts (1)
  • CreateUserDto (9-39)
src/auth/middleware/auth.middleware.ts (2)
src/auth/auth.service.ts (1)
  • Injectable (10-74)
src/auth/guard/auth.guard.ts (1)
  • Injectable (11-35)
src/opt/group/dto/update-group.dto.ts (1)
src/opt/group/dto/create-group.dto.ts (1)
  • CreateGroupDto (3-17)
src/opt/destiny/destiny.controller.ts (2)
src/opt/destiny/dto/create-destiny.dto.ts (1)
  • CreateDestinyDto (5-57)
src/opt/destiny/dto/update-destiny.dto.ts (1)
  • UpdateDestinyDto (5-5)
src/opt/destiny/dto/update-destiny.dto.ts (1)
src/opt/destiny/dto/create-destiny.dto.ts (1)
  • CreateDestinyDto (5-57)
src/opt/budget/budget.service.ts (2)
src/opt/budget/dto/create-budget.dto.ts (1)
  • CreateBudgetDto (5-25)
src/opt/budget/dto/update-budget.dto.ts (1)
  • UpdateBudgetDto (5-5)
src/opt/activity/activity.controller.ts (2)
src/opt/activity/dto/create-activity.dto.ts (1)
  • CreateActivityDto (6-48)
src/opt/activity/dto/update-activity.dto.ts (1)
  • UpdateActivityDto (5-5)
src/opt/activity/activity.service.ts (2)
src/opt/activity/dto/create-activity.dto.ts (1)
  • CreateActivityDto (6-48)
src/opt/activity/dto/update-activity.dto.ts (1)
  • UpdateActivityDto (5-5)
src/opt/trip/dto/update-trip.dto.ts (1)
src/opt/trip/dto/create-trip.dto.ts (1)
  • CreateTripDto (14-81)
src/opt/destiny/destiny.service.ts (2)
src/opt/destiny/dto/create-destiny.dto.ts (1)
  • CreateDestinyDto (5-57)
src/opt/destiny/dto/update-destiny.dto.ts (1)
  • UpdateDestinyDto (5-5)
src/opt/budget/budget.controller.ts (2)
src/opt/budget/dto/create-budget.dto.ts (1)
  • CreateBudgetDto (5-25)
src/opt/budget/dto/update-budget.dto.ts (1)
  • UpdateBudgetDto (5-5)
src/opt/trip/trip.service.ts (2)
src/opt/trip/dto/create-trip.dto.ts (1)
  • CreateTripDto (14-81)
src/opt/trip/dto/update-trip.dto.ts (1)
  • UpdateTripDto (8-27)
🔇 Additional comments (82)
src/opt/group/dto/update-group.dto.ts (1)

1-5: Good implementation of DTO inheritance pattern

The change simplifies the UpdateGroupDto by extending PartialType(CreateGroupDto) instead of manually defining each property. This follows best practices for maintaining DTOs in NestJS by:

  1. Reducing code duplication
  2. Automatically making all properties from CreateGroupDto optional
  3. Ensuring better maintainability as changes to CreateGroupDto are automatically reflected

This pattern is consistent with other DTOs in the codebase and aligns with NestJS recommended patterns.

Dockerfile (1)

2-2: Updated Node.js base image to latest Alpine version

The change from node:20.15 to node:22.14.0-alpine3.17 provides benefits like:

  • Smaller image size due to Alpine Linux
  • Updated Node.js version with latest features and security patches
  • More precise versioning (specifying patch version)

This is a good change for production deployments.

prisma/migrations/20240921180952_set_new_default_value_for_trip_satus_on_trip_table/migration.sql (1)

1-2: Default trip status set to 'DRAFT'

Setting the default status to 'DRAFT' for the Trip table is a good practice that:

  1. Ensures consistency for new trip records
  2. Simplifies application logic by providing a predictable initial state
  3. Aligns with the typical workflow where trips start in draft mode before being finalized

This migration appears correct and follows good database design principles.

src/opt/budget/dto/update-budget.dto.ts (1)

1-5: Good implementation of UpdateBudgetDto.

The class properly implements NestJS best practices by extending PartialType(CreateBudgetDto), which makes all properties optional for partial updates while maintaining the validation rules from the base DTO.

.gitignore (1)

5-5: Good practice adding openapi.json to .gitignore.

Adding the generated OpenAPI specification file to .gitignore is appropriate as it's typically generated at runtime and shouldn't be committed to the repository.

Note: According to the summary, dbschema/edgeql-js was removed from .gitignore. Please verify if this directory should now be tracked in git, as this change means these files will now be committed.

src/opt/activity/dto/update-activity.dto.ts (1)

1-5: Well-structured UpdateActivityDto implementation.

The class properly follows NestJS patterns by extending PartialType(CreateActivityDto), making all properties optional for partial updates while preserving the validation constraints from the base DTO. This approach ensures type safety and reduces code duplication.

src/opt/destiny/dto/update-destiny.dto.ts (1)

1-5: Consistent implementation of UpdateDestinyDto.

The class properly follows the established pattern in the codebase by extending PartialType(CreateDestinyDto). This makes all properties optional for partial updates while maintaining the validation constraints defined in the base DTO. The consistent approach across all DTOs demonstrates good architectural practices.

src/auth/guard/auth.guard.ts (2)

1-2: Clean import declaration for Express Request type.

The import statement for the Request type from 'express' is properly added, providing type safety for the extractTokenFromHeaders method parameter on line 31.


31-34: Token extraction logic looks correct.

The method properly extracts the Bearer token from Authorization headers using destructuring and nullish coalescing. It correctly returns undefined if the token type isn't 'Bearer'.

prisma/migrations/20240902013014_fix_destination_table/migration.sql (1)

1-10:

Details

❓ Verification inconclusive

Consider data migration strategy before dropping columns.

The migration drops the postalCode column and adds country and countryCode columns. The warning correctly states that data in postalCode will be lost. If this is a production database and the data is valuable, consider implementing a data migration strategy before executing this migration.


🏁 Script executed:

#!/bin/bash
# Check if there's data in the postalCode column that might be lost
echo "Checking for data in the Destination.postalCode column that will be lost..."
fd --extension ts --extension js | xargs grep -l "Destination.*postalCode" | grep -v "migration"

Length of output: 257


I've noticed that the initial script returned no output, which makes it challenging to infer if any additional code depends on the postalCode column outside the migration context. Please run the above script to double-check for any remaining references to postalCode elsewhere in the codebase. If the new search also returns no output, then—assuming this truly reflects the current state of the repository—the risk of data loss from this migration should be minimal. However, given that this migration permanently drops data, I recommend a final manual review to ensure that the column isn’t used in production logic elsewhere.


🏁 Script executed:

#!/bin/bash
echo "Searching for any occurrences of 'postalCode' outside migration files..."
rg -i "postalCode" --glob '!prisma/migrations/**'

Length of output: 332


Attention: Verify Data Migration Impact

After running searches for references to the postalCode column outside migration files (using both fd/grep and rg), no usage in the TypeScript/JavaScript codebase was detected. This suggests that the column is not referenced in application logic. However, since the migration permanently drops the column—and given the limited scope of our automated searches—it’s important to manually verify that no production logic (e.g., in raw SQL queries or external integrations) depends on this column. Additionally, if the data stored in postalCode holds any value for auditing or historical analysis, consider implementing a proper data migration strategy prior to executing the migration.

  • Verify that there are no production SQL queries or external dependencies using the postalCode column.
  • Ensure that any valuable data is either archived or migrated before dropping the column.
src/opt/opt.module.ts (2)

3-5: Appropriate module imports added.

The new imports for ActivityModule, BudgetModule, and DestinyModule are correctly added to expand the functionality of the OptModule.


12-18: Module configuration follows NestJS best practices.

The imports array is properly structured with all required modules. The addition of BudgetModule, DestinyModule, and ActivityModule to the OptModule follows NestJS best practices for module composition.

src/opt/budget/budget.module.ts (3)

1-9: Well-organized imports and dependencies.

The imports are properly organized, separating the application-specific imports from the external NestJS imports. The module correctly imports PrismaModule for database access and declares the necessary controller and service.


10-14: Module structure follows NestJS best practices.

The @module decorator is properly configured with imports, controllers, and providers arrays. The structure follows NestJS conventions for module definition.


15-23: Middleware configuration correctly implements NestModule.

The BudgetModule correctly implements the NestModule interface and configures both LoggerMiddleware and AuthMiddleware for the 'budget' routes. This setup ensures logging and authentication for all budget-related requests.

The middleware configuration pattern is consistent with other modules in the codebase (like ActivityModule), demonstrating adherence to established project patterns.

src/opt/destiny/destiny.module.ts (1)

1-14: Module structure follows NestJS best practices.

The module correctly imports PrismaModule and sets up controllers and providers. The implementation of NestModule for configuring middleware is also a good practice for handling cross-cutting concerns like logging and authentication.

src/opt/activity/activity.module.ts (1)

1-23: LGTM! Well-structured NestJS module with proper middleware configuration.

The ActivityModule is correctly implemented with appropriate imports, controller and service registration, and middleware configuration. The module follows NestJS best practices by implementing the NestModule interface and configuring both logging and authentication middleware for the 'activity' routes.

prisma/migrations/20240915182741_add_place_id_property_on_destiny_table/migration.sql (1)

1-12: Consider making placeId a required field with non-null constraint.

The current migration adds placeId as a nullable field with a unique constraint. If this field is meant to be required in your application logic, consider making it non-nullable.

If you need to make this field required, you'll need two migrations:

  1. First add the nullable column (as you've done)
  2. Populate existing records with values
  3. Then add a non-null constraint
-- Example follow-up migration to make placeId required
ALTER TABLE "Destiny" ALTER COLUMN "placeId" SET NOT NULL;

Also, be aware that the unique constraint will fail if you have any duplicate placeId values or NULL values in multiple rows. Ensure your data migration strategy accounts for this.

src/suite/user/dto/update-user.dto.ts (1)

1-5: Good use of PartialType for clean DTO inheritance

This refactoring improves code maintainability by extending from CreateUserDto using NestJS's PartialType utility. Now all properties from CreateUserDto are automatically included as optional fields, reducing duplication and ensuring consistency between DTOs.

src/auth/auth.service.ts (1)

17-23: Good addition of user validation method

The new validateUser method provides a reusable way to validate users by ID, which can be used across different endpoints.

src/auth/auth.module.ts (1)

24-28: LGTM! Good implementation of the NestModule interface

The implementation of NestModule and the configure method follows NestJS best practices. The LoggerMiddleware is properly applied to all routes starting with 'auth'.

src/opt/trip/dto/create-trip.dto.ts (1)

39-40: LGTM! Good use of Type transformation

The addition of @Type(() => Date) is a good practice for ensuring proper transformation of string dates to Date objects when data is received from HTTP requests.

Also applies to: 45-46

prisma/migrations/20241026145046_change_trip_relation_kind_to_many_to_many/migration.sql (2)

12-29: LGTM! Well-structured many-to-many relationship implementation

The implementation of the many-to-many relationship between Member and Trip using a junction table with appropriate indexes and cascading foreign key constraints follows database best practices.


1-11:

Details

❓ Verification inconclusive

Warning: Data loss during migration

This migration will drop the tripId column from the Member table, resulting in the loss of all existing relationship data. If this is being applied to a production database with meaningful data, consider implementing a data migration script to preserve these relationships by transferring data to the new junction table.

Check if this is intended or if a separate data migration script exists:


🏁 Script executed:

#!/bin/bash
# Look for any data migration scripts that might handle this relationship change
fd -t f 'data-migration|seed' --full-path . | grep -i 'member\|trip' | sort

Length of output: 77


Data Loss Warning: Verify Data Migration Intent

The migration drops the tripId column from the Member table, which results in data loss of existing relationships. Our search for any associated data migration or seeding scripts (using a name search for keywords like "data-migration" and "seed" related to member/trip) returned no matches. This absence suggests that no supplemental migration for transferring the data into a new junction table is currently in place.

  • Please confirm that dropping tripId without preserving the existing relationship data is intended.
  • If this change is applied to a production database with meaningful data, consider implementing a data migration script to transfer data to the new junction table.
  • Manual verification is needed to ensure that the migration plan aligns with the project's data preservation requirements.
src/opt/activity/dto/create-activity.dto.ts (1)

32-47: LGTM! Well-structured DTO with appropriate validations

The overall structure of the DTO is well-organized with appropriate validation decorators and Swagger documentation.

src/auth/middleware/auth.middleware.ts (3)

10-10: Great addition of Swagger decorators for API documentation.

Adding these Swagger decorators will significantly improve the API documentation, making it more comprehensible for developers consuming your API.


13-18: Well-structured API documentation.

The @ApiBearerAuth() decorator correctly indicates that this middleware requires a bearer token, and the added API documentation clearly describes the purpose and possible responses from this middleware.


31-33: Improved error handling for token expiration.

This change enhances error handling by specifically checking for token expiration and returning a more descriptive error message with the appropriate 401 status code, which is semantically correct for expired authentication.

src/opt/destiny/destiny.controller.ts (3)

17-20: Well-structured controller with appropriate Swagger tags.

The controller is properly decorated with @ApiTags and follows RESTful design principles with dependency injection.


22-30: CRUD implementation follows best practices.

The create endpoint is properly implemented with correct status codes and return types.


1-77:

Details

❌ Incorrect review comment

Consider adding authentication and authorization checks.

The controller doesn't appear to have any authentication or authorization checks, which might be necessary depending on the business requirements.

Verify if this controller should require authentication by running:


🏁 Script executed:

#!/bin/bash
# Look for authentication decorators or guards applied to the controller or module
rg -A 5 "DestinyController" --type ts
rg -A 10 -B 5 "DestinyModule" --type ts

Length of output: 3109


Authentication is already enforced via middleware at the module level.
The DestinyModule configures AuthMiddleware (along with LoggerMiddleware) for all 'destiny' routes, so additional auth decorators in the DestinyController are not necessary unless more granular checks are required.

Please verify that the current middleware setup meets your business requirements.

Likely an incorrect or invalid review comment.

src/opt/destiny/dto/create-destiny.dto.ts (1)

5-8: Well-structured DTO with proper validation.

The name field is correctly marked as required with appropriate validation and Swagger documentation.

src/opt/activity/activity.controller.ts (2)

17-20: Well-structured controller with appropriate Swagger tags.

The controller follows RESTful design principles with dependency injection and proper Swagger decorations.


22-32: CRUD implementation follows best practices.

The create endpoint is properly implemented with correct status codes and return types.

prisma/migrations/20241026162534_add_expenses_models_and_fix_enums/migration.sql (2)

4-5:

Details

❓ Verification inconclusive

Confirm safe removal of enum values.

These lines warn about removing existing enum values, which could break if rows referencing "Pending", "Completed", "Failed", "Low", "Medium", or "High" still exist in the database. Ensure that all old enum references are safely migrated or updated before running this script to avoid runtime failures.

Run a script or database query to ensure no rows still contain the old enum values:


🏁 Script executed:

#!/bin/bash
# Checking Payment and Activity tables for old enum values
echo "==== Checking Payment table for old PaymentStatus enums ===="
psql -c "SELECT status, COUNT(*) FROM Payment GROUP BY status;"
echo "==== Checking Activity table for old Priority enums ===="
psql -c "SELECT priority, COUNT(*) FROM Activity GROUP BY priority;"

Length of output: 580


Action Required: Manually Verify Removal of Old Enum Values

The verification script did not run successfully due to the missing psql command, so we could not confirm that no rows still contain the deprecated enum values. Please verify manually that:

  • The Payment table does not include any rows with the old PaymentStatus values ("Pending", "Completed", "Failed").
  • The Activity table does not include any rows with the old Priority values ("Low", "Medium", "High").

Make sure to run these queries in an environment where the psql tool is available. Once manual verification confirms that no rows reference these deprecated enum values, you can proceed safely with the migration.


41-44:

Details

✅ Verification successful

Check data type consistency for foreign keys.

tripId is defined as TEXT NOT NULL, but other references in the schema may use integers or UUIDs for IDs. Verify consistency across the schema to prevent mismatched data types and potential errors.

You may run the following to look up existing columns for trip IDs:


🏁 Script executed:

#!/bin/bash
fd | xargs grep -A 5 'tripId'

Length of output: 11716


Trip ID Data Type Consistency Confirmed

After verifying the codebase:

  • The migration files (including the one at prisma/migrations/20241026162534_add_expenses_models_and_fix_enums/migration.sql) define "tripId" as TEXT NOT NULL.
  • The Prisma schema shows tripId is modeled as a String, and related DTOs also reference it as a string.
  • All references across migrations and schema consistently use a textual data type for tripId.

No inconsistencies were found, so no further changes are necessary regarding this aspect.

src/auth/auth.controller.ts (1)

31-33:

Details

❓ Verification inconclusive

Strengthen type definitions for the user object.

request['user'] is assumed to have an id. Ensure that the Request type is extended or that you have a type guard to confirm this property exists. This helps avoid undefined accesses in production.

You can verify any custom definitions of Request in the codebase:


🏁 Script executed:

#!/bin/bash
fd | xargs rg 'interface Request'

Length of output: 35


Action: Enhance the Request type to safely access the user object.

The current implementation assumes that request['user'] always has an id property. Our initial search for a custom Request type (using fd | xargs rg 'interface Request') produced no results, which suggests there isn’t an extended type definition in the repository. Please consider one of the following:

  • Extend the Request interface: Use module augmentation (e.g., for Express) to explicitly declare that Request includes a user with an id (and other expected properties).
  • Add a type guard: If extending the interface isn’t feasible, implement a type check to ensure that request.user exists and conforms to the expected structure before accessing its id.

Manual verification of whether a custom type exists (perhaps declared in a different file, such as in a declaration file or within a global augmentation block) is recommended.

src/opt/budget/budget.service.ts (1)

1-9: Properly structured service with dependency injection.

The service is correctly set up with the necessary imports and Prisma client injection.

src/opt/destiny/destiny.service.ts (1)

1-9: Properly structured service with dependency injection.

The service is correctly set up with the necessary imports and Prisma client injection.

src/opt/activity/activity.service.ts (1)

1-9: Properly structured service with dependency injection.

The service is correctly set up with the necessary imports and Prisma client injection.

src/opt/budget/budget.controller.ts (1)

1-20: Well-structured controller with proper Swagger documentation.

The controller is correctly set up with the necessary imports, proper class decoration, and dependency injection.

prisma/migrations/20240901223710_new_relations/migration.sql (4)

30-30: Check usage of _TripGroupToUser before dropping the table.
Confirm you have mapped user-group associations to the new structure.


22-28:

Details

❓ Verification inconclusive

Validate non-null constraints for newly added userId column.
When adding userId on tables Budget and TripGroup, confirm valid user references exist for all rows.


🏁 Script executed:

#!/bin/bash
# Verify that all Budget and TripGroup rows have valid user references
echo "SELECT * FROM \"Budget\" WHERE \"userId\" IS NULL;" | psql -h <host> -U <user> <database>
echo "SELECT * FROM \"TripGroup\" WHERE \"userId\" IS NULL;" | psql -h <host> -U <user> <database>

Length of output: 278


Manual Verification Needed:
The migration adds a non-null userId column to both the Budget and TripGroup tables. Please ensure that before applying this migration, all existing rows in these tables have a valid user reference. The current verification script failed due to placeholder values (<host>, <user>, <database>), so you need to re-run the following SQL queries with your actual database connection parameters:

  • Budget table:

    SELECT * FROM "Budget" WHERE "userId" IS NULL;
  • TripGroup table:

    SELECT * FROM "TripGroup" WHERE "userId" IS NULL;

Manually verify that these queries return no rows.


1-9:

Details

❓ Verification inconclusive

Potential irreversible data loss when dropping or altering columns.
Ensure data is either migrated or safely discarded before proceeding.

Below is a script to confirm that the affected tables and columns are empty before dropping them:


🏁 Script executed:

#!/bin/bash
# This script checks record counts for TripGroup and _TripGroupToUser tables.
# Replace <host>, <user>, <database> with actual DB parameters.

echo "SELECT 'TripGroup count:', COUNT(*) FROM \"TripGroup\";" | psql -h <host> -U <user> <database>
echo "SELECT '_TripGroupToUser count:', COUNT(*) FROM \"_TripGroupToUser\";" | psql -h <host> -U <user> <database>

Length of output: 283


Manual Verification Required: Check DB Parameters and Table Status
The migration warns about irreversible data loss when dropping or altering columns. However, the provided shell script for verifying record counts failed due to placeholder syntax errors (i.e. <host>, <user>, <database> causing unexpected token issues). Before proceeding:

  • Replace the placeholders with actual database connection parameters.
  • Manually run the corrected script to confirm that the TripGroup and _TripGroupToUser tables are empty (or that data is safely migrated/discarded).

After verifying, ensure that all data-impacting operations are safe to execute in production.


10-20:

Details

✅ Verification successful

Confirm references are no longer needed before dropping foreign keys.
Double-check downstream queries or references to ensure you’re not creating orphaned data.


🏁 Script executed:

#!/bin/bash
# Searches for references to dropped foreign keys in other migration scripts or application code.
fd -e sql -e ts -e js -e prisma | xargs rg "Activity_tripId_fkey|Activity_destinationId_fkey|_TripGroupToUser"

Length of output: 2123


Foreign Key Removal: References Verified

We've confirmed via the search results that the foreign keys in question are only referenced within the migration files. The keys defined in the earlier migration (20240820133449_new_schema/migration.sql) are being dropped as expected in the current migration (20240901223710_new_relations/migration.sql). There are no downstream queries or application code dependencies on these constraints.

  • Verify that dropping the _TripGroupToUser table is intentional and that any critical data has been handled beforehand.
  • Ensure that no orphaned data remains due to these changes.
prisma/migrations/20240905124058_chande_name_from_destination_to_destiny/migration.sql (4)

11-19: Enum rename looks correct.
Removing DESTINATION and using DESTINY aligns with your domain changes.


45-101: New tables and indexes align with the updated domain model.
Implementation for Destiny and bridging tables is logically consistent with the new naming scheme.


20-25:

Details

✅ Verification successful

Confirm no leftover references to old foreign keys.
Dropping constraints in _ActivityToDestination or _DestinationToTrip can lead to orphaned records if not handled carefully.


🏁 Script executed:

#!/bin/bash
# Look for usage of old references to _ActivityToDestination / _DestinationToTrip DDL or code references
fd -e sql -e ts -e js -e prisma | xargs rg "_DestinationToTrip|_ActivityToDestination"

Length of output: 3091


Review Update: Validate Foreign Key Cleanup and Data Safety

The migration file at prisma/migrations/20240905124058_chande_name_from_destination_to_destiny/migration.sql (Lines 20–25) now drops the foreign keys from _ActivityToDestination and _DestinationToTrip as intended. Our search confirms that the only references to these keys appear in migration files (including warnings about dropping tables), with no stray or application-level references remaining.

  • Ensure that any data within these join tables is handled appropriately (e.g., migrated or cleaned up) to avoid orphaned records.
  • Confirm that the deletion strategy (including cascading deletions) has been reviewed in the context of overall data integrity.

1-9:

Details

❓ Verification inconclusive

Data loss risk from dropping columns and tables.
Back up existing data related to Destination or handle incomplete references to avoid runtime errors.


🏁 Script executed:

#!/bin/bash
# Check if Destination table and references in Activity exist
echo "SELECT COUNT(*) FROM \"Destination\";" | psql -h <host> -U <user> <database>
echo "SELECT COUNT(*) FROM \"Activity\" WHERE \"destinationId\" IS NOT NULL;" | psql -h <host> -U <user> <database>

Length of output: 265


Attention: Validate Data Backup and Replace Placeholders
The migration script in prisma/migrations/20240905124058_chande_name_from_destination_to_destiny/migration.sql highlights serious data loss risks—dropping destinationId from Activity, the Destination table, and associated join tables. The verification shell script failed due to placeholder tokens (<host>, <user>, <database>). Please ensure the following before applying the migration:

  • Replace Placeholders: Update the verification command with actual connection details or run the queries manually.
  • Manual Verification: Confirm that the Destination table exists and check for non-null references in Activity.destinationId in your environment.
  • Backup Data: Back up all data linked to Destination and related references to avoid unexpected data loss.

Make sure these steps are completed in your production/staging environment before proceeding with the migration.

src/opt/trip/trip.service.ts (2)

1-9: Imports and setup look fine.
No conflicts or syntax risks here.


95-114: Error handling is comprehensive.
Logging the error and returning an appropriate HTTP exception is a good practice.

prisma/migrations/20240902020448_add_validations_and_qr_suport/migration.sql (12)

35-36: Review Activity Table Alteration

Altering the "name" column on the "Activity" table to VARCHAR(255) is straightforward. Please verify that existing data lengths do not exceed 255 characters to avoid truncation.


37-40: Review Currency Table Alteration

Setting the "name" to VARCHAR(50) and "symbol" to VARCHAR(10) in the "Currency" table is clear. Confirm that none of the existing currency names or symbols exceed the new length limitations.


41-48: Review Destination Table Alteration

Multiple columns in the "Destination" table are altered to fixed VARCHAR lengths. This change is effective if existing data complies with these new length constraints, so please ensure that no data will be inadvertently truncated.


50-53: Review Guest Table Alteration

The "Guest" table columns "name" and "email" are now set to VARCHAR(100). This is generally acceptable—but please verify that all guest entries meet these new constraints.


54-57: Review Member Table Alteration

Altering the "name" and "email" columns in the "Member" table to VARCHAR(100) should align with expected input sizes. Ensure that no existing entries exceed the new limits.


58-61: Review PaymentPlan Table Alteration

Updating the "name" and "description" fields for the "PaymentPlan" table—with VARCHAR(100) and VARCHAR(255) respectively—is clear. Double-check that longer descriptions in the existing data are handled appropriately.


62-65: Review Role Table Alteration

Altering the "name" and "description" columns in the "Role" table (to VARCHAR(50) and VARCHAR(255) respectively) is consistent with schema tightening. Please confirm that this does not disrupt any role-related operations.


66-70: Review Trip Table Alteration and New Columns

In the "Trip" table, new columns "qrCode" and "shareableLink" are added as TEXT, and the "title" column is now VARCHAR(255). Ensure that the application layer correctly handles TEXT types and that any business logic involving these fields is updated accordingly.


71-73: Review TripGroup Table Alteration

The "TripGroup" table's "name" column is updated to VARCHAR(100). This change appears standard; please verify that all group names in the current dataset fall within this limit.


81-86: Review Users Table Alteration

Altering multiple columns ("username", "password", "name", "email") in the "users" table to specified VARCHAR lengths is consistent with the other changes. Confirm that these limits are in line with application validation rules.


87-104: Review Index Creation Statements

The creation of indexes on various tables (e.g., "Activity", "Budget", "Destination", "Member", "Payment", and "Trip") is clearly intended to optimize query performance. Verify that these indexes offer the expected benefits without introducing unnecessary overhead.


1-33:

Details

❓ Verification inconclusive

Informative Warning Block Present

The detailed warning comments provide clear insights into potential data loss and schema changes. Ensure that a complete backup is taken and proper testing is performed before applying this migration in production.


Migration Safety Verification – Please Review Before Production

The migration script at prisma/migrations/20240902020448_add_validations_and_qr_suport/migration.sql includes an extensive warning block that details potential data loss and truncation risks when casting various Text columns to specific VarChar lengths. This level of detail is very informative, and the warnings themselves are clear. Before proceeding, please ensure the following:

  • A complete backup of all affected tables is taken.
  • Comprehensive testing (including staging verifications for data truncation edge cases) is performed before deploying these changes to production.
  • Confirm that the migration directory name (i.e., "qr_suport") is intentional and not a typographical error.

Proceed with caution and verify these aspects to maintain data integrity during the migration.

prisma/schema.prisma (16)

11-16: User Model Field Constraints Updated

The User model now enforces character limits on "username", "password", "name", and "email" using @db.VarChar. Confirm that these constraints are compatible with existing data and any front-end validations.


35-45: Role Model Definition

The Role model now includes permission flags (read, write, create, update, delete) along with updated constraints on "name" and "description". This design is clear and aligns with role-based access requirements.


47-67: Account Model Field Constraints Updated

Length restrictions for "type", "provider", and "providerAccountId" in the Account model have been updated to match the migration adjustments. Ensure that these constraints consistently map to the underlying database types.


69-96: Trip Model Enhancements

The Trip model now includes new fields "qrCode" and "shareableLink", and the "title" field is explicitly constrained to VARCHAR(255). Please ensure that any application functionality involving trip sharing or QR code generation is updated to utilize these new fields.


98-111: Budget Model Update

The addition of the "userId" field and the revised relation in the Budget model align with the updated schema. Verify that any queries or business logic referencing budgets are aware of this new relationship.


113-132: Expense Model Column Updates

Confining the "name" field of the Expense model to VARCHAR(255) is consistent with the migration. Ensure that expense names and related validations are updated accordingly.


134-145: ExpenseMember Model

This model now includes an index on the combination of memberId and expenseId, which should improve lookup performance. The changes here are straightforward.


147-156: Currency Model Field Constraints Updated

The Currency model now enforces a VARCHAR(50) limit on "name" and a VARCHAR(10) on "symbol", which matches the migration. No further adjustments needed.


158-167: PaymentPlan Model Update

Updated field constraints for "name" and "description" in the PaymentPlan model are consistent with the database schema changes. Please ensure any UI or validations accommodating payment plans reflect these limits.


169-183: Payment Model Update

The Payment model’s structure, including the status default and relations to PaymentPlan, User, and Currency, remains intact. The updated constraints appear consistent.


197-213: Activity Model Definition

The Activity model has been updated with a VARCHAR(255) constraint on "name" and maintains its indexes on "startTime" and "endTime". This update appears consistent with overall schema changes.


215-235: Destiny Model Updates

The Destiny model now enforces length constraints on various textual fields (e.g., "name", "address", "city") via @db.VarChar, aligning with the migration strategy. All relationships and indexes appear intact.


237-247: Member Model Field Constraints Updated

The Member model now requires "name" and "email" to conform to VARCHAR(100) limits, with "email" remaining unique. This is in accordance with the migration changes.


249-255: Guest Model Update

The Guest model enforces VARCHAR(100) for "name" and "email" along with uniqueness constraints, consistent with prior modifications.


257-266: Invitation Model

The Invitation model remains largely unchanged aside from relational specifics (with onDelete Cascade). It consistently supports the schema.


268-306: Enum Definitions

The enum definitions for TripType, TripPriority, TripStatus, PaymentStatus, and Priority have been neatly updated to reflect new categories and statuses. These changes are clear and consistent with application requirements.

prisma/seed.ts (2)

32-39: Code addition follows the established pattern.

The addition of MXN currency follows the same pattern as other currencies in the seed file. This is a good approach for consistency.


40-40: Helpful logging addition.

Adding a console log to confirm successful seeding operations improves the developer experience when running the seed script.

package.json (1)

30-30:

Details

✅ Verification successful

Prisma dependencies updated.

The update from version 5.18.0 to 5.21.1 for both Prisma packages is a good practice to keep dependencies current.

Also applies to: 53-53


🌐 Web query:

What are the changes between Prisma 5.18.0 and 5.21.1?

💡 Result:

Prisma ORM versions 5.18.0 to 5.21.1 introduced several key changes, including new features, bug fixes, and breaking adjustments. Here's a structured overview:


New Features & Enhancements

  1. UUIDv7 Support (5.18.0)
    Added native support for UUIDv7 via @default(uuid(7)) in schemas, enabling temporally sortable IDs[10].

  2. strictUndefinedChecks Preview (5.20.0)
    Disallows explicit undefined values in queries, triggering runtime errors unless Prisma.skip is used. Enabled via Preview feature flag[1][4].

  3. Global Field Omission (5.20.0)
    Expanded the omit API (introduced in 5.13.0) to allow omitting fields globally or per-client instance[1].

  4. prismaSchemaFolder Improvements (Multiple Versions)
    Updated relative path resolution for multi-file schemas and added stricter validation for conflicting schema files[1][7].


Bug Fixes & Stability

  • Regression Fixes in 5.19.1
    Addressed schema engine errors (#25101) and incorrect Json[] handling in relationJoins Preview feature[4][7].
  • typedSql Fixes (5.20.0)
    Resolved parsing issues in the typedSql Preview feature for raw SQL type safety[4].
  • SQLite Path Correction (5.18.0)
    Fixed database file location mismatches when using prismaSchemaFolder[10].

Breaking Changes

  • prismaSchemaFolder Validation (Post-5.18.0)
    Conflicts between prisma/schema folders and schema.prisma files now throw errors[1].
  • Schema Engine Requirements (5.21.1)
    Introduced a 2-15 minute delay during prisma generate in some deployments, linked to engine initialization[8].

Deprecations & Compatibility

  • Node.js Versions
    Minimum supported versions raised to Node.js 18.18.0, 20.9.0, and 22.11.0[7].
  • TypeScript 5.1.0 Requirement
    Enforced stricter TypeScript compatibility[7].

These changes reflect Prisma’s focus on type safety, performance, and developer experience, though users should test for regressions like the prisma generate delay in 5.21.1[8]. For detailed upgrade steps, refer to the official migration guide.

Citations:


Prisma Dependency Update Approved

The update from Prisma 5.18.0 to 5.21.1 is a solid move for keeping our dependencies current. Notable changes in this release include:

  • New Features & Enhancements:
    • Native support for UUIDv7 via @default(uuid(7)) and improvements around schema file resolution.

  • Bug Fixes & Stability:
    • Various regression fixes and corrections in query parsing and SQLite file handling.

  • Breaking Changes:
    • Enhanced prismaSchemaFolder validations which might impact multi-file schemas, and a potential delay during prisma generate due to engine initialization.

Please ensure that any schema configurations and migration practices conform to these changes (refer to the official migration guide for details).

  • Files to review:
    package.json – lines 30 and 53 (updated to "@prisma/client": "^5.21.1")

Overall, the update is approved. Just verify that none of the breaking changes affect our existing setups.


# Construye la aplicación NestJS
RUN npm run build
RUN node --run build
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Verify Node.js command syntax

The commands node --run build and CMD ["node", "--run", "start:prod"] use the --run flag which is not a standard Node.js flag. This appears to be an error and may prevent the container from building and running correctly.

The correct commands should likely be:

-RUN node --run build
+RUN npm run build
-CMD ["node", "--run", "start:prod"]
+CMD ["npm", "run", "start:prod"]

Please verify the intended command syntax.

Also applies to: 26-26

Comment on lines +5 to +25
export class CreateBudgetDto {
@ApiProperty({ description: 'El monto del presupuesto' })
@IsNumber()
amount: number;

@ApiProperty({ description: 'El valor mínimo del presupuesto' })
@IsNumber()
min: number;

@ApiProperty({ description: 'El valor máximo del presupuesto' })
@IsNumber()
max: number;

@ApiProperty({ description: 'El ID de la moneda asociada al presupuesto' })
@IsNumber()
currencyId: number;

@ApiProperty({ description: 'El ID del usuario propietario del presupuesto' })
@IsString()
userId: string;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance validation with more constraints to ensure data integrity.

The current validation only checks types but doesn't enforce logical constraints for budget values.

import { IsNumber, IsString } from 'class-validator';
+import { IsNotEmpty, IsPositive, IsUUID, Min, Max } from 'class-validator';

import { ApiProperty } from '@nestjs/swagger';

export class CreateBudgetDto {
  @ApiProperty({ description: 'El monto del presupuesto' })
  @IsNumber()
+  @IsPositive({ message: 'Amount must be a positive number' })
  amount: number;

  @ApiProperty({ description: 'El valor mínimo del presupuesto' })
  @IsNumber()
+  @Min(0, { message: 'Minimum value cannot be negative' })
  min: number;

  @ApiProperty({ description: 'El valor máximo del presupuesto' })
  @IsNumber()
+  @IsPositive({ message: 'Maximum value must be positive' })
  max: number;

  @ApiProperty({ description: 'El ID de la moneda asociada al presupuesto' })
  @IsNumber()
+  @IsPositive({ message: 'Currency ID must be positive' })
  currencyId: number;

  @ApiProperty({ description: 'El ID del usuario propietario del presupuesto' })
  @IsString()
+  @IsNotEmpty({ message: 'User ID cannot be empty' })
+  @IsUUID(4, { message: 'User ID must be a valid UUID' })
  userId: string;
}

Additionally, consider adding a custom validator to ensure that min is less than max:

@ValidatorConstraint({ name: 'isMinLessThanMax', async: false })
export class IsMinLessThanMaxConstraint implements ValidateBy {
  validate(value: any, args: ValidationArguments) {
    const object = args.object as CreateBudgetDto;
    return object.min < object.max;
  }

  defaultMessage(args: ValidationArguments) {
    return 'Minimum value must be less than maximum value';
  }
}

// And in your DTO class:
@Validate(IsMinLessThanMaxConstraint)
export class CreateBudgetDto {
  // existing properties
}

Comment on lines +13 to +17

await prisma.$connect().catch((error) => {
Logger.error('Failed to connect to the database', error);
// throw new Error(error);
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve database connection error handling strategy

Adding error handling for database connection failures is good, but consider whether silently logging errors without throwing is appropriate. The current implementation allows the application to continue running with a potentially disconnected database.

Consider implementing one of these approaches:

 await prisma.$connect().catch((error) => {
   Logger.error('Failed to connect to the database', error);
-  // throw new Error(error);
+  throw new Error(`Database connection failed: ${error.message}`);
 });

Or implement a retry mechanism:

 await prisma.$connect().catch(async (error) => {
   Logger.error('Failed to connect to the database', error);
+  // Retry connection
+  Logger.log('Retrying database connection...');
+  try {
+    await prisma.$connect();
+    Logger.log('Database connection established after retry');
+  } catch (retryError) {
+    Logger.error('Failed to connect after retry', retryError);
+    throw new Error(`Database connection failed after retry: ${retryError.message}`);
+  }
 });
📝 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.

Suggested change
await prisma.$connect().catch((error) => {
Logger.error('Failed to connect to the database', error);
// throw new Error(error);
});
await prisma.$connect().catch((error) => {
Logger.error('Failed to connect to the database', error);
throw new Error(`Database connection failed: ${error.message}`);
});

Comment on lines +40 to 44
@UseGuards(AuthGuard)
findAll(@Req() request: Request) {
const userId = request['user'].id;
return this.tripService.findAll(userId);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve type safety when accessing user from request

While adding authentication is good, accessing the user via bracket notation (request['user'].id) isn't type-safe and lacks error handling.

Consider using a custom decorator or a more type-safe approach:

 @UseGuards(AuthGuard)
-findAll(@Req() request: Request) {
-  const userId = request['user'].id;
+findAll(@Req() request: Request) {
+  if (!request['user'] || !request['user'].id) {
+    throw new UnauthorizedException('User information not found in request');
+  }
+  const userId = request['user'].id;
   return this.tripService.findAll(userId);
 }

Even better, create a custom user decorator:

// user.decorator.ts
import { createParamDecorator, ExecutionContext, UnauthorizedException } from '@nestjs/common';

export const GetUser = createParamDecorator(
  (data: string | undefined, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    if (!request.user) {
      throw new UnauthorizedException('User not found in request');
    }
    return data ? request.user[data] : request.user;
  },
);

// Using in controller
@Get()
@UseGuards(AuthGuard)
findAll(@GetUser('id') userId: string) {
  return this.tripService.findAll(userId);
}

Comment on lines +60 to 67
const token = await this.jwtService.signAsync(payload, {
expiresIn: '30d',
});
const isPasswordValid = await bcryptjs.compare(password, user.password);

if (!isPasswordValid) {
throw new UnauthorizedException('Invalid email or password-');
throw new BadRequestException('Invalid email or password-');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix security issues with authentication flow

Several issues need addressing:

  1. Token is generated before password validation, which is inefficient
  2. There's a typo ("-" character) in the error message
  3. 30-day JWT expiration is quite long by security standards
  4. Using BadRequestException instead of UnauthorizedException for auth failures is misleading

Suggested improvements:

-  const token = await this.jwtService.signAsync(payload, {
-    expiresIn: '30d',
-  });
 const isPasswordValid = await bcryptjs.compare(password, user.password);

 if (!isPasswordValid) {
-  throw new BadRequestException('Invalid email or password-');
+  throw new UnauthorizedException('Invalid email or password');
 }

+ const token = await this.jwtService.signAsync(payload, {
+   expiresIn: '1d', // Consider a shorter expiration and implement refresh tokens
+ });
📝 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.

Suggested change
const token = await this.jwtService.signAsync(payload, {
expiresIn: '30d',
});
const isPasswordValid = await bcryptjs.compare(password, user.password);
if (!isPasswordValid) {
throw new UnauthorizedException('Invalid email or password-');
throw new BadRequestException('Invalid email or password-');
}
const isPasswordValid = await bcryptjs.compare(password, user.password);
if (!isPasswordValid) {
throw new UnauthorizedException('Invalid email or password');
}
const token = await this.jwtService.signAsync(payload, {
expiresIn: '1d', // Consider a shorter expiration and implement refresh tokens
});

Comment on lines +51 to +60
@Get(':id')
@ApiOperation({ summary: 'Obtener un presupuesto por id' })
@ApiParam({ name: 'id', description: 'El id del presupuesto' })
@ApiResponse({
status: 200,
description: 'El presupuesto encontrado',
})
async findOne(@Param('id') id: number): Promise<Budget> {
return this.budgetService.findOne(id);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Validate and transform the id parameter.

Add proper validation and transformation for the id parameter to ensure it's a number before passing it to the service.

+ import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put } from '@nestjs/common';

  @Get(':id')
  @ApiOperation({ summary: 'Obtener un presupuesto por id' })
  @ApiParam({ name: 'id', description: 'El id del presupuesto' })
  @ApiResponse({
    status: 200,
    description: 'El presupuesto encontrado',
  })
- async findOne(@Param('id') id: number): Promise<Budget> {
+ async findOne(@Param('id', ParseIntPipe) id: number): Promise<Budget> {
    return this.budgetService.findOne(id);
  }

Comment on lines +62 to +74
@Put(':id')
@ApiOperation({ summary: 'Actualizar un presupuesto' })
@ApiParam({ name: 'id', description: 'El id del presupuesto a actualizar' })
@ApiResponse({
status: 200,
description: 'El presupuesto ha sido actualizado exitosamente.',
})
async update(
@Param('id') id: number,
@Body() updateBudgetDto: UpdateBudgetDto,
): Promise<Budget> {
return this.budgetService.update(id, updateBudgetDto);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add validation for update parameters.

Ensure both the id parameter and the update DTO are properly validated.

+ import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, UsePipes, ValidationPipe } from '@nestjs/common';

  @Put(':id')
  @ApiOperation({ summary: 'Actualizar un presupuesto' })
  @ApiParam({ name: 'id', description: 'El id del presupuesto a actualizar' })
  @ApiResponse({
    status: 200,
    description: 'El presupuesto ha sido actualizado exitosamente.',
  })
+ @UsePipes(new ValidationPipe({ transform: true }))
  async update(
-   @Param('id') id: number,
+   @Param('id', ParseIntPipe) id: number,
    @Body() updateBudgetDto: UpdateBudgetDto,
  ): Promise<Budget> {
    return this.budgetService.update(id, updateBudgetDto);
  }
📝 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.

Suggested change
@Put(':id')
@ApiOperation({ summary: 'Actualizar un presupuesto' })
@ApiParam({ name: 'id', description: 'El id del presupuesto a actualizar' })
@ApiResponse({
status: 200,
description: 'El presupuesto ha sido actualizado exitosamente.',
})
async update(
@Param('id') id: number,
@Body() updateBudgetDto: UpdateBudgetDto,
): Promise<Budget> {
return this.budgetService.update(id, updateBudgetDto);
}
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, UsePipes, ValidationPipe } from '@nestjs/common';
@Put(':id')
@ApiOperation({ summary: 'Actualizar un presupuesto' })
@ApiParam({ name: 'id', description: 'El id del presupuesto a actualizar' })
@ApiResponse({
status: 200,
description: 'El presupuesto ha sido actualizado exitosamente.',
})
@UsePipes(new ValidationPipe({ transform: true }))
async update(
@Param('id', ParseIntPipe) id: number,
@Body() updateBudgetDto: UpdateBudgetDto,
): Promise<Budget> {
return this.budgetService.update(id, updateBudgetDto);
}

Comment on lines +32 to +34
-- AlterTable
ALTER TABLE "Activity" DROP COLUMN "destinationId",
ADD COLUMN "destinyId" TEXT;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Migrate destinationId data to destinyId.
Before dropping destinationId, ensure a safe migration path to destinyId.

Comment on lines +116 to 135
async update(id: string, updateTripDto: UpdateTripDto) {
const {
title,
description,
userId,
budgetId,
tripGroupId,
startDate,
endDate,
priority,
status,
tripType,
} = createTripDto;
shareableLink,
qrCode,
budget,
budgetId,
destinies,
activities,
tripGroupId,
} = updateTripDto;

console.log(destinies);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use transactions for multiple upserts and creates.
Performing separate queries for destinies, activities, and budget within a single update call could lead to partial updates if a step fails.

- return this.prisma.trip.update({ ... });
+ return this.prisma.$transaction(async (tx) => {
+   return tx.trip.update({ ... });
+ });

Remove console.log.
Replace with a logger or remove for cleaner production code.

Also applies to: 136-187

Comment on lines +74 to +80
-- AlterTable
ALTER TABLE "accounts" DROP CONSTRAINT "accounts_pkey",
ALTER COLUMN "type" SET DATA TYPE VARCHAR(30),
ALTER COLUMN "provider" SET DATA TYPE VARCHAR(50),
ALTER COLUMN "providerAccountId" SET DATA TYPE VARCHAR(100),
ADD CONSTRAINT "accounts_pkey" PRIMARY KEY ("provider", "providerAccountId");

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Review Accounts Table Primary Key Modification

Modifying the primary key for the "accounts" table—including dropping the existing constraint and reintroducing it with the columns "provider" and "providerAccountId"—is a high-risk operation. Ensure this change runs within a transaction to prevent leaving the table without a primary key in case of partial failure. Also, validate that existing records conform to the new format.


Below is a shell script to verify whether the migration is using an explicit transaction (i.e. wrapping the ALTER TABLE operation within transaction control commands such as BEGIN/COMMIT). This will help us confirm the safety precautions mentioned in the review comment.


🏁 Script executed:

#!/bin/bash
# This script checks if the migration file is wrapped in a transaction block.
echo "Scanning for transaction control commands (BEGIN/COMMIT) in migration file..."
grep -Ei "BEGIN|COMMIT" prisma/migrations/20240902020448_add_validations_and_qr_suport/migration.sql || echo "No transaction control commands found."

Length of output: 354


Action Required: Wrap migration in a transaction

The migration currently performs a high-risk primary key modification on the "accounts" table without being wrapped in a transaction block. This is dangerous because if part of the migration fails, the table may be left without a primary key. Please update the migration to include explicit transaction control commands (i.e., BEGIN and COMMIT) to ensure atomicity and data consistency. Verify that all existing records conform to the new format before applying this change.

  • File: prisma/migrations/20240902020448_add_validations_and_qr_suport/migration.sql
  • Lines: 74-80 (adjust as needed after adding transaction wrappers)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (1)
src/app.controller.ts (1)

1-11: ⚠️ Potential issue

Controller has inconsistent implementation with imports

The controller route has been changed from empty string to a forward slash ("/"), but there's an inconsistency: based on the AI summary, the intention was to remove the AppService dependency and getHello method, but they're still present in the code.

Consider completing the refactoring by applying this change:

import { Controller, Get } from '@nestjs/common';
-import { AppService } from './app.service';

@Controller('/')
export class AppController {
-  constructor(private readonly appService: AppService) {}

-  @Get()
-  getHello(): string {
-    return this.appService.getHello();
-  }
}
🧹 Nitpick comments (1)
prisma/migrations/20250410223907_/migration.sql (1)

4-6: Dropping the Unique Index on _ActivityToDestiny

Dropping the unique index _ActivityToDestiny_AB_unique is appropriate since the new primary key constraint already enforces uniqueness. As a suggestion, consider using DROP INDEX IF EXISTS if your DBMS supports it, to prevent migration failures in cases where the index might be absent.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c64c65f and bfc7b08.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • package.json (1 hunks)
  • prisma/migrations/20250410223907_/migration.sql (1 hunks)
  • prisma/migrations/migration_lock.toml (1 hunks)
  • src/app.controller.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • prisma/migrations/migration_lock.toml
🔇 Additional comments (8)
prisma/migrations/20250410223907_/migration.sql (5)

1-3: Composite Primary Key Constraint for _ActivityToDestiny

The addition of the composite primary key ("A", "B") ensures that each record in the _ActivityToDestiny table is uniquely identified. This enforcement of data integrity is well implemented.


7-12: Primary Key Constraint and Index Removal for _ActivityToTrip

The changes for _ActivityToTrip mirror those of _ActivityToDestiny by introducing a composite primary key and dropping the existing unique index. This consistent approach promotes database integrity. Ensure that any foreign key references or application logic interacting with these tables are updated accordingly.


13-18: Enforcing Uniqueness on _DestinyToTrip

Adding the composite primary key constraint and removing the unique index for _DestinyToTrip is straightforward and aligns well with best practices. The automatic index creation by the primary key will maintain efficient query performance.


19-24: Establishing Primary Key for _GroupMembers

The migration segment that adds the composite primary key for _GroupMembers and drops the former unique index is clear and maintains data integrity. This change ensures that duplicate records are avoided in many-to-many relationships common in group membership scenarios.


25-29: Configuring Primary Key for _MemberToTrip

Introducing the primary key constraint on _MemberToTrip in place of the unique index is consistent with the changes made to other join tables. This update solidifies relational structure and improves integrity enforcement across the schema.

package.json (3)

23-30:

Details

❓ Verification inconclusive

Major version upgrades need careful migration

You've updated several NestJS packages from v10 to v11 and Prisma from v5 to v6. These major version upgrades likely include breaking changes that require code modifications.

Verify compatibility with NestJS v11:


🏁 Script executed:

#!/bin/bash
# Check NestJS v11 breaking changes that might affect your code
echo "Checking for NestJS v11 migration guides..."
curl -s https://github.com/nestjs/nest/releases | grep -A 10 "v11.0.0" || echo "Couldn't fetch NestJS releases"

# Check if there are deprecated APIs in use
echo -e "\nChecking for potential deprecated API usage..."
rg -i "deprecated|remove.*in.*v11" --type ts

Length of output: 397


Manual verification required for NestJS v11 and Prisma v6 migration

  • The automated checks for deprecated API usage returned no warnings, which is encouraging.
  • However, the script intended to fetch NestJS v11 migration details did not retrieve the expected information ("Couldn't fetch NestJS releases"). This weakens our automated inference.
  • Action needed: Please manually review the official NestJS v11 migration guide and the Prisma v6 release notes to confirm that no breaking changes affect our code. Adjustments might be necessary if the official guides highlight modifications incompatible with our current implementation.

41-45:

Details

❓ Verification inconclusive

Type definition upgrades may require code changes

The upgrade from @types/express v4 to v5 and @types/node v20 to v22 might introduce type incompatibilities in your code.

Check for potential type issues:


🏁 Script executed:

#!/bin/bash
# Check for Express type usage that might be affected
echo "Checking for Express type usage..."
rg "Express|Request|Response|NextFunction" --type ts

# Look for TypeScript errors after the upgrade
echo -e "\nLooking for tsconfig.json to verify TypeScript version compatibility..."
cat tsconfig.json 2>/dev/null || echo "tsconfig.json not found"

Length of output: 6218


Action Required: Manually verify potential type incompatibilities after upgrading type definitions

After scanning the code for usage of Express types and reviewing the TypeScript configuration, no immediate issues were flagged. However, note that with "skipLibCheck": true in your tsconfig.json, some declaration file mismatches from upgrading to @types/express v5 and @types/node v22 might be masked.

  • Review Usage: Ensure that files importing Express types (e.g., src/opt/trip/trip.controller.ts, src/middleware/logger/logger.middleware.ts, src/auth/auth.controller.ts, etc.) still behave as expected.
  • Temporarily Tighten Type Checks: Consider disabling skipLibCheck or running a full compile to catch any subtle type errors that might not be reported otherwise.

Please confirm with a thorough compilation and testing pass to ensure that no breaking changes have been introduced by the type upgrades.


30-31:

Details

❓ Verification inconclusive

Security-critical dependency update

Upgrading Prisma from v5 to v6 and bcryptjs from v2 to v3 are significant changes that could affect data access and authentication security.

Check for compatibility issues:


🏁 Script executed:

#!/bin/bash
# Check for Prisma v6 migration guide
echo "Checking for Prisma v6 migration guide..."
curl -s https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6 || echo "Couldn't fetch Prisma migration guide"

# Check for bcryptjs v3 changes (this package is critical for authentication)
echo -e "\nChecking bcryptjs usage in codebase..."
rg "bcryptjs" --type ts -A 3 -B 3

Length of output: 78052


Security-critical dependency update – Manual Verification Required

The updates in package.json now show the following changes:

  • @prisma/client has been updated to v6. The Prisma v6 migration guide confirms several breaking changes that could affect data access.
  • bcryptjs has been updated to v3. Our initial automated search in TypeScript files didn’t surface any direct usage of bcryptjs. However, please double-check whether bcryptjs might be used in other file types (e.g., plain JavaScript files or dynamic imports) to ensure that the upgrade won’t inadvertently affect authentication behavior.

Please perform a manual verification of the authentication flows and database access logic to confirm compatibility with these new versions.

Comment on lines 22 to 62
"dependencies": {
"@nestjs/common": "^10.4.1",
"@nestjs/config": "^3.2.3",
"@nestjs/core": "^10.3.9",
"@nestjs/jwt": "^10.2.0",
"@nestjs/common": "^11.0.16",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.16",
"@nestjs/jwt": "^11.0.0",
"@nestjs/mapped-types": "*",
"@nestjs/platform-express": "^10.3.9",
"@nestjs/swagger": "^7.3.1",
"@prisma/client": "^5.18.0",
"bcryptjs": "^2.4.3",
"@nestjs/platform-express": "^11.0.16",
"@nestjs/swagger": "^11.1.2",
"@prisma/client": "^6.6.0",
"bcryptjs": "^3.0.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"postgres": "^3.4.4",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
"postgres": "^3.4.5",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.14.12",
"@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"prisma": "^5.18.0",
"@nestjs/cli": "^11.0.6",
"@nestjs/schematics": "^11.0.5",
"@nestjs/testing": "^11.0.16",
"@types/express": "^5.0.1",
"@types/jest": "^29.5.14",
"@types/node": "^22.14.0",
"@types/supertest": "^6.0.3",
"@typescript-eslint/eslint-plugin": "^8.29.1",
"@typescript-eslint/parser": "^8.29.1",
"eslint": "^9.24.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-prettier": "^5.2.6",
"jest": "^29.7.0",
"prettier": "^3.5.3",
"prisma": "^6.6.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"supertest": "^7.1.0",
"ts-jest": "^29.3.1",
"ts-loader": "^9.5.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.16.2",
"typescript": "^5.5.4"
"tsx": "^4.19.3",
"typescript": "^5.8.3"
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Update package-lock.json and run comprehensive tests

These are extensive dependency upgrades across the board. Make sure to regenerate package-lock.json and run comprehensive tests for functionality, performance, and security.

After updating dependencies:

  1. Delete node_modules and package-lock.json
  2. Run npm install to generate a fresh lockfile
  3. Run the full test suite including E2E tests
  4. Verify application startup and core functionality

Comment on lines +48 to +50
"eslint": "^9.24.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-prettier": "^5.2.6",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

ESLint configuration needs update

You've upgraded ESLint from v8 to v9 and the TypeScript ESLint plugins from v6 to v8, which likely require updates to your ESLint configuration files.

Verify ESLint compatibility:


🏁 Script executed:

#!/bin/bash
# Check for ESLint configuration files
echo "Checking for ESLint configuration files..."
find . -name ".eslintrc*" -type f | xargs cat

# Check ESLint plugin compatibility
echo -e "\nChecking for ESLint plugin compatibility..."
curl -s https://github.com/typescript-eslint/typescript-eslint/releases | grep -A 10 "v8.0.0" || echo "Couldn't fetch TypeScript-ESLint releases"

Length of output: 7166


ESLint Configuration Update Required

After verifying the ESLint configuration files across the repository, it appears that while the dependency versions in package.json have been upgraded to ESLint v9 and associated plugins (including TypeScript ESLint plugins v8), the configuration files still include legacy settings. For example, the TypeScript ESLint config still explicitly disables rules such as @typescript-eslint/interface-name-prefix (which has been deprecated) along with other rules that may no longer be necessary or might need to be updated to the new recommended settings.

  • Action Items:
    • Review and update your ESLint configuration files (e.g., .eslintrc.js and similar files) to remove deprecated rules such as @typescript-eslint/interface-name-prefix.
    • Align your configuration with the breaking changes and updated recommendations from the TypeScript ESLint v8 documentation.
    • Consider consolidating multiple ESLint configurations if practical, to avoid redundancy and ensure consistency.

Please update these configurations accordingly to ensure proper integration with ESLint v9 and the new plugin versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants