feat(learn): sharing moves a studyset into a space of its own

Step 4 (d) of ADR 0044 (D14, D23, D27, D28), without its screens yet.

- `StudysetSharing`: refuses a studyset with a publication in its tree
  and a device that can't seal, before anything is made; makes the
  space, readies it, exports the tree with its progress, imports it
  under new IDs with its top placed in the space, and deletes the old
  one for good once the copy is whole. Failing or aborted, the space
  is deleted and the studyset stays as it was.
- `SyncSpaceSetup`: syncs until the person's membership of the new
  space came, then makes its first key and seals it to them.
- `Privacy` writes a top studyset placed in a space with that space's
  key; a studyset can be inserted under an ID chosen beforehand.
- The archive's export and import take `moved`, keeping each item's
  link to Explore and each card's origin.
- An import that fails midway takes back what it wrote, as an aborted
  one did.

Whats-New: An import that fails partway no longer leaves part of the studyset behind.
Whats-New-De: Ein Import, der unterwegs scheitert, lässt kein halbes Lernset mehr zurück.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-11 14:13:04 +01:00
commit d3e8b7d1c6
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -156,8 +156,9 @@ class FakeStudysetGateway() implements StudysetGateway {
DateTime updatedAt, {
String? parentId,
String position = 'a0',
String? id,
}) async {
final id = 'studyset-${_nextId++}';
id ??= 'studyset-${_nextId++}';
_rows[id] = (
id: id,
payload: payload,