Data Model

Core Entities

ParcelDataset

Represents a logical dataset/version of parcels.

Important fields:

  • id (UUID primary key)
  • name
  • slug (unique, stable key)
  • description
  • is_active
  • created_by, created_at, updated_at

RasterDataset

Catalog row for DEM/landcover background overlays.

Important fields:

  • id
  • name, slug (unique)
  • dataset_type (DEM, LANDCOVER)
  • status (PENDING, READY, FAILED)
  • is_active, is_default
  • min_zoom, max_zoom
  • bounds fields: minx, miny, maxx, maxy
  • default_style
  • style_variants JSON (label, tile_url_template, default_opacity)

Parcel

Represents a land parcel version row (not just a single mutable record).

Important fields:

  • id (UUID primary key)
  • user (owner)
  • dataset (FK to ParcelDataset)
  • parcel_uid (stable logical parcel identity across versions)
  • parcel_id (business parcel identifier; one active row per dataset + parcel_id)
  • name, parcel_type, address, description
  • workflow fields: status, priority, tags
  • valuation/survey fields: estimated_value, last_surveyed, boundary_accuracy
  • geometry (PolygonField, SRID 4326)
  • versioning fields: valid_from, valid_to, record_status, parent_version, transaction
  • is_public, timestamps

Active-row constraints:

  • partial unique on dataset + parcel_id where valid_to IS NULL AND record_status = active
  • partial unique on dataset + parcel_uid where valid_to IS NULL AND record_status = active

Computed helpers include:

  • area_sqm, area_hectares, area_acres, area_sqft
  • centroid, perimeter_meters

ParcelTransaction

Audit event that records why version rows changed.

Important fields:

  • id (UUID)
  • dataset
  • transaction_type (e.g. edit, map_inline_edit, batch_group_edit, upload_replace, void)
  • source
  • effective_at
  • instrument_ref, notes
  • created_by, created_at

ParcelUpload

Tracks upload jobs and outcomes.

Important fields:

  • id (UUID)
  • user
  • dataset
  • filename, file_type
  • total_features, processed_features, failed_features
  • status, error_log, timestamps

UserProfile

Extends Django user with:

  • organization
  • phone
  • is_internal_user

Key Relationships

  • User 1 -> N Parcel
  • User 1 -> N ParcelTransaction (created_by)
  • ParcelDataset 1 -> N Parcel
  • ParcelDataset 1 -> N ParcelTransaction
  • User 1 -> N ParcelUpload
  • ParcelDataset 1 -> N ParcelUpload
  • User 1 -> 1 UserProfile
  • Parcel (version row) N -> 1 ParcelTransaction (nullable bootstrap cases)
  • Parcel (child version) N -> 1 Parcel (parent version)

Dataset Scope Rule

All major parcel query entry points are constrained to the active dataset. Writes default to the active dataset when not explicitly set. Only one dataset may be active at a time.