implement user favorite management features#33
Conversation
alesr
left a comment
There was a problem hiding this comment.
Hi @antonioualex, thanks so much for submitting your solution for the assignment! I’ve left a couple of questions for you to take a look at when you have a moment. No rush, take your time. 😊
| func cleanExit(code int) { | ||
| // Allow deferred functions to run before exiting | ||
| defer os.Exit(code) | ||
| } |
There was a problem hiding this comment.
Could you please elaborate on what is happening here?
The server returns an error, logs the error and then?
There was a problem hiding this comment.
The server returns an error, logs the error and then calls cleanExit(1). Inside cleanExit(), os.Exit(1) is scheduled as a deferred function. When cleanExit() finishes, the deferred os.Exit(1) executes immediately. The cleanExit function doesn't actually accomplish what its comment and name suggests creating confusion about when exit will occur. Besides that, there's nothing left in that scope to run. I would remove cleanExit() entirely and use os.Exit(1) directly in main() so it can be clearer and doesn't create false expectations.
| sqldb := sql.OpenDB(pgdriver.NewConnector( | ||
| pgdriver.WithNetwork(cfg.Network), | ||
| pgdriver.WithAddr(cfg.Address), | ||
| pgdriver.WithTLSConfig(nil), |
There was a problem hiding this comment.
Why do we need to pass nil to the WithTLSConfig?
Is TLS enabled by default? What does it mean to add this flag and pass a nil configuration?
There was a problem hiding this comment.
It means no custom TLS configuration is provided which overrides the default behavior. When I pass nil to WithTLSConfig(), the connector will use disabled ssl mode which is needed for local development. The correct approach would be to use, pgdriver.WithInsecure(cfg bool) and pass the value through configuration.
| func Run(ctx context.Context, cfg *config.Config) error { | ||
| slog.Info("Starting GWI application...") | ||
|
|
||
| db, err := setupDatabase(cfg.Database) |
There was a problem hiding this comment.
What would be the benefit of not initializing the database here, but pass it as an argument to the run function?
There was a problem hiding this comment.
🤔 It would give better testability by giving the opportunity to inject a mock database.
|
|
||
| favorite.ID = 0 // Ensure ID is zero (default value) for insertion | ||
|
|
||
| return s.favoriteRepository.Insert(ctx, favorite) |
There was a problem hiding this comment.
What happens to the insert if the user closes the connection with the server?
There was a problem hiding this comment.
A context cancellation will occur and if it is before or during the database operation execution, then it will not be performed and an error context.Canceled will be returned. In this case it will also log user info and will return an error InternalServerError in the application layer, which is not correct, should return (and handle) a different type of error. If context cancellation occurs after the database write completes, then the data will be stored in the database and the connection will close before the success response reaches the client.
|
Hi @alesr, thank you very much for your review, appreciate it!! 😊 😄 😄 |
GWI Favorites Asset Service - Implementation
Overview
This PR implements a user favorites management system for the GWI platform, allowing users to manage personalized lists of favorite assets (Charts, Insights, and Audiences) through a RESTful API.
🚀 Features Implemented
Core API Endpoints
GET /favorite/- Retrieve all user favoritesPOST /favorite/{aid}- Add asset to favoritesPATCH /favorite/{id}- Update favorite descriptionDELETE /favorite/{id}- Remove from favoritesDatabase & Persistence
🔧 Technical Implementation
Technology Stack
Testing Strategy
📁 Project Structure