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
+9
View File
@@ -0,0 +1,9 @@
# Dashboard Slice
This slice owns the home overview experience.
- `domain/dashboard_models.dart`: lightweight dashboard task and summary types.
- `presentation/dashboard_view.dart`: dashboard screen and interactions.
If you want to change the founder daily workflow, this is usually the first
screen to inspect after the app shell.
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
# Dashboard Domain
Dashboard-owned value types live here. These models should stay dumb and stable
so the dashboard UI can evolve without changing persistence contracts everywhere.
@@ -0,0 +1,73 @@
// ignore_for_file: sort_constructors_first
import 'package:flutter/foundation.dart';
/// Lightweight task shown on the dashboard home surface.
@immutable
class DashboardTask {
const DashboardTask({
required this.id,
required this.title,
required this.description,
required this.when,
this.done = false,
});
final String id;
final String title;
final String description;
final DateTime when;
final bool done;
DashboardTask copyWith({
String? id,
String? title,
String? description,
DateTime? when,
bool? done,
}) {
return DashboardTask(
id: id ?? this.id,
title: title ?? this.title,
description: description ?? this.description,
when: when ?? this.when,
done: done ?? this.done,
);
}
Map<String, dynamic> toJson() {
return <String, dynamic>{
'id': id,
'title': title,
'description': description,
'when': when.toUtc().toIso8601String(),
'done': done,
};
}
factory DashboardTask.fromJson(Map<String, dynamic> json) {
return DashboardTask(
id: json['id'] as String,
title: json['title'] as String,
description: json['description'] as String,
when: DateTime.parse(json['when'] as String).toLocal(),
done: json['done'] as bool? ?? false,
);
}
}
/// Summary numbers consumed by the dashboard UI.
@immutable
class DashboardSummary {
const DashboardSummary({
required this.activePeople,
required this.upcomingPlans,
required this.pendingIdeas,
required this.weeklyConsistency,
});
final int activePeople;
final int upcomingPlans;
final int pendingIdeas;
final int weeklyConsistency;
}
@@ -0,0 +1,4 @@
# Dashboard Presentation
This folder contains the overview/home UI for the relationship workspace.
Use it for founder-facing summary screens, not for deeper people-specific flows.
File diff suppressed because it is too large Load Diff