Files
2026-07-27 14:42:23 +02:00

61 lines
2.2 KiB
Dart

import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../../core/models/models.dart';
import '../../core/network/api_client_provider.dart';
import '../../core/network/node_master_api_client.dart';
import '../../core/polling/polling_async_notifier.dart';
part 'nodes_repository.g.dart';
/// Wraps the `/nodes/*` endpoints — the registry of sibling NodeMaster
/// hosts and the server-side fan-out status view.
class NodesRepository {
const NodesRepository(this._client);
final NodeMasterApiClient _client;
Future<List<RemoteNode>> getAll() => _client.getAllRemoteNodes();
Future<RemoteNode> get(String id) => _client.getRemoteNode(id);
Future<RemoteNode> add(RemoteNode node) => _client.addRemoteNode(node);
Future<RemoteNode> update(String id, RemoteNode node) => _client.updateRemoteNode(id, node);
Future<void> delete(String id) => _client.deleteRemoteNode(id);
Future<List<AggregatedNodeStatus>> getAggregated() => _client.getAggregated();
}
/// Null when no connection is active, mirroring [apiClientProvider].
@riverpod
NodesRepository? nodesRepository(Ref ref) {
final client = ref.watch(apiClientProvider);
if (client == null) return null;
return NodesRepository(client);
}
/// The registered-nodes list. Manual-refresh only, same reasoning as
/// `servicesListProvider` — this backs Fleet's registry table (M6).
@riverpod
Future<List<RemoteNode>> remoteNodesList(Ref ref) async {
final repo = ref.watch(nodesRepositoryProvider);
if (repo == null) return [];
return repo.getAll();
}
/// The live `/nodes/aggregated` fan-out result, polled every 25s. Shared
/// by the Dashboard's "Fleet" stat tile and the Fleet screen's card grid
/// (M6) — one poll, cached by Riverpod, rather than each screen running
/// its own duplicate timer against the same endpoint.
@riverpod
class AggregatedNodes extends _$AggregatedNodes with PollingMixin<List<AggregatedNodeStatus>> {
@override
Duration get interval => const Duration(seconds: 25);
@override
Future<List<AggregatedNodeStatus>> fetch() async {
final repo = ref.watch(nodesRepositoryProvider);
if (repo == null) return [];
return repo.getAggregated();
}
@override
Future<List<AggregatedNodeStatus>> build() => startPolling();
}