This document describes the database schema for the Asset Bundle Registry service. The schema uses PostgreSQL and is managed through migrations located in src/migrations/.
erDiagram
registries {
VARCHAR id PK "Entity ID (CID)"
VARCHAR type "Entity type"
BIGINT timestamp "Deployment timestamp"
VARCHAR_ARRAY pointers "Content pointers"
JSONB content "Entity content files"
JSONB metadata "Entity metadata"
VARCHAR status "Registry status"
JSONB bundles "Bundle conversion status"
VARCHAR deployer "Deployer address"
JSONB versions "Asset bundle versions"
}
historical_registries {
VARCHAR id PK "Entity ID (CID)"
VARCHAR type "Entity type"
BIGINT timestamp "Deployment timestamp"
VARCHAR_ARRAY pointers "Content pointers"
JSONB content "Entity content files"
JSONB metadata "Entity metadata"
VARCHAR status "Registry status"
JSONB bundles "Bundle conversion status"
VARCHAR deployer "Deployer address"
JSONB versions "Asset bundle versions"
BIGINT migrated_at "Migration timestamp"
}
profiles {
VARCHAR id PK "Profile entity ID"
VARCHAR pointer UK "User address"
BIGINT timestamp "Deployment timestamp"
JSONB content "Profile content"
JSONB metadata "Profile metadata"
BIGINT local_timestamp "Local sync timestamp"
}
processed_profile_snapshots {
VARCHAR hash PK "Snapshot hash"
TIMESTAMP process_time "Processing timestamp"
}
failed_profile_fetches {
VARCHAR entity_id PK "Failed entity ID"
VARCHAR pointer "User address"
BIGINT timestamp "Original timestamp"
JSONB auth_chain "Auth chain data"
BIGINT first_failed_at "First failure timestamp"
BIGINT last_retry_at "Last retry timestamp"
INTEGER retry_count "Number of retries"
TEXT error_message "Error description"
}
registries ||--o| historical_registries : "rotates to"
profiles ||--o| failed_profile_fetches : "may fail"
profiles ||--o| processed_profile_snapshots : "generates"
The database contains the following tables:
registries- Stores active entity registrations with their bundle conversion statushistorical_registries- Archives previous entity versions when new deployments occurprofiles- Caches validated user profiles from Catalyst serversprocessed_profile_snapshots- Tracks which profile snapshots have been processedfailed_profile_fetches- Stores failed profile fetch attempts for retry
Stores active entity registrations including scenes, wearables, emotes, and worlds with their asset bundle conversion status.
| Column | Type | Nullable | Description |
|---|---|---|---|
id |
VARCHAR(255) | NOT NULL | Primary Key. Entity content identifier (CID) from Catalyst. |
type |
VARCHAR(255) | NOT NULL | Entity type: scene, wearable, emote, profile, or world. |
timestamp |
BIGINT | NOT NULL | Unix timestamp (milliseconds) when the entity was deployed to Catalyst. |
pointers |
VARCHAR(255)[] | NOT NULL | Array of pointers where this entity is active (coordinates or URNs). |
content |
JSONB | NOT NULL | Entity content files with file paths and content hashes. |
metadata |
JSONB | NULL | Entity-specific metadata (varies by entity type). |
status |
VARCHAR(255) | NOT NULL | Registry status: complete, pending, failed, obsolete, or fallback. |
bundles |
JSONB | NOT NULL | Asset bundle and LOD conversion status per platform (Windows, Mac). |
deployer |
VARCHAR(255) | NOT NULL | Ethereum address of the entity deployer. |
versions |
JSONB | NULL | Asset bundle version information per platform (version string, build date). |
- Primary Key:
id - GIN Index:
pointers- For efficient array containment queries - Index:
status- For filtering by conversion status - Index:
timestamp- For ordering by deployment time - Index:
deployer- For querying entities by owner - Index:
registries_id_lower_idxonLOWER(id)- Case-insensitive entity ID lookups
{
"assets": {
"windows": "complete|pending|failed",
"mac": "complete|pending|failed"
},
"lods": {
"windows": "complete|pending|failed",
"mac": "complete|pending|failed"
}
}{
"assets": {
"windows": { "version": "v5", "buildDate": "2024-01-15" },
"mac": { "version": "v5", "buildDate": "2024-01-15" }
}
}- Entity ID is the content identifier (CID) from Catalyst
- Status transitions:
pending→complete(on successful conversion) orfailed(on error) - When a new entity is deployed to the same pointer, the old entity becomes
obsoleteorfallback - The
fallbackstatus indicates the entity is served while newer content is being processed - Timestamps stored in milliseconds (BIGINT)
Archives previous entity versions when new deployments occur. Used for audit trails and analytics.
| Column | Type | Nullable | Description |
|---|---|---|---|
id |
VARCHAR(255) | NOT NULL | Primary Key. Entity content identifier (CID). |
type |
VARCHAR(255) | NOT NULL | Entity type: scene, wearable, emote, profile, or world. |
timestamp |
BIGINT | NOT NULL | Unix timestamp (milliseconds) when the entity was deployed. |
pointers |
VARCHAR(255)[] | NOT NULL | Array of pointers where this entity was active. |
content |
JSONB | NOT NULL | Entity content files. |
metadata |
JSONB | NULL | Entity-specific metadata. |
status |
VARCHAR(255) | NOT NULL | Final status before archival. |
bundles |
JSONB | NOT NULL | Final bundle conversion status. |
deployer |
VARCHAR(255) | NOT NULL | Ethereum address of the entity deployer. |
versions |
JSONB | NULL | Asset bundle version information. |
migrated_at |
BIGINT | NOT NULL | Unix timestamp (milliseconds) when the entity was moved to historical. |
- Primary Key:
id - Index:
deployer- For querying historical entities by owner - GIN Index:
pointers- For efficient array containment queries
- Entities are moved here when replaced by new deployments
- The
migrated_attimestamp records when the rotation occurred - Historical records are immutable after creation
Caches validated user profiles fetched from Catalyst servers for fast retrieval.
| Column | Type | Nullable | Description |
|---|---|---|---|
id |
VARCHAR(255) | NOT NULL | Primary Key. Profile entity content identifier (CID). |
pointer |
VARCHAR(255) | NOT NULL | Unique. Ethereum address of the profile owner (lowercase). |
timestamp |
BIGINT | NOT NULL | Unix timestamp (milliseconds) from Catalyst deployment. |
content |
JSONB | NOT NULL | Profile content files (avatar images, etc.). |
metadata |
JSONB | NOT NULL | Profile metadata including avatar configuration. |
local_timestamp |
BIGINT | NOT NULL | Unix timestamp (milliseconds) when profile was cached locally. |
- Primary Key:
id - Unique Constraint:
pointer- One profile per Ethereum address - Index:
idx_profiles_timestampontimestamp- For ordering by deployment time - Index:
idx_profiles_local_timestamponlocal_timestamp- For cache freshness queries
- Each Ethereum address has exactly one active profile
- Profiles are periodically validated for ownership (curation job)
local_timestamptracks when the profile was synced to this service- Profile metadata follows the Decentraland Profile schema
Tracks which Catalyst profile snapshots have been processed to avoid reprocessing.
| Column | Type | Nullable | Description |
|---|---|---|---|
hash |
VARCHAR(255) | NOT NULL | Primary Key. Snapshot content hash. |
process_time |
TIMESTAMP | NOT NULL | When the snapshot was processed. |
- Primary Key:
hash
- Used to deduplicate snapshot processing during profile sync
- Prevents reprocessing the same Catalyst snapshot multiple times
Stores failed profile fetch attempts for retry processing.
| Column | Type | Nullable | Description |
|---|---|---|---|
entity_id |
VARCHAR(255) | NOT NULL | Primary Key. Profile entity ID that failed to fetch. |
pointer |
VARCHAR(255) | NOT NULL | Ethereum address of the profile. |
timestamp |
BIGINT | NOT NULL | Original deployment timestamp from the event. |
auth_chain |
JSONB | NULL | Authentication chain data (if available). |
first_failed_at |
BIGINT | NOT NULL | Unix timestamp (milliseconds) of first failure. |
last_retry_at |
BIGINT | NULL | Unix timestamp (milliseconds) of last retry attempt. |
retry_count |
INTEGER | NOT NULL | Number of retry attempts. Defaults to 0. |
error_message |
TEXT | NULL | Error description from the last failure. |
- Primary Key:
entity_id - Index:
idx_failed_fetches_pointeronLOWER(pointer)- Case-insensitive address lookup - Index:
idx_failed_fetches_entity_idonLOWER(entity_id)- Case-insensitive entity lookup - Index:
idx_failed_fetches_retry_countonretry_count- For retry prioritization
- Failed fetches are retried with exponential backoff
- The
retry_countdetermines retry priority and backoff delay - Successful retries remove the record from this table
- Records with high retry counts may require manual intervention