Files
GameTime/server/lib/application/ports.dart
Blomios 60912ebde4 feat(server): API de synchronisation incrémentale LWW (ticket #50)
Ajoute l'endpoint api/sync_api.dart, les use cases de synchronisation
(application/sync_use_cases.dart) et l'adapter Postgres
(infrastructure/postgres/synced_resource_repository.dart) implémentant
un upsert LWW atomique via CTE (INSERT ... ON CONFLICT ... WHERE
client_updated_at < EXCLUDED.client_updated_at, avec fallback UNION
ALL pour le cas ignoré). dart pub get OK, dart analyze clean, dart
test 15/15 vert. SQL d'upsert relu manuellement et jugé correct ; pas
de test de bout en bout contre un vrai PostgreSQL faute d'accès
Docker dans ce sandbox.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 10:23:36 +02:00

62 lines
1.4 KiB
Dart

import '../domain/domain.dart';
abstract interface class UserRepository {
Future<UserAccount?> findByEmail(String email);
Future<UserAccount?> findById(String id);
Future<void> insert(UserAccount user);
Future<void> updatePasswordHash({
required String userId,
required String passwordHash,
required DateTime updatedAt,
});
}
abstract interface class AuthSessionRepository {
Future<void> insert(AuthSession session);
Future<AuthSession?> findByTokenHash(String tokenHash);
Future<void> revoke({required String sessionId, required DateTime revokedAt});
}
enum SyncWriteStatus { accepted, ignoredOlder }
final class SyncWriteResult {
const SyncWriteResult({required this.status, required this.resource});
final SyncWriteStatus status;
final SyncedResource resource;
}
abstract interface class SyncedResourceRepository {
Future<SyncWriteResult> upsertWithLww(SyncedResource resource);
Future<List<SyncedResource>> findAllForUserSince({
required String ownerUserId,
DateTime? since,
});
}
abstract interface class PasswordHasher {
Future<String> hash(String password);
Future<bool> verify({required String password, required String passwordHash});
}
abstract interface class OpaqueTokenService {
String generateToken();
String hashToken(String token);
}
abstract interface class Clock {
DateTime now();
}
abstract interface class IdGenerator {
String newId();
}