Skip to content

Conversation

@MichaelBoegner
Copy link
Owner

@MichaelBoegner MichaelBoegner commented Oct 16, 2025

Summary

This PR refactors the service layer from pure functions to struct-based services, introducing dependency injection and improved encapsulation. The changes move from a functional programming approach to an object-oriented service pattern.

What changed

  • Converting standalone functions to methods on service structs (UserService, TokenService, InterviewService, etc.)
  • Introducing service constructors that accept dependencies via dependency injection
  • Updating all handlers and tests to use the new service-based architecture

@MichaelBoegner MichaelBoegner self-assigned this Oct 16, 2025
@MichaelBoegner MichaelBoegner added the enhancement New feature or request label Oct 16, 2025
Copy link

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 refactors the service layer from pure functions to struct-based services, introducing dependency injection and improved encapsulation. The changes move from a functional programming approach to an object-oriented service pattern.

Key changes include:

  • Converting standalone functions to methods on service structs (UserService, TokenService, InterviewService, etc.)
  • Introducing service constructors that accept dependencies via dependency injection
  • Updating all handlers and tests to use the new service-based architecture

Reviewed Changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
user/service.go Converted user functions to UserService methods with dependency injection
user/service_test.go Updated tests to use UserService struct instead of standalone functions
user/repository_mock.go Changed mock field from private to public for external access
user/model.go Added UserService struct and constructor
token/service.go Converted token functions to TokenService methods
token/service_test.go Updated tests to use TokenService struct
token/model.go Added TokenService struct and constructor
interview/service.go Converted interview functions to InterviewService methods
interview/service_test.go Updated tests to use InterviewService struct
interview/model.go Added InterviewService struct and constructor
conversation/service.go Converted conversation functions to ConversationService methods
conversation/service_test.go Updated tests to use ConversationService struct
conversation/model.go Added ConversationService struct and constructor
mailer/service.go Updated method receivers from Mailer to MailerService
mailer/model.go Renamed Mailer struct to MailerService and updated constructor
chatgpt/service.go Updated method receivers from OpenAIClient to AIService
chatgpt/model.go Renamed OpenAIClient to AIService and updated constructor
billing/service.go Converted billing functions to BillingService methods
billing/service_test.go Updated tests to use BillingService struct
billing/model.go Renamed Billing to BillingService and added dependency injection
dashboard/service.go Converted dashboard functions to DashboardService methods
dashboard/model.go Added DashboardService struct and constructor
handlers/model.go Updated Handler struct to use service dependencies instead of repositories
handlers/handlers.go Updated all handlers to use service methods instead of standalone functions
handlers/handlers_test.go Updated tests to use new service-based architecture
internal/server/server.go Updated server initialization to create and inject services
internal/testutil/server.go Updated test server to use service-based architecture
internal/testutil/helpers.go Updated helper functions to accept service parameters
internal/mocks/openai_mock.go Renamed MockOpenAIClient to MockAIService
internal/mocks/mailer_mock.go Renamed MockMailer to MockMailerService
learninglog/03_29_2025.md Updated documentation to reflect new service naming

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

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

Copilot reviewed 31 out of 31 changed files in this pull request and generated 8 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

}

user, err := h.UserRepo.GetUser(params.UserID)
user, err := h.UserService.UserRepo.GetUser(params.UserID)
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Direct access to h.UserService.UserRepo breaks encapsulation. This should use h.UserService.GetUser(params.UserID) to maintain proper abstraction boundaries.

Suggested change
user, err := h.UserService.UserRepo.GetUser(params.UserID)
user, err := h.UserService.GetUser(params.UserID)

Copilot uses AI. Check for mistakes.
}

err = h.InterviewRepo.UpdateStatus(interviewID, userID, payload.Status)
err = h.InterviewService.InterviewRepo.UpdateStatus(interviewID, userID, payload.Status)
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Direct access to h.InterviewService.InterviewRepo breaks encapsulation. Consider adding an UpdateStatus method to InterviewService to maintain proper abstraction boundaries.

Suggested change
err = h.InterviewService.InterviewRepo.UpdateStatus(interviewID, userID, payload.Status)
err = h.InterviewService.UpdateStatus(interviewID, userID, payload.Status)

Copilot uses AI. Check for mistakes.
Comment on lines +1057 to +1059
exists, err := h.BillingService.BillingRepo.HasWebhookBeenProcessed(webhookID)
if err != nil {
h.Logger.Error("h.BillingRepo.HasWebhookBeenProcessed failed", "error", err)
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Direct access to h.BillingService.BillingRepo breaks encapsulation. Consider adding a HasWebhookBeenProcessed method to BillingService to maintain proper abstraction boundaries.

Suggested change
exists, err := h.BillingService.BillingRepo.HasWebhookBeenProcessed(webhookID)
if err != nil {
h.Logger.Error("h.BillingRepo.HasWebhookBeenProcessed failed", "error", err)
exists, err := h.BillingService.HasWebhookBeenProcessed(webhookID)
if err != nil {
h.Logger.Error("h.BillingService.HasWebhookBeenProcessed failed", "error", err)

Copilot uses AI. Check for mistakes.
}

exists, err := h.UserRepo.HasActiveOrCancelledSubscription(SubCreatedAttrs.UserEmail)
exists, err := h.UserService.UserRepo.HasActiveOrCancelledSubscription(SubCreatedAttrs.UserEmail)
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Direct access to h.UserService.UserRepo breaks encapsulation. Consider adding a HasActiveOrCancelledSubscription method to UserService to maintain proper abstraction boundaries.

Suggested change
exists, err := h.UserService.UserRepo.HasActiveOrCancelledSubscription(SubCreatedAttrs.UserEmail)
exists, err := h.UserService.HasActiveOrCancelledSubscription(SubCreatedAttrs.UserEmail)

Copilot uses AI. Check for mistakes.
}

err = h.BillingRepo.MarkWebhookProcessed(webhookID, eventType)
err = h.BillingService.BillingRepo.MarkWebhookProcessed(webhookID, eventType)
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Direct access to h.BillingService.BillingRepo breaks encapsulation. Consider adding a MarkWebhookProcessed method to BillingService to maintain proper abstraction boundaries.

Suggested change
err = h.BillingService.BillingRepo.MarkWebhookProcessed(webhookID, eventType)
err = h.BillingService.MarkWebhookProcessed(webhookID, eventType)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants