Files
kooltab-backoffice/docs/flutter-planned-tabs-prompt.md
T
2026-10-08 00:25:30 +02:00

4.2 KiB

KoolTap Flutter App — Planned Tab Sync

Add support for planned tab names that are synced from the server. The server now returns a plannedTabNames list in the sync response. The app should create open tabs for any planned names that don't already have an open tab.

Background

The dashboard admin can manage a list of "planned customers" (e.g. "Jan", "Marie", "Thomas"). These names are sent to the device in every sync response. The device should ensure those tabs exist — creating new ones if a planned name doesn't already have an open tab.

Existing Files (read these first)

  • lib/models/remote_command.dart — contains SyncResponse, RemoteCommand, SnapshotTab, etc.
  • lib/services/remote_sync_service.dart — the sync loop that processes the sync response
  • lib/services/bar_tab_service.dart — creates and manages tabs (has createTab(String customerName))
  • lib/models/bar_tab.dart — the BarTab model
  • lib/database/app_database.dart — the Drift database schema
  • lib/viewmodels/remote_sync_view_model.dart — wraps the sync service as ChangeNotifier
  • lib/utils/app_config.dart — server URL constant

What to Change

1. Update SyncResponse model

In lib/models/remote_command.dart, add plannedTabNames to the existing SyncResponse class (it already exists — add the field):

class SyncResponse {
  final String cursor;
  final List<RemoteCommand> commands;
  final List<String> plannedTabNames;   // ← add this

  SyncResponse({
    required this.cursor,
    required this.commands,
    required this.plannedTabNames,       // ← add this
  });

  factory SyncResponse.fromJson(Map<String, dynamic> json) => SyncResponse(
    cursor: json['cursor'] as String,
    commands: (json['commands'] as List)
        .map((e) => RemoteCommand.fromJson(e as Map<String, dynamic>))
        .toList(),
    plannedTabNames: (json['plannedTabNames'] as List?)       // ← add this
        ?.map((e) => e as String)
        .toList() ?? [],
  );
}

2. Process planned names in the sync service

In lib/services/remote_sync_service.dart, inside the _performSync() method (or wherever the sync response is handled), add logic to process plannedTabNames after commands are processed but before updating the cursor.

The logic:

// After processing commands and before updating cursor:
// Ensure planned tabs exist
for (final name in response.plannedTabNames) {
  final hasOpenTab = openTabs.any((t) => t.customerName == name);
  if (!hasOpenTab) {
    await barTabService.createTab(name);
  }
}
// Also: if a tab is open for a customer NOT in plannedTabNames,
// should we close it? Probably not — just leave it.

Where openTabs is the list of currently open tabs (already available from barTabService.getOpenTabs() or similar). Look for getOpenTabs() in BarTabService or access the local database.

3. Handle the first sync (no existing tabs)

On first sync, the device might have zero open tabs and receive a list of planned names. The code should create tabs for all planned names.

Important Notes

  • BarTabService.createTab(String customerName) already exists — it opens a new tab with version 1. Call it directly.
  • Do NOT close existing tabs that aren't in the planned list — planned tabs are additive only
  • If a planned name already has an open tab (same customerName), skip creating it
  • The sync service already tracks openTabs — it sends them in the SyncRequest via SnapshotTab. You can get the current open tabs from the local database using BarTabService.getOpenTabs() or BarTabService.openTabs stream
  • This logic should run inside the existing sync loop, after processing commands but before saving the cursor

Testing

  • Add "Jan" and "Marie" as planned names in the dashboard
  • Run a sync on the Flutter app — tabs for "Jan" and "Marie" should appear
  • Remove "Jan" from planned names and re-sync — the "Jan" tab should NOT be closed (planned tabs are additive only)
  • Add a new name "Thomas" — a new tab should appear on next sync

Files to Modify

  • lib/models/remote_command.dart — add plannedTabNames field to SyncResponse
  • lib/services/remote_sync_service.dart — add planned tab creation logic in sync loop