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— containsSyncResponse,RemoteCommand,SnapshotTab, etc.lib/services/remote_sync_service.dart— the sync loop that processes the sync responselib/services/bar_tab_service.dart— creates and manages tabs (hascreateTab(String customerName))lib/models/bar_tab.dart— theBarTabmodellib/database/app_database.dart— the Drift database schemalib/viewmodels/remote_sync_view_model.dart— wraps the sync service asChangeNotifierlib/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 theSyncRequestviaSnapshotTab. You can get the current open tabs from the local database usingBarTabService.getOpenTabs()orBarTabService.openTabsstream - 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— addplannedTabNamesfield toSyncResponselib/services/remote_sync_service.dart— add planned tab creation logic in sync loop