feat(02-01): Drift tables, DAOs, scheduling utility, domain models with tests
- Add Rooms, Tasks, TaskCompletions Drift tables with schema v2 migration - Create RoomsDao with CRUD, watchAll, watchWithStats, cascade delete, reorder - Create TasksDao with CRUD, watchInRoom (sorted by due), completeTask, overdue detection - Implement calculateNextDueDate and catchUpToPresent pure scheduling functions - Define IntervalType enum (8 types), EffortLevel enum, FrequencyInterval model - Add formatRelativeDate German formatter and curatedRoomIcons icon list - Enable PRAGMA foreign_keys in beforeOpen migration strategy - All 30 unit tests passing (17 scheduling + 6 rooms DAO + 7 tasks DAO) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
247
lib/core/database/database.steps.dart
Normal file
247
lib/core/database/database.steps.dart
Normal file
@@ -0,0 +1,247 @@
|
||||
// dart format width=80
|
||||
import 'package:drift/internal/versioned_schema.dart' as i0;
|
||||
import 'package:drift/drift.dart' as i1;
|
||||
import 'package:drift/drift.dart'; // GENERATED BY drift_dev, DO NOT MODIFY.
|
||||
|
||||
// ignore_for_file: type=lint,unused_import
|
||||
//
|
||||
final class Schema2 extends i0.VersionedSchema {
|
||||
Schema2({required super.database}) : super(version: 2);
|
||||
@override
|
||||
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||
rooms,
|
||||
tasks,
|
||||
taskCompletions,
|
||||
];
|
||||
late final Shape0 rooms = Shape0(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'rooms',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [_column_0, _column_1, _column_2, _column_3, _column_4],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null,
|
||||
);
|
||||
late final Shape1 tasks = Shape1(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'tasks',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [
|
||||
_column_0,
|
||||
_column_5,
|
||||
_column_1,
|
||||
_column_6,
|
||||
_column_7,
|
||||
_column_8,
|
||||
_column_9,
|
||||
_column_10,
|
||||
_column_11,
|
||||
_column_4,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null,
|
||||
);
|
||||
late final Shape2 taskCompletions = Shape2(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'task_completions',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [],
|
||||
columns: [_column_0, _column_12, _column_13],
|
||||
attachedDatabase: database,
|
||||
),
|
||||
alias: null,
|
||||
);
|
||||
}
|
||||
|
||||
class Shape0 extends i0.VersionedTable {
|
||||
Shape0({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get id =>
|
||||
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<String> get name =>
|
||||
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get iconName =>
|
||||
columnsByName['icon_name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<int> get sortOrder =>
|
||||
columnsByName['sort_order']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get createdAt =>
|
||||
columnsByName['created_at']! as i1.GeneratedColumn<int>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<int> _column_0(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'id',
|
||||
aliasedName,
|
||||
false,
|
||||
hasAutoIncrement: true,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT',
|
||||
);
|
||||
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>(
|
||||
'name',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.string,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
i1.GeneratedColumn<String> _column_2(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>(
|
||||
'icon_name',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.string,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_3(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'sort_order',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL DEFAULT 0',
|
||||
defaultValue: const i1.CustomExpression('0'),
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_4(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'created_at',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
|
||||
class Shape1 extends i0.VersionedTable {
|
||||
Shape1({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get id =>
|
||||
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get roomId =>
|
||||
columnsByName['room_id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<String> get name =>
|
||||
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get description =>
|
||||
columnsByName['description']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<int> get intervalType =>
|
||||
columnsByName['interval_type']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get intervalDays =>
|
||||
columnsByName['interval_days']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get anchorDay =>
|
||||
columnsByName['anchor_day']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get effortLevel =>
|
||||
columnsByName['effort_level']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get nextDueDate =>
|
||||
columnsByName['next_due_date']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get createdAt =>
|
||||
columnsByName['created_at']! as i1.GeneratedColumn<int>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<int> _column_5(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'room_id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL REFERENCES rooms(id)',
|
||||
);
|
||||
i1.GeneratedColumn<String> _column_6(String aliasedName) =>
|
||||
i1.GeneratedColumn<String>(
|
||||
'description',
|
||||
aliasedName,
|
||||
true,
|
||||
type: i1.DriftSqlType.string,
|
||||
$customConstraints: 'NULL',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_7(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'interval_type',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_8(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'interval_days',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL DEFAULT 1',
|
||||
defaultValue: const i1.CustomExpression('1'),
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_9(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'anchor_day',
|
||||
aliasedName,
|
||||
true,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NULL',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_10(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'effort_level',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_11(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'next_due_date',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
|
||||
class Shape2 extends i0.VersionedTable {
|
||||
Shape2({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get id =>
|
||||
columnsByName['id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get taskId =>
|
||||
columnsByName['task_id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get completedAt =>
|
||||
columnsByName['completed_at']! as i1.GeneratedColumn<int>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<int> _column_12(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'task_id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL REFERENCES tasks(id)',
|
||||
);
|
||||
i1.GeneratedColumn<int> _column_13(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>(
|
||||
'completed_at',
|
||||
aliasedName,
|
||||
false,
|
||||
type: i1.DriftSqlType.int,
|
||||
$customConstraints: 'NOT NULL',
|
||||
);
|
||||
i0.MigrationStepWithVersion migrationSteps({
|
||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||
}) {
|
||||
return (currentVersion, database) async {
|
||||
switch (currentVersion) {
|
||||
case 1:
|
||||
final schema = Schema2(database: database);
|
||||
final migrator = i1.Migrator(database, schema);
|
||||
await from1To2(migrator, schema);
|
||||
return 2;
|
||||
default:
|
||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
i1.OnUpgrade stepByStep({
|
||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||
}) => i0.VersionedSchema.stepByStepHelper(
|
||||
step: migrationSteps(from1To2: from1To2),
|
||||
);
|
||||
Reference in New Issue
Block a user