Skip to content

Dashboard Display Decks (1/2) #40

Description

@cwon33

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

  • DeckProgress structure includes lastOpenedAt and completedAt fields.
  • updateDeckProgress() successfully adds or updates a deck’s progress and timestamps in AsyncStorage.
  • When a deck’s viewedCount equals totalCount, completedAt is automatically set.
  • getCategorizedDecks() correctly returns three arrays: recent, upNext, and completed.
  • recent decks are sorted by most recent lastOpenedAt first.
  • upNext decks contain only unopened decks (no progress or viewedCount == 0).
  • completed decks include only fully finished decks (viewedCount >= totalCount).
  • Data persists correctly across app reloads and profile switches.
  • Functions are modular and ready for consumption by the frontend Dashboard.tsx.

Resources

Metadata

Metadata

Labels

No labels
No labels
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions