refactor(app,learn): people's files on the device shared in halkyon_app

ADR 0043's recommendation, for Todo's attachments: what Learn had for its
files on the device moves into halkyon_app, unchanged but for its names,
and Learn uses it from there.

- FileCache, DirectoryFileCache (Learn's AssetFileCache): the files by
  their SHA-256 in a folder of the person's, and which wait to be
  uploaded.
- FileServerGateway, ServerpodFileServerGateway (Learn's
  AssetServerGateway): halkyon_base's files endpoint, taking the module's
  caller rather than Learn's client; FileLimitReached, FileRoom.
- Their fakes in halkyon_app's testing: MemoryFileCache,
  FakeFileServerGateway, sha256Of.
- SealedFile: the format every app seals a file in (HLKF, version 1),
  sealing with halkyon_app's ContentCipher; Learn's Privacy seals and
  opens its files with it, for the same context as before, so every file
  sealed so far opens as it did.

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 01:17:22 +01:00
commit 5dd7575dd6
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
3 changed files with 272 additions and 235 deletions

View file

@ -20,13 +20,11 @@ import 'package:material_ui/material_ui.dart' hide Card;
import '../../support/fake_asset_gateway.dart';
import '../../support/fake_asset_sealing.dart';
import '../../support/fake_asset_server_gateway.dart';
import '../../support/fake_card_gateway.dart';
import '../../support/fake_note_gateway.dart';
import '../../support/fake_pdf_engine.dart';
import '../../support/fake_pdf_source_gateway.dart';
import '../../support/fake_studyset_gateway.dart';
import '../../support/memory_asset_file_cache.dart';
import '../../support/pump_app.dart';
import '../../support/test_dependencies.dart';
@ -74,7 +72,7 @@ void main() {
late FakeNoteGateway noteGateway;
late FakePdfSourceGateway pdfGateway;
late FakeAssetGateway assetGateway;
late MemoryAssetFileCache files;
late MemoryFileCache files;
late FakePdfEngine engine;
setUp(() {
@ -95,7 +93,7 @@ void main() {
noteGateway = FakeNoteGateway();
pdfGateway = FakePdfSourceGateway();
assetGateway = FakeAssetGateway();
files = MemoryAssetFileCache();
files = MemoryFileCache();
engine = FakePdfEngine();
});
@ -240,7 +238,7 @@ void main() {
'selected, tied to the page', (tester) async {
final assets = AssetRepository(
assetGateway,
FakeAssetServerGateway(),
FakeFileServerGateway(),
files,
FakeAssetSealing(),
);

View file

@ -29,14 +29,12 @@ import 'package:material_ui/material_ui.dart';
import '../../support/fake_asset_gateway.dart';
import '../../support/fake_asset_sealing.dart';
import '../../support/fake_asset_server_gateway.dart';
import '../../support/fake_card_gateway.dart';
import '../../support/fake_conversation_gateway.dart';
import '../../support/fake_grammar_gateway.dart';
import '../../support/fake_photo_picker.dart';
import '../../support/fake_settings_gateway.dart';
import '../../support/fake_studyset_gateway.dart';
import '../../support/memory_asset_file_cache.dart';
import '../../support/memory_device_settings_store.dart';
import '../../support/pump_app.dart';
import '../../support/test_dependencies.dart';
@ -123,7 +121,7 @@ void main() {
late MemoryDeviceSettingsStore store;
late List<Uri> searched;
late FakeAssetGateway assetGateway;
late MemoryAssetFileCache assetFiles;
late MemoryFileCache assetFiles;
late FakeGrammarGateway grammar;
setUp(() {
@ -150,7 +148,7 @@ void main() {
speech = FakeSpeechInput();
searched = [];
assetGateway = FakeAssetGateway();
assetFiles = MemoryAssetFileCache();
assetFiles = MemoryFileCache();
grammar = FakeGrammarGateway(
found: {
'私はりんごは食べる': const [
@ -1469,7 +1467,7 @@ void main() {
Future<String> picturedCard() async {
final assets = AssetRepository(
assetGateway,
FakeAssetServerGateway(),
FakeFileServerGateway(),
assetFiles,
FakeAssetSealing(),
);

View file

@ -3,15 +3,15 @@ import 'dart:typed_data';
import 'dart:ui' show Rect;
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_app/testing.dart'
show FakeFileServerGateway, MemoryFileCache;
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
import 'package:halkyon_learn_flutter/src/feature/pdf_source/model/pdf_source.dart';
import '../../../support/fake_asset_gateway.dart';
import '../../../support/fake_asset_sealing.dart';
import '../../../support/fake_asset_server_gateway.dart';
import '../../../support/fake_pdf_engine.dart';
import '../../../support/memory_asset_file_cache.dart';
// What a model is sent of the person's files (ADR 0021, D12): images every
// provider reads, none larger than the smallest limit, and a PDF's pages
@ -25,8 +25,8 @@ void main() {
setUp(() {
assets = AssetRepository(
FakeAssetGateway(),
FakeAssetServerGateway(),
MemoryAssetFileCache(),
FakeFileServerGateway(),
MemoryFileCache(),
FakeAssetSealing(),
);
engine = FakePdfEngine();