Skip to content

Commit 2c44857

Browse files
committed
Merge remote-tracking branch 'origin/feature/macdive-native-xml' into feature/macdive-sqlite
# Conflicts: # CHANGELOG.md
2 parents 7e5d24a + f8c4616 commit 2c44857

67 files changed

Lines changed: 2310 additions & 155 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ android/fastlane/play-store-key.json
6464
.venv/
6565
venv/
6666
.python-version
67+
68+
# Sample data
69+
scripts/sample_data/

CHANGELOG.md

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ All notable changes to Submersion are documented in this file.
88
### Added
99

1010
- MacDive UDDF imports now capture substantially richer dive data: boat
11-
name and captain, dive operator, surface conditions, dive-number-of-day,
12-
weather (stored in the existing weather description field), plus site
13-
water type, body of water, and difficulty rating.
11+
name and captain, dive operator, surface conditions, weather (stored
12+
in the existing weather description field), plus site water type, body
13+
of water, and difficulty rating.
1414
- **MacDive native XML import.** MacDive's own `.xml` logbook format is now
1515
a first-class import source. Unlike MacDive UDDF (which doesn't emit tags),
1616
the native XML export carries dive tags — so users migrating tag metadata
@@ -28,13 +28,13 @@ All notable changes to Submersion are documented in this file.
2828
SQLite won't create duplicates.
2929
- **MacDive (SQLite) source override** in the import wizard's
3030
detected-source dropdown, alongside MacDive (CSV) and MacDive (XML).
31-
32-
### Fixed
33-
3431
- Cross-format import deduplication: stable per-dive UUIDs from MacDive,
3532
Shearwater Cloud, Subsurface SSRF, and generic UDDF are now preserved on
3633
the `dive_data_sources` sidecar. Re-importing the same dives in a
3734
different format no longer creates duplicates.
35+
36+
### Fixed
37+
3838
- MacDive UDDF: equipment / gear now imports correctly. The parser
3939
previously only scanned Submersion's private equipment extension,
4040
missing the standard UDDF gear location (`<diver><owner><equipment>`)
@@ -61,6 +61,29 @@ All notable changes to Submersion are documented in this file.
6161
path instead, which decodes MacDive's UDDF profile correctly.
6262

6363

64+
## 1.4.6 (2026-04-22)
65+
66+
### Bug Fixes
67+
68+
- log download failures to the file log (#258)
69+
- DB readonly-rollback recovery + cooperative import cancellation (#255)
70+
71+
### Documentation
72+
73+
- implementation plans for MacDive import milestones 1-4
74+
- design spec for robust MacDive import (UDDF, XML, SQLite, photos)
75+
76+
### Chores
77+
78+
- bump version to 1.4.6+92
79+
- changelog + plan update for MacDive UDDF gap-fill milestone
80+
81+
### Other
82+
83+
- ignore sample data
84+
- Revert "chore: changelog + plan update for MacDive UDDF gap-fill milestone"
85+
86+
6487
## 1.4.5 (2026-04-21)
6588

6689
### Features

docs/superpowers/plans/2026-04-21-macdive-uddf-gap-fill.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
- All 12 tasks landed or explicitly skipped (Task 3 proven non-bug; see Task 3 section).
1818
- Schema bumped v69 → v70 (source_uuid on dive_data_sources) → v71
19-
(7 new dive + site metadata columns: dive_number_of_day, boat_name,
20-
boat_captain, dive_operator, surface_conditions on dives; water_type,
21-
body_of_water on dive_sites).
19+
(6 new dive + site metadata columns: boat_name, boat_captain,
20+
dive_operator, surface_conditions on dives; water_type, body_of_water
21+
on dive_sites). Task 8 and Task 10's snippets below show an earlier
22+
plan that also added `dive_number_of_day`; see "Post-completion
23+
revision" note directly below.
2224
- Cross-format import dedup now works via `dive_data_sources.source_uuid`.
2325
- Parser-to-DB gap closed for MacDive rich fields. `weather` now lands
2426
on the existing weather_description column. difficulty continues to
@@ -31,6 +33,21 @@
3133
to a future milestone, likely via dive-events.
3234
- Real-sample regression test passes (gated behind `@Tags(['real-data'])`).
3335

36+
### Post-completion revision: dive_number_of_day is derived, not stored
37+
38+
Originally this milestone planned a `dive_number_of_day` INT column on
39+
`dives`, populated from UDDF `<divenumberofday>`. After landing,
40+
review found the value is trivially derivable from `diveDateTime`
41+
(`ROW_NUMBER() OVER (PARTITION BY DATE(diveDateTime) ORDER BY
42+
diveDateTime)`) and has no current reader in the app. Storing it would
43+
also desync the moment a diver manually adds a dive between two
44+
imported dives. The column, its v71 ALTER, parser extraction,
45+
`IncomingDiveData` field, and importer write path were all removed.
46+
Task 8's "Add fields to the domain model" snippet and Task 10's DB
47+
write snippet in this document are the pre-revision plan; they are
48+
kept for historical context. `<divenumberofday>` is now ignored on
49+
import and computed on demand if/when the UI needs it.
50+
3451
---
3552

3653
## File Structure

lib/core/database/database.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class Dives extends Table {
127127
TextColumn get buddy => text().nullable()();
128128
TextColumn get diveMaster => text().nullable()();
129129
// MacDive import fields — common dive metadata
130-
IntColumn get diveNumberOfDay => integer().nullable()();
131130
TextColumn get boatName => text().nullable()();
132131
TextColumn get boatCaptain => text().nullable()();
133132
TextColumn get diveOperator => text().nullable()();
@@ -3284,11 +3283,6 @@ class AppDatabase extends _$AppDatabase {
32843283
.map((r) => r.data['name'] as String)
32853284
.toSet();
32863285
if (divesCols.isNotEmpty) {
3287-
if (!divesExisting.contains('dive_number_of_day')) {
3288-
await customStatement(
3289-
'ALTER TABLE dives ADD COLUMN dive_number_of_day INTEGER',
3290-
);
3291-
}
32923286
if (!divesExisting.contains('boat_name')) {
32933287
await customStatement(
32943288
'ALTER TABLE dives ADD COLUMN boat_name TEXT',

lib/core/domain/models/incoming_dive_data.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class IncomingDiveData {
2323
final String? boatName;
2424
final String? boatCaptain;
2525
final String? diveOperator;
26-
final int? diveNumberOfDay;
2726
final String? sourceUuid;
2827

2928
const IncomingDiveData({
@@ -42,7 +41,6 @@ class IncomingDiveData {
4241
this.boatName,
4342
this.boatCaptain,
4443
this.diveOperator,
45-
this.diveNumberOfDay,
4644
this.sourceUuid,
4745
});
4846

@@ -105,7 +103,6 @@ class IncomingDiveData {
105103
boatName: data['boatName'] as String?,
106104
boatCaptain: data['boatCaptain'] as String?,
107105
diveOperator: data['diveOperator'] as String?,
108-
diveNumberOfDay: data['diveNumberOfDay'] as int?,
109106
sourceUuid: data['sourceUuid'] as String?,
110107
);
111108
}

0 commit comments

Comments
 (0)