Data Models
Data Models
This section summarises the core graph schema. Full details live in database/neo4j-core-schema.md.
Node Labels
| Label | Purpose |
|——-|———|
| ObjectClass | Blueprint / template definition |
| ObjectInstance | Physical item |
| PlingsIdentifier | Physical or digital identifier (QR/NFC) |
| ScanEvent | Historical scan record |
| SubSpace | Tiny compartment definition (see subspace docs) |
Relationship Types (excerpt)
| Type | Between | Description |
|——|———|————-|
| INSTANCE_OF | ObjectInstance → ObjectClass | Ties instance to blueprint |
| PART_OF | ObjectInstance → ObjectInstance | Composition hierarchy |
| IN, ON, UNDER, … | ObjectInstance ↔ ObjectInstance | Spatial predicates |
| IDENTIFIES | PlingsIdentifier → ObjectInstance | Identifier mapping |
| SCANNED | ScanEvent → PlingsIdentifier | Event record |
| SUBCLASS_OF | ObjectClass → ObjectClass | Class taxonomy |
| Functional predicates | Obj ↔ Obj | Compatibility (POWERS, WORKS_WITH, etc.) |
Core GraphQL Types
ObjectInstance
type ObjectInstance = {
id: string; // Unique identifier
name: string; // Display name
description?: string; // Optional description
owner: string; // Owner identifier
statuses: string[]; // Current status list
imageUrls: string[]; // Array of image URLs
mainImageUrl?: string; // Primary image URL
location?: string; // Current location description
partOf?: ObjectInstance; // Parent object reference
spatialChildren?: ObjectInstance[]; // Child objects
};
Status System Types
StatusDefinition
type StatusDefinition = {
key: string; // Status identifier (e.g., "for_sale")
name: string; // Display name (e.g., "For Sale")
description: string; // Human-readable description
color: string; // UI color identifier
category: string; // Grouping category
isTerminal: boolean; // Whether this is an end-of-life status
conflictsWith: string[]; // Mutually exclusive statuses
requiresActiveFalse: boolean; // Cannot coexist with "active"
};
StatusValidationResult
type StatusValidationResult = {
valid: boolean;
errors: string[];
warnings: string[];
};
Status Categories
operational- Normal operational statescommerce- Sale, auction, transfer statescustody- External custody situationstransit- Movement and shipping statesproblem- Lost, stolen, broken statesservice- Maintenance and repair statesend-of-life- Terminal disposal states
Image Management Types
Image Upload Input
type ImageUploadInput = {
objectId: string; // Target object ID
images: File[]; // Array of image files
};
Image Delete Input
type ImageDeleteInput = {
objectId: string; // Target object ID
imageUrls: string[]; // URLs of images to delete
};
Image Update Input
type ImageUpdateInput = {
objectId: string; // Target object ID
newImages?: File[]; // Optional new images to add
deleteImageUrls?: string[]; // Optional image URLs to delete
};
Image Storage Structure
- Bucket:
object-images(Supabase Storage) - Path Pattern:
objects/ObjectInstance/{objectId}/{uniqueFilename} - Supported Formats: JPEG, PNG, WebP
- Size Limits: 5MB per file
- Auto-generated: UUID-based unique filenames
Postgres Tables
See supabase_schema.sql for DDL. Key tables:
object_instances- Core object metadata withmain_image_urlandneo4j_idobject_images- Individual image records withobject_instance_id,public_url,uploaded_atorganizations,organization_members- Multi-tenancyfunctional_predicates,spatial_predicates- Relationship definitions
⚠️ CRITICAL: Column names verified against production database:
object_images.object_instance_id(FK to object_instances)object_images.public_url(NOT image_url)object_images.uploaded_at(NOT created_at)object_instances.neo4j_id(updated from legacy terminusdb_id)
RLS policies enforce tenant isolation and ownership checks.
Status: Updated with comprehensive image management types (2025-06-18)
Last Updated: Thu Jul 10 09:18:47 CEST 2025 - Standardized PlingsIdentifier relationship from POINTS_TO to IDENTIFIES