Files
geutebruck/geutebruck_app/OFFLINE_FIRST_SETUP.md
Administrator 14893e62a5 feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP
This MVP release provides a complete full-stack solution for managing action mappings
in Geutebruck's GeViScope and GeViSoft video surveillance systems.

## Features

### Flutter Web Application (Port 8081)
- Modern, responsive UI for managing action mappings
- Action picker dialog with full parameter configuration
- Support for both GSC (GeViScope) and G-Core server actions
- Consistent UI for input and output actions with edit/delete capabilities
- Real-time action mapping creation, editing, and deletion
- Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers)

### FastAPI REST Backend (Port 8000)
- RESTful API for action mapping CRUD operations
- Action template service with comprehensive action catalog (247 actions)
- Server management (G-Core and GeViScope servers)
- Configuration tree reading and writing
- JWT authentication with role-based access control
- PostgreSQL database integration

### C# SDK Bridge (gRPC, Port 50051)
- Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll)
- Action mapping creation with correct binary format
- Support for GSC and G-Core action types
- Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug)
- Action ID lookup table with server-specific action IDs
- Configuration reading/writing via SetupClient

## Bug Fixes
- **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet
- Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)`
- Proper filter flags and VideoInput=0 for action mappings
- Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft)

## Technical Stack
- **Frontend**: Flutter Web, Dart, Dio HTTP client
- **Backend**: Python FastAPI, PostgreSQL, Redis
- **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK
- **Authentication**: JWT tokens
- **Configuration**: GeViSoft .set files (binary format)

## Credentials
- GeViSoft/GeViScope: username=sysadmin, password=masterkey
- Default admin: username=admin, password=admin123

## Deployment
All services run on localhost:
- Flutter Web: http://localhost:8081
- FastAPI: http://localhost:8000
- SDK Bridge gRPC: localhost:50051
- GeViServer: localhost (default port)

Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 18:10:54 +01:00

7.4 KiB

Offline-First Architecture Setup Guide

Overview

The Flutter app has been upgraded to use an offline-first architecture with local persistence using Hive. This means:

Instant UI updates - All CRUD operations update local storage first Offline capable - Edit servers without network connection Explicit sync - Changes are synced to the server only when you press the sync button Conflict tracking - Unsaved changes are tracked with a dirty count indicator Cross-platform - Works on Web, Windows Desktop, Mobile (Hive supports all platforms)

Setup Steps

1. Install Dependencies

cd C:\DEV\COPILOT\geutebruck_app
flutter pub get

2. Generate Hive Type Adapters

flutter packages pub run build_runner build --delete-conflicting-outputs

This generates server_hive_model.g.dart with the Hive type adapter.

3. Run the Development Server

Option A: Using the new dev script (with hot reload):

.\dev-run.bat

Then:

  • Press r for hot reload (instant updates)
  • Press R for hot restart
  • Press q to quit

Option B: Traditional way:

flutter run -d chrome --web-port 8081

Architecture Changes

Data Flow

Old Architecture (Direct API):

UI → BLoC → Repository → API → Database
     ↓
   State

New Architecture (Local-First):

UI → BLoC → Repository → Local Storage (Hive)
     ↓                           ↓
   State                    Dirty Flag
                                 ↓
                          Sync Button Pressed
                                 ↓
                          Sync Service → API → Database
                                 ↓
                          Clear Dirty Flags

Key Components

  1. ServerHiveModel (lib/data/models/server_hive_model.dart)

    • Hive-compatible model with sync tracking
    • Fields: isDirty, syncOperation, lastModified
  2. ServerLocalDataSource (lib/data/data_sources/local/server_local_data_source.dart)

    • Manages Hive box operations
    • Handles dirty server tracking
    • Soft deletes for sync
  3. SyncService (lib/data/services/sync_service.dart)

    • Syncs dirty servers to API
    • Downloads fresh data from API
    • Conflict resolution
  4. ServerRepository (lib/data/repositories/server_repository_impl.dart)

    • Local-first CRUD operations
    • Sync operations
    • Dirty count tracking
  5. ServerBloc (lib/presentation/blocs/server/server_bloc.dart)

    • New events: SyncServersEvent, DownloadServersEvent, CheckDirtyCountEvent
    • New states: ServerSyncing, ServerSyncSuccess, ServerDownloading

UI Features

Servers Management Screen

Sync Button (AppBar)

  • Shows red badge with dirty count
  • Disabled when no changes to sync
  • Tooltip shows number of unsaved changes

Download Button (AppBar)

  • Cloud download icon
  • Fetches latest data from server
  • Preserves local unsaved changes

Server Cards

  • No visual changes (existing UI)
  • Operations are now instant

User Workflow

Creating a Server

  1. Click "Add Server" button
  2. Choose G-Core or GeViScope
  3. Fill in the form
  4. Click "Create Server"
  5. Server is saved locally with isDirty=true and syncOperation='create'
  6. 🔴 Sync button shows "1" badge
  7. Click sync button when ready
  8. Server is created on GeViServer via API
  9. Dirty flag is cleared

Editing a Server

  1. Click edit icon on a server
  2. Modify fields
  3. Click "Update Server"
  4. Server is updated locally with isDirty=true and syncOperation='update'
  5. 🔴 Sync button shows dirty count
  6. Click sync button when ready
  7. Server is updated on GeViServer via API
  8. Dirty flag is cleared

Deleting a Server

  1. Click delete icon on a server
  2. Confirm deletion
  3. Server is marked as deleted locally (soft delete with syncOperation='delete')
  4. Server disappears from list
  5. 🔴 Sync button shows dirty count
  6. Click sync button when ready
  7. Server is deleted from GeViServer via API
  8. Server record is permanently removed from local storage

Syncing Changes

Manual Sync:

  • Click the sync button in the AppBar
  • All dirty servers are synced sequentially
  • Success message shows count of synced items
  • Errors are reported individually

Download/Refresh:

  • Click the cloud download button
  • Fetches all servers from API
  • Replaces local data (except dirty servers)
  • Dirty servers are preserved for later sync

Development Tips

Hot Reload

With dev-run.bat, you get instant feedback:

  • Save a .dart file
  • Press r in the terminal
  • Changes appear instantly without losing app state

Debugging Hive

View Hive data:

// In your code, temporarily add:
final box = await Hive.openBox<ServerHiveModel>('servers');
print('All servers: ${box.values.toList()}');
print('Dirty servers: ${box.values.where((s) => s.isDirty).toList()}');

Clear all local data:

// In your code, temporarily add:
final box = await Hive.openBox<ServerHiveModel>('servers');
await box.clear();

Or use the download button to replace all data from the server.

Testing Offline Functionality

  1. Start app and load servers (downloads from API)
  2. Disconnect network (disable WiFi or unplug)
  3. Create/Edit/Delete servers (works offline!)
  4. Reconnect network
  5. Click sync button (pushes all changes)

Troubleshooting

Issue: "Bad state: Type ServerHiveModelAdapter not registered"

Solution: Run the code generator:

flutter packages pub run build_runner build --delete-conflicting-outputs

Issue: "MissingPluginException(No implementation found for method...)"

Solution: Restart the app completely (not hot reload):

  • Stop the running app (Ctrl+C)
  • Run .\dev-run.bat again

Issue: Sync button not showing dirty count

Solution: Trigger a reload by navigating away and back, or check that the BLoC is emitting states correctly.

Issue: "Failed to load servers"

Cause: No data in local storage yet

Solution: Click the download button to fetch servers from the API

Performance Benefits

  • Instant operations: Create/Update/Delete is instantaneous (no network wait)
  • Reduced API calls: Only sync when explicitly requested
  • Better UX: Users can edit multiple servers before syncing
  • Offline capable: Works without internet connection
  • Reduced server load: Batch operations instead of individual API calls

Future Windows Desktop Port

The architecture is ready for Windows desktop:

  • Hive works on Windows desktop
  • All dependencies are cross-platform
  • No web-specific code

When porting to Windows:

  1. Add Windows as a target platform
  2. Run the same code
  3. Hive will use native Windows storage

Next Steps

  1. Test the flow:

    • Create a server
    • Edit it
    • Check dirty count
    • Sync it
    • Download from server
  2. Consider enhancements:

    • Auto-sync on app close
    • Sync interval (e.g., every 5 minutes)
    • Conflict resolution UI (if server data changed)
    • Undo/redo for local changes
  3. Port to Windows:

    • Add windows directory
    • Run flutter run -d windows
    • Same codebase, native Windows app

Summary

You now have a production-ready offline-first architecture that:

  • Works instantly on the client side
  • Syncs explicitly to the server
  • Tracks unsaved changes
  • Works offline
  • Ready for Windows desktop

Enjoy the speed! 🚀