Skip to main content

Farm Data Model (FDM) Database Schema

This document provides a comprehensive overview of the Farm Data Model (FDM) database schema. It details each schema and table, their properties, and columns, explaining their purpose and how they relate to the overall data structure.

Schema Overview

The FDM database is organized into three distinct PostgreSQL schemas:

  1. fdm: Contains the core tables related to farm management, fields, cultivations, fertilizers, soil data, etc.
  2. fdm-authn: Handles authentication, storing user accounts, sessions, and related information. This schema is largely managed by the better-auth library.
  3. fdm-authz: Manages authorization, defining roles, permissions, and maintaining an audit trail.

fdm Schema (Core Farm Data)

This schema holds the primary data related to farm operations.

Farms & Fields

farms

Purpose: Stores basic information about each farm entity in the system.

ColumnTypeConstraintsDescription
b_id_farmtextPrimary KeyUnique identifier for the farm.
b_name_farmtextName of the farm.
b_businessid_farmtextBusiness ID associated with the farm.
b_address_farmtextPhysical address of the farm.
b_postalcode_farmtextPostal code of the farm address.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_id_farm.

fields

Purpose: Stores information about each agricultural field, including its geometry and identifiers.

ColumnTypeConstraintsDescription
b_idtextPrimary KeyUnique identifier for the field.
b_nametextNot NullName of the field.
b_geometrygeometry (Polygon, SRID 4326)Polygon geometry representing the field boundary. See Custom Types section.
b_id_sourcetextOptional identifier from an external data source.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_id.
  • GIST index on b_geometry for spatial queries.

fieldAcquiring

Purpose: Tracks the relationship between a farm and a field it manages, including the method and timeframe of acquisition. Replaces the old farmManaging concept.

ColumnTypeConstraintsDescription
b_idtextNot Null, Foreign Key (references fields.b_id)Identifier of the field being acquired.
b_id_farmtextNot Null, Foreign Key (references farms.b_id_farm)Identifier of the farm acquiring the field.
b_starttimestamp with time zoneTimestamp indicating the start of the farm's management/acquisition.
b_acquiring_methodacquiringMethodEnumNot Null (default: 'unknown')Method by which the farm acquired the field (e.g., 'owner', 'lease').
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Constraints:

  • Primary Key on (b_id, b_id_farm).
acquiringMethodEnum
  • Name: b_acquiring_method
  • Possible values: owner, lease, unknown

fieldDiscarding

Purpose: Marks when a field is no longer actively managed or used within the system.

ColumnTypeConstraintsDescription
b_idtextPrimary Key, Foreign Key (references fields.b_id)Identifier of the field being discarded.
b_endtimestamp with time zoneTimestamp indicating when the field was discarded.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Cultivations

cultivationsCatalogue

Purpose: A standardized catalogue of possible cultivation types (crops, cover crops, etc.).

ColumnTypeConstraintsDescription
b_lu_cataloguetextPrimary KeyUnique identifier for the cultivation type in the catalogue.
b_lu_sourcetextNot NullIdentifier for the source of this catalogue entry (e.g., 'BRP', 'EuroCrops').
b_lu_nametextNot NullName of the cultivation (often in the local language, e.g., Dutch).
b_lu_name_entextEnglish name of the cultivation.
b_lu_harvestableharvestableEnumNot NullIndicates if/how the cultivation is typically harvested ('none', 'once', 'multiple').
b_lu_hcat3textHierarchical grouping code (e.g., from EuroCrops).
b_lu_hcat3_nametextHuman-readable name of the hierarchical grouping.
hashtextA hash value representing the content of the catalogue entry, for change tracking.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_lu_catalogue.
harvestableEnum
  • Name: b_lu_harvestable
  • Possible values: none, once, multiple

cultivations

Purpose: Represents an instance of a cultivation being grown, linking it to its catalogue definition.

ColumnTypeConstraintsDescription
b_lutextPrimary KeyUnique identifier for this specific cultivation instance.
b_lu_cataloguetextNot Null, Foreign Key (references cultivationsCatalogue.b_lu_catalogue)Links to the type of cultivation in the catalogue.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_lu.

