feat: add local-first private AI digest workflow

Migrate app code into canonical feature slices, add phone-only AI digest scheduling and review, wire local notification/background task support, and cover the flow with tests.
This commit is contained in:
Rijad Zuzo
2026-05-17 00:17:20 +02:00
parent dab50abf0e
commit f655adfbea
212 changed files with 24178 additions and 15895 deletions
+4
View File
@@ -0,0 +1,4 @@
# Moments Domain
Relationship capture and timeline models live here. Keep this folder focused on
recorded events and notes about interactions.
@@ -0,0 +1,63 @@
// ignore_for_file: sort_constructors_first
import 'package:flutter/foundation.dart';
/// Timeline event stored for a specific relationship.
@immutable
class RelationshipMoment {
const RelationshipMoment({
required this.id,
required this.personId,
required this.title,
required this.summary,
required this.at,
required this.type,
});
final String id;
final String personId;
final String title;
final String summary;
final DateTime at;
final String type;
RelationshipMoment copyWith({
String? id,
String? personId,
String? title,
String? summary,
DateTime? at,
String? type,
}) {
return RelationshipMoment(
id: id ?? this.id,
personId: personId ?? this.personId,
title: title ?? this.title,
summary: summary ?? this.summary,
at: at ?? this.at,
type: type ?? this.type,
);
}
Map<String, dynamic> toJson() {
return <String, dynamic>{
'id': id,
'personId': personId,
'title': title,
'summary': summary,
'at': at.toUtc().toIso8601String(),
'type': type,
};
}
factory RelationshipMoment.fromJson(Map<String, dynamic> json) {
return RelationshipMoment(
id: json['id'] as String,
personId: json['personId'] as String,
title: json['title'] as String,
summary: json['summary'] as String,
at: DateTime.parse(json['at'] as String).toLocal(),
type: json['type'] as String,
);
}
}