Add app source and tests
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
440
lib/Peach/informatics/AppDataManager.dart
Normal file
440
lib/Peach/informatics/AppDataManager.dart
Normal file
@@ -0,0 +1,440 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../about/external/data/Docker.dart';
|
||||
import '../about/external/data/Health.dart';
|
||||
import '../about/external/data/Kafka.dart';
|
||||
import '../about/external/data/Redis.dart';
|
||||
import '../about/internal/application/DeploymentRecord.dart';
|
||||
import '../about/internal/application/ServerProfile.dart';
|
||||
import '../about/internal/application/ServiceConfig.dart';
|
||||
import '../about/internal/application/StepTracker.dart';
|
||||
import '../about/internal/file/BuildService.dart';
|
||||
import '../about/internal/file/ConnectFileStorage.dart';
|
||||
import '../comms/Comms.dart';
|
||||
import '../comms/ConnectComms.dart';
|
||||
import '../memory/ConnectInternalMemory.dart';
|
||||
import 'DataManager.dart';
|
||||
|
||||
/// The single concrete [DataManager], constructed once in `ParentViewModel` and
|
||||
/// shared by every screen. It holds no logic — it only forwards each call to
|
||||
/// whichever of the three collaborators owns it.
|
||||
class AppDataManager implements DataManager {
|
||||
final ConnectInternalMemory memory;
|
||||
final ConnectComms comms;
|
||||
final ConnectFileStorage files;
|
||||
|
||||
AppDataManager(this.memory, this.comms, this.files);
|
||||
|
||||
// ── memory ────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<List<ServerProfile>> getServers() => memory.getServers();
|
||||
|
||||
@override
|
||||
Future setServers(List<ServerProfile> servers) => memory.setServers(servers);
|
||||
|
||||
@override
|
||||
Future deleteServerSecret(String serverId) =>
|
||||
memory.deleteServerSecret(serverId);
|
||||
|
||||
@override
|
||||
Future<List<DeploymentRecord>> getDeployments() => memory.getDeployments();
|
||||
|
||||
@override
|
||||
Future<List<DeploymentRecord>> addDeployment(DeploymentRecord record) =>
|
||||
memory.addDeployment(record);
|
||||
|
||||
@override
|
||||
Future clearDeployments() => memory.clearDeployments();
|
||||
|
||||
@override
|
||||
Future<String> getThemeMode() => memory.getThemeMode();
|
||||
|
||||
@override
|
||||
Future setThemeMode(String mode) => memory.setThemeMode(mode);
|
||||
|
||||
// ── comms: session ────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
bool get isConnected => comms.isConnected;
|
||||
|
||||
@override
|
||||
bool get canRevert => comms.canRevert;
|
||||
|
||||
@override
|
||||
Stream<LogLine> get logs => comms.logs;
|
||||
|
||||
@override
|
||||
Stream<TransferProgress?> get transferProgress => comms.transferProgress;
|
||||
|
||||
@override
|
||||
Stream<List<DeployStep>> get stepStream => comms.stepStream;
|
||||
|
||||
@override
|
||||
Future<void> connect(ServerProfile s) => comms.connect(s);
|
||||
|
||||
@override
|
||||
void requestCancel() => comms.requestCancel();
|
||||
|
||||
@override
|
||||
void disconnect() => comms.disconnect();
|
||||
|
||||
@override
|
||||
void dispose() => comms.dispose();
|
||||
|
||||
// ── comms: deployment ─────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<DeployResult> deploy({
|
||||
required ServerProfile server,
|
||||
required ServiceConfig service,
|
||||
required Uint8List jarBytes,
|
||||
required String jarLabel,
|
||||
}) => comms.deploy(
|
||||
server: server,
|
||||
service: service,
|
||||
jarBytes: jarBytes,
|
||||
jarLabel: jarLabel,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<DeployResult> deployWeb({
|
||||
required ServerProfile server,
|
||||
required ServiceConfig service,
|
||||
required Uint8List archiveBytes,
|
||||
required int fileCount,
|
||||
}) => comms.deployWeb(
|
||||
server: server,
|
||||
service: service,
|
||||
archiveBytes: archiveBytes,
|
||||
fileCount: fileCount,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<DeployResult> restartOnly(
|
||||
ServerProfile server,
|
||||
ServiceConfig service,
|
||||
) => comms.restartOnly(server, service);
|
||||
|
||||
@override
|
||||
Future<DeployResult> revert() => comms.revert();
|
||||
|
||||
@override
|
||||
Future<void> discardBackup() => comms.discardBackup();
|
||||
|
||||
// ── comms: provisioning ───────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<DeployResult> installSystemdUnit({
|
||||
required ServerProfile server,
|
||||
required String unitName,
|
||||
required String unitContent,
|
||||
bool enable = true,
|
||||
bool startNow = true,
|
||||
}) => comms.installSystemdUnit(
|
||||
server: server,
|
||||
unitName: unitName,
|
||||
unitContent: unitContent,
|
||||
enable: enable,
|
||||
startNow: startNow,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<String> detectPackageManager(ServerProfile server) =>
|
||||
comms.detectPackageManager(server);
|
||||
|
||||
@override
|
||||
Future<Map<String, String>> probeEnvironment(
|
||||
ServerProfile server,
|
||||
List<String> detectByKey,
|
||||
) => comms.probeEnvironment(server, detectByKey);
|
||||
|
||||
@override
|
||||
Future<DeployResult> installEnvironment({
|
||||
required ServerProfile server,
|
||||
required String command,
|
||||
required List<String> units,
|
||||
}) =>
|
||||
comms.installEnvironment(server: server, command: command, units: units);
|
||||
|
||||
@override
|
||||
Future<DeployResult> installPackages({
|
||||
required ServerProfile server,
|
||||
required String command,
|
||||
String? enableUnit,
|
||||
}) => comms.installPackages(
|
||||
server: server,
|
||||
command: command,
|
||||
enableUnit: enableUnit,
|
||||
);
|
||||
|
||||
// ── comms: service & health ───────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<HealthResult> checkHealth(
|
||||
ServerProfile server,
|
||||
ServiceConfig service,
|
||||
) => comms.checkHealth(server, service);
|
||||
|
||||
@override
|
||||
Future<String> serviceStatus(ServerProfile server, ServiceConfig service) =>
|
||||
comms.serviceStatus(server, service);
|
||||
|
||||
@override
|
||||
Future<DeployResult> serviceControl(
|
||||
ServerProfile server,
|
||||
ServiceConfig service,
|
||||
String action,
|
||||
) => comms.serviceControl(server, service, action);
|
||||
|
||||
@override
|
||||
Future<List<String>> nginxRoots(ServerProfile server) =>
|
||||
comms.nginxRoots(server);
|
||||
|
||||
// ── comms: logs ───────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<void> fetchLogs(
|
||||
ServerProfile server,
|
||||
ServiceConfig service, {
|
||||
DateTime? since,
|
||||
DateTime? until,
|
||||
}) => comms.fetchLogs(server, service, since: since, until: until);
|
||||
|
||||
@override
|
||||
Future<void> followLogs(ServerProfile server, ServiceConfig service) =>
|
||||
comms.followLogs(server, service);
|
||||
|
||||
@override
|
||||
void stopLogs() => comms.stopLogs();
|
||||
|
||||
// ── comms: redis ──────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<(bool, String)> redisPing(
|
||||
ServerProfile server, {
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
int db = 0,
|
||||
}) => comms.redisPing(server, host: host, port: port, pass: pass, db: db);
|
||||
|
||||
@override
|
||||
Future<String> redisConfigPassword(ServerProfile server) =>
|
||||
comms.redisConfigPassword(server);
|
||||
|
||||
@override
|
||||
Future<int> redisDbSize(
|
||||
ServerProfile server, {
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
int db = 0,
|
||||
}) => comms.redisDbSize(server, host: host, port: port, pass: pass, db: db);
|
||||
|
||||
@override
|
||||
Future<(int, Map<int, int>)> redisDatabases(
|
||||
ServerProfile server, {
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
}) => comms.redisDatabases(server, host: host, port: port, pass: pass);
|
||||
|
||||
@override
|
||||
Future<List<(String, String)>> redisKeysTyped(
|
||||
ServerProfile server, {
|
||||
String pattern = '*',
|
||||
String filterType = '',
|
||||
int limit = 50000,
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
int db = 0,
|
||||
}) => comms.redisKeysTyped(
|
||||
server,
|
||||
pattern: pattern,
|
||||
filterType: filterType,
|
||||
limit: limit,
|
||||
host: host,
|
||||
port: port,
|
||||
pass: pass,
|
||||
db: db,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<String>> redisKeys(
|
||||
ServerProfile server, {
|
||||
String pattern = '*',
|
||||
int limit = 100000,
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
int db = 0,
|
||||
}) => comms.redisKeys(
|
||||
server,
|
||||
pattern: pattern,
|
||||
limit: limit,
|
||||
host: host,
|
||||
port: port,
|
||||
pass: pass,
|
||||
db: db,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<RedisEntry> redisGet(
|
||||
ServerProfile server,
|
||||
String key, {
|
||||
String host = '127.0.0.1',
|
||||
int port = 6379,
|
||||
String pass = '',
|
||||
int db = 0,
|
||||
}) => comms.redisGet(server, key, host: host, port: port, pass: pass, db: db);
|
||||
|
||||
// ── comms: docker ─────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<DockerStatus> dockerStatus(ServerProfile server) =>
|
||||
comms.dockerStatus(server);
|
||||
|
||||
@override
|
||||
Future<List<DockerContainer>> dockerPs(
|
||||
ServerProfile server, {
|
||||
bool all = true,
|
||||
}) => comms.dockerPs(server, all: all);
|
||||
|
||||
@override
|
||||
Future<String> dockerAction(ServerProfile server, String id, String action) =>
|
||||
comms.dockerAction(server, id, action);
|
||||
|
||||
@override
|
||||
Future<String> dockerLogs(
|
||||
ServerProfile server,
|
||||
String id, {
|
||||
int tail = 300,
|
||||
}) => comms.dockerLogs(server, id, tail: tail);
|
||||
|
||||
@override
|
||||
Future<String> dockerTest(ServerProfile server) => comms.dockerTest(server);
|
||||
|
||||
@override
|
||||
Future<(bool, String)> dockerRun(ServerProfile server, DockerRunSpec spec) =>
|
||||
comms.dockerRun(server, spec);
|
||||
|
||||
// ── comms: kafka ──────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<KafkaStatus> kafkaDetect(ServerProfile server) =>
|
||||
comms.kafkaDetect(server);
|
||||
|
||||
@override
|
||||
Future<String> kafkaTest(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
}) => comms.kafkaTest(
|
||||
server,
|
||||
binDir: binDir,
|
||||
suffix: suffix,
|
||||
bootstrap: bootstrap,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<KafkaTopic>> kafkaTopics(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
bool includeInternal = false,
|
||||
}) => comms.kafkaTopics(
|
||||
server,
|
||||
binDir: binDir,
|
||||
suffix: suffix,
|
||||
bootstrap: bootstrap,
|
||||
includeInternal: includeInternal,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<List<KafkaConsumerGroup>> kafkaGroups(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
}) => comms.kafkaGroups(
|
||||
server,
|
||||
binDir: binDir,
|
||||
suffix: suffix,
|
||||
bootstrap: bootstrap,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<KafkaCluster> kafkaCluster(
|
||||
ServerProfile server, {
|
||||
required String binDir,
|
||||
required String suffix,
|
||||
required String bootstrap,
|
||||
}) => comms.kafkaCluster(
|
||||
server,
|
||||
binDir: binDir,
|
||||
suffix: suffix,
|
||||
bootstrap: bootstrap,
|
||||
);
|
||||
|
||||
// ── comms: remote filesystem ──────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
Future<List<RemoteEntry>> listDir(ServerProfile server, String path) =>
|
||||
comms.listDir(server, path);
|
||||
|
||||
@override
|
||||
Future<String> resolveHome(ServerProfile server) => comms.resolveHome(server);
|
||||
|
||||
@override
|
||||
Future<void> uploadFile(
|
||||
ServerProfile server,
|
||||
Uint8List bytes,
|
||||
String remotePath,
|
||||
) => comms.uploadFile(server, bytes, remotePath);
|
||||
|
||||
@override
|
||||
Future<Uint8List> downloadFile(ServerProfile server, String remotePath) =>
|
||||
comms.downloadFile(server, remotePath);
|
||||
|
||||
@override
|
||||
Future<void> deleteRemote(
|
||||
ServerProfile server,
|
||||
String remotePath,
|
||||
bool isDir,
|
||||
) => comms.deleteRemote(server, remotePath, isDir);
|
||||
|
||||
// ── files ─────────────────────────────────────────────────────────────────
|
||||
|
||||
@override
|
||||
bool get buildSupported => files.buildSupported;
|
||||
|
||||
@override
|
||||
Stream<LogLine> get buildLogs => files.buildLogs;
|
||||
|
||||
@override
|
||||
Stream<List<DeployStep>> get buildStepStream => files.buildStepStream;
|
||||
|
||||
@override
|
||||
Future<BuildResult> build(ServiceConfig service) => files.build(service);
|
||||
|
||||
@override
|
||||
Future<BuildResult> buildWeb(ServiceConfig service) =>
|
||||
files.buildWeb(service);
|
||||
|
||||
@override
|
||||
void cancelBuild() => files.cancelBuild();
|
||||
|
||||
@override
|
||||
Future<Uint8List> readArtifact(String path) => files.readArtifact(path);
|
||||
|
||||
@override
|
||||
Future<bool> artifactExists(String path) => files.artifactExists(path);
|
||||
|
||||
@override
|
||||
Future<(Uint8List, int)> packageWeb(String directoryPath) =>
|
||||
files.packageWeb(directoryPath);
|
||||
}
|
||||
Reference in New Issue
Block a user