init: rough companion app stub

This commit is contained in:
2026-05-07 18:35:58 +02:00
commit 5f017ac05d
73 changed files with 3520 additions and 0 deletions
@@ -0,0 +1,6 @@
import '../../domain/models/floor_plan.dart';
abstract class FloorPlanRepository {
Future<FloorPlan?> getFloorPlan();
Future<FloorPlan> saveFloorPlan(FloorPlan plan);
}
@@ -0,0 +1,7 @@
import '../../domain/models/onboarding_status.dart';
abstract class OnboardingRepository {
Future<OnboardingStatus> getStatus();
/// Creates the first admin user and returns the issued JWT.
Future<String> createAdminUser({required String username, required String password});
}
@@ -0,0 +1,15 @@
import '../../domain/models/floor_plan.dart';
import '../sources/localiser/floor_client.dart';
import 'floor_plan_repository.dart';
class PhoenixFloorPlanRepository implements FloorPlanRepository {
const PhoenixFloorPlanRepository({required this.client});
final FloorClient client;
@override
Future<FloorPlan?> getFloorPlan() => throw UnimplementedError();
@override
Future<FloorPlan> saveFloorPlan(FloorPlan plan) => throw UnimplementedError();
}
@@ -0,0 +1,27 @@
import '../../domain/models/onboarding_status.dart';
import '../sources/localiser/onboarding_client.dart';
import 'onboarding_repository.dart';
class PhoenixOnboardingRepository implements OnboardingRepository {
const PhoenixOnboardingRepository({required this.client});
final OnboardingClient client;
@override
Future<OnboardingStatus> getStatus() async {
final checklist = await client.getChecklist();
if (!checklist.hasAdmin) return OnboardingStatus.notStarted;
if (!checklist.hasFloors) return OnboardingStatus.awaitingFloorPlan;
if (!checklist.hasSensorsPlaced) return OnboardingStatus.awaitingFirstSensor;
return OnboardingStatus.complete;
}
@override
Future<String> createAdminUser({
required String username,
required String password,
}) async {
final response = await client.setup(username, password);
return response.token;
}
}
@@ -0,0 +1,27 @@
import '../../domain/models/sensor.dart';
import '../../domain/models/position.dart';
import '../sources/localiser/sensor_client.dart';
import 'sensor_repository.dart';
class PhoenixSensorRepository implements SensorRepository {
const PhoenixSensorRepository({required this.client});
final SensorClient client;
@override
Future<List<Sensor>> getSensors() => throw UnimplementedError();
@override
Future<Sensor> getSensor(String id) => throw UnimplementedError();
@override
Future<Sensor> createSensor({required String name, required Position position}) =>
throw UnimplementedError();
@override
Future<Sensor> updateSensor(String id, {String? name, Position? position}) =>
throw UnimplementedError();
@override
Future<void> deleteSensor(String id) => throw UnimplementedError();
}
@@ -0,0 +1,37 @@
import '../../domain/models/tag.dart';
import '../../domain/models/particle.dart';
import '../sources/localiser/tag_client.dart';
import '../sources/localiser/realtime_data_client.dart';
import 'tag_repository.dart';
class PhoenixTagRepository implements TagRepository {
const PhoenixTagRepository({
required this.tagClient,
required this.realtime,
});
final TagClient tagClient;
final RealtimeDataClient realtime;
@override
Future<List<Tag>> getTags() => throw UnimplementedError();
@override
Future<Tag> getTag(String id) => throw UnimplementedError();
@override
Future<Tag> createTag({required String id, required String name}) =>
throw UnimplementedError();
@override
Future<Tag> updateTag(String id, {String? name}) => throw UnimplementedError();
@override
Future<void> deleteTag(String id) => throw UnimplementedError();
@override
Stream<List<TagPosition>> watchPositions() => throw UnimplementedError();
@override
Stream<List<Particle>> watchParticleCloud() => throw UnimplementedError();
}
@@ -0,0 +1,10 @@
import '../../domain/models/sensor.dart';
import '../../domain/models/position.dart';
abstract class SensorRepository {
Future<List<Sensor>> getSensors();
Future<Sensor> getSensor(String id);
Future<Sensor> createSensor({required String name, required Position position});
Future<Sensor> updateSensor(String id, {String? name, Position? position});
Future<void> deleteSensor(String id);
}
+16
View File
@@ -0,0 +1,16 @@
import '../../domain/models/tag.dart';
import '../../domain/models/particle.dart';
abstract class TagRepository {
Future<List<Tag>> getTags();
Future<Tag> getTag(String id);
Future<Tag> createTag({required String id, required String name});
Future<Tag> updateTag(String id, {String? name});
Future<void> deleteTag(String id);
/// Live stream of all tag positions, pushed by localiserd over Phoenix channel.
Stream<List<TagPosition>> watchPositions();
/// Live stream of particle filter cloud snapshots.
Stream<List<Particle>> watchParticleCloud();
}