Skip to content

Mini Dashboard: data layer (db, sync, API) #191

Description

@tfield

Mini Dashboard Data Layer

Parent: #76
Split from: #105
Blocked by: #89 (backend endpoint must exist first)
Blocks: the UI ticket (see #105 comments)

Overview

Add the IndexedDB store, sync function, and API wrapper needed for mini-dashboard data. This provides the data layer that the UI ticket consumes.

TypeScript Types

Add these to RavenEye/app/types/ (new file or existing as appropriate):

type Quartile = "top" | "upperMiddle" | "lowerMiddle" | "bottom" | "noData";

interface DashboardMetric {
  team: number;
  code: string;
  label: string;
  quartile: Quartile;
}

interface DashboardTeamData {
  teamNumber: number;
  matchesTracked: number;
  metrics: DashboardMetric[];
}

interface DashboardData {
  tournamentId: string;
  ownerTeam: number;
  teams: DashboardTeamData[];
}

interface MiniDashboardResponse {
  data: DashboardData | null;
  success: boolean;
  reason: string | null;
}

Requirements

New IndexedDB store

  • Add a new IndexedDB object store: miniDashboard (key path: tournamentId).
  • Each record stores the full API response from GET /api/report/mini-dashboard/{tournamentId}.
  • Add a repository method to read mini-dashboard data for a given tournament.
  • Bump DB_VERSION in db.ts.

API wrapper

Add to rb.ts:

export async function getMiniDashboard(tournamentId: string): Promise<DashboardData> {
  return rbfetch(`/api/report/mini-dashboard/${tournamentId}`)
    .then((resp) => {
      if (!resp.ok) throw new Error(`Failed to fetch mini-dashboard: ${resp.status}`);
      return resp.json();
    })
    .then((json: MiniDashboardResponse) => {
      if (!json.success) throw new Error(json.reason ?? "Unknown error");
      return json.data!;
    });
}

Sync function

  • Add syncMiniDashboard() in sync.ts that:
    • Fetches from the backend endpoint for each recent tournament only (use the same tournament list as useRecentTournamentList()).
    • Stores the response in the miniDashboard store.
    • Updates the "Dashboard Data" sync status (replacing the current dummy in useDashboardDataSyncStatus()).
  • Include syncMiniDashboard() in the hourly doSync() cycle alongside the other config syncs.

Key files to modify

  • RavenEye/app/common/storage/db.ts — new miniDashboard store, bump DB_VERSION, new repository methods
  • RavenEye/app/common/storage/rb.ts — new getMiniDashboard(tournamentId) API wrapper
  • RavenEye/app/common/sync/sync.ts — new syncMiniDashboard(), replace dummy useDashboardDataSyncStatus()
  • RavenEye/app/types/ — new TypeScript types for dashboard data

Key files to reference

  • RavenEye/app/common/storage/db.ts — IndexedDB repository pattern (DB_VERSION, store creation in onupgradeneeded, get/put methods)
  • RavenEye/app/common/sync/sync.ts — sync orchestration: doSync() (line 72), useDashboardDataSyncStatus() dummy (lines 583-594), sync function pattern (e.g., syncRobotAlertList() lines 513-553)
  • RavenEye/app/common/storage/rb.ts — API wrapper pattern (e.g., getRobotAlertList())
  • RavenEye/app/common/storage/dbhooks.ts — existing hook patterns (useSyncStatus, useMatchSchedule, etc.)

Acceptance criteria

  • New miniDashboard IndexedDB store exists and is populated during sync
  • useDashboardDataSyncStatus() returns real sync status (not the dummy error)
  • Dashboard Data row on the sync page shows accurate status
  • syncMiniDashboard() is included in the doSync() hourly cycle
  • Only recent tournaments are synced (not all tournaments)
  • npm run typecheck passes with no errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    front-endIssue pertains almost entirely to the front-end

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions