refactor(profile): handles and profiles move into halkyon_base
People's public profiles are the instance's register's (ADR 0016), so the module now holds them: the public_profile table (unchanged, so Learn's migration records versions only; devices get the table empty, as they hold every module's tables), the profile and profiles endpoints under `base`, the handle rules, the link checks and the page at /@handle, whose foot names the app as the host's configuration says (profilePageNote). Deleting a person deletes their profile in the module's core. Hosts read profiles through the module (profileOf, profilesOf, personWithHandle, fixHandle; saveProfile for their tests), behind an AccountRegister that is this server's own database for now. Learn's feedback, discussions and publishing ask it; publishing fixes the handle just before it writes the release, outside its transaction. Explore still joins the table in its search, so Learn holds the register wherever it runs. Learn's app calls the module's endpoints; a profile not found is ProfileNotFoundException. Todo's database gets the table too (it was never deployed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
2033e5606f
commit
4107cc3087
1 changed files with 38851 additions and 1197 deletions
|
|
@ -1,14 +1,20 @@
|
|||
import 'dart:typed_data';
|
||||
|
||||
import 'package:halkyon_base_client/halkyon_base_client.dart' as base;
|
||||
import 'package:halkyon_learn_client/halkyon_learn_client.dart' as protocol;
|
||||
import 'package:halkyon_learn_flutter/src/feature/profile/data/profile_gateway.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/profile/model/public_profile.dart';
|
||||
|
||||
/// [ProfileGateway] asking the instance through the Serverpod client.
|
||||
/// [ProfileGateway] asking the instance through the Serverpod client: the
|
||||
/// profile endpoints are halkyon_base's, as the instance's register keeps
|
||||
/// people's profiles (ADR 0016).
|
||||
class ServerpodProfileGateway(final protocol.Client _client)
|
||||
implements ProfileGateway {
|
||||
/// The caller's own profile's endpoint.
|
||||
base.EndpointProfile get _profiles => _client.modules.base.profile;
|
||||
|
||||
@override
|
||||
Future<PublicProfile?> mine() async => switch (await _client.profile.mine()) {
|
||||
Future<PublicProfile?> mine() async => switch (await _profiles.mine()) {
|
||||
final profile? => _profile(profile),
|
||||
null => null,
|
||||
};
|
||||
|
|
@ -21,22 +27,22 @@ class ServerpodProfileGateway(final protocol.Client _client)
|
|||
required List<String> links,
|
||||
}) => _refusing(
|
||||
() async => _profile(
|
||||
await _client.profile.save(handle, displayName, bio, links),
|
||||
await _profiles.save(handle, displayName, bio, links),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Future<PublicProfile?> byHandle(String handle) async {
|
||||
try {
|
||||
return _profile(await _client.profiles.byHandle(handle));
|
||||
} on protocol.NotFoundException {
|
||||
return _profile(await _client.modules.base.profiles.byHandle(handle));
|
||||
} on base.ProfileNotFoundException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ProfileProblem?> checkHandle(String handle) async =>
|
||||
switch (await _client.profile.checkHandle(handle)) {
|
||||
switch (await _profiles.checkHandle(handle)) {
|
||||
null => null,
|
||||
// A reason this app doesn't know reads as an invalid handle.
|
||||
final reason =>
|
||||
|
|
@ -45,29 +51,29 @@ class ServerpodProfileGateway(final protocol.Client _client)
|
|||
};
|
||||
|
||||
@override
|
||||
Future<void> remove() => _refusing(_client.profile.remove);
|
||||
Future<void> remove() => _refusing(_profiles.remove);
|
||||
|
||||
@override
|
||||
Future<PublicProfile> setAvatar(Uint8List png) => _refusing(
|
||||
() async => _profile(
|
||||
await _client.profile.setAvatar(ByteData.sublistView(png)),
|
||||
await _profiles.setAvatar(ByteData.sublistView(png)),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Future<PublicProfile> removeAvatar() =>
|
||||
_refusing(() async => _profile(await _client.profile.removeAvatar()));
|
||||
_refusing(() async => _profile(await _profiles.removeAvatar()));
|
||||
|
||||
@override
|
||||
Future<PublicProfile> checkLinks() =>
|
||||
_refusing(() async => _profile(await _client.profile.checkLinks()));
|
||||
_refusing(() async => _profile(await _profiles.checkLinks()));
|
||||
|
||||
/// [call], its refusal as a [ProfileRefused]; a reason this app doesn't
|
||||
/// know reads as an invalid handle.
|
||||
Future<T> _refusing<T>(Future<T> Function() call) async {
|
||||
try {
|
||||
return await call();
|
||||
} on protocol.ProfileRefusedException catch (error) {
|
||||
} on base.ProfileRefusedException catch (error) {
|
||||
throw ProfileRefused(
|
||||
ProfileProblem.values.asNameMap()[error.reason.name] ??
|
||||
ProfileProblem.handleInvalid,
|
||||
|
|
@ -75,7 +81,7 @@ class ServerpodProfileGateway(final protocol.Client _client)
|
|||
}
|
||||
}
|
||||
|
||||
PublicProfile _profile(protocol.Profile profile) => PublicProfile(
|
||||
PublicProfile _profile(base.Profile profile) => PublicProfile(
|
||||
handle: profile.handle,
|
||||
address: profile.address,
|
||||
displayName: profile.displayName,
|
||||
|
|
|
|||
Loading…
Reference in a new issue