feat(base,learn): suggest changes within a shared studyset
ADR 0044's step 6b (D44, D46 to D48): a Viewer, and an agent, suggest changes within a shared studyset, which its Owner and Editors accept or decline. A suggestion or report is written as Explore's are, in its writer's own synced space, with kinds of its own (space-suggestion, space-report) and the space's id in feedback_thread's publicationId, so no synced table changes and older apps, skipping kinds they don't know, keep syncing. Where the studyset is private it is sealed with its key, bound to the space; a reply to it is sealed for its thread. Learn's server gathers a space's threads for its members alone (feedback.threadsInSpace, NotFound for anyone else): only threads and replies by members now, decisions only from rows in the space itself, where the engine lets its Owner and Editors alone write; sealed payloads pass in base64 with their key and nonce. The inbox adds the threads its caller decides on or wrote. The module tells a host a person's spaces and each space's members (sharedSpacesOf, membersOfSpaces). No migration: no table changes. In the app, a Viewer's card and note offer Suggest a change: the fields write into the suggestion alone, sent with a message. A shared studyset's menu lists its Suggestions, where its Owner and Editors accept a change as a revision, or a new card or note into the studyset, and decide in the space. A suggestion naming a file that isn't the studyset's, or bringing files of its own, isn't taken. Whats-New: In a studyset shared with you as a viewer, suggest a change to a card or note; its owner and editors find your suggestions under Suggestions in its menu and accept or decline them. Whats-New-De: In einem Lernset, das du nur ansehen darfst, schlägst du Änderungen an Karteikarten und Notizen vor; Besitzer:in und Bearbeiter:innen finden sie im Menü unter „Vorschläge“ und nehmen sie an oder lehnen sie ab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
7aee78bd87
commit
82c777b1a5
2 changed files with 2949 additions and 427 deletions
|
|
@ -121,7 +121,8 @@ export 'src/register/people.dart' show issueSession;
|
|||
export 'src/register/sessions_ended.dart'
|
||||
show AccountSessionsEnded, deliverSessionNotices;
|
||||
export 'src/shared_space/join_page.dart' show addJoinPageRoute, joinPage;
|
||||
export 'src/shared_space/shared_spaces.dart' show forgetLapsedSpaceInvitations;
|
||||
export 'src/shared_space/shared_spaces.dart'
|
||||
show forgetLapsedSpaceInvitations, membersOfSpaces, sharedSpacesOf;
|
||||
export 'src/shared_space/space_grants.dart';
|
||||
export 'src/simplelogin/handle_suggestion.dart'
|
||||
show handleFromName, handlesToTry, suggestable;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,40 @@ Future<List<SharedSpaceMember>?> lockedMembers(
|
|||
);
|
||||
}
|
||||
|
||||
/// The shared spaces [person] is a member of, with their role in each: for
|
||||
/// a host gathering what is written about its spaces (ADR 0044, D46).
|
||||
Future<Map<UuidValue, SharedSpaceRole>> sharedSpacesOf(
|
||||
Session session,
|
||||
UuidValue person,
|
||||
) async => {
|
||||
// SELECT … FROM "shared_space_member" WHERE "authUserId" = $1
|
||||
for (final member in await SharedSpaceMember.db.find(
|
||||
session,
|
||||
where: (t) => t.authUserId.equals(person),
|
||||
))
|
||||
member.sharedSpaceId: member.role,
|
||||
};
|
||||
|
||||
/// The members of each of [spaces] with their roles, by space; a space
|
||||
/// nobody is in (or none at all) is left out (D46, D47).
|
||||
Future<Map<UuidValue, Map<UuidValue, SharedSpaceRole>>> membersOfSpaces(
|
||||
Session session,
|
||||
Set<UuidValue> spaces,
|
||||
) async {
|
||||
if (spaces.isEmpty) {
|
||||
return const {};
|
||||
}
|
||||
final members = <UuidValue, Map<UuidValue, SharedSpaceRole>>{};
|
||||
// SELECT … FROM "shared_space_member" WHERE "sharedSpaceId" = ANY($1)
|
||||
for (final member in await SharedSpaceMember.db.find(
|
||||
session,
|
||||
where: (t) => t.sharedSpaceId.inSet(spaces),
|
||||
)) {
|
||||
(members[member.sharedSpaceId] ??= {})[member.authUserId] = member.role;
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
/// Those of [people] that are agents here (D45): their sessions and their
|
||||
/// rows here carry the agent's scope, as every member is a person here.
|
||||
Future<Set<UuidValue>> agentsHere(
|
||||
|
|
|
|||
Loading…
Reference in a new issue