Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema: spec-driven
created: 2026-08-19
skip_specs: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Context

See [proposal.md](proposal.md) for the motivation of this change.

1. `CourseDto.fromJson` assigns both `totalContents` and `totalLessons` from `'contents_count'`. `totalDuration` is also a deprecated field.
2. In `CoursesTable` (`packages/core/lib/data/db/tables/courses_table.dart`), both `totalDuration` and `totalLessons` exist as columns. Since the app has not been released yet, we can safely delete these columns from the database without a schema migration.
3. In `CourseRepository` (`packages/courses/lib/repositories/course_repository.dart`), `_lessonDtoToCompanion` method uses verbose conditional expressions `val != null ? Value(val) : const Value.absent()` for over 30 nullable fields.

## Goals / Non-Goals

**Goals:**
- Completely remove `totalDuration` and `totalLessons` from `CourseDto` and `CoursesTable`.
- Update UI references in `course_card.dart` and `info_page.dart` to use `totalContents`.
- Regenerate generated drift file `app_database.g.dart` to apply the database schema changes.
- Refactor `_lessonDtoToCompanion` to use `Value.absentIfNull` for all nullable fields to simplify mapping logic.

**Non-Goals:**
- Database schema migration scripts (since this is pre-release code).

## Decisions

### 1. Completely remove `totalDuration` and `totalLessons` columns and fields
We will:
- Delete `totalDuration` and `totalLessons` columns from `CoursesTable` in `courses_table.dart`.
- Delete `totalDuration` and `totalLessons` fields from `CourseDto` in `course_dto.dart`.
- Transition all UI files (`course_card.dart` and `info_page.dart`) and repository mapping helpers to use `totalContents`.
- Regenerate the database files using `dart run build_runner build --delete-conflicting-outputs` in the core package.

### 2. Refactor `_lessonDtoToCompanion` to use `Value.absentIfNull`
For all nullable fields mapped from `LessonDto` to `LessonsTableCompanion` in `packages/courses/lib/repositories/course_repository.dart`, we will replace `dto.field != null ? Value(dto.field) : const Value.absent()` with `Value.absentIfNull(dto.field)`.

## Risks / Trade-offs

- **Risk:** Build runner fails or other packages depend on the removed columns.
- **Mitigation:** Run `flutter analyze` on the entire monorepo after code generation to resolve any remaining references to `totalLessons` or `totalDuration`.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Why

1. `CourseDto.fromJson` contains a dead assignment where both `totalContents` and `totalLessons` are parsed from `json['contents_count']`. Because `totalLessons` is deprecated and redundant with `totalContents`, it should be completely removed, alongside the old deprecated `totalDuration` field.
2. The app is not released yet, so we can clean up the database columns `totalDuration` and `totalLessons` in `CoursesTable` directly without needing schema migrations.
3. `_lessonDtoToCompanion` in `CourseRepository` contains over 30 lines of verbose conditional checks for nullable fields (`dto.field != null ? Value(dto.field) : const Value.absent()`). These can be simplified using Drift's native `Value.absentIfNull` constructor to improve readability.

## What Changes

- Remove `totalDuration` and `totalLessons` fields completely from `CourseDto`.
- Remove `totalDuration` and `totalLessons` columns from `CoursesTable` in `courses_table.dart`, and regenerate drift schema.
- Update repository mapping functions (`rowToCourseDto` and `_courseDtoToCompanion`) to omit removed fields.
- Refactor the 30+ field mappings in `_lessonDtoToCompanion` to use `Value.absentIfNull`.

## Capabilities

### New Capabilities
<!-- None — this is a pure refactor change with no requirement/behavior changes -->

### Modified Capabilities
<!-- None — this is a pure refactor change with no requirement/behavior changes -->

> **Note:** This is a pure refactor / code cleanup. No spec-level behaviour changes.
> `skip_specs: true` has been set in `.openspec.yaml`.

## Impact

- **Files:**
- `packages/core/lib/data/models/course_dto.dart`
- `packages/core/lib/data/db/tables/courses_table.dart`
- `packages/courses/lib/repositories/course_repository.dart`
- **Scope:** Cleanups of JSON deserialization, database schema, and DB companion mapping.
- **Risk:** Medium (requires regenerating code and checking all usages of these fields/columns).
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## 1. DTO and Database Column Removal

- [x] 1.1 Delete `totalDuration` and `totalLessons` fields from `CourseDto` (`packages/core/lib/data/models/course_dto.dart`)
- [x] 1.2 Delete `totalDuration` and `totalLessons` columns from `CoursesTable` (`packages/core/lib/data/db/tables/courses_table.dart`)
- [x] 1.3 Update repository mapping helpers (`rowToCourseDto` and `_courseDtoToCompanion` in `course_repository.dart`) to completely omit these removed columns and DTO fields
- [x] 1.4 Run drift code generation (`dart run build_runner build --delete-conflicting-outputs` inside `packages/core`) to regenerate `app_database.g.dart`
- [x] 1.5 Fix `totalLessons` usages and compiler errors in `packages/exams`
- [x] 1.6 Fix `totalDuration` usages and dynamic list return type compiler error in `packages/profile`

## 2. Refactor Companion Mappings

- [x] 2.1 Refactor the 30+ nullable mapping fields in `_lessonDtoToCompanion` inside `packages/courses/lib/repositories/course_repository.dart` to use `Value.absentIfNull`

## 3. Verification

- [x] 3.1 Run static analysis across `packages/courses` and `packages/core` to ensure compilation is clean and all deprecated field usages are resolved
- [x] 3.2 Run test suite in `packages/courses` to verify no regressions are introduced

Loading