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:
338
drift_schemas/household_keeper/drift_schema_v2.json
Normal file
338
drift_schemas/household_keeper/drift_schema_v2.json
Normal file
@@ -0,0 +1,338 @@
|
||||
{
|
||||
"_meta": {
|
||||
"description": "This file contains a serialized version of schema entities for drift.",
|
||||
"version": "1.3.0"
|
||||
},
|
||||
"options": {
|
||||
"store_date_time_values_as_text": false
|
||||
},
|
||||
"entities": [
|
||||
{
|
||||
"id": 0,
|
||||
"references": [],
|
||||
"type": "table",
|
||||
"data": {
|
||||
"name": "rooms",
|
||||
"was_declared_in_moor": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "PRIMARY KEY AUTOINCREMENT",
|
||||
"dialectAwareDefaultConstraints": {
|
||||
"sqlite": "PRIMARY KEY AUTOINCREMENT"
|
||||
},
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
"auto-increment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"getter_name": "name",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"allowed-lengths": {
|
||||
"min": 1,
|
||||
"max": 100
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "icon_name",
|
||||
"getter_name": "iconName",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "sort_order",
|
||||
"getter_name": "sortOrder",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": "const CustomExpression('0')",
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"getter_name": "createdAt",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": "() => DateTime.now()",
|
||||
"dsl_features": []
|
||||
}
|
||||
],
|
||||
"is_virtual": false,
|
||||
"without_rowid": false,
|
||||
"constraints": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"references": [
|
||||
0
|
||||
],
|
||||
"type": "table",
|
||||
"data": {
|
||||
"name": "tasks",
|
||||
"was_declared_in_moor": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "PRIMARY KEY AUTOINCREMENT",
|
||||
"dialectAwareDefaultConstraints": {
|
||||
"sqlite": "PRIMARY KEY AUTOINCREMENT"
|
||||
},
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
"auto-increment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "room_id",
|
||||
"getter_name": "roomId",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "REFERENCES rooms (id)",
|
||||
"dialectAwareDefaultConstraints": {
|
||||
"sqlite": "REFERENCES rooms (id)"
|
||||
},
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"foreign_key": {
|
||||
"to": {
|
||||
"table": "rooms",
|
||||
"column": "id"
|
||||
},
|
||||
"initially_deferred": false,
|
||||
"on_update": null,
|
||||
"on_delete": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"getter_name": "name",
|
||||
"moor_type": "string",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"allowed-lengths": {
|
||||
"min": 1,
|
||||
"max": 200
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"getter_name": "description",
|
||||
"moor_type": "string",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "interval_type",
|
||||
"getter_name": "intervalType",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [],
|
||||
"type_converter": {
|
||||
"dart_expr": "const EnumIndexConverter<IntervalType>(IntervalType.values)",
|
||||
"dart_type_name": "IntervalType"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "interval_days",
|
||||
"getter_name": "intervalDays",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": "const CustomExpression('1')",
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "anchor_day",
|
||||
"getter_name": "anchorDay",
|
||||
"moor_type": "int",
|
||||
"nullable": true,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "effort_level",
|
||||
"getter_name": "effortLevel",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [],
|
||||
"type_converter": {
|
||||
"dart_expr": "const EnumIndexConverter<EffortLevel>(EffortLevel.values)",
|
||||
"dart_type_name": "EffortLevel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "next_due_date",
|
||||
"getter_name": "nextDueDate",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
},
|
||||
{
|
||||
"name": "created_at",
|
||||
"getter_name": "createdAt",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": "() => DateTime.now()",
|
||||
"dsl_features": []
|
||||
}
|
||||
],
|
||||
"is_virtual": false,
|
||||
"without_rowid": false,
|
||||
"constraints": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"references": [
|
||||
1
|
||||
],
|
||||
"type": "table",
|
||||
"data": {
|
||||
"name": "task_completions",
|
||||
"was_declared_in_moor": false,
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"getter_name": "id",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "PRIMARY KEY AUTOINCREMENT",
|
||||
"dialectAwareDefaultConstraints": {
|
||||
"sqlite": "PRIMARY KEY AUTOINCREMENT"
|
||||
},
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
"auto-increment"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "task_id",
|
||||
"getter_name": "taskId",
|
||||
"moor_type": "int",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"defaultConstraints": "REFERENCES tasks (id)",
|
||||
"dialectAwareDefaultConstraints": {
|
||||
"sqlite": "REFERENCES tasks (id)"
|
||||
},
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": [
|
||||
{
|
||||
"foreign_key": {
|
||||
"to": {
|
||||
"table": "tasks",
|
||||
"column": "id"
|
||||
},
|
||||
"initially_deferred": false,
|
||||
"on_update": null,
|
||||
"on_delete": null
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "completed_at",
|
||||
"getter_name": "completedAt",
|
||||
"moor_type": "dateTime",
|
||||
"nullable": false,
|
||||
"customConstraints": null,
|
||||
"default_dart": null,
|
||||
"default_client_dart": null,
|
||||
"dsl_features": []
|
||||
}
|
||||
],
|
||||
"is_virtual": false,
|
||||
"without_rowid": false,
|
||||
"constraints": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"fixed_sql": [
|
||||
{
|
||||
"name": "rooms",
|
||||
"sql": [
|
||||
{
|
||||
"dialect": "sqlite",
|
||||
"sql": "CREATE TABLE IF NOT EXISTS \"rooms\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"name\" TEXT NOT NULL, \"icon_name\" TEXT NOT NULL, \"sort_order\" INTEGER NOT NULL DEFAULT 0, \"created_at\" INTEGER NOT NULL);"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tasks",
|
||||
"sql": [
|
||||
{
|
||||
"dialect": "sqlite",
|
||||
"sql": "CREATE TABLE IF NOT EXISTS \"tasks\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"room_id\" INTEGER NOT NULL REFERENCES rooms (id), \"name\" TEXT NOT NULL, \"description\" TEXT NULL, \"interval_type\" INTEGER NOT NULL, \"interval_days\" INTEGER NOT NULL DEFAULT 1, \"anchor_day\" INTEGER NULL, \"effort_level\" INTEGER NOT NULL, \"next_due_date\" INTEGER NOT NULL, \"created_at\" INTEGER NOT NULL);"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "task_completions",
|
||||
"sql": [
|
||||
{
|
||||
"dialect": "sqlite",
|
||||
"sql": "CREATE TABLE IF NOT EXISTS \"task_completions\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"task_id\" INTEGER NOT NULL REFERENCES tasks (id), \"completed_at\" INTEGER NOT NULL);"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user