Skip to content

Data import and export

This page introduces the import and export architecture used by NAHPU. It is written for contributors who know basic programming concepts but are still learning the NAHPU codebase. Start here, then read the focused pages for import workflows, export workflows, templates and presets, and adding a taxon group.

NAHPU has three kinds of portable information:

  1. Project data: projects, specimens, sites, events, personnel, taxonomy, media metadata, attributes, and relationships. Drift stores this data in SQLite.
  2. Reproducibility settings: controlled lists, record-export presets, document templates, document layouts, and related configuration. The nahpu_configs Rust crate stores these values in redb.
  3. Files: media, fonts, maps, and associated files. Dart services manage their paths and metadata in the app documents directory.

SharedPreferences stores local UI choices, such as the currently selected layout. It is not a project-data store and should not be used for values that another installation must reproduce.

Flutter screen
│ user action and progress state
Riverpod provider or Dart service
├── Drift queries and validation ──► SQLite project database
├── file and media services ───────► app documents directory
└── generated bridge binding
rust/src/api wrapper
reusable nahpu_api crate
parser, writer, archive, GIS, package, or PDF output

Screens select files and display previews; they should not own database queries, merge decisions, or serialization. Dart services assemble records, resolve project relationships, validate application rules, and decide what is safe to write. Rust wrappers convert Dart-friendly values to bridge-friendly types. Reusable parsing, writing, conversion, and package behavior belongs in the appropriate NAHPU API crate.

Not every path uses every layer. Taxonomy import uses a Rust tabular reader, while project merge is coordinated almost entirely in Dart. A full database backup uses archive wrappers but does not convert project rows into a new wire format.

WorkflowDirectionMain formatsWhat it is forRestorable?
Taxonomy importImportXLSX, CSV, TSVAdd taxon registry rowsNo
Project informationBothJSON, QRCreate or share project metadataNo
Record exchangeBothJSON, ZIP, TAR.GZMove one site, event, or specimenRecord-level
Project transferBothJSON.GZ, ZIP, TAR.GZMerge or copy one projectImportable/mergeable
Database backupBothSQLite, ZIP, TAR.GZRestore the complete installationYes
User configsBothJSON, JSON.GZReproduce settings and presetsConfig-only
Record exportExportCSV, TSV, XLSX, JSONSpreadsheet, analysis, or database exchangeNo
Statistics exportExportCSV, TSV, XLSX, JSONSave calculated tablesNo
Publishing bundlesExportDwC-A, DwC-DP, NAHPU DPStandards exchange or reproducible packageDepends on format
Document exportExportPDFLabels, tags, sheets, and reportsNo
Coordinate exchangeBothGeoJSON, KML, GPX, Shapefile ZIP, QRMove point coordinatesRecord-level
Map-layer importImportGeoJSON, Shapefile ZIP, PMTilesAdd reference layers to mapsIncluded in full backup
Templates and presetsBothJSONReuse output configurationConfig-only

The lower-level API crates may support formats that the current Flutter screens do not expose. Document the shipped UI behavior separately from crate capabilities; adding a crate function does not automatically add an app feature.

Use this sequence when adding or changing an exchange workflow:

  1. Inspect the input or build an explicit output request.
  2. Check type markers, schema versions, required fields, project ownership, and archive paths.
  3. Produce a preview, manifest, or import plan before mutating data.
  4. Stage archives and intermediate files in a unique temporary directory.
  5. Write the database transaction or final output file.
  6. Copy media and associated files only after their manifest entries validate.
  7. Invalidate affected providers and show warnings or errors to the user.
  8. Delete temporary files on both success and failure.

Version markers must be rejected when they are newer than the current reader. Older versions need an explicit in-memory migration or compatibility adapter. Never silently attach a row to another project, fall back to another taxon group, or partially replace a database after a failed validation.