cultivationStarting

Purpose: Records the event of starting a specific cultivation instance on a particular field. Replaces fieldSowing.

ColumnTypeConstraintsDescription
b_idtextNot Null, Foreign Key (references fields.b_id)Identifier of the field where the cultivation is started.
b_lutextNot Null, Foreign Key (references cultivations.b_lu)Identifier of the cultivation instance being started.
b_lu_starttimestamp with time zoneTimestamp indicating the start of the cultivation (e.g., sowing date).
b_sowing_amountnumeric (custom)Amount of seed/material used for sowing (units may vary).
b_sowing_methodtextMethod used for sowing/planting.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Constraints:

  • Primary Key on (b_id, b_lu).

cultivationEnding

Purpose: Marks the end date for a specific cultivation instance.

ColumnTypeConstraintsDescription
b_lutextPrimary Key, Foreign Key (references cultivations.b_lu)Identifier of the cultivation instance ending.
b_lu_endtimestamp with time zoneTimestamp indicating the end of the cultivation (e.g., final harvest, termination).
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

cultivationCatalogueSelecting

Purpose: Indicates which cultivation catalogues are actively selected or used by a specific farm.

ColumnTypeConstraintsDescription
b_id_farmtextNot Null, Foreign Key (references farms.b_id_farm)Identifier of the farm selecting the catalogue source.
b_lu_sourcetextNot NullIdentifier of the cultivation catalogue source being selected.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Constraints:

  • Primary Key on (b_id_farm, b_lu_source).

Harvestables

harvestables

Purpose: Represents a potential or actual harvestable product derived from a cultivation.

ColumnTypeConstraintsDescription
b_id_harvestabletextPrimary KeyUnique identifier for the harvestable product.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_id_harvestable.

harvestableAnalyses

Purpose: Stores the results of analyses performed on harvested products.

ColumnTypeConstraintsDescription
b_id_harvestable_analysistextPrimary KeyUnique identifier for the harvest analysis record.
b_lu_yieldnumeric (custom)Measured yield of the harvestable product (units may vary, e.g., kg/ha).
b_lu_n_harvestablenumeric (custom)Nitrogen content in the harvested portion.
b_lu_n_residuenumeric (custom)Nitrogen content in the crop residue.
b_lu_p_harvestablenumeric (custom)Phosphorus content in the harvested portion.
b_lu_p_residuenumeric (custom)Phosphorus content in the crop residue.
b_lu_k_harvestablenumeric (custom)Potassium content in the harvested portion.
b_lu_k_residuenumeric (custom)Potassium content in the crop residue.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on b_id_harvestable_analysis.

harvestableSampling

Purpose: Links a harvestable product instance to its analysis results, recording the sampling date.

ColumnTypeConstraintsDescription
b_id_harvestabletextNot Null, Foreign Key (references harvestables.b_id_harvestable)Identifier of the harvestable product sampled.
b_id_harvestable_analysistextNot Null, Foreign Key (references harvestableAnalyses.b_id_harvestable_analysis)Identifier of the analysis performed on the sample.
b_sampling_datetimestamp with time zoneTimestamp when the harvestable product was sampled for analysis.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Constraints:

  • Primary Key on (b_id_harvestable, b_id_harvestable_analysis).

cultivationHarvesting

Purpose: Records a specific harvesting event, linking the cultivation instance to the resulting harvestable product.

ColumnTypeConstraintsDescription
b_id_harvestingtextPrimary KeyUnique identifier for this harvesting event.
b_id_harvestabletextNot Null, Foreign Key (references harvestables.b_id_harvestable)Identifier of the harvestable product obtained from this event.
b_lutextNot Null, Foreign Key (references cultivations.b_lu)Identifier of the cultivation instance that was harvested.
b_lu_harvest_datetimestamp with time zoneTimestamp when the harvesting event occurred.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Fertilizers

fertilizersCatalogue

Purpose: A standardized catalogue of fertilizer products, detailing their composition and properties.

