Skip to content
This repository was archived by the owner on Nov 23, 2025. It is now read-only.

Dev#5

Merged
RandithaK merged 20 commits intomainfrom
dev
Nov 8, 2025
Merged

Dev#5
RandithaK merged 20 commits intomainfrom
dev

Conversation

@RandithaK
Copy link
Copy Markdown
Member

No description provided.

AdithaBuwaneka and others added 20 commits October 31, 2025 16:05
- Implemented new endpoints in ProjectController for project requests, listing, and quote management.
- Added ApiResponse DTO for standardized API responses.
- Introduced ProgressUpdateDto, ProjectRequestDto, ProjectResponseDto, QuoteDto, and RejectionDto for request handling.
- Enhanced ProjectService and ProjectServiceImpl with new methods for project management.
- Added exception handling for project-related operations.
feat: Enhance role-based access control for project and service listings
Enhance project and service management with new endpoints and DTOs
Copilot AI review requested due to automatic review settings November 8, 2025 11:14
@TechTorque-2025 TechTorque-2025 deleted a comment from coderabbitai bot Nov 8, 2025
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a complete transformation of the Project Service from stub implementations to a fully functional microservice managing both standard services (from appointments) and custom vehicle modification projects. The implementation includes invoice generation, file uploads, service notes, progress tracking, and comprehensive role-based access control.

Key Changes:

  • Implemented all business logic for service and project management (previously were stubs)
  • Added complete invoice generation system with line items and tax calculation
  • Implemented file storage service for progress photos with security controls
  • Created comprehensive data seeder with test data for development

Reviewed Changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
StandardServiceServiceImpl.java Implemented all 11 service methods with complete business logic including invoice generation
ProjectServiceImpl.java Completed implementation of all project management methods with workflow validation
FileStorageServiceImpl.java New file storage service with path traversal prevention and multi-file support
ServiceController.java Enhanced from stubs to fully functional REST endpoints with proper error handling
ProjectController.java Completed controller implementation with validation and access control
DataSeeder.java New comprehensive data seeder with services, projects, notes, photos, and invoices
Multiple DTOs Created 9 new DTOs for request/response handling
Multiple Entities Created 7 new entities (ServiceNote, ProgressPhoto, Invoice, InvoiceItem, Quote, etc.)
Multiple Repositories Added 4 new repositories with custom query methods
Exception classes Added 5 custom exception classes for proper error handling
GlobalExceptionHandler.java Comprehensive exception handler with proper HTTP status codes
GatewayHeaderFilter.java Enhanced to handle SUPER_ADMIN role mapping
OpenApiConfig.java New Swagger/OpenAPI configuration
Test configuration Added H2 test database configuration
Documentation Extensive updates to README, new QUICK_START and IMPLEMENTATION_SUMMARY
CI/CD Added GitHub Actions workflows for build and deployment

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

private static final String CUSTOMER_1_ID = "customer";
private static final String CUSTOMER_2_ID = "testuser";
private static final String EMPLOYEE_1_ID = "employee";
private static final String EMPLOYEE_2_ID = "employee";
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

EMPLOYEE_1_ID and EMPLOYEE_2_ID both have the same value 'employee'. This will cause both employees to appear as the same user in the seeded data, which could lead to confusion during testing and development.

Suggested change
private static final String EMPLOYEE_2_ID = "employee";
private static final String EMPLOYEE_2_ID = "employee2";

Copilot uses AI. Check for mistakes.
.build();
invoice.getItems().add(additionalItem);

subtotal = subtotal.add(itemDto.getAmount());
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

The subtotal is being recalculated inside the loop but the initial value was already set from dto.getActualCost(). This means the invoice's subtotal will include the actualCost twice: once from line 291 and again when recalculated here. The subtotal should start from the actualCost before the loop, or be reset before recalculating.

Copilot uses AI. Check for mistakes.

@Override
public String storeFile(MultipartFile file, String serviceId) {
String originalFilename = StringUtils.cleanPath(file.getOriginalFilename());
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Potential NullPointerException if file.getOriginalFilename() returns null. The method should check for null before calling StringUtils.cleanPath().

Copilot uses AI. Check for mistakes.
Comment on lines +76 to +77
Project project = projectService.getProjectDetails(projectId, userId, userRoles)
.orElseThrow(() -> new RuntimeException("Project not found or access denied"));
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Throwing generic RuntimeException instead of the custom ProjectNotFoundException that exists in the codebase. This bypasses the GlobalExceptionHandler and returns a 500 status instead of the appropriate 404 or 403 status.

Copilot uses AI. Check for mistakes.
String invoiceNumber = generateInvoiceNumber();

BigDecimal subtotal = dto.getActualCost();
BigDecimal taxRate = new BigDecimal("0.15"); // 15% tax
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

The tax rate is hardcoded as a magic number. This should be extracted as a configurable property (e.g., @value("${invoice.tax-rate:0.15}")) to allow different tax rates per deployment or region without code changes.

Copilot uses AI. Check for mistakes.
# JPA Configuration
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=false
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

[nitpick] In test configuration, spring.jpa.show-sql is set to false while logging.level.org.hibernate.SQL is set to DEBUG. These settings are contradictory. For test environments, it's typically better to set show-sql=true for debugging test failures.

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +60
com.techtorque.project_service.entity.ServiceStatus statusEnum =
com.techtorque.project_service.entity.ServiceStatus.valueOf(status.toUpperCase());
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

[nitpick] Fully qualified class name is unnecessarily verbose. Since ServiceStatus is not ambiguous in this context, add an import statement instead of using the fully qualified name for better readability.

Copilot uses AI. Check for mistakes.
BigDecimal totalAmount = subtotal.add(taxAmount);

Invoice invoice = Invoice.builder()
.invoiceNumber("INV-" + System.currentTimeMillis())
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

Using System.currentTimeMillis() for invoice number generation could lead to collisions if multiple invoices are generated in quick succession. Consider using the existing generateInvoiceNumber() method from StandardServiceServiceImpl or UUID for uniqueness.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +43
if (originalFilename.contains("..")) {
throw new FileStorageException("Filename contains invalid path sequence: " + originalFilename);
}
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

The path traversal check only looks for '..' but should also validate against absolute paths and other dangerous patterns. Consider using Path.normalize() and checking if the resulting path starts with the expected storage location to prevent directory traversal attacks more comprehensively.

Copilot uses AI. Check for mistakes.

@OneToMany(mappedBy = "invoice", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@Builder.Default
private List<InvoiceItem> items = new ArrayList<>();
Copy link

Copilot AI Nov 8, 2025

Choose a reason for hiding this comment

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

getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.
getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.
getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.
getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.
getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.
getItems exposes the internal representation stored in field items. The value may be modified after this call to getItems.

Copilot uses AI. Check for mistakes.
@RandithaK RandithaK merged commit be822d5 into main Nov 8, 2025
14 of 15 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants