-
Notifications
You must be signed in to change notification settings - Fork 6
Add hideout progress endpoints for modules and parts #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add POST /progress/hideout/module/:moduleId endpoint for module completion tracking - Add POST /progress/hideout/part/:partId endpoint for part progress and item counts - Implement game mode support (pvp/pve/dual) for hideout progress - Add validation for hideout module IDs, part IDs, and update payloads - Add OpenAPI documentation for new hideout endpoints - Update ProgressService with hideout-specific update methods - Add hideout-relate
📝 WalkthroughWalkthroughThis pull request introduces two new HTTP endpoints ( Changes
Sequence DiagramsequenceDiagram
participant Client
participant Handler as updateHideoutModule<br/>Handler
participant Validator as ValidationService
participant Service as ProgressService
participant DB as Firestore
Client->>Handler: POST /api/progress/hideout/module/:moduleId<br/>{state: 'completed'}
Handler->>Handler: Extract & validate auth token
Handler->>Validator: validateHideoutModuleUpdate(body)
Validator-->>Handler: validated state
Handler->>Validator: validateModuleId(moduleId)
Validator-->>Handler: moduleId confirmed
Handler->>Handler: Determine gameMode<br/>(from token or query override)
Handler->>Service: updateHideoutModule(userId, moduleId,<br/>state, gameMode)
Service->>DB: Update user progress doc<br/>with module state & timestamp<br/>(scoped by gameMode)
DB-->>Service: Success
Service->>Service: Log success event
Service-->>Handler: Promise resolved
Handler->>Handler: Build ApiResponse
Handler-->>Client: 200 OK<br/>{moduleId, state, message}
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
functions/src/handlers/progressHandler.ts (1)
141-166: Consider validating gameMode query parameter for dual tokens.The handler correctly follows the established pattern for other progress endpoints. However, when
gameMode === 'dual', the query parameter is used directly without validating it's one of['pvp', 'pve']. An invalid value like?gameMode=invalidwould propagate to the service layer.This is a pre-existing pattern across all handlers (lines 325-328, 416-419, 498-501, 597-600), so it's not introduced by this PR. Consider addressing this in a follow-up for all endpoints.
If you choose to address this:
// Use token's game mode if specified, otherwise allow query parameter override (for dual tokens) let gameMode = req.apiToken?.gameMode || 'pvp'; if (gameMode === 'dual') { - gameMode = req.query.gameMode as string || 'pvp'; + const queryGameMode = req.query.gameMode as string; + gameMode = (queryGameMode === 'pvp' || queryGameMode === 'pve') ? queryGameMode : 'pvp'; }functions/src/services/ProgressService.ts (1)
14-16: Minor:HideoutModuleUpdateRequestis imported but unused.Only
HideoutModuleStatusis used in theupdateHideoutModulemethod signature (line 259). However, keeping the import may be intentional for completeness or future use, so this is a very minor observation.import { ProgressDocument, FormattedProgress, TaskStatus, MultipleTaskUpdateRequest, ObjectiveUpdateRequest, HideoutModuleStatus, - HideoutModuleUpdateRequest, HideoutPartUpdateRequest, ServiceOptions, TaskCompletion } from '../types/api.js';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
functions/src/handlers/progressHandler.ts(2 hunks)functions/src/index.ts(2 hunks)functions/src/services/ProgressService.ts(2 hunks)functions/src/services/ValidationService.ts(3 hunks)functions/src/types/api.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-25T16:14:25.438Z
Learnt from: CR
Repo: tarkovtracker-org/TarkovTracker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-25T16:14:25.438Z
Learning: Applies to functions/src/middleware/**/*.ts : Implement authentication and error handling as Express middleware under /functions/src/middleware/
Applied to files:
functions/src/index.ts
🧬 Code graph analysis (1)
functions/src/services/ProgressService.ts (2)
functions/src/types/api.ts (3)
HideoutModuleStatus(148-148)ProgressDocument(82-95)HideoutPartUpdateRequest(154-157)functions/src/middleware/errorHandler.ts (1)
errors(114-123)
🔇 Additional comments (13)
functions/src/types/api.ts (1)
147-157: LGTM!The new hideout types are well-defined and consistent with existing patterns (
TaskStatus,ObjectiveUpdateRequest). TheHideoutModuleStatuscorrectly excludes the 'failed' state since hideout modules don't have a failure concept, andHideoutPartUpdateRequestmirrors the existingObjectiveUpdateRequeststructure.functions/src/services/ValidationService.ts (4)
122-128: LGTM!The
validateHideoutModuleStatustype guard correctly narrows to theHideoutModuleStatusunion type using direct equality checks, which is consistent with how state validation is done inline invalidateHideoutPartUpdate.
130-151: LGTM!The
validateHideoutModuleUpdatemethod correctly mirrors the existingvalidateTaskUpdatepattern, with proper null/type checks and appropriate error messages.
153-184: LGTM!The
validateHideoutPartUpdatemethod mirrors the existingvalidateObjectiveUpdatepattern exactly, maintaining consistency across the codebase. Both state and count validation logic are correctly implemented with proper type narrowing and error messages.
196-214: LGTM!The
validateModuleIdandvalidatePartIdmethods follow the established patterns fromvalidateTaskIdandvalidateObjectiveId, with consistent null checks, type validation, and trimming behavior.functions/src/index.ts (2)
97-98: LGTM!The new hideout routes are correctly registered after the
verifyBearermiddleware (line 89), ensuring authentication is enforced. The route naming pattern (/progress/hideout/module/:moduleId) is consistent with existing progress routes.
118-119: LGTM!The v2 API routes mirror the non-v2 routes and point to the same handlers, maintaining consistency with how other endpoints are structured (e.g., lines 114-117 for task endpoints).
functions/src/handlers/progressHandler.ts (4)
76-140: OpenAPI documentation is comprehensive.The OpenAPI block correctly documents the endpoint, parameters, request body, and response schemas. The security requirement for
bearerAuthand the game mode query parameter documentation are accurate.
168-240: OpenAPI documentation for hideout part endpoint is accurate.The documentation correctly describes the optional nature of both
stateandcountfields, matching the validation logic that requires at least one to be provided.
241-266: LGTM!The
updateHideoutParthandler correctly mirrors the pattern fromupdateTaskObjective(lines 589-614), including spreadingupdateDatainto the response to return whichever fields were provided.
622-623: LGTM!The new handlers are correctly added to the default export, making them available for route registration.
functions/src/services/ProgressService.ts (2)
253-293: LGTM!The
updateHideoutModulemethod correctly mirrors the state-handling pattern fromupdateTaskObjective, with appropriate logging and error handling. The use ofFieldValue.delete()for the timestamp when uncompleting is consistent with existing behavior.
295-341: LGTM!The
updateHideoutPartmethod is a clean implementation that mirrorsupdateTaskObjective(lines 207-251). Both state and count updates are handled correctly, and the error handling follows established patterns.
|
Thank you for the PR I will check it and migrate it over to the new project since we are modularizing the functions and backend from the frontend and going to be deprecating the usage of firebase (Also this main branch is behind due to technical issues which will trigger a domino effect of lost fixes and features that got lost after deployment of the latest version so can't deploy this or merge without causing more issues to resurface.) |
Thanks for the explanation! I completely understand the situation regarding the migration/refactor and the state of the main branch. It sounds like a solid plan to move this over to the new project once it's ready. Please do tag me when the migration is stable enough, and I'll be happy to port these changes or reopen the PR there. Good luck with the migration! |
Summary
Fixes #163
This PR adds new API endpoints to manage hideout progression, mirroring the existing task progress API while keeping the current data model and conventions.
ProgressServiceto update hideout modules and parts in a game-mode-aware way./apiand/api/v2.Changes
1. API types
File:
functions/src/types/api.tsHideoutModuleStatus = 'completed' | 'uncompleted'HideoutModuleUpdateRequest { state: HideoutModuleStatus }HideoutPartUpdateRequest { state?: 'completed' | 'uncompleted'; count?: number }These mirror the existing
TaskStatus/TaskUpdateRequest/ObjectiveUpdateRequesttypes but for hideout modules and parts.2. ValidationService
File:
functions/src/services/ValidationService.tsvalidateHideoutModuleStatus(status)validateHideoutModuleUpdate(body)validateHideoutPartUpdate(body)validateModuleId(moduleId)validatePartId(partId)These follow the same patterns and error messages as:
validateTaskStatusvalidateTaskUpdatevalidateObjectiveUpdatevalidateTaskId/validateObjectiveId3. ProgressService
File:
functions/src/services/ProgressService.tsExtend imports from
../types/api.jsto include:HideoutModuleStatusHideoutModuleUpdateRequestHideoutPartUpdateRequestAdd methods:
updateHideoutModule(userId, moduleId, state, gameMode)${gameMode}.hideoutModules.${moduleId}.completed→complete = true,timestamp = now.uncompleted→complete = false,timestampdeleted.updateHideoutPart(userId, partId, update, gameMode)${gameMode}.hideoutParts.${partId}.stateis provided, togglescompleteandtimestampthe same way as task objectives.countis provided, updates${baseKey}.count.Both methods use the same logging and error patterns as
updateTaskObjective.4. HTTP handlers and OpenAPI
File:
functions/src/handlers/progressHandler.tsAdd handler:
updateHideoutModuleRoute:
POST /progress/hideout/module/{moduleId}Permission: requires
WP.Uses:
validateUserIdvalidateModuleIdvalidateHideoutModuleUpdateResolves
gameModethe same way asupdateSingleTask.Calls
progressService.updateHideoutModuleand returns:{ "success": true, "data": { "moduleId": "...", "state": "completed | uncompleted", "message": "Hideout module updated successfully" } }Includes a full
@openapiblock similar to the existing task update endpoint.Add handler:
updateHideoutPartRoute:
POST /progress/hideout/part/{partId}Permission: requires
WP.Uses:
validateUserIdvalidatePartIdvalidateHideoutPartUpdateSame
gameModeresolution as other progress endpoints.Calls
progressService.updateHideoutPartand returns:{ "success": true, "data": { "partId": "...", "state": "completed | uncompleted | undefined", "count": 0, "message": "Hideout part updated successfully" } }Includes a full
@openapiblock similar toupdateTaskObjective.Update the default export to include the two new handlers:
updateHideoutModuleupdateHideoutPart5. Route registration
File:
functions/src/index.tsUnder
/apiscope:POST /api/progress/hideout/module/:moduleId→progressHandler.updateHideoutModulePOST /api/progress/hideout/part/:partId→progressHandler.updateHideoutPartUnder
/api/v2scope:POST /api/v2/progress/hideout/module/:moduleId→progressHandler.updateHideoutModulePOST /api/v2/progress/hideout/part/:partId→progressHandler.updateHideoutPartThese mirror the existing task progress routes so that hideout progression can be managed in both API versions.
Rationale
hideoutModulesProgress,hideoutPartsProgress), but there was no public API to update this state in a controlled way.Notes
formatProgress), only to the write path./progress/hideout/{moduleId}instead of/progress/hideout/module/{moduleId}), I am happy to adjust the paths to match your naming conventions.