ColumnTypeConstraintsDescription
p_id_cataloguetextPrimary KeyUnique identifier for the fertilizer type in the catalogue.
p_sourcetextNot NullIdentifier for the source of this catalogue entry (e.g., 'SRM', 'NMI').
p_name_nltextNot NullName of the fertilizer (often in Dutch).
p_name_entextEnglish name of the fertilizer.
p_descriptiontextAdditional descriptive text about the fertilizer.
p_dmnumeric (custom)Dry Matter content (%).
p_densitynumeric (custom)Density (e.g., kg/m³).
p_omnumeric (custom)Organic Matter content (%).
... (many more nutrient columns like p_n_rt, p_p_rt, p_k_rt, etc.)numeric (custom)Content of various macro/micro-nutrients and elements.
p_type_manurebooleanFlag indicating if it's a manure type fertilizer.
p_type_mineralbooleanFlag indicating if it's a mineral type fertilizer.
p_type_compostbooleanFlag indicating if it's a compost type fertilizer.
hashtextA hash value representing the content of the catalogue entry, for change tracking.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on p_id_catalogue.

fertilizers

Purpose: Represents an instance of a fertilizer product (e.g., a specific batch or acquisition).

ColumnTypeConstraintsDescription
p_idtextPrimary KeyUnique identifier for this fertilizer instance.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on p_id.

fertilizerAcquiring

Purpose: Tracks the acquisition of a specific fertilizer instance by a farm.

ColumnTypeConstraintsDescription
b_id_farmtextNot Null, Foreign Key (references farms.b_id_farm)Identifier of the farm acquiring the fertilizer.
p_idtextNot Null, Foreign Key (references fertilizers.p_id)Identifier of the fertilizer instance being acquired.
p_acquiring_amountnumeric (custom)Quantity of fertilizer acquired (in kg).
p_acquiring_datetimestamp with time zoneTimestamp when the fertilizer was acquired.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

fertilizerPicking

Purpose: Links a specific fertilizer instance to its corresponding entry in the fertilizersCatalogue.

ColumnTypeConstraintsDescription
p_idtextNot Null, Foreign Key (references fertilizers.p_id)Identifier of the fertilizer instance.
p_id_cataloguetextNot Null, Foreign Key (references fertilizersCatalogue.p_id_catalogue)Identifier of the catalogue entry matching this fertilizer instance.
p_picking_datetimestamp with time zoneTimestamp when this fertilizer instance was matched to a catalogue entry.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

fertilizerApplying (formerly fertilizerApplication)

Purpose: Logs the event of applying a specific fertilizer instance to a field.

ColumnTypeConstraintsDescription
p_app_idtextPrimary KeyUnique identifier for this application event.
b_idtextNot Null, Foreign Key (references fields.b_id)Identifier of the field where the fertilizer was applied.
p_idtextNot Null, Foreign Key (references fertilizers.p_id)Identifier of the fertilizer instance applied.
p_app_amountnumeric (custom)Amount of fertilizer applied (typically kg/ha).
p_app_methodapplicationMethodEnumMethod used for application (e.g., 'injection', 'spraying').
p_app_datetimestamp with time zoneTimestamp when the application occurred.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Indexes:

  • Unique index on p_app_id.
applicationMethodEnum
  • Name: p_app_method
  • Possible values: slotted coulter, incorporation, injection, spraying, broadcasting, spoke wheel, pocket placement

fertilizerCatalogueEnabling

Purpose: Indicates which fertilizer catalogue sources are actively enabled or used by a specific farm.

ColumnTypeConstraintsDescription
b_id_farmtextNot Null, Foreign Key (references farms.b_id_farm)Identifier of the farm enabling the catalogue source.
p_sourcetextNot NullIdentifier of the fertilizer catalogue source being enabled.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

Constraints:

  • Primary Key on (b_id_farm, p_source).

Soil

soilAnalysis

Purpose: Stores the results of a soil analysis.

