diff --git a/apps/app_seeds/android/app/build.gradle.kts b/apps/app_seeds/android/app/build.gradle.kts
index b0e4713..ecc470d 100644
--- a/apps/app_seeds/android/app/build.gradle.kts
+++ b/apps/app_seeds/android/app/build.gradle.kts
@@ -73,6 +73,17 @@ android {
} else {
signingConfigs.getByName("debug")
}
+ // R8: shrink + optimize + obfuscate the Java/Kotlin bytecode and strip
+ // unused resources — Play's "app optimization" recommendation (smaller
+ // download, less memory). Native .so libs are untouched, so this does
+ // not change device/ABI compatibility. Keep rules for reflection/JNI
+ // heavy deps (OCR, SQLCipher, notifications) live in proguard-rules.pro.
+ isMinifyEnabled = true
+ isShrinkResources = true
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro",
+ )
}
}
}
diff --git a/apps/app_seeds/android/app/proguard-rules.pro b/apps/app_seeds/android/app/proguard-rules.pro
new file mode 100644
index 0000000..3d061e3
--- /dev/null
+++ b/apps/app_seeds/android/app/proguard-rules.pro
@@ -0,0 +1,40 @@
+# R8/ProGuard keep rules for Tane (org.comunes.tane).
+#
+# R8 is enabled for release builds (see build.gradle.kts). It shrinks/optimizes
+# the Java/Kotlin bytecode and can break code reached only via reflection or JNI
+# — the native plugins below load their Java classes from C, so R8 can't see the
+# references and would strip/rename them. Keep them explicitly. Start
+# conservative; trim only after a release smoke test proves a class is unused.
+
+# --- Flutter engine & embedding (defensive; usually handled by the plugin) ---
+-keep class io.flutter.** { *; }
+-keep class io.flutter.plugins.** { *; }
+-dontwarn io.flutter.embedding.**
+
+# --- On-device OCR: tesseract4android (JNI) ---
+# libtesseract/libleptonica call back into these Java classes by name.
+-keep class com.googlecode.tesseract.android.** { *; }
+-keep class com.googlecode.leptonica.android.** { *; }
+-keep class io.paratoner.flutter_tesseract_ocr.** { *; }
+
+# --- QR scanning: zxing_barcode_scanner (pure ZXing, platform view) ---
+-keep class com.shirisharyal.zxing_barcode_scanner.** { *; }
+
+# --- Encrypted DB: SQLCipher / sqlite3 native loader ---
+# sqlite3 is reached over FFI (dlopen), but keep the loader plugin classes.
+-keep class eu.simonbinder.sqlite3_flutter_libs.** { *; }
+-keep class net.zetetic.** { *; }
+-dontwarn net.zetetic.**
+
+# --- Local notifications ---
+# Published keep rules for flutter_local_notifications' Gson-serialized models.
+-keep class com.dexterous.** { *; }
+-keep class com.google.gson.** { *; }
+-keep class * extends com.google.gson.TypeAdapter
+-keepattributes Signature
+-keepattributes *Annotation*
+-dontwarn com.google.errorprone.annotations.**
+
+# --- Core library desugaring ---
+-dontwarn java.lang.invoke.**
+-dontwarn build.IgnoreJava8API
diff --git a/apps/app_seeds/android/app/src/main/AndroidManifest.xml b/apps/app_seeds/android/app/src/main/AndroidManifest.xml
index 677d645..3ea677f 100644
--- a/apps/app_seeds/android/app/src/main/AndroidManifest.xml
+++ b/apps/app_seeds/android/app/src/main/AndroidManifest.xml
@@ -5,6 +5,19 @@
+
+
+
+
+
+
+
when (call.method) {
"getCoarseLatLon" -> getCoarseLatLon(result)
+ "hasCamera" -> result.success(hasCameraHardware())
else -> result.notImplemented()
}
}
@@ -72,6 +73,15 @@ class MainActivity : FlutterActivity() {
}
}
+ /**
+ * Whether this device has any camera. Camera-less devices (Chromebooks,
+ * Android Automotive, many TVs) are supported — see AndroidManifest's
+ * uses-feature required="false" — so the QR scan and camera-capture UI
+ * hide themselves when this is false instead of offering broken actions.
+ */
+ private fun hasCameraHardware(): Boolean =
+ packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
+
private fun hasLocationPermission(): Boolean =
ContextCompat.checkSelfPermission(
this,
diff --git a/apps/app_seeds/drift_schemas/drift_schema_v14.json b/apps/app_seeds/drift_schemas/drift_schema_v14.json
new file mode 100644
index 0000000..623b534
--- /dev/null
+++ b/apps/app_seeds/drift_schemas/drift_schema_v14.json
@@ -0,0 +1,2509 @@
+{
+ "_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": "varieties",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "label",
+ "getter_name": "label",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "species_id",
+ "getter_name": "speciesId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "cultivar_name",
+ "getter_name": "cultivarName",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "category",
+ "getter_name": "category",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "notes",
+ "getter_name": "notes",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_draft",
+ "getter_name": "isDraft",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_draft\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_draft\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_organic",
+ "getter_name": "isOrganic",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_organic\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_organic\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "needs_reproduction",
+ "getter_name": "needsReproduction",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"needs_reproduction\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"needs_reproduction\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "sow_months",
+ "getter_name": "sowMonths",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "transplant_months",
+ "getter_name": "transplantMonths",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "flowering_months",
+ "getter_name": "floweringMonths",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "fruiting_months",
+ "getter_name": "fruitingMonths",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "seed_harvest_months",
+ "getter_name": "seedHarvestMonths",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 1,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "variety_vernacular_names",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "variety_id",
+ "getter_name": "varietyId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "name",
+ "getter_name": "name",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "language",
+ "getter_name": "language",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "region",
+ "getter_name": "region",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 2,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "species",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "scientific_name",
+ "getter_name": "scientificName",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "wikidata_qid",
+ "getter_name": "wikidataQid",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "gbif_key",
+ "getter_name": "gbifKey",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "family",
+ "getter_name": "family",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_bundled",
+ "getter_name": "isBundled",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_bundled\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_bundled\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "viability_years",
+ "getter_name": "viabilityYears",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 3,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "species_common_names",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "species_id",
+ "getter_name": "speciesId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "name",
+ "getter_name": "name",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "language",
+ "getter_name": "language",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 4,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "lots",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "variety_id",
+ "getter_name": "varietyId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "type",
+ "getter_name": "type",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('\\'seed\\'')",
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(LotType.values)",
+ "dart_type_name": "LotType"
+ }
+ },
+ {
+ "name": "harvest_year",
+ "getter_name": "harvestYear",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "harvest_month",
+ "getter_name": "harvestMonth",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_kind",
+ "getter_name": "quantityKind",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_precise",
+ "getter_name": "quantityPrecise",
+ "moor_type": "double",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_label",
+ "getter_name": "quantityLabel",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "presentation",
+ "getter_name": "presentation",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(Presentation.values)",
+ "dart_type_name": "Presentation"
+ }
+ },
+ {
+ "name": "storage_location",
+ "getter_name": "storageLocation",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "offer_status",
+ "getter_name": "offerStatus",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('\\'private\\'')",
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(OfferStatus.values)",
+ "dart_type_name": "OfferStatus"
+ }
+ },
+ {
+ "name": "seedbank_id",
+ "getter_name": "seedbankId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "origin_name",
+ "getter_name": "originName",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "origin_place",
+ "getter_name": "originPlace",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "abundance",
+ "getter_name": "abundance",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(Abundance.values)",
+ "dart_type_name": "Abundance"
+ }
+ },
+ {
+ "name": "preservation_format",
+ "getter_name": "preservationFormat",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PreservationFormat.values)",
+ "dart_type_name": "PreservationFormat"
+ }
+ },
+ {
+ "name": "price_amount",
+ "getter_name": "priceAmount",
+ "moor_type": "double",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "price_currency",
+ "getter_name": "priceCurrency",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 5,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "germination_tests",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "lot_id",
+ "getter_name": "lotId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "tested_on",
+ "getter_name": "testedOn",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "sample_size",
+ "getter_name": "sampleSize",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "germinated_count",
+ "getter_name": "germinatedCount",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "notes",
+ "getter_name": "notes",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 6,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "condition_checks",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "lot_id",
+ "getter_name": "lotId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "checked_on",
+ "getter_name": "checkedOn",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "container_count",
+ "getter_name": "containerCount",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "desiccant_state",
+ "getter_name": "desiccantState",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(DesiccantState.values)",
+ "dart_type_name": "DesiccantState"
+ }
+ },
+ {
+ "name": "notes",
+ "getter_name": "notes",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 7,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "garden_outcomes",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "lot_id",
+ "getter_name": "lotId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "year",
+ "getter_name": "year",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "rating",
+ "getter_name": "rating",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(GardenOutcomeRating.values)",
+ "dart_type_name": "GardenOutcomeRating"
+ }
+ },
+ {
+ "name": "notes",
+ "getter_name": "notes",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 8,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "movements",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "lot_id",
+ "getter_name": "lotId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "type",
+ "getter_name": "type",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(MovementType.values)",
+ "dart_type_name": "MovementType"
+ }
+ },
+ {
+ "name": "occurred_on",
+ "getter_name": "occurredOn",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "counterparty_id",
+ "getter_name": "counterpartyId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_kind",
+ "getter_name": "quantityKind",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_precise",
+ "getter_name": "quantityPrecise",
+ "moor_type": "double",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "quantity_label",
+ "getter_name": "quantityLabel",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "parent_movement_id",
+ "getter_name": "parentMovementId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "plantare_id",
+ "getter_name": "plantareId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "notes",
+ "getter_name": "notes",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 9,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "parties",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "display_name",
+ "getter_name": "displayName",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "public_key",
+ "getter_name": "publicKey",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "kind",
+ "getter_name": "kind",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('\\'person\\'')",
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PartyKind.values)",
+ "dart_type_name": "PartyKind"
+ }
+ },
+ {
+ "name": "note",
+ "getter_name": "note",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 10,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "attachments",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "parent_type",
+ "getter_name": "parentType",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(ParentType.values)",
+ "dart_type_name": "ParentType"
+ }
+ },
+ {
+ "name": "parent_id",
+ "getter_name": "parentId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "kind",
+ "getter_name": "kind",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(AttachmentKind.values)",
+ "dart_type_name": "AttachmentKind"
+ }
+ },
+ {
+ "name": "uri",
+ "getter_name": "uri",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "bytes",
+ "getter_name": "bytes",
+ "moor_type": "blob",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "thumbnail",
+ "getter_name": "thumbnail",
+ "moor_type": "blob",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "mime_type",
+ "getter_name": "mimeType",
+ "moor_type": "string",
+ "nullable": true,
+ "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": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 11,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "external_links",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "parent_type",
+ "getter_name": "parentType",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(ParentType.values)",
+ "dart_type_name": "ParentType"
+ }
+ },
+ {
+ "name": "parent_id",
+ "getter_name": "parentId",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "url",
+ "getter_name": "url",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "title",
+ "getter_name": "title",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 12,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "plantares",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "variety_id",
+ "getter_name": "varietyId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "direction",
+ "getter_name": "direction",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PlantareDirection.values)",
+ "dart_type_name": "PlantareDirection"
+ }
+ },
+ {
+ "name": "counterparty",
+ "getter_name": "counterparty",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "owed_description",
+ "getter_name": "owedDescription",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "made_on",
+ "getter_name": "madeOn",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "due_by",
+ "getter_name": "dueBy",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "status",
+ "getter_name": "status",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('\\'open\\'')",
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PlantareStatus.values)",
+ "dart_type_name": "PlantareStatus"
+ }
+ },
+ {
+ "name": "settled_on",
+ "getter_name": "settledOn",
+ "moor_type": "int",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "note",
+ "getter_name": "note",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "pledge_id",
+ "getter_name": "pledgeId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "debtor_key",
+ "getter_name": "debtorKey",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "creditor_key",
+ "getter_name": "creditorKey",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "debtor_signature",
+ "getter_name": "debtorSignature",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "creditor_signature",
+ "getter_name": "creditorSignature",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "movement_id",
+ "getter_name": "movementId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "remote_state",
+ "getter_name": "remoteState",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PlantareRemoteState.values)",
+ "dart_type_name": "PlantareRemoteState"
+ }
+ },
+ {
+ "name": "return_kind",
+ "getter_name": "returnKind",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('\\'similar\\'')",
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(PlantareReturnKind.values)",
+ "dart_type_name": "PlantareReturnKind"
+ }
+ },
+ {
+ "name": "work_hours",
+ "getter_name": "workHours",
+ "moor_type": "double",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 13,
+ "references": [],
+ "type": "table",
+ "data": {
+ "name": "sales",
+ "was_declared_in_moor": false,
+ "columns": [
+ {
+ "name": "id",
+ "getter_name": "id",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "created_at",
+ "getter_name": "createdAt",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "updated_at",
+ "getter_name": "updatedAt",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "last_author",
+ "getter_name": "lastAuthor",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "is_deleted",
+ "getter_name": "isDeleted",
+ "moor_type": "bool",
+ "nullable": false,
+ "customConstraints": null,
+ "defaultConstraints": "CHECK (\"is_deleted\" IN (0, 1))",
+ "dialectAwareDefaultConstraints": {
+ "sqlite": "CHECK (\"is_deleted\" IN (0, 1))"
+ },
+ "default_dart": "const CustomExpression('0')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "schema_row_version",
+ "getter_name": "schemaRowVersion",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": "const CustomExpression('1')",
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "variety_id",
+ "getter_name": "varietyId",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "direction",
+ "getter_name": "direction",
+ "moor_type": "string",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": [],
+ "type_converter": {
+ "dart_expr": "const EnumNameConverter(SaleDirection.values)",
+ "dart_type_name": "SaleDirection"
+ }
+ },
+ {
+ "name": "counterparty",
+ "getter_name": "counterparty",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "amount",
+ "getter_name": "amount",
+ "moor_type": "double",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "currency",
+ "getter_name": "currency",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "sold_on",
+ "getter_name": "soldOn",
+ "moor_type": "int",
+ "nullable": false,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ },
+ {
+ "name": "note",
+ "getter_name": "note",
+ "moor_type": "string",
+ "nullable": true,
+ "customConstraints": null,
+ "default_dart": null,
+ "default_client_dart": null,
+ "dsl_features": []
+ }
+ ],
+ "is_virtual": false,
+ "without_rowid": false,
+ "constraints": [],
+ "explicit_pk": [
+ "id"
+ ]
+ }
+ },
+ {
+ "id": 14,
+ "references": [
+ 0
+ ],
+ "type": "index",
+ "data": {
+ "on": 0,
+ "name": "idx_varieties_deleted_draft",
+ "sql": null,
+ "unique": false,
+ "columns": [
+ {
+ "column": "is_deleted",
+ "order_by": null
+ },
+ {
+ "column": "is_draft",
+ "order_by": null
+ }
+ ]
+ }
+ },
+ {
+ "id": 15,
+ "references": [
+ 4
+ ],
+ "type": "index",
+ "data": {
+ "on": 4,
+ "name": "idx_lots_variety",
+ "sql": null,
+ "unique": false,
+ "columns": [
+ {
+ "column": "variety_id",
+ "order_by": null
+ }
+ ]
+ }
+ },
+ {
+ "id": 16,
+ "references": [
+ 10
+ ],
+ "type": "index",
+ "data": {
+ "on": 10,
+ "name": "idx_attachments_parent",
+ "sql": null,
+ "unique": false,
+ "columns": [
+ {
+ "column": "parent_type",
+ "order_by": null
+ },
+ {
+ "column": "parent_id",
+ "order_by": null
+ },
+ {
+ "column": "kind",
+ "order_by": null
+ }
+ ]
+ }
+ }
+ ],
+ "fixed_sql": [
+ {
+ "name": "varieties",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"varieties\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"label\" TEXT NOT NULL, \"species_id\" TEXT NULL, \"cultivar_name\" TEXT NULL, \"category\" TEXT NULL, \"notes\" TEXT NULL, \"is_draft\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_draft\" IN (0, 1)), \"is_organic\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_organic\" IN (0, 1)), \"needs_reproduction\" INTEGER NOT NULL DEFAULT 0 CHECK (\"needs_reproduction\" IN (0, 1)), \"sow_months\" INTEGER NULL, \"transplant_months\" INTEGER NULL, \"flowering_months\" INTEGER NULL, \"fruiting_months\" INTEGER NULL, \"seed_harvest_months\" INTEGER NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "variety_vernacular_names",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"variety_vernacular_names\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"variety_id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"language\" TEXT NULL, \"region\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "species",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"species\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"scientific_name\" TEXT NOT NULL, \"wikidata_qid\" TEXT NULL, \"gbif_key\" INTEGER NULL, \"family\" TEXT NULL, \"is_bundled\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_bundled\" IN (0, 1)), \"viability_years\" INTEGER NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "species_common_names",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"species_common_names\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"species_id\" TEXT NOT NULL, \"name\" TEXT NOT NULL, \"language\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "lots",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"lots\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"variety_id\" TEXT NOT NULL, \"type\" TEXT NOT NULL DEFAULT 'seed', \"harvest_year\" INTEGER NULL, \"harvest_month\" INTEGER NULL, \"quantity_kind\" TEXT NULL, \"quantity_precise\" REAL NULL, \"quantity_label\" TEXT NULL, \"presentation\" TEXT NULL, \"storage_location\" TEXT NULL, \"offer_status\" TEXT NOT NULL DEFAULT 'private', \"seedbank_id\" TEXT NULL, \"origin_name\" TEXT NULL, \"origin_place\" TEXT NULL, \"abundance\" TEXT NULL, \"preservation_format\" TEXT NULL, \"price_amount\" REAL NULL, \"price_currency\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "germination_tests",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"germination_tests\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"lot_id\" TEXT NOT NULL, \"tested_on\" INTEGER NULL, \"sample_size\" INTEGER NULL, \"germinated_count\" INTEGER NULL, \"notes\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "condition_checks",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"condition_checks\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"lot_id\" TEXT NOT NULL, \"checked_on\" INTEGER NULL, \"container_count\" INTEGER NULL, \"desiccant_state\" TEXT NULL, \"notes\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "garden_outcomes",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"garden_outcomes\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"lot_id\" TEXT NOT NULL, \"year\" INTEGER NULL, \"rating\" TEXT NULL, \"notes\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "movements",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"movements\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"last_author\" TEXT NOT NULL, \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"lot_id\" TEXT NOT NULL, \"type\" TEXT NOT NULL, \"occurred_on\" INTEGER NULL, \"counterparty_id\" TEXT NULL, \"quantity_kind\" TEXT NULL, \"quantity_precise\" REAL NULL, \"quantity_label\" TEXT NULL, \"parent_movement_id\" TEXT NULL, \"plantare_id\" TEXT NULL, \"notes\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "parties",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"parties\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"display_name\" TEXT NOT NULL, \"public_key\" TEXT NULL, \"kind\" TEXT NOT NULL DEFAULT 'person', \"note\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "attachments",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"attachments\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"parent_type\" TEXT NOT NULL, \"parent_id\" TEXT NOT NULL, \"kind\" TEXT NOT NULL, \"uri\" TEXT NULL, \"bytes\" BLOB NULL, \"thumbnail\" BLOB NULL, \"mime_type\" TEXT NULL, \"sort_order\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "external_links",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"external_links\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"parent_type\" TEXT NOT NULL, \"parent_id\" TEXT NOT NULL, \"url\" TEXT NOT NULL, \"title\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "plantares",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"plantares\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"variety_id\" TEXT NULL, \"direction\" TEXT NOT NULL, \"counterparty\" TEXT NULL, \"owed_description\" TEXT NULL, \"made_on\" INTEGER NOT NULL, \"due_by\" INTEGER NULL, \"status\" TEXT NOT NULL DEFAULT 'open', \"settled_on\" INTEGER NULL, \"note\" TEXT NULL, \"pledge_id\" TEXT NULL, \"debtor_key\" TEXT NULL, \"creditor_key\" TEXT NULL, \"debtor_signature\" TEXT NULL, \"creditor_signature\" TEXT NULL, \"movement_id\" TEXT NULL, \"remote_state\" TEXT NULL, \"return_kind\" TEXT NOT NULL DEFAULT 'similar', \"work_hours\" REAL NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "sales",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE TABLE IF NOT EXISTS \"sales\" (\"id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL, \"updated_at\" TEXT NOT NULL, \"last_author\" TEXT NOT NULL, \"is_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted\" IN (0, 1)), \"schema_row_version\" INTEGER NOT NULL DEFAULT 1, \"variety_id\" TEXT NULL, \"direction\" TEXT NOT NULL, \"counterparty\" TEXT NULL, \"amount\" REAL NULL, \"currency\" TEXT NULL, \"sold_on\" INTEGER NOT NULL, \"note\" TEXT NULL, PRIMARY KEY (\"id\"));"
+ }
+ ]
+ },
+ {
+ "name": "idx_varieties_deleted_draft",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE INDEX idx_varieties_deleted_draft ON varieties (is_deleted, is_draft)"
+ }
+ ]
+ },
+ {
+ "name": "idx_lots_variety",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE INDEX idx_lots_variety ON lots (variety_id)"
+ }
+ ]
+ },
+ {
+ "name": "idx_attachments_parent",
+ "sql": [
+ {
+ "dialect": "sqlite",
+ "sql": "CREATE INDEX idx_attachments_parent ON attachments (parent_type, parent_id, kind)"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/apps/app_seeds/fastlane/Fastfile b/apps/app_seeds/fastlane/Fastfile
index 6a52523..5f3437a 100644
--- a/apps/app_seeds/fastlane/Fastfile
+++ b/apps/app_seeds/fastlane/Fastfile
@@ -16,13 +16,24 @@ default_platform(:android)
AAB_PATH = "build/app/outputs/bundle/release/app-release.aab".freeze
platform :android do
- desc "Upload the signed AAB + store listing to Google Play (internal track)"
+ desc "Upload the signed AAB + store listing to Google Play (production, 100%)"
lane :deploy_play do
+ supply(
+ track: "production",
+ aab: AAB_PATH,
+ release_status: "completed", # publish to 100% of users (subject to review)
+ skip_upload_apk: true, # we ship the AAB, not a raw APK
+ skip_upload_changelogs: false,
+ )
+ end
+
+ desc "Upload the signed AAB to the internal test track (manual QA safety net)"
+ lane :deploy_internal do
supply(
track: "internal",
aab: AAB_PATH,
release_status: "completed", # internal testing has no review delay
- skip_upload_apk: true, # we ship the AAB, not a raw APK
+ skip_upload_apk: true,
skip_upload_changelogs: false,
)
end
diff --git a/apps/app_seeds/lib/bootstrap.dart b/apps/app_seeds/lib/bootstrap.dart
index 57ab427..e0ecc26 100644
--- a/apps/app_seeds/lib/bootstrap.dart
+++ b/apps/app_seeds/lib/bootstrap.dart
@@ -9,6 +9,7 @@ import 'data/variety_repository.dart';
import 'di/injector.dart';
import 'i18n/strings.g.dart';
import 'services/auto_backup_service.dart';
+import 'services/camera_availability.dart';
import 'services/coarse_location.dart';
import 'services/inbox_service.dart';
import 'services/locale_store.dart';
@@ -50,6 +51,11 @@ class _BootstrapState extends State {
Future _boot() async {
await configureDependencies();
+ // Detect camera presence once, before the home screen builds, so camera-less
+ // devices (Chromebooks, Automotive, some TVs) hide the QR scan / camera UI
+ // instead of offering broken actions. Non-Android platforms keep the default.
+ await initCameraAvailability();
+
// The saved language lives in the keystore, so it can only be applied once
// DI is up. Until now the splash showed in the device language (it has no
// text), so there is no visible flip.
diff --git a/apps/app_seeds/lib/data/variety_repository.dart b/apps/app_seeds/lib/data/variety_repository.dart
index dd5e877..da4b511 100644
--- a/apps/app_seeds/lib/data/variety_repository.dart
+++ b/apps/app_seeds/lib/data/variety_repository.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
import 'package:async/async.dart';
import 'package:commons_core/commons_core.dart';
import 'package:drift/drift.dart';
@@ -652,13 +654,27 @@ class VarietyRepository {
required this.idGen,
required this.nodeId,
int Function()? nowMillis,
+ Uint8List? Function(Uint8List)? thumbnailBuilder,
}) : _now = nowMillis ?? (() => DateTime.now().millisecondsSinceEpoch),
+ _thumbnailBuilder = thumbnailBuilder,
_clock = Hlc.zero(nodeId);
final AppDatabase _db;
final IdGen idGen;
final String nodeId;
final int Function() _now;
+
+ /// Builds the small list-avatar thumbnail from a full photo. Injected (from
+ /// `services/offer_thumbnail.dart` in production) so the data layer stays free
+ /// of the image codec and unit tests run without decoding. Null → no
+ /// thumbnail is stored and the list falls back to the full photo.
+ final Uint8List? Function(Uint8List)? _thumbnailBuilder;
+
+ /// The thumbnail for [photoBytes], or null when no builder is wired or the
+ /// bytes aren't decodable. Wrapped in a Value for direct use in a companion.
+ Value _thumbValue(Uint8List photoBytes) =>
+ Value(_thumbnailBuilder?.call(photoBytes));
+
Hlc _clock;
/// Emits the non-deleted inventory, ordered by category then label, each with
@@ -696,7 +712,11 @@ class VarietyRepository {
_db.select(_db.species).watch().map((_) {}),
_db.select(_db.lots).watch().map((_) {}),
]);
- return triggers.asyncMap(
+ // Coalesce bursts: a single quick-add or handover touches several of these
+ // tables at once, and each would otherwise re-run the full (7-query) load.
+ // Debouncing collapses the burst into one reload — decisive with a large
+ // inventory.
+ return _debounce(triggers, const Duration(milliseconds: 250)).asyncMap(
(_) async => (items: await _loadInventory(), drafts: await _loadDrafts()),
);
}
@@ -929,7 +949,10 @@ class VarietyRepository {
return rows.map((l) => l.varietyId).toSet();
}
- /// Loads the first photo BLOB for each of [varietyIds] (one query).
+ /// Loads the first photo's small [thumbnail] for each of [varietyIds] (one
+ /// query) — for the inventory-list avatar. Falls back to the full-resolution
+ /// [bytes] only when a thumbnail hasn't been generated yet (older rows,
+ /// pending lazy backfill), so the list stays correct meanwhile.
Future