feat(train): the body's figures in a sealed, synced profile (ADR 0030, D33, D34)

A person's profile, one row per person (its ID derived from theirs),
sealed like a workout: sex, birth date, height, weight, resting and
maximum heart rate, VO2max, training background, typical day and sleep
goal, each optional. "Your body" in the account sheet edits it; the
Loop's setup is to reuse its form. The migration only adds the synced
table `profile`, deleted with the person's sync space.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-28 18:02:04 +01:00
commit de6fe5c15a
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -0,0 +1,23 @@
import 'dart:async';
import 'package:halkyon_app/halkyon_app.dart';
import 'package:halkyon_train_flutter/src/feature/profile/data/profile_gateway.dart';
/// [ProfileGateway] in memory, whose rows a test changes as an instance
/// could.
class MemoryProfileGateway() implements ProfileGateway {
final rows = <String, Envelope>{};
final _remote = StreamController<void>.broadcast();
/// As a sync bringing others' changes.
void bringRemoteChanges() => _remote.add(null);
@override
Future<Envelope?> read(String id) async => rows[id];
@override
Future<void> write(String id, Envelope envelope) async => rows[id] = envelope;
@override
Stream<void> get remoteChanges => _remote.stream;
}