ColumnTypeConstraintsDescription
a_idtextPrimary KeyUnique identifier for the soil analysis record.
a_datetimestamp with time zoneTimestamp indicating when the analysis was performed or reported.
a_sourcetextSource or laboratory that performed the analysis.
a_p_alnumeric (custom)P-Al value (Phosphate extracted with Ammonium Lactate).
a_p_ccnumeric (custom)P-CaCl2 value (Plant-available Phosphorus extracted with CaCl2).
a_som_loinumeric (custom)Soil Organic Matter content determined by Loss on Ignition (%).
b_gwl_classgwlClassEnumGroundwater level classification.
b_soiltype_agrsoiltypeEnumAgricultural soil type classification.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.
soiltypeEnum
  • Name: b_soiltype_agr
  • Possible values: moerige_klei, rivierklei, dekzand, zeeklei, dalgrond, veen, loess, duinzand, maasklei
gwlClassEnum
  • Name: b_gwl_class
  • Possible values: II, IV, IIIb, V, VI, VII, Vb, -, Va, III, VIII, sVI, I, IIb, sVII, IVu, bVII, sV, sVb, bVI, IIIa

soilSampling

Purpose: Records the details of a soil sampling event, linking a field location to a soil analysis.

ColumnTypeConstraintsDescription
b_id_samplingtextPrimary KeyUnique identifier for the soil sampling event.
b_idtextNot Null, Foreign Key (references fields.b_id)Identifier of the field where the sample was taken.
a_idtextNot Null, Foreign Key (references soilAnalysis.a_id)Identifier of the analysis performed on this sample.
b_depthnumeric (custom)Depth at which the soil sample was taken (units may vary, e.g., cm).
b_sampling_datetimestamp with time zoneTimestamp when the sample was collected.
b_sampling_geometrygeometry (MultiPoint, SRID 4326)MultiPoint geometry representing the location(s) where the sample(s) were taken. See Custom Types section.
createdtimestamp with time zoneNot NullTimestamp when this record was created (default: now()).
updatedtimestamp with time zoneTimestamp when this record was last updated.

fdm-authn Schema (Authentication)

This schema handles user authentication, sessions, accounts, and related functionalities.

Note: This schema is largely defined and managed by the better-auth library. While the specific table structures are documented here for completeness, refer to the better-auth documentation for the most detailed information on its implementation and usage.

user

Purpose: Stores user account information.

ColumnTypeConstraintsDescription
idtextPrimary KeyUnique identifier for the user.
nametextNot NullUser's display name.
emailtextNot Null, UniqueUser's email address.
emailVerifiedbooleanNot NullFlag indicating if the email address is verified.
imagetextURL to the user's profile image.
createdAttimestampNot NullTimestamp when the user account was created.
updatedAttimestampNot NullTimestamp when the user account was last updated.
firstnametextUser's first name.
surnametextUser's surname.
langtextNot NullUser's preferred language code (e.g., 'en', 'nl').
farm_activetextIdentifier of the user's currently active farm.

session

Purpose: Stores active user sessions.

ColumnTypeConstraintsDescription
idtextPrimary KeyUnique identifier for the session.
expiresAttimestampNot NullTimestamp when the session expires.
tokentextNot Null, UniqueThe session token.
createdAttimestampNot NullTimestamp when the session was created.
updatedAttimestampNot NullTimestamp when the session was last updated.
ipAddresstextIP address associated with the session.
userAgenttextUser agent string of the client.
userIdtextNot Null, Foreign Key (references user.id, onDelete: cascade)Identifier of the user associated with the session.

account

Purpose: Links user accounts to external authentication providers (e.g., OAuth providers) or stores credentials for password-based login.

ColumnTypeConstraintsDescription
idtextPrimary KeyUnique identifier for the account link.
accountIdtextNot NullThe user's ID as provided by the external provider or internal system.
providerIdtextNot NullIdentifier of the authentication provider (e.g., 'google', 'credentials').
userIdtextNot Null, Foreign Key (references user.id, onDelete: cascade)Identifier of the FDM user associated with this account.
accessTokentextAccess token provided by the OAuth provider.
refreshTokentextRefresh token provided by the OAuth provider.
idTokentextID token provided by the OAuth provider.
accessTokenExpiresAttimestampTimestamp when the access token expires.
refreshTokenExpiresAttimestampTimestamp when the refresh token expires (if applicable).
scopetextScope granted by the OAuth provider.
passwordtextHashed password for credentials-based authentication.
createdAttimestampNot NullTimestamp when the account link was created.
updatedAttimestampNot NullTimestamp when the account link was last updated.

