Conversation
WalkthroughThe integration of PUBG API support enhances the application by incorporating PUBG data alongside existing features. This update includes adding environment variables, configuring settings, and implementing new functionality across various components like the API, parser, and frontend. It introduces a new PUBG client, updates caching mechanisms for PUBG data, and extends the database schema to accommodate PUBG integrations. Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
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 as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Review Status
Actionable comments generated: 7
Configuration used: CodeRabbit UI
Files ignored due to path filters (10)
apps/api/go.modis excluded by:!**/*.modapps/api/go.sumis excluded by:!**/*.sumapps/parser/go.modis excluded by:!**/*.modapps/parser/go.sumis excluded by:!**/*.sumfrontend/dashboard/src/assets/integrations/pubg.svgis excluded by:!**/*.svgfrontend/dashboard/src/locales/en.jsonis excluded by:!**/*.jsongo.workis excluded by:!**/*.workgo.work.sumis excluded by:!**/*.sumlibs/pubg/go.modis excluded by:!**/*.modlibs/pubg/go.sumis excluded by:!**/*.sum
Files selected for processing (30)
- .env.example (1 hunks)
- apps/api/app/app.go (3 hunks)
- apps/api/internal/impl_protected/impl_protected.go (3 hunks)
- apps/api/internal/impl_protected/integrations/integrations.go (1 hunks)
- apps/api/internal/impl_protected/integrations/pubg.go (1 hunks)
- apps/parser/cmd/main.go (3 hunks)
- apps/parser/internal/cacher/cacher.go (3 hunks)
- apps/parser/internal/cacher/pubg.go (1 hunks)
- apps/parser/internal/types/pubg_api.go (1 hunks)
- apps/parser/internal/types/services/services.go (2 hunks)
- apps/parser/internal/types/variables_cacher.go (2 hunks)
- apps/parser/internal/variables/pubg/lifetime/duo.go (1 hunks)
- apps/parser/internal/variables/pubg/lifetime/solo.go (1 hunks)
- apps/parser/internal/variables/pubg/lifetime/squad.go (1 hunks)
- apps/parser/internal/variables/pubg/season/duo.go (1 hunks)
- apps/parser/internal/variables/pubg/season/solo.go (1 hunks)
- apps/parser/internal/variables/pubg/season/squad.go (1 hunks)
- apps/parser/internal/variables/variables.go (2 hunks)
- frontend/dashboard/src/api/integrations/index.ts (1 hunks)
- frontend/dashboard/src/api/integrations/pubg.ts (1 hunks)
- frontend/dashboard/src/components/integrations/pubg.vue (1 hunks)
- frontend/dashboard/src/pages/Integrations.vue (2 hunks)
- libs/api/api.proto (2 hunks)
- libs/api/messages/integrations_pubg/integrations_pubg.proto (1 hunks)
- libs/config/config.go (2 hunks)
- libs/config/src/index.js (1 hunks)
- libs/gomodels/integrations.go (1 hunks)
- libs/migrations/migrations/20240315145552_pubg_integration.sql (1 hunks)
- libs/migrations/seeds/integrations.go (1 hunks)
- libs/pubg/pubg.go (1 hunks)
Files skipped from review due to trivial changes (1)
- apps/parser/internal/variables/pubg/season/duo.go
Additional comments: 35
frontend/dashboard/src/api/integrations/index.ts (1)
- 6-6: The addition of the PUBG integration export (
export * from './pubg.js';) is correctly implemented and aligns with the PR's objectives to integrate PUBG API functionality into the application.libs/migrations/migrations/20240315145552_pubg_integration.sql (1)
- 1-10: The SQL migration for adding the
PUBGvalue to theintegrations_service_enumtype is correctly implemented. However, it's worth noting that the down migration does not remove the added enum value, which is a common practice due to the complexity of altering enum types in PostgreSQL. Consider adding a comment to clarify this decision for future maintainers.libs/api/messages/integrations_pubg/integrations_pubg.proto (1)
- 1-11: The protobuf definitions for PUBG integrations are correctly implemented and align with the PR's objectives. While the current structures are sufficient for handling nicknames, consider planning for future expansions that might require more complex data structures.
apps/parser/internal/types/pubg_api.go (1)
- 1-18: The Go structures defined for handling PUBG data are well-structured and seem to align with the expected data from the PUBG API. Ensure that these structures remain aligned with the PUBG API data and consider the stability and updates of the third-party library
github.com/NovikovRoman/pubgused here.frontend/dashboard/src/api/integrations/pubg.ts (1)
- 1-27: The Vue.js composition API hooks for PUBG integration are correctly implemented and align with the PR's objectives. Consider adding error handling for the API calls to improve the user experience in case of failures or issues with the PUBG API.
.env.example (1)
- 46-46: The addition of the
PUBG_API_KEYSenvironment variable is correctly implemented and essential for the PUBG API integration, allowing the application to utilize multiple API keys. This is a crucial addition for managing API rate limits effectively.apps/parser/internal/variables/pubg/lifetime/squad.go (1)
- 30-30: The game mode
SquadFPPModeis hardcoded. Consider making this configurable to easily extend support for other game modes in the future.apps/parser/internal/types/services/services.go (1)
- 36-36: LGTM! Consider adding documentation for the
PubgClientfield to explain its purpose and usage within the application.apps/parser/internal/variables/pubg/lifetime/duo.go (1)
- 34-34: The game mode
DuoFPPModeis hardcoded. Consider making this configurable to easily extend support for other game modes in the future.apps/parser/internal/types/variables_cacher.go (1)
- 31-32: LGTM! Consider adding documentation for the new methods
GetPubgLifetimeDataandGetPubgCurrentSeasonto explain their purpose and expected return values.libs/config/src/index.js (1)
- 37-37: LGTM! Consider adding documentation for the
PUBG_API_KEYconfiguration parameter to explain its purpose and how to obtain a valid key.frontend/dashboard/src/components/integrations/pubg.vue (1)
- 20-34: Consider adding a loading state to the component to provide feedback to the user during data fetching and updates. This can improve the user experience by indicating that an operation is in progress.
libs/gomodels/integrations.go (1)
- 47-47: The addition of
IntegrationServicePubgconstant is correctly implemented and follows the existing naming convention for integration services. This change is necessary for supporting PUBG integration throughout the application.apps/api/internal/impl_protected/integrations/integrations.go (1)
- 15-15: The addition of the
PubgClientfield to theIntegrationsstruct is correctly implemented. This change enables the application to utilize the PUBG client for fetching player statistics. Ensure that thepubg.Clientis properly initialized elsewhere in the application to avoid nil pointer dereferences.frontend/dashboard/src/pages/Integrations.vue (2)
- 12-12: The import of the
Pubgcomponent is correctly added, following the existing pattern for integrating components. This change is necessary for displaying the PUBG integration option on theIntegrations.vuepage.- 59-61: The addition of the
Pubgcomponent to the grid layout is correctly implemented, ensuring that PUBG integration is displayed alongside other integrations. This enhances the user interface by providing users with the option to integrate PUBG statistics.apps/parser/internal/cacher/pubg.go (1)
- 13-29: The implementation of
GetPubgCurrentSeasonfunction correctly fetches and caches the current PUBG season. The use of mutex locks ensures thread safety during cache access and update. This is a good practice for managing shared resources in concurrent environments.apps/parser/internal/cacher/cacher.go (2)
- 31-33: The addition of synchronization mutexes for PUBG data (
pubgLifetimeDataandpubgCurrentSeason) is correctly implemented. This ensures thread-safe access to PUBG-related cache data, which is crucial for concurrent processing.- 53-55: The introduction of cache structures for PUBG (
pubgLifetimeDataandpubgCurrentSeason) is correctly done, following the existing pattern for caching game data. This facilitates efficient data retrieval and management for PUBG player statistics.libs/config/config.go (1)
- 49-49: The addition of the
PubgApiKeysfield to theConfigstruct is correctly implemented, allowing the application to support multiple API keys for the PUBG API. This is a crucial feature for managing API rate limits effectively.apps/api/app/app.go (1)
- 135-138: The initialization of the
pubg.Clientusing a Redis store is correctly implemented. This setup allows for efficient caching and management of PUBG data, addressing potential API rate limit challenges. Ensure that the Redis client is properly configured and that thePubgApiKeysare securely managed.apps/parser/internal/variables/pubg/lifetime/solo.go (5)
- 13-41: The implementation of
LifetimeKDSolovariable and its handler function correctly calculates the K/D ratio for solo game mode. This is a valuable statistic for players, and the calculation method is accurate. Ensure that division by zero is handled appropriately to avoid runtime errors.- 43-71: The
LifetimeWinsSolovariable and its handler function are correctly implemented to calculate the number of wins in solo game mode. This statistic is straightforward and correctly utilizes the PUBG API data.- 73-101: The
LifetimeMaxKillsSolovariable correctly calculates the maximum number of kills in a single solo game. This statistic is an interesting metric for players to track their performance. The implementation follows the established pattern and correctly uses the PUBG API data.- 103-131: The
LifetimeWinrateSolovariable and its handler function correctly calculate the winrate in solo game mode. This is an important statistic for evaluating player performance. Ensure that division by zero is handled to avoid potential runtime errors.- 133-161: The
LifetimeAverageDamageSolovariable and its handler function correctly calculate the average damage dealt in solo game mode. This statistic provides valuable insight into a player's offensive capabilities. The calculation method is accurate, and division by zero should be handled appropriately.apps/api/internal/impl_protected/impl_protected.go (3)
- 40-40: The import statement for the PUBG client library is correctly added and follows Go's convention for organizing imports alphabetically.
- 88-88: The addition of the
PubgClientfield to theOptsstruct is correctly implemented for dependency injection, following Go's best practices.- 109-109: The modification to include the PUBG client in the
Integrationsstruct initialization within theNewfunction is correctly implemented.apps/parser/cmd/main.go (2)
- 25-25: The import statement for the PUBG package is correctly added and follows Go's convention for organizing imports alphabetically.
- 152-155: The PUBG client initialization with a Redis store and error handling is correctly implemented. Using
logger.Fatalfor critical errors during initialization is appropriate.libs/pubg/pubg.go (1)
- 1-191: The implementation of the PUBG client library is well-done, with comprehensive error handling, retry logic, and caching mechanism. It correctly manages API keys, rate limiting, and data fetching from the PUBG API.
apps/parser/internal/variables/variables.go (1)
- 127-134: The addition of PUBG lifetime statistics variables to the parser's capabilities is correctly implemented, enhancing the application's ability to handle PUBG-related data.
libs/api/api.proto (2)
- 62-62: The import statement for
integrations_pubg.protois correctly added, following the convention for organizing imports in protobuf files.- 144-145: The addition of RPC methods
IntegrationsPubgGetandIntegrationsPubgPutto theProtectedservice is correctly implemented, enhancing the application's support for PUBG integrations.
|
|
||
| stats := data.Data.Attributes.GameModeStats[pubg.SquadFPPMode] | ||
|
|
||
| result.Result = fmt.Sprintf("%.2f", float64(stats.Kills)/float64(stats.Losses)) |
There was a problem hiding this comment.
Consider adding a check to ensure stats.Losses is not zero before performing division to avoid a potential division by zero error.
|
|
||
| stats := data.Data.Attributes.GameModeStats[pubg.DuoFPPMode] | ||
|
|
||
| result.Result = fmt.Sprintf("%.2f", float64(stats.Kills)/float64(stats.Losses)) |
There was a problem hiding this comment.
Consider adding a check to ensure stats.Losses is not zero before performing division to avoid a potential division by zero error.
| _, err := db.Query( | ||
| `INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
| "DONATEPAY", | ||
| ) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| _, err = db.Query( | ||
| `INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
| "VALORANT", | ||
| ) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| _, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "VALORANT") | ||
| _, err = db.Query( | ||
| `INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
| "DONATE_STREAM", | ||
| ) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| _, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "DONATE_STREAM") | ||
| _, err = db.Query( | ||
| `INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
| "DONATELLO", | ||
| ) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| _, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "DONATELLO") | ||
| _, err = db.Query( | ||
| `INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
| "PUBG", | ||
| ) |
There was a problem hiding this comment.
Consider refactoring the repetitive insertion queries to use a loop or a batch insertion method. This would improve maintainability and adhere to the DRY principle.
| func (c *Integrations) IntegrationsPubgGet( | ||
| ctx context.Context, _ *emptypb.Empty, | ||
| ) (*integrations_pubg.GetDataResponse, error) { | ||
| dashboardId := ctx.Value("dashboardId").(string) |
There was a problem hiding this comment.
Consider verifying the presence and type of dashboardId in the context before casting it to a string. This can prevent potential runtime panics if dashboardId is not present or not a string.
Also applies to: 37-37
| @@ -0,0 +1 @@ | |||
| package lifetime | |||
There was a problem hiding this comment.
The package is declared as package lifetime, which seems incorrect given the file's location and purpose (apps/parser/internal/variables/pubg/season/solo.go). It's likely that the package name should reflect its specific context, such as package season or a more specific name related to PUBG season statistics for solo play.
| @@ -0,0 +1 @@ | |||
| package lifetime | |||
There was a problem hiding this comment.
The package is declared as package lifetime, which seems incorrect given the file's location and purpose (apps/parser/internal/variables/pubg/season/squad.go). Consider renaming the package to better reflect its specific context, such as package season or a more specific name related to PUBG season statistics for squad play.
| func (c *cacher) GetPubgLifetimeData(ctx context.Context) (*pubg.LifetimeStatsPlayer, error) { | ||
| c.locks.pubgLifetimeData.Lock() | ||
| defer c.locks.pubgLifetimeData.Unlock() | ||
|
|
||
| if c.cache.pubgLifetimeData != nil { | ||
| return c.cache.pubgLifetimeData, nil | ||
| } | ||
|
|
||
| c.cache.pubgLifetimeData = &pubg.LifetimeStatsPlayer{} | ||
|
|
||
| if c.cache.pubgCurrentSeason == nil { | ||
| _, err := c.GetPubgCurrentSeason(ctx) | ||
| if err != nil { | ||
| c.services.Logger.Sugar().Error(err) | ||
| return nil, err | ||
| } | ||
| } | ||
|
|
||
| integrations := c.GetEnabledChannelIntegrations(ctx) | ||
|
|
||
| if integrations == nil { | ||
| return nil, errors.New("no enabled integrations") | ||
| } | ||
|
|
||
| integration, ok := lo.Find( | ||
| integrations, func(i *model.ChannelsIntegrations) bool { | ||
| return i.Integration.Service == "PUBG" && i.Enabled | ||
| }, | ||
| ) | ||
| if !ok { | ||
| return nil, errors.New("pubg integration not enabled") | ||
| } | ||
|
|
||
| userLifetimeStats, err := c.services.PubgClient.GetLifetimeStats( | ||
| ctx, | ||
| lo.FromPtr(integration.Data.UserId), | ||
| ) | ||
| if err != nil { | ||
| if errors.Is(err, tpubg.ErrOverloaded) { | ||
| return nil, tpubg.ErrOverloaded | ||
| } | ||
| if errors.Is(err, tpubg.ErrPubg) { | ||
| return nil, tpubg.ErrPubg | ||
| } | ||
|
|
||
| c.services.Logger.Sugar().Error(err) | ||
| return nil, errors.Unwrap(err) | ||
| } | ||
| c.cache.pubgLifetimeData = userLifetimeStats | ||
|
|
||
| return c.cache.pubgLifetimeData, nil | ||
| } |
There was a problem hiding this comment.
The GetPubgLifetimeData function correctly fetches and caches PUBG player lifetime stats. It demonstrates proper error handling and logging, and efficiently reuses the GetPubgCurrentSeason function to ensure the current season is available. Consider adding more detailed error messages to improve debugging and user feedback.
- result.Result = err.Error()
+ result.Result = "Failed to fetch PUBG lifetime data: " + err.Error()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.
| func (c *cacher) GetPubgLifetimeData(ctx context.Context) (*pubg.LifetimeStatsPlayer, error) { | |
| c.locks.pubgLifetimeData.Lock() | |
| defer c.locks.pubgLifetimeData.Unlock() | |
| if c.cache.pubgLifetimeData != nil { | |
| return c.cache.pubgLifetimeData, nil | |
| } | |
| c.cache.pubgLifetimeData = &pubg.LifetimeStatsPlayer{} | |
| if c.cache.pubgCurrentSeason == nil { | |
| _, err := c.GetPubgCurrentSeason(ctx) | |
| if err != nil { | |
| c.services.Logger.Sugar().Error(err) | |
| return nil, err | |
| } | |
| } | |
| integrations := c.GetEnabledChannelIntegrations(ctx) | |
| if integrations == nil { | |
| return nil, errors.New("no enabled integrations") | |
| } | |
| integration, ok := lo.Find( | |
| integrations, func(i *model.ChannelsIntegrations) bool { | |
| return i.Integration.Service == "PUBG" && i.Enabled | |
| }, | |
| ) | |
| if !ok { | |
| return nil, errors.New("pubg integration not enabled") | |
| } | |
| userLifetimeStats, err := c.services.PubgClient.GetLifetimeStats( | |
| ctx, | |
| lo.FromPtr(integration.Data.UserId), | |
| ) | |
| if err != nil { | |
| if errors.Is(err, tpubg.ErrOverloaded) { | |
| return nil, tpubg.ErrOverloaded | |
| } | |
| if errors.Is(err, tpubg.ErrPubg) { | |
| return nil, tpubg.ErrPubg | |
| } | |
| c.services.Logger.Sugar().Error(err) | |
| return nil, errors.Unwrap(err) | |
| } | |
| c.cache.pubgLifetimeData = userLifetimeStats | |
| return c.cache.pubgLifetimeData, nil | |
| } |
There was a problem hiding this comment.
Actionable comments posted: 0
Review Status
Configuration used: CodeRabbit UI
Files ignored due to path filters (5)
apps/api/go.modis excluded by!**/*.mod,!**/*.modapps/api/go.sumis excluded by!**/*.sum,!**/*.sumapps/parser/go.modis excluded by!**/*.mod,!**/*.modfrontend/dashboard/src/locales/en.jsonis excluded by!**/*.jsongo.work.sumis excluded by!**/*.sum,!**/*.sum
Files selected for processing (5)
- apps/parser/internal/variables/variables.go (2 hunks)
- frontend/dashboard/src/api/integrations/index.ts (1 hunks)
- libs/api/api.proto (2 hunks)
- libs/gomodels/integrations.go (1 hunks)
- libs/migrations/seeds/integrations.go (1 hunks)
Additional Context Used
Additional comments not posted (6)
frontend/dashboard/src/api/integrations/index.ts (1)
6-6: The addition ofexport * from './pubg.js';aligns with the existing pattern for exporting integration modules. Ensure thatpubg.jsis correctly implemented and tested.libs/migrations/seeds/integrations.go (1)
51-57: Consider refactoring the repetitive insertion queries to use a loop or a batch insertion method. This would improve maintainability and adhere to the DRY principle. For now, the addition of the "PUBG" integration record is consistent with the existing pattern.libs/gomodels/integrations.go (1)
47-48: The addition ofIntegrationServicePubgconstant aligns with the existing pattern for defining integration services. Ensure that this new constant is correctly used wherever integration services are handled in the project.apps/parser/internal/variables/variables.go (1)
128-135: The addition of PUBG lifetime variables aligns with the existing pattern for defining and adding variables. Ensure that these variables are correctly implemented and tested in their respective files.libs/api/api.proto (2)
63-63: The addition ofimport "messages/integrations_pubg/integrations_pubg.proto";aligns with the existing pattern for extending the API with new integrations. Ensure that theintegrations_pubg.protofile is correctly implemented and tested.
152-153: The addition ofIntegrationsPubgGetandIntegrationsPubgPutRPC methods is consistent with the project's approach to extending the API. Ensure that these methods are correctly implemented and tested in the backend.
During watching PUBG pro players streams I realized that tons of people asking about their stats, so I decided to add integration with API. It has low limits (10 per minutes but response is complex) that's why I implemented support of multiple api keys and good ttl caching. Also PUBG is ready to expand limits.
The problem is that PUBG needs probably 30 variables about stats and it's to much for one game and only few is really needed. So, I just implemented some of them for testing purposes. Plus, there is maybe too complicated to create right command to show statistic and probably we need to provide default command for it.
Of course, I'm ready to give my api key for production.
Summary by CodeRabbit
New Features
Enhancements
Documentation
PUBG_API_KEYS.Database Changes
Bug Fixes