feat(app): ask 'how did it do?' when a harvest is noted (schema v13)
The note growers most wish they had two seasons later — did it do well, was it worth keeping — never had a home. New append-only GardenOutcomes table (lotId, season year, three-face rating, free note); the question appears ONCE, inline, right after recording a harvest in the batch story, and is skippable without a trace. The answer shows as one more story line. Rides backups/sync like every mutable table (JSON codec, LWW import, HLC clock absorb). Migration v12→v13 guarded + verified from every historical version.
This commit is contained in:
parent
92fd84590b
commit
bb5b3d4a43
20 changed files with 6030 additions and 15 deletions
|
|
@ -18,6 +18,7 @@ part 'database.g.dart';
|
|||
Lots,
|
||||
GerminationTests,
|
||||
ConditionChecks,
|
||||
GardenOutcomes,
|
||||
Movements,
|
||||
Parties,
|
||||
Attachments,
|
||||
|
|
@ -31,7 +32,7 @@ class AppDatabase extends _$AppDatabase {
|
|||
|
||||
/// Current schema version; also stamped into interchange exports so an
|
||||
/// importer knows which app generation wrote the file (data-model §7).
|
||||
static const int currentSchemaVersion = 12;
|
||||
static const int currentSchemaVersion = 13;
|
||||
|
||||
@override
|
||||
int get schemaVersion => currentSchemaVersion;
|
||||
|
|
@ -187,6 +188,14 @@ class AppDatabase extends _$AppDatabase {
|
|||
await addIfMissing('return_kind', plantares.returnKind);
|
||||
await addIfMissing('work_hours', plantares.workHours);
|
||||
}
|
||||
// v13: GardenOutcomes — the per-season "how did it do in my garden"
|
||||
// answer (rating + note) captured when a harvest is recorded. Guarded
|
||||
// (see the v7 note above).
|
||||
if (from < 13) {
|
||||
if (!await _hasTable('garden_outcomes')) {
|
||||
await m.createTable(gardenOutcomes);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -5765,6 +5765,624 @@ class ConditionChecksCompanion extends UpdateCompanion<ConditionCheck> {
|
|||
}
|
||||
}
|
||||
|
||||
class $GardenOutcomesTable extends GardenOutcomes
|
||||
with TableInfo<$GardenOutcomesTable, GardenOutcome> {
|
||||
@override
|
||||
final GeneratedDatabase attachedDatabase;
|
||||
final String? _alias;
|
||||
$GardenOutcomesTable(this.attachedDatabase, [this._alias]);
|
||||
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||
@override
|
||||
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
||||
'id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
);
|
||||
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||
'createdAt',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<int> createdAt = GeneratedColumn<int>(
|
||||
'created_at',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: true,
|
||||
);
|
||||
static const VerificationMeta _updatedAtMeta = const VerificationMeta(
|
||||
'updatedAt',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<String> updatedAt = GeneratedColumn<String>(
|
||||
'updated_at',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
);
|
||||
static const VerificationMeta _lastAuthorMeta = const VerificationMeta(
|
||||
'lastAuthor',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<String> lastAuthor = GeneratedColumn<String>(
|
||||
'last_author',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
);
|
||||
static const VerificationMeta _isDeletedMeta = const VerificationMeta(
|
||||
'isDeleted',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<bool> isDeleted = GeneratedColumn<bool>(
|
||||
'is_deleted',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.bool,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||
'CHECK ("is_deleted" IN (0, 1))',
|
||||
),
|
||||
defaultValue: const Constant(false),
|
||||
);
|
||||
static const VerificationMeta _schemaRowVersionMeta = const VerificationMeta(
|
||||
'schemaRowVersion',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<int> schemaRowVersion = GeneratedColumn<int>(
|
||||
'schema_row_version',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
defaultValue: const Constant(1),
|
||||
);
|
||||
static const VerificationMeta _lotIdMeta = const VerificationMeta('lotId');
|
||||
@override
|
||||
late final GeneratedColumn<String> lotId = GeneratedColumn<String>(
|
||||
'lot_id',
|
||||
aliasedName,
|
||||
false,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: true,
|
||||
);
|
||||
static const VerificationMeta _yearMeta = const VerificationMeta('year');
|
||||
@override
|
||||
late final GeneratedColumn<int> year = GeneratedColumn<int>(
|
||||
'year',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumnWithTypeConverter<GardenOutcomeRating?, String>
|
||||
rating = GeneratedColumn<String>(
|
||||
'rating',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
).withConverter<GardenOutcomeRating?>($GardenOutcomesTable.$converterratingn);
|
||||
static const VerificationMeta _notesMeta = const VerificationMeta('notes');
|
||||
@override
|
||||
late final GeneratedColumn<String> notes = GeneratedColumn<String>(
|
||||
'notes',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.string,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
lastAuthor,
|
||||
isDeleted,
|
||||
schemaRowVersion,
|
||||
lotId,
|
||||
year,
|
||||
rating,
|
||||
notes,
|
||||
];
|
||||
@override
|
||||
String get aliasedName => _alias ?? actualTableName;
|
||||
@override
|
||||
String get actualTableName => $name;
|
||||
static const String $name = 'garden_outcomes';
|
||||
@override
|
||||
VerificationContext validateIntegrity(
|
||||
Insertable<GardenOutcome> instance, {
|
||||
bool isInserting = false,
|
||||
}) {
|
||||
final context = VerificationContext();
|
||||
final data = instance.toColumns(true);
|
||||
if (data.containsKey('id')) {
|
||||
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
|
||||
} else if (isInserting) {
|
||||
context.missing(_idMeta);
|
||||
}
|
||||
if (data.containsKey('created_at')) {
|
||||
context.handle(
|
||||
_createdAtMeta,
|
||||
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||
);
|
||||
} else if (isInserting) {
|
||||
context.missing(_createdAtMeta);
|
||||
}
|
||||
if (data.containsKey('updated_at')) {
|
||||
context.handle(
|
||||
_updatedAtMeta,
|
||||
updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta),
|
||||
);
|
||||
} else if (isInserting) {
|
||||
context.missing(_updatedAtMeta);
|
||||
}
|
||||
if (data.containsKey('last_author')) {
|
||||
context.handle(
|
||||
_lastAuthorMeta,
|
||||
lastAuthor.isAcceptableOrUnknown(data['last_author']!, _lastAuthorMeta),
|
||||
);
|
||||
} else if (isInserting) {
|
||||
context.missing(_lastAuthorMeta);
|
||||
}
|
||||
if (data.containsKey('is_deleted')) {
|
||||
context.handle(
|
||||
_isDeletedMeta,
|
||||
isDeleted.isAcceptableOrUnknown(data['is_deleted']!, _isDeletedMeta),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('schema_row_version')) {
|
||||
context.handle(
|
||||
_schemaRowVersionMeta,
|
||||
schemaRowVersion.isAcceptableOrUnknown(
|
||||
data['schema_row_version']!,
|
||||
_schemaRowVersionMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('lot_id')) {
|
||||
context.handle(
|
||||
_lotIdMeta,
|
||||
lotId.isAcceptableOrUnknown(data['lot_id']!, _lotIdMeta),
|
||||
);
|
||||
} else if (isInserting) {
|
||||
context.missing(_lotIdMeta);
|
||||
}
|
||||
if (data.containsKey('year')) {
|
||||
context.handle(
|
||||
_yearMeta,
|
||||
year.isAcceptableOrUnknown(data['year']!, _yearMeta),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('notes')) {
|
||||
context.handle(
|
||||
_notesMeta,
|
||||
notes.isAcceptableOrUnknown(data['notes']!, _notesMeta),
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {id};
|
||||
@override
|
||||
GardenOutcome map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||
return GardenOutcome(
|
||||
id: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}id'],
|
||||
)!,
|
||||
createdAt: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}created_at'],
|
||||
)!,
|
||||
updatedAt: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}updated_at'],
|
||||
)!,
|
||||
lastAuthor: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}last_author'],
|
||||
)!,
|
||||
isDeleted: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.bool,
|
||||
data['${effectivePrefix}is_deleted'],
|
||||
)!,
|
||||
schemaRowVersion: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}schema_row_version'],
|
||||
)!,
|
||||
lotId: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}lot_id'],
|
||||
)!,
|
||||
year: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}year'],
|
||||
),
|
||||
rating: $GardenOutcomesTable.$converterratingn.fromSql(
|
||||
attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}rating'],
|
||||
),
|
||||
),
|
||||
notes: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.string,
|
||||
data['${effectivePrefix}notes'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
$GardenOutcomesTable createAlias(String alias) {
|
||||
return $GardenOutcomesTable(attachedDatabase, alias);
|
||||
}
|
||||
|
||||
static JsonTypeConverter2<GardenOutcomeRating, String, String>
|
||||
$converterrating = const EnumNameConverter<GardenOutcomeRating>(
|
||||
GardenOutcomeRating.values,
|
||||
);
|
||||
static JsonTypeConverter2<GardenOutcomeRating?, String?, String?>
|
||||
$converterratingn = JsonTypeConverter2.asNullable($converterrating);
|
||||
}
|
||||
|
||||
class GardenOutcome extends DataClass implements Insertable<GardenOutcome> {
|
||||
final String id;
|
||||
final int createdAt;
|
||||
final String updatedAt;
|
||||
final String lastAuthor;
|
||||
final bool isDeleted;
|
||||
final int schemaRowVersion;
|
||||
final String lotId;
|
||||
final int? year;
|
||||
final GardenOutcomeRating? rating;
|
||||
final String? notes;
|
||||
const GardenOutcome({
|
||||
required this.id,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.lastAuthor,
|
||||
required this.isDeleted,
|
||||
required this.schemaRowVersion,
|
||||
required this.lotId,
|
||||
this.year,
|
||||
this.rating,
|
||||
this.notes,
|
||||
});
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
map['id'] = Variable<String>(id);
|
||||
map['created_at'] = Variable<int>(createdAt);
|
||||
map['updated_at'] = Variable<String>(updatedAt);
|
||||
map['last_author'] = Variable<String>(lastAuthor);
|
||||
map['is_deleted'] = Variable<bool>(isDeleted);
|
||||
map['schema_row_version'] = Variable<int>(schemaRowVersion);
|
||||
map['lot_id'] = Variable<String>(lotId);
|
||||
if (!nullToAbsent || year != null) {
|
||||
map['year'] = Variable<int>(year);
|
||||
}
|
||||
if (!nullToAbsent || rating != null) {
|
||||
map['rating'] = Variable<String>(
|
||||
$GardenOutcomesTable.$converterratingn.toSql(rating),
|
||||
);
|
||||
}
|
||||
if (!nullToAbsent || notes != null) {
|
||||
map['notes'] = Variable<String>(notes);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
GardenOutcomesCompanion toCompanion(bool nullToAbsent) {
|
||||
return GardenOutcomesCompanion(
|
||||
id: Value(id),
|
||||
createdAt: Value(createdAt),
|
||||
updatedAt: Value(updatedAt),
|
||||
lastAuthor: Value(lastAuthor),
|
||||
isDeleted: Value(isDeleted),
|
||||
schemaRowVersion: Value(schemaRowVersion),
|
||||
lotId: Value(lotId),
|
||||
year: year == null && nullToAbsent ? const Value.absent() : Value(year),
|
||||
rating: rating == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(rating),
|
||||
notes: notes == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(notes),
|
||||
);
|
||||
}
|
||||
|
||||
factory GardenOutcome.fromJson(
|
||||
Map<String, dynamic> json, {
|
||||
ValueSerializer? serializer,
|
||||
}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return GardenOutcome(
|
||||
id: serializer.fromJson<String>(json['id']),
|
||||
createdAt: serializer.fromJson<int>(json['createdAt']),
|
||||
updatedAt: serializer.fromJson<String>(json['updatedAt']),
|
||||
lastAuthor: serializer.fromJson<String>(json['lastAuthor']),
|
||||
isDeleted: serializer.fromJson<bool>(json['isDeleted']),
|
||||
schemaRowVersion: serializer.fromJson<int>(json['schemaRowVersion']),
|
||||
lotId: serializer.fromJson<String>(json['lotId']),
|
||||
year: serializer.fromJson<int?>(json['year']),
|
||||
rating: $GardenOutcomesTable.$converterratingn.fromJson(
|
||||
serializer.fromJson<String?>(json['rating']),
|
||||
),
|
||||
notes: serializer.fromJson<String?>(json['notes']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||
return <String, dynamic>{
|
||||
'id': serializer.toJson<String>(id),
|
||||
'createdAt': serializer.toJson<int>(createdAt),
|
||||
'updatedAt': serializer.toJson<String>(updatedAt),
|
||||
'lastAuthor': serializer.toJson<String>(lastAuthor),
|
||||
'isDeleted': serializer.toJson<bool>(isDeleted),
|
||||
'schemaRowVersion': serializer.toJson<int>(schemaRowVersion),
|
||||
'lotId': serializer.toJson<String>(lotId),
|
||||
'year': serializer.toJson<int?>(year),
|
||||
'rating': serializer.toJson<String?>(
|
||||
$GardenOutcomesTable.$converterratingn.toJson(rating),
|
||||
),
|
||||
'notes': serializer.toJson<String?>(notes),
|
||||
};
|
||||
}
|
||||
|
||||
GardenOutcome copyWith({
|
||||
String? id,
|
||||
int? createdAt,
|
||||
String? updatedAt,
|
||||
String? lastAuthor,
|
||||
bool? isDeleted,
|
||||
int? schemaRowVersion,
|
||||
String? lotId,
|
||||
Value<int?> year = const Value.absent(),
|
||||
Value<GardenOutcomeRating?> rating = const Value.absent(),
|
||||
Value<String?> notes = const Value.absent(),
|
||||
}) => GardenOutcome(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
lastAuthor: lastAuthor ?? this.lastAuthor,
|
||||
isDeleted: isDeleted ?? this.isDeleted,
|
||||
schemaRowVersion: schemaRowVersion ?? this.schemaRowVersion,
|
||||
lotId: lotId ?? this.lotId,
|
||||
year: year.present ? year.value : this.year,
|
||||
rating: rating.present ? rating.value : this.rating,
|
||||
notes: notes.present ? notes.value : this.notes,
|
||||
);
|
||||
GardenOutcome copyWithCompanion(GardenOutcomesCompanion data) {
|
||||
return GardenOutcome(
|
||||
id: data.id.present ? data.id.value : this.id,
|
||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||
lastAuthor: data.lastAuthor.present
|
||||
? data.lastAuthor.value
|
||||
: this.lastAuthor,
|
||||
isDeleted: data.isDeleted.present ? data.isDeleted.value : this.isDeleted,
|
||||
schemaRowVersion: data.schemaRowVersion.present
|
||||
? data.schemaRowVersion.value
|
||||
: this.schemaRowVersion,
|
||||
lotId: data.lotId.present ? data.lotId.value : this.lotId,
|
||||
year: data.year.present ? data.year.value : this.year,
|
||||
rating: data.rating.present ? data.rating.value : this.rating,
|
||||
notes: data.notes.present ? data.notes.value : this.notes,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('GardenOutcome(')
|
||||
..write('id: $id, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
..write('updatedAt: $updatedAt, ')
|
||||
..write('lastAuthor: $lastAuthor, ')
|
||||
..write('isDeleted: $isDeleted, ')
|
||||
..write('schemaRowVersion: $schemaRowVersion, ')
|
||||
..write('lotId: $lotId, ')
|
||||
..write('year: $year, ')
|
||||
..write('rating: $rating, ')
|
||||
..write('notes: $notes')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
id,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
lastAuthor,
|
||||
isDeleted,
|
||||
schemaRowVersion,
|
||||
lotId,
|
||||
year,
|
||||
rating,
|
||||
notes,
|
||||
);
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
(other is GardenOutcome &&
|
||||
other.id == this.id &&
|
||||
other.createdAt == this.createdAt &&
|
||||
other.updatedAt == this.updatedAt &&
|
||||
other.lastAuthor == this.lastAuthor &&
|
||||
other.isDeleted == this.isDeleted &&
|
||||
other.schemaRowVersion == this.schemaRowVersion &&
|
||||
other.lotId == this.lotId &&
|
||||
other.year == this.year &&
|
||||
other.rating == this.rating &&
|
||||
other.notes == this.notes);
|
||||
}
|
||||
|
||||
class GardenOutcomesCompanion extends UpdateCompanion<GardenOutcome> {
|
||||
final Value<String> id;
|
||||
final Value<int> createdAt;
|
||||
final Value<String> updatedAt;
|
||||
final Value<String> lastAuthor;
|
||||
final Value<bool> isDeleted;
|
||||
final Value<int> schemaRowVersion;
|
||||
final Value<String> lotId;
|
||||
final Value<int?> year;
|
||||
final Value<GardenOutcomeRating?> rating;
|
||||
final Value<String?> notes;
|
||||
final Value<int> rowid;
|
||||
const GardenOutcomesCompanion({
|
||||
this.id = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
this.updatedAt = const Value.absent(),
|
||||
this.lastAuthor = const Value.absent(),
|
||||
this.isDeleted = const Value.absent(),
|
||||
this.schemaRowVersion = const Value.absent(),
|
||||
this.lotId = const Value.absent(),
|
||||
this.year = const Value.absent(),
|
||||
this.rating = const Value.absent(),
|
||||
this.notes = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
});
|
||||
GardenOutcomesCompanion.insert({
|
||||
required String id,
|
||||
required int createdAt,
|
||||
required String updatedAt,
|
||||
required String lastAuthor,
|
||||
this.isDeleted = const Value.absent(),
|
||||
this.schemaRowVersion = const Value.absent(),
|
||||
required String lotId,
|
||||
this.year = const Value.absent(),
|
||||
this.rating = const Value.absent(),
|
||||
this.notes = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
}) : id = Value(id),
|
||||
createdAt = Value(createdAt),
|
||||
updatedAt = Value(updatedAt),
|
||||
lastAuthor = Value(lastAuthor),
|
||||
lotId = Value(lotId);
|
||||
static Insertable<GardenOutcome> custom({
|
||||
Expression<String>? id,
|
||||
Expression<int>? createdAt,
|
||||
Expression<String>? updatedAt,
|
||||
Expression<String>? lastAuthor,
|
||||
Expression<bool>? isDeleted,
|
||||
Expression<int>? schemaRowVersion,
|
||||
Expression<String>? lotId,
|
||||
Expression<int>? year,
|
||||
Expression<String>? rating,
|
||||
Expression<String>? notes,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (id != null) 'id': id,
|
||||
if (createdAt != null) 'created_at': createdAt,
|
||||
if (updatedAt != null) 'updated_at': updatedAt,
|
||||
if (lastAuthor != null) 'last_author': lastAuthor,
|
||||
if (isDeleted != null) 'is_deleted': isDeleted,
|
||||
if (schemaRowVersion != null) 'schema_row_version': schemaRowVersion,
|
||||
if (lotId != null) 'lot_id': lotId,
|
||||
if (year != null) 'year': year,
|
||||
if (rating != null) 'rating': rating,
|
||||
if (notes != null) 'notes': notes,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
|
||||
GardenOutcomesCompanion copyWith({
|
||||
Value<String>? id,
|
||||
Value<int>? createdAt,
|
||||
Value<String>? updatedAt,
|
||||
Value<String>? lastAuthor,
|
||||
Value<bool>? isDeleted,
|
||||
Value<int>? schemaRowVersion,
|
||||
Value<String>? lotId,
|
||||
Value<int?>? year,
|
||||
Value<GardenOutcomeRating?>? rating,
|
||||
Value<String?>? notes,
|
||||
Value<int>? rowid,
|
||||
}) {
|
||||
return GardenOutcomesCompanion(
|
||||
id: id ?? this.id,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
lastAuthor: lastAuthor ?? this.lastAuthor,
|
||||
isDeleted: isDeleted ?? this.isDeleted,
|
||||
schemaRowVersion: schemaRowVersion ?? this.schemaRowVersion,
|
||||
lotId: lotId ?? this.lotId,
|
||||
year: year ?? this.year,
|
||||
rating: rating ?? this.rating,
|
||||
notes: notes ?? this.notes,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||
final map = <String, Expression>{};
|
||||
if (id.present) {
|
||||
map['id'] = Variable<String>(id.value);
|
||||
}
|
||||
if (createdAt.present) {
|
||||
map['created_at'] = Variable<int>(createdAt.value);
|
||||
}
|
||||
if (updatedAt.present) {
|
||||
map['updated_at'] = Variable<String>(updatedAt.value);
|
||||
}
|
||||
if (lastAuthor.present) {
|
||||
map['last_author'] = Variable<String>(lastAuthor.value);
|
||||
}
|
||||
if (isDeleted.present) {
|
||||
map['is_deleted'] = Variable<bool>(isDeleted.value);
|
||||
}
|
||||
if (schemaRowVersion.present) {
|
||||
map['schema_row_version'] = Variable<int>(schemaRowVersion.value);
|
||||
}
|
||||
if (lotId.present) {
|
||||
map['lot_id'] = Variable<String>(lotId.value);
|
||||
}
|
||||
if (year.present) {
|
||||
map['year'] = Variable<int>(year.value);
|
||||
}
|
||||
if (rating.present) {
|
||||
map['rating'] = Variable<String>(
|
||||
$GardenOutcomesTable.$converterratingn.toSql(rating.value),
|
||||
);
|
||||
}
|
||||
if (notes.present) {
|
||||
map['notes'] = Variable<String>(notes.value);
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return (StringBuffer('GardenOutcomesCompanion(')
|
||||
..write('id: $id, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
..write('updatedAt: $updatedAt, ')
|
||||
..write('lastAuthor: $lastAuthor, ')
|
||||
..write('isDeleted: $isDeleted, ')
|
||||
..write('schemaRowVersion: $schemaRowVersion, ')
|
||||
..write('lotId: $lotId, ')
|
||||
..write('year: $year, ')
|
||||
..write('rating: $rating, ')
|
||||
..write('notes: $notes, ')
|
||||
..write('rowid: $rowid')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class $MovementsTable extends Movements
|
||||
with TableInfo<$MovementsTable, Movement> {
|
||||
@override
|
||||
|
|
@ -10810,6 +11428,7 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||
late final $ConditionChecksTable conditionChecks = $ConditionChecksTable(
|
||||
this,
|
||||
);
|
||||
late final $GardenOutcomesTable gardenOutcomes = $GardenOutcomesTable(this);
|
||||
late final $MovementsTable movements = $MovementsTable(this);
|
||||
late final $PartiesTable parties = $PartiesTable(this);
|
||||
late final $AttachmentsTable attachments = $AttachmentsTable(this);
|
||||
|
|
@ -10828,6 +11447,7 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||
lots,
|
||||
germinationTests,
|
||||
conditionChecks,
|
||||
gardenOutcomes,
|
||||
movements,
|
||||
parties,
|
||||
attachments,
|
||||
|
|
@ -13499,6 +14119,312 @@ typedef $$ConditionChecksTableProcessedTableManager =
|
|||
ConditionCheck,
|
||||
PrefetchHooks Function()
|
||||
>;
|
||||
typedef $$GardenOutcomesTableCreateCompanionBuilder =
|
||||
GardenOutcomesCompanion Function({
|
||||
required String id,
|
||||
required int createdAt,
|
||||
required String updatedAt,
|
||||
required String lastAuthor,
|
||||
Value<bool> isDeleted,
|
||||
Value<int> schemaRowVersion,
|
||||
required String lotId,
|
||||
Value<int?> year,
|
||||
Value<GardenOutcomeRating?> rating,
|
||||
Value<String?> notes,
|
||||
Value<int> rowid,
|
||||
});
|
||||
typedef $$GardenOutcomesTableUpdateCompanionBuilder =
|
||||
GardenOutcomesCompanion Function({
|
||||
Value<String> id,
|
||||
Value<int> createdAt,
|
||||
Value<String> updatedAt,
|
||||
Value<String> lastAuthor,
|
||||
Value<bool> isDeleted,
|
||||
Value<int> schemaRowVersion,
|
||||
Value<String> lotId,
|
||||
Value<int?> year,
|
||||
Value<GardenOutcomeRating?> rating,
|
||||
Value<String?> notes,
|
||||
Value<int> rowid,
|
||||
});
|
||||
|
||||
class $$GardenOutcomesTableFilterComposer
|
||||
extends Composer<_$AppDatabase, $GardenOutcomesTable> {
|
||||
$$GardenOutcomesTableFilterComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnFilters<String> get id => $composableBuilder(
|
||||
column: $table.id,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get createdAt => $composableBuilder(
|
||||
column: $table.createdAt,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get updatedAt => $composableBuilder(
|
||||
column: $table.updatedAt,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get lastAuthor => $composableBuilder(
|
||||
column: $table.lastAuthor,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<bool> get isDeleted => $composableBuilder(
|
||||
column: $table.isDeleted,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get schemaRowVersion => $composableBuilder(
|
||||
column: $table.schemaRowVersion,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get lotId => $composableBuilder(
|
||||
column: $table.lotId,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get year => $composableBuilder(
|
||||
column: $table.year,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnWithTypeConverterFilters<
|
||||
GardenOutcomeRating?,
|
||||
GardenOutcomeRating,
|
||||
String
|
||||
>
|
||||
get rating => $composableBuilder(
|
||||
column: $table.rating,
|
||||
builder: (column) => ColumnWithTypeConverterFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<String> get notes => $composableBuilder(
|
||||
column: $table.notes,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
}
|
||||
|
||||
class $$GardenOutcomesTableOrderingComposer
|
||||
extends Composer<_$AppDatabase, $GardenOutcomesTable> {
|
||||
$$GardenOutcomesTableOrderingComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
ColumnOrderings<String> get id => $composableBuilder(
|
||||
column: $table.id,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get createdAt => $composableBuilder(
|
||||
column: $table.createdAt,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get updatedAt => $composableBuilder(
|
||||
column: $table.updatedAt,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get lastAuthor => $composableBuilder(
|
||||
column: $table.lastAuthor,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<bool> get isDeleted => $composableBuilder(
|
||||
column: $table.isDeleted,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get schemaRowVersion => $composableBuilder(
|
||||
column: $table.schemaRowVersion,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get lotId => $composableBuilder(
|
||||
column: $table.lotId,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get year => $composableBuilder(
|
||||
column: $table.year,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get rating => $composableBuilder(
|
||||
column: $table.rating,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<String> get notes => $composableBuilder(
|
||||
column: $table.notes,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
}
|
||||
|
||||
class $$GardenOutcomesTableAnnotationComposer
|
||||
extends Composer<_$AppDatabase, $GardenOutcomesTable> {
|
||||
$$GardenOutcomesTableAnnotationComposer({
|
||||
required super.$db,
|
||||
required super.$table,
|
||||
super.joinBuilder,
|
||||
super.$addJoinBuilderToRootComposer,
|
||||
super.$removeJoinBuilderFromRootComposer,
|
||||
});
|
||||
GeneratedColumn<String> get id =>
|
||||
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<int> get createdAt =>
|
||||
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<String> get updatedAt =>
|
||||
$composableBuilder(column: $table.updatedAt, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<String> get lastAuthor => $composableBuilder(
|
||||
column: $table.lastAuthor,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<bool> get isDeleted =>
|
||||
$composableBuilder(column: $table.isDeleted, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<int> get schemaRowVersion => $composableBuilder(
|
||||
column: $table.schemaRowVersion,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<String> get lotId =>
|
||||
$composableBuilder(column: $table.lotId, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<int> get year =>
|
||||
$composableBuilder(column: $table.year, builder: (column) => column);
|
||||
|
||||
GeneratedColumnWithTypeConverter<GardenOutcomeRating?, String> get rating =>
|
||||
$composableBuilder(column: $table.rating, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<String> get notes =>
|
||||
$composableBuilder(column: $table.notes, builder: (column) => column);
|
||||
}
|
||||
|
||||
class $$GardenOutcomesTableTableManager
|
||||
extends
|
||||
RootTableManager<
|
||||
_$AppDatabase,
|
||||
$GardenOutcomesTable,
|
||||
GardenOutcome,
|
||||
$$GardenOutcomesTableFilterComposer,
|
||||
$$GardenOutcomesTableOrderingComposer,
|
||||
$$GardenOutcomesTableAnnotationComposer,
|
||||
$$GardenOutcomesTableCreateCompanionBuilder,
|
||||
$$GardenOutcomesTableUpdateCompanionBuilder,
|
||||
(
|
||||
GardenOutcome,
|
||||
BaseReferences<_$AppDatabase, $GardenOutcomesTable, GardenOutcome>,
|
||||
),
|
||||
GardenOutcome,
|
||||
PrefetchHooks Function()
|
||||
> {
|
||||
$$GardenOutcomesTableTableManager(
|
||||
_$AppDatabase db,
|
||||
$GardenOutcomesTable table,
|
||||
) : super(
|
||||
TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
createFilteringComposer: () =>
|
||||
$$GardenOutcomesTableFilterComposer($db: db, $table: table),
|
||||
createOrderingComposer: () =>
|
||||
$$GardenOutcomesTableOrderingComposer($db: db, $table: table),
|
||||
createComputedFieldComposer: () =>
|
||||
$$GardenOutcomesTableAnnotationComposer($db: db, $table: table),
|
||||
updateCompanionCallback:
|
||||
({
|
||||
Value<String> id = const Value.absent(),
|
||||
Value<int> createdAt = const Value.absent(),
|
||||
Value<String> updatedAt = const Value.absent(),
|
||||
Value<String> lastAuthor = const Value.absent(),
|
||||
Value<bool> isDeleted = const Value.absent(),
|
||||
Value<int> schemaRowVersion = const Value.absent(),
|
||||
Value<String> lotId = const Value.absent(),
|
||||
Value<int?> year = const Value.absent(),
|
||||
Value<GardenOutcomeRating?> rating = const Value.absent(),
|
||||
Value<String?> notes = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => GardenOutcomesCompanion(
|
||||
id: id,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
lastAuthor: lastAuthor,
|
||||
isDeleted: isDeleted,
|
||||
schemaRowVersion: schemaRowVersion,
|
||||
lotId: lotId,
|
||||
year: year,
|
||||
rating: rating,
|
||||
notes: notes,
|
||||
rowid: rowid,
|
||||
),
|
||||
createCompanionCallback:
|
||||
({
|
||||
required String id,
|
||||
required int createdAt,
|
||||
required String updatedAt,
|
||||
required String lastAuthor,
|
||||
Value<bool> isDeleted = const Value.absent(),
|
||||
Value<int> schemaRowVersion = const Value.absent(),
|
||||
required String lotId,
|
||||
Value<int?> year = const Value.absent(),
|
||||
Value<GardenOutcomeRating?> rating = const Value.absent(),
|
||||
Value<String?> notes = const Value.absent(),
|
||||
Value<int> rowid = const Value.absent(),
|
||||
}) => GardenOutcomesCompanion.insert(
|
||||
id: id,
|
||||
createdAt: createdAt,
|
||||
updatedAt: updatedAt,
|
||||
lastAuthor: lastAuthor,
|
||||
isDeleted: isDeleted,
|
||||
schemaRowVersion: schemaRowVersion,
|
||||
lotId: lotId,
|
||||
year: year,
|
||||
rating: rating,
|
||||
notes: notes,
|
||||
rowid: rowid,
|
||||
),
|
||||
withReferenceMapper: (p0) => p0
|
||||
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
|
||||
.toList(),
|
||||
prefetchHooksCallback: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
typedef $$GardenOutcomesTableProcessedTableManager =
|
||||
ProcessedTableManager<
|
||||
_$AppDatabase,
|
||||
$GardenOutcomesTable,
|
||||
GardenOutcome,
|
||||
$$GardenOutcomesTableFilterComposer,
|
||||
$$GardenOutcomesTableOrderingComposer,
|
||||
$$GardenOutcomesTableAnnotationComposer,
|
||||
$$GardenOutcomesTableCreateCompanionBuilder,
|
||||
$$GardenOutcomesTableUpdateCompanionBuilder,
|
||||
(
|
||||
GardenOutcome,
|
||||
BaseReferences<_$AppDatabase, $GardenOutcomesTable, GardenOutcome>,
|
||||
),
|
||||
GardenOutcome,
|
||||
PrefetchHooks Function()
|
||||
>;
|
||||
typedef $$MovementsTableCreateCompanionBuilder =
|
||||
MovementsCompanion Function({
|
||||
required String id,
|
||||
|
|
@ -15800,6 +16726,8 @@ class $AppDatabaseManager {
|
|||
$$GerminationTestsTableTableManager(_db, _db.germinationTests);
|
||||
$$ConditionChecksTableTableManager get conditionChecks =>
|
||||
$$ConditionChecksTableTableManager(_db, _db.conditionChecks);
|
||||
$$GardenOutcomesTableTableManager get gardenOutcomes =>
|
||||
$$GardenOutcomesTableTableManager(_db, _db.gardenOutcomes);
|
||||
$$MovementsTableTableManager get movements =>
|
||||
$$MovementsTableTableManager(_db, _db.movements);
|
||||
$$PartiesTableTableManager get parties =>
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ enum PreservationFormat {
|
|||
/// - `fresh` — just renewed (lila/violet).
|
||||
enum DesiccantState { none, add, replace, dry, fresh }
|
||||
|
||||
/// How a sowing from this batch turned out in the grower's own garden — the
|
||||
/// note people most wish they had two seasons later. Deliberately coarse
|
||||
/// (three faces, not a breeder's scorecard): the free-text note carries any
|
||||
/// nuance.
|
||||
enum GardenOutcomeRating { good, mixed, poor }
|
||||
|
||||
/// Append-only event kinds on a Lot (data-model §2.4).
|
||||
enum MovementType {
|
||||
received,
|
||||
|
|
|
|||
|
|
@ -142,6 +142,18 @@ class ConditionChecks extends Table with SyncColumns {
|
|||
TextColumn get notes => text().nullable()();
|
||||
}
|
||||
|
||||
/// "How did it do in MY garden" — one optional, skippable answer per season
|
||||
/// (v13). Captured at the natural moment (recording a harvest), shown as one
|
||||
/// more line of the lot's story. Deliberately minimal — a coarse rating plus a
|
||||
/// free note; the note carries any nuance. Mirrors [GerminationTests]: a dated
|
||||
/// log under a Lot.
|
||||
class GardenOutcomes extends Table with SyncColumns {
|
||||
TextColumn get lotId => text()();
|
||||
IntColumn get year => integer().nullable()(); // season, e.g. 2026
|
||||
TextColumn get rating => textEnum<GardenOutcomeRating>().nullable()();
|
||||
TextColumn get notes => text().nullable()();
|
||||
}
|
||||
|
||||
/// The append-only event log on a Lot — history + provenance DAG.
|
||||
class Movements extends Table with AppendOnlyColumns {
|
||||
TextColumn get lotId => text()();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue