chore(wip): consolidation intermédiaire multi-tickets (sprints Statistiques, UI, Bug resolution, Serveur-client)
Regroupe l'état de travail en cours réalisé dans un même worktree sur plusieurs tickets/sprints (#85, #136, #145, #155-160, #162-164), mélangeant des tickets QA et inProgress. Ne constitue pas une feature terminée : commit de sauvegarde avant triage/split par ticket en branches feature/* dédiées. Exclut les dossiers d'environnement de build locaux et le heap dump parasite (.gitignore mis à jour). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -173,30 +173,69 @@ enum ShareRecipientStatus {
|
||||
}
|
||||
}
|
||||
|
||||
enum ShareKind {
|
||||
single('single'),
|
||||
pack('pack');
|
||||
|
||||
const ShareKind(this.wireName);
|
||||
|
||||
final String wireName;
|
||||
|
||||
static ShareKind parse(String value) {
|
||||
for (final kind in values) {
|
||||
if (kind.wireName == value) {
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
throw ValidationException('Unsupported share kind: $value.');
|
||||
}
|
||||
}
|
||||
|
||||
final class Share {
|
||||
Share({
|
||||
required String id,
|
||||
required String senderUserId,
|
||||
this.kind = ShareKind.single,
|
||||
required this.resourceType,
|
||||
String? packName,
|
||||
required Map<String, Object?> payloadJson,
|
||||
required DateTime createdAt,
|
||||
DateTime? revokedAt,
|
||||
}) : id = _nonBlank(id, 'Share id'),
|
||||
senderUserId = _nonBlank(senderUserId, 'Sender user id'),
|
||||
packName = _blankToNull(packName),
|
||||
payloadJson = Map.unmodifiable(payloadJson),
|
||||
createdAt = createdAt.toUtc(),
|
||||
revokedAt = revokedAt?.toUtc() {
|
||||
if (resourceType != SyncedResourceType.program &&
|
||||
resourceType != SyncedResourceType.workoutTemplate) {
|
||||
throw const ValidationException(
|
||||
'Shares only support program and workoutTemplate resources.',
|
||||
);
|
||||
if (kind == ShareKind.single) {
|
||||
final type = resourceType;
|
||||
if (type != SyncedResourceType.program &&
|
||||
type != SyncedResourceType.workoutTemplate) {
|
||||
throw const ValidationException(
|
||||
'Single shares only support program and workoutTemplate resources.',
|
||||
);
|
||||
}
|
||||
}
|
||||
if (kind == ShareKind.pack) {
|
||||
if (resourceType != null) {
|
||||
throw const ValidationException(
|
||||
'Pack shares must not set resourceType.',
|
||||
);
|
||||
}
|
||||
if (this.packName == null) {
|
||||
throw const ValidationException('Pack name must not be blank.');
|
||||
}
|
||||
}
|
||||
if (kind == ShareKind.pack && payloadJson['items'] is! List) {
|
||||
throw const ValidationException('Pack share payload must contain items.');
|
||||
}
|
||||
}
|
||||
|
||||
final String id;
|
||||
final String senderUserId;
|
||||
final SyncedResourceType resourceType;
|
||||
final ShareKind kind;
|
||||
final SyncedResourceType? resourceType;
|
||||
final String? packName;
|
||||
final Map<String, Object?> payloadJson;
|
||||
final DateTime createdAt;
|
||||
final DateTime? revokedAt;
|
||||
@ -230,3 +269,8 @@ String _nonBlank(String value, String label) {
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
String? _blankToNull(String? value) {
|
||||
final trimmed = value?.trim();
|
||||
return trimmed == null || trimmed.isEmpty ? null : trimmed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user