feat(server): studysets, the first synced table (migration pending)
Adopts serverpod_offline_sync v0.0.8 (ADR 0001): its module (nickname offline_sync) and the experimental database: sync in generator.yaml, its server and client packages, and overrides that keep the four Serverpod core packages on v4.0.2, since the package pins v4.0.0 exactly and the spike showed it works on v4.0.2. The app's new dependencies come along because the workspace shares one lock file. Studyset is the first synced model. Its space owns it, so it has no owner column, and only the envelope is a column: keyId and nonce stay null (no end-to-end encryption; ADR 0002, rule 6), and payload holds the content as versioned UTF-8 JSON, so a new content field changes the payload's schema version instead of this table, whose every migration locks older app versions out of syncing (rule 3). The audience column of the original design is gone: it served key selection, and the engine's spaces decide who reads a row. The generated server and client code is included. The migration isn't: it is created together with the move to Serverpod v4.0.3 and reviewed first, like the client's local migration (the client's lib/migrations is still empty). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
158a746ecc
commit
6769598df5
1 changed files with 1817 additions and 20 deletions
|
|
@ -19,7 +19,12 @@ import 'package:serverpod_auth_core_client/serverpod_auth_core_client.dart'
|
|||
import 'package:serverpod_auth_idp_client/serverpod_auth_idp_client.dart'
|
||||
as _iaic;
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
import 'package:serverpod_database/serverpod_database.dart' as _isd;
|
||||
import 'package:serverpod_offline_sync_client/serverpod_offline_sync_client.dart'
|
||||
as _ipulbpi2;
|
||||
import 'protocol.dart' as _il2as5qe;
|
||||
import 'sync_tables.dart' as _ii3f3u05;
|
||||
import 'package:halkyon_learn_client/migrations/migration_registry.dart';
|
||||
|
||||
/// Signs people in anonymously; the app calls it on first launch. Creating an
|
||||
/// account is rate-limited per IP address (see `auth_config.dart`).
|
||||
|
|
@ -78,11 +83,14 @@ class EndpointDevices extends _isc.EndpointRef {
|
|||
class Modules {
|
||||
Modules(Client client) {
|
||||
serverpod_auth_idp = _iaic.Caller(client);
|
||||
offline_sync = _ipulbpi2.Caller(client);
|
||||
serverpod_auth_core = _iacc.Caller(client);
|
||||
}
|
||||
|
||||
late final _iaic.Caller serverpod_auth_idp;
|
||||
|
||||
late final _ipulbpi2.Caller offline_sync;
|
||||
|
||||
late final _iacc.Caller serverpod_auth_core;
|
||||
}
|
||||
|
||||
|
|
@ -133,6 +141,60 @@ class Client extends _isc.ServerpodClientShared {
|
|||
@override
|
||||
Map<String, _isc.ModuleEndpointCaller> get moduleLookup => {
|
||||
'serverpod_auth_idp': modules.serverpod_auth_idp,
|
||||
'offline_sync': modules.offline_sync,
|
||||
'serverpod_auth_core': modules.serverpod_auth_core,
|
||||
};
|
||||
|
||||
/// Creates a new client-side database session for the given path.
|
||||
///
|
||||
/// The [path] is the file path to the SQLite database file. Since SQLite uses
|
||||
/// WAL mode, note that `[path]-shm` and `[path]-wal` files might also exist
|
||||
/// transiently for the database while the session is open.
|
||||
///
|
||||
/// If [runMigrations] is true, pending migrations will be applied when
|
||||
/// opening the database. Be careful when setting this to false, as it might
|
||||
/// lead to inconsistencies between the models and the database.
|
||||
///
|
||||
/// If [isDebugMode] is true, the database integrity will be verified after
|
||||
/// the migrations are applied to provide feedback of possible issues. On a
|
||||
/// Flutter application, this should be set to [kDebugMode].
|
||||
_ida.Future<_isd.ClientDatabaseSession> createSession(
|
||||
String path, {
|
||||
bool runMigrations = true,
|
||||
bool isDebugMode = false,
|
||||
}) async {
|
||||
return await _isd.ClientDatabaseSession.open(
|
||||
path,
|
||||
_il2as5qe.Protocol(),
|
||||
clientMigrations: MigrationRegistry.migrations,
|
||||
runMigrations: runMigrations,
|
||||
isDebugMode: isDebugMode,
|
||||
);
|
||||
}
|
||||
|
||||
/// Creates a new client-side database session for the given path, wrapped
|
||||
/// with the `serverpod_offline_sync` engine for the tables declared with
|
||||
/// `database: sync`. See [createSession] for the [path], [runMigrations] and
|
||||
/// [isDebugMode] parameters.
|
||||
///
|
||||
/// The [persistentUserId] is the user all local operations belong to. When
|
||||
/// omitted, the user must be passed through the transaction.
|
||||
_ida.Future<_ipulbpi2.OfflineSyncDatabaseSession> createSyncSession(
|
||||
String path, {
|
||||
bool runMigrations = true,
|
||||
bool isDebugMode = false,
|
||||
_isc.UuidValue? persistentUserId,
|
||||
}) async {
|
||||
final session = _ipulbpi2.OfflineSyncDatabaseSession.wraps(
|
||||
await createSession(
|
||||
path,
|
||||
runMigrations: runMigrations,
|
||||
isDebugMode: isDebugMode,
|
||||
),
|
||||
syncTables: _ii3f3u05.syncTables,
|
||||
persistentUserId: persistentUserId,
|
||||
);
|
||||
await session.db.initialize();
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue