Backend: Extend ProfileService for Dashboard Deck Categorization
This is a one week ticket
Task
This ticket focuses on extending profileService.ts to support all backend data operations required for the Dashboard scrolling containers (Recent, Up Next, and Completed).
The goal is to store and retrieve deck progress information for each profile, making it possible for the frontend Dashboard to categorize decks and display them in the correct sections.
This ticket is backend-only — no UI changes or rendering logic are needed yet.
Implementation Requirements
1. Extend Deck Progress Data Structure
Update the DeckProgress structure in profileService.ts to include all data necessary for categorization:
{
viewedCardIds: number[];
viewedCount: number;
totalCount: number;
lastOpenedAt?: string; // Tracks when the user last opened a deck
completedAt?: string; // Timestamp when deck is completed
}
Each profile’s progress object should map deckId → DeckProgress.
This structure will be stored in AsyncStorage under the "profiles" key.
2. Add New AsyncStorage Utility Functions
Implement the following backend functions in profileService.ts:
updateDeckProgress(profileId: number, deckId: string, updates: Partial)
- Retrieves the current profile from AsyncStorage.
- Updates or initializes the progress[deckId] entry with new data.
- Always updates lastOpenedAt to new Date().toISOString() when a deck is opened.
- Automatically sets completedAt if viewedCount >= totalCount.
- Persists changes back to AsyncStorage.
getCategorizedDecks(profileId: number, allDecks: Deck[])
- Reads the profile’s progress data from AsyncStorage.
- Returns an object grouping decks into three arrays:
- recent: decks that have been started (viewedCount > 0) but not yet completed, sorted by lastOpenedAt (most recent first).
- upNext: decks that have never been opened (viewedCount === 0 or no progress entry).
- completed: decks that have viewedCount >= totalCount.
getProfileProgress(profileId: number)
- Returns the raw progress object for a given profile.
- Used internally by other components or services to retrieve the current profile’s deck progress.
3. Data Persistence Rules
- All profile and progress data should be saved in AsyncStorage under the "profiles" key.
- When a deck is opened or a card is viewed, updateDeckProgress() should update the corresponding deck progress entry.
- Each profile should maintain its own independent progress data.
Example of stored profile data:
{
"id": 1,
"name": "Ava",
"createdAt": "2025-10-26T13:45:00.000Z",
"lastActiveAt": "2025-11-05T18:12:00.000Z",
"progress": {
"deck_0": {
"viewedCardIds": [0, 1, 2],
"viewedCount": 3,
"totalCount": 5,
"lastOpenedAt": "2025-11-05T17:00:00.000Z"
},
"deck_1": {
"viewedCardIds": [5, 6],
"viewedCount": 5,
"totalCount": 5,
"completedAt": "2025-10-30T13:40:00.000Z"
}
}
}
4. Integration with Existing Functions
- Ensure updateDeckProgress() updates only the selected profile and not others.
- Verify that getCategorizedDecks() uses the existing act_safety_decks.json data to determine available decks.
Set up
- Open services/profileService.ts.
- Extend the DeckProgress type with lastOpenedAt and completedAt.
- Implement updateDeckProgress(), getCategorizedDecks(), and getProfileProgress() functions.
- Ensure all functions read and write through AsyncStorage using the "profiles" key.
Acceptance Criteria
Resources
Backend: Extend ProfileService for Dashboard Deck Categorization
This is a one week ticket
Task
This ticket focuses on extending
profileService.tsto support all backend data operations required for the Dashboard scrolling containers (Recent, Up Next, and Completed).The goal is to store and retrieve deck progress information for each profile, making it possible for the frontend Dashboard to categorize decks and display them in the correct sections.
This ticket is backend-only — no UI changes or rendering logic are needed yet.
Implementation Requirements
1. Extend Deck Progress Data Structure
Update the
DeckProgressstructure inprofileService.tsto include all data necessary for categorization:Each profile’s progress object should map deckId → DeckProgress.
This structure will be stored in AsyncStorage under the "profiles" key.
2. Add New AsyncStorage Utility Functions
Implement the following backend functions in profileService.ts:
updateDeckProgress(profileId: number, deckId: string, updates: Partial)
getCategorizedDecks(profileId: number, allDecks: Deck[])
getProfileProgress(profileId: number)
3. Data Persistence Rules
Example of stored profile data:
4. Integration with Existing Functions
Set up
Acceptance Criteria
Resources