verification

Purpose: Stores tokens used for verification purposes (e.g., email verification, password reset).

ColumnTypeConstraintsDescription
idtextPrimary KeyUnique identifier for the verification record.
identifiertextNot NullIdentifier associated with the verification (e.g., email).
valuetextNot NullThe verification token or code.
expiresAttimestampNot NullTimestamp when the verification token expires.
createdAttimestampTimestamp when the verification record was created.
updatedAttimestampTimestamp when the verification record was last updated.

rateLimit

Purpose: Used for tracking and enforcing rate limits on certain actions.

ColumnTypeConstraintsDescription
idtextPrimary KeyUnique identifier for the rate limit record.
keytextKey identifying the resource being rate-limited.
countintegerCurrent count of requests for the key.
lastRequestbigintTimestamp (as number/epoch) of the last request.

fdm-authz Schema (Authorization)

This schema manages roles, permissions, and auditing for authorization purposes.

role

Purpose: Defines roles assigned to principals (users) for specific resources.

ColumnTypeConstraintsDescription
role_idtextPrimary KeyUnique identifier for the role assignment.
resourcetextNot NullType of the resource (e.g., 'farm', 'field').
resource_idtextNot NullIdentifier of the specific resource instance.
principal_idtextNot NullIdentifier of the principal (user) being assigned the role.
roletextNot NullThe role being assigned (e.g., 'admin', 'viewer').
createdtimestamp with time zoneNot NullTimestamp when the role assignment was created (default: now()).
deletedtimestamp with time zoneTimestamp when the role assignment was revoked (soft delete).

Indexes:

  • Composite index on (resource, resource_id, principal_id, role, deleted).

audit

Purpose: Logs authorization checks (audit trail) to record who attempted what action on which resource.

ColumnTypeConstraintsDescription
audit_idtextPrimary KeyUnique identifier for the audit log entry.
audit_timestamptimestamp with time zoneNot NullTimestamp when the audit event occurred (default: now()).
audit_origintextNot NullSystem or component originating the audit log (e.g., 'api', 'app').
principal_idtextNot NullIdentifier of the principal (user) performing the action.
target_resourcetextNot NullType of the resource being acted upon.
target_resource_idtextNot NullIdentifier of the specific resource instance being acted upon.
granting_resourcetextNot NullType of the resource through which access was potentially granted.
granting_resource_idtextNot NullIdentifier of the specific granting resource instance.
actiontextNot NullThe action being attempted (e.g., 'read', 'update', 'delete').
allowedbooleanNot NullWhether the action was allowed based on authorization rules.
durationintegerNot NullDuration of the authorization check in milliseconds.

Custom Types

These custom types are defined in schema-custom-types.ts to handle specific data representations.

numericCasted

  • Purpose: A workaround for Drizzle ORM potentially returning numeric SQL types as strings. This custom type ensures that numeric values are correctly parsed as numbers (float) in the application layer.
  • SQL Type: numeric or numeric(precision, scale)
  • Application Type: number

geometry

  • Purpose: Handles PostGIS geometry types, allowing storage and retrieval of GeoJSON-like data.
  • SQL Type: geometry (optionally constrained, e.g., geometry(Polygon, 4326))
  • Application Type: GeoJSON Geometry object (e.g., Polygon, MultiPoint).
  • Dependencies: Requires the PostGIS extension enabled in the PostgreSQL database.
  • Current Implementation: The provided code in schema-custom-types.ts includes parsing logic primarily for Polygon and MultiPoint types when reading from the database (especially from hexewkb format). Writing uses ST_GeomFromGeoJSON. Support for other geometry types might be limited or require additional parsing logic.
  • SRID: Assumes SRID 4326 (WGS 84).