Files
julian 5035bfc117
Build directus image / build-and-publish (push) Has been cancelled
Strip ghost-collection entries from snapshot
Third CI dry-run failure: schema-apply tried to "Create migrations_applied"
and "Create positions" as Directus collections — both already exist as
raw tables created by db-init pre-schema. The conflict halts schema-apply
on a fresh CI DB.

Why these end up in the snapshot at all: `directus schema snapshot`
auto-discovers every table in the public schema, including ones owned by
db-init (positions hypertable, migrations_applied guard). It registers
them as ghost entries with no fields and no relations — just enough
metadata to make Directus aware of the table.

In local dev this never tripped because the tables existed BEFORE the
snapshot ran, and any subsequent apply was a no-op against directus_collections
which already had matching ghost rows. On a fresh CI DB the order is:
  1. db-init pre-schema → creates the tables
  2. bootstrap → installs Directus system tables (NOT the ghosts)
  3. schema-apply → tries to "Create" the ghosts → conflict → fail

Fixes:

- snapshots/schema.yaml: stripped the migrations_applied and positions
  entries (24 lines each) from the collections: section. The user
  collections remain untouched.

- scripts/schema-snapshot.sh: post-process step that filters the same
  ghost names from every future snapshot capture. Awk-based, applied
  after `docker compose cp` writes the file out. The ghost list is a
  bash array near the top of the new step — add to it when introducing
  more db-init-only tables.

Snapshot is now 105 KB → ~103 KB. The user collections, fields, and
relations are unchanged. positions and migrations_applied stay as
raw Postgres tables managed by db-init/, never registered in
directus_collections, never shown in the admin UI. That matches the
schema-as-code split: Directus owns user collections; db-init owns the
positions hypertable and the runner's guard table.

Three CI iterations to get the boot pipeline right (port collision →
ordering → ghost entries). The dry-run gate has now caught three
distinct failure modes that would have damaged stage if pushed
unguarded.
2026-05-02 10:59:02 +02:00

4224 lines
102 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
version: 1
directus: 11.17.4
vendor: postgres
collections:
- collection: classes
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: classes
color: null
display_template: '{{code}} — {{name}}'
group: null
hidden: false
icon: category
item_duplication_fields: null
note: >-
Per-event classification (e.g. M-1, C-2, S-3 in Rally Albania). Class
drives standings grouping.
preview_url: null
singleton: false
sort: 8
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: classes
- collection: devices
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: devices
color: null
display_template: '{{model}} — {{imei}}'
group: null
hidden: false
icon: gps_fixed
item_duplication_fields: null
note: >-
Durable GPS tracker catalog. IMEI is the canonical identifier. Belongs
to orgs via organization_devices.
preview_url: null
singleton: false
sort: 3
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: devices
- collection: entries
meta:
accountability: all
archive_app_filter: true
archive_field: status
archive_value: withdrawn
collapse: open
collection: entries
color: null
display_template: '#{{race_number}} — {{class_id.code}}'
group: null
hidden: false
icon: how_to_reg
item_duplication_fields: null
note: >-
The unit of timing. One row per (vehicle or solo participant) registered
for an event. team_id deferred until Phase 2.
preview_url: null
singleton: false
sort: 9
sort_field: null
translations: null
unarchive_value: registered
versioning: false
schema:
name: entries
- collection: entry_crew
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: entry_crew
color: null
display_template: '{{user_id.first_name}} {{user_id.last_name}} — {{role}}'
group: null
hidden: false
icon: groups
item_duplication_fields: null
note: >-
Junction: which users participate in which entries with what racing
role.
preview_url: null
singleton: false
sort: 10
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: entry_crew
- collection: entry_devices
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: entry_devices
color: null
display_template: '{{device_id.imei}} — {{mount_position}}'
group: null
hidden: false
icon: sensors
item_duplication_fields: null
note: >-
Junction: which devices are mounted on which entry, optionally body-worn
on a specific crew member.
preview_url: null
singleton: false
sort: 11
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: entry_devices
- collection: events
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: events
color: null
display_template: '{{name}}'
group: null
hidden: false
icon: event
item_duplication_fields: null
note: >-
An event = a single rally / time-trial / regatta / etc. Lives in exactly
one organization. The container for classes, entries, course definition.
preview_url: null
singleton: false
sort: 7
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: events
- collection: organization_devices
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: organization_devices
color: null
display_template: '{{device_id.model}} {{device_id.imei}} — {{organization_id.name}}'
group: null
hidden: false
icon: device_hub
item_duplication_fields: null
note: 'Junction: which devices belong to which orgs.'
preview_url: null
singleton: false
sort: 6
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: organization_devices
- collection: organization_users
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: organization_users
color: null
display_template: >-
{{user_id.first_name}} {{user_id.last_name}} — {{role}} —
{{organization_id.name}}
group: null
hidden: false
icon: person_add
item_duplication_fields: null
note: 'Junction: which users belong to which orgs and with what role.'
preview_url: null
singleton: false
sort: 4
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: organization_users
- collection: organization_vehicles
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: organization_vehicles
color: null
display_template: '{{vehicle_id.make}} {{vehicle_id.model}} — {{organization_id.name}}'
group: null
hidden: false
icon: garage
item_duplication_fields: null
note: 'Junction: which vehicles belong to which orgs.'
preview_url: null
singleton: false
sort: 5
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: organization_vehicles
- collection: organizations
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: organizations
color: null
display_template: '{{name}}'
group: null
hidden: false
icon: corporate_fare
item_duplication_fields: null
note: >-
Tenant root. Each event, vehicle, device and user belongs to one or more
organizations via junction tables.
preview_url: null
singleton: false
sort: 1
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: organizations
- collection: vehicles
meta:
accountability: all
archive_app_filter: true
archive_field: null
archive_value: null
collapse: open
collection: vehicles
color: null
display_template: '{{make}} {{model}} ({{year}})'
group: null
hidden: false
icon: directions_car
item_duplication_fields: null
note: >-
Durable vehicle catalog. Belongs to orgs via organization_vehicles. No
ownership modelling — vehicles are org-scoped only.
preview_url: null
singleton: false
sort: 2
sort_field: null
translations: null
unarchive_value: null
versioning: false
schema:
name: vehicles
fields:
- collection: classes
field: id
type: uuid
meta:
collection: classes
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: classes
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: event_id
type: uuid
meta:
collection: classes
conditions: null
display: null
display_options: null
field: event_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Event this class belongs to
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: event_id
table: classes
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: events
foreign_key_column: id
- collection: classes
field: code
type: string
meta:
collection: classes
conditions: null
display: null
display_options: null
field: code
group: null
hidden: false
interface: input
note: >-
Short code (e.g. "M-1", "C-2"). Unique within the event (composite
unique via db-init/005).
options: null
readonly: false
required: true
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: code
table: classes
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: name
type: string
meta:
collection: classes
conditions: null
display: null
display_options: null
field: name
group: null
hidden: false
interface: input
note: Human-readable name (e.g. "MOTO Under 450cc")
options: null
readonly: false
required: true
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: name
table: classes
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: description
type: text
meta:
collection: classes
conditions: null
display: null
display_options: null
field: description
group: null
hidden: false
interface: input-multiline
note: Eligibility rules in plain text
options: null
readonly: false
required: false
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: description
table: classes
data_type: text
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: sort_order
type: integer
meta:
collection: classes
conditions: null
display: null
display_options: null
field: sort_order
group: null
hidden: false
interface: input
note: Display ordering within event
options: null
readonly: false
required: false
searchable: true
sort: 6
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: sort_order
table: classes
data_type: integer
default_value: null
max_length: null
numeric_precision: 32
numeric_scale: 0
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: date_created
type: timestamp
meta:
collection: classes
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 7
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: classes
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: classes
field: date_updated
type: timestamp
meta:
collection: classes
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 8
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: classes
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: id
type: uuid
meta:
collection: devices
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: imei
type: string
meta:
collection: devices
conditions: null
display: null
display_options: null
field: imei
group: null
hidden: false
interface: input
note: Canonical 15-digit IMEI. UNIQUE across the whole system.
options: null
readonly: false
required: true
searchable: true
sort: 2
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: imei
table: devices
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: model
type: string
meta:
collection: devices
conditions: null
display: null
display_options: null
field: model
group: null
hidden: false
interface: input
note: >-
Hardware model (e.g. "FMB920", "FMB003") — drives IO mapping in the
processor service.
options: null
readonly: false
required: true
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: model
table: devices
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: serial_number
type: string
meta:
collection: devices
conditions: null
display: null
display_options: null
field: serial_number
group: null
hidden: false
interface: input
note: Manufacturer serial number (optional)
options: null
readonly: false
required: false
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: serial_number
table: devices
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: notes
type: text
meta:
collection: devices
conditions: null
display: null
display_options: null
field: notes
group: null
hidden: false
interface: input-multiline
note: Free-form notes
options: null
readonly: false
required: false
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: notes
table: devices
data_type: text
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: date_created
type: timestamp
meta:
collection: devices
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: devices
field: date_updated
type: timestamp
meta:
collection: devices
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 7
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: directus_users
field: phone
type: string
meta:
collection: directus_users
conditions: null
display: null
display_options: null
field: phone
group: null
hidden: false
interface: input
note: Phone number (optional)
options: null
readonly: false
required: false
searchable: true
sort: 1
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: phone
table: directus_users
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: directus_users
field: birth_date
type: date
meta:
collection: directus_users
conditions: null
display: null
display_options: null
field: birth_date
group: null
hidden: false
interface: datetime
note: >-
Used for age-derived class eligibility (e.g. M-5/M-6/M-7 senior/veteran
classes)
options: null
readonly: false
required: false
searchable: true
sort: 2
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: birth_date
table: directus_users
data_type: date
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: directus_users
field: nationality
type: string
meta:
collection: directus_users
conditions: null
display: null
display_options: null
field: nationality
group: null
hidden: false
interface: input
note: ISO 3166-1 alpha-2 country code (e.g. "AL", "IT")
options:
placeholder: AL
readonly: false
required: false
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: nationality
table: directus_users
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: id
type: uuid
meta:
collection: entries
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: entries
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: event_id
type: uuid
meta:
collection: entries
conditions: null
display: null
display_options: null
field: event_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Event this entry races in
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: event_id
table: entries
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: events
foreign_key_column: id
- collection: entries
field: vehicle_id
type: uuid
meta:
collection: entries
conditions: null
display: null
display_options: null
field: vehicle_id
group: null
hidden: false
interface: select-dropdown-m2o
note: 'Nullable: null for foot races (trail-run / hike disciplines)'
options:
template: '{{make}} {{model}}'
readonly: false
required: false
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: vehicle_id
table: entries
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: vehicles
foreign_key_column: id
- collection: entries
field: class_id
type: uuid
meta:
collection: entries
conditions: null
display: null
display_options: null
field: class_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Class this entry competes in
options:
template: '{{code}} — {{name}}'
readonly: false
required: true
searchable: true
sort: 4
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: class_id
table: entries
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: classes
foreign_key_column: id
- collection: entries
field: race_number
type: integer
meta:
collection: entries
conditions: null
display: null
display_options: null
field: race_number
group: null
hidden: false
interface: input
note: >-
Per Rally Albania §5: 1199 moto, 2xx quad, 3xx car, 4xx SSV. Unique
within event (composite unique via db-init/005).
options: null
readonly: false
required: true
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: race_number
table: entries
data_type: integer
default_value: null
max_length: null
numeric_precision: 32
numeric_scale: 0
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: status
type: string
meta:
collection: entries
conditions: null
display: null
display_options: null
field: status
group: null
hidden: false
interface: select-dropdown
note: >-
Lifecycle: registered → confirmed → started → finished.
dnf/dns/dq/withdrawn are terminal failure states.
options:
choices:
- text: Registered
value: registered
- text: Confirmed
value: confirmed
- text: Started
value: started
- text: Finished
value: finished
- text: DNF (Did Not Finish)
value: dnf
- text: DNS (Did Not Start)
value: dns
- text: DQ (Disqualified)
value: dq
- text: Withdrawn
value: withdrawn
readonly: false
required: true
searchable: true
sort: 6
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: status
table: entries
data_type: character varying
default_value: registered
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: registered_at
type: timestamp
meta:
collection: entries
conditions: null
display: null
display_options: null
field: registered_at
group: null
hidden: false
interface: datetime
note: When the entry was registered
options: null
readonly: false
required: false
searchable: true
sort: 7
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: registered_at
table: entries
data_type: timestamp with time zone
default_value: CURRENT_TIMESTAMP
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: notes
type: text
meta:
collection: entries
conditions: null
display: null
display_options: null
field: notes
group: null
hidden: false
interface: input-multiline
note: Free-form notes
options: null
readonly: false
required: false
searchable: true
sort: 8
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: notes
table: entries
data_type: text
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: date_created
type: timestamp
meta:
collection: entries
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 9
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: entries
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entries
field: date_updated
type: timestamp
meta:
collection: entries
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 10
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: entries
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_crew
field: id
type: uuid
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: entry_crew
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_crew
field: entry_id
type: uuid
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: entry_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options: null
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: entry_id
table: entry_crew
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: entries
foreign_key_column: id
- collection: entry_crew
field: user_id
type: uuid
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: user_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{first_name}} {{last_name}} ({{email}})'
readonly: false
required: true
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: user_id
table: entry_crew
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: directus_users
foreign_key_column: id
- collection: entry_crew
field: role
type: string
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: role
group: null
hidden: false
interface: select-dropdown
note: >-
On-track racing role (distinct from organization_users.role which is a
permissions concept)
options:
choices:
- text: Pilot
value: pilot
- text: Co-Pilot
value: co-pilot
- text: Navigator
value: navigator
- text: Mechanic
value: mechanic
- text: Rider
value: rider
- text: Runner
value: runner
- text: Hiker
value: hiker
readonly: false
required: true
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: role
table: entry_crew
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_crew
field: date_created
type: timestamp
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 5
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: entry_crew
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_crew
field: date_updated
type: timestamp
meta:
collection: entry_crew
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: entry_crew
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_devices
field: id
type: uuid
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: entry_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_devices
field: entry_id
type: uuid
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: entry_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options: null
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: entry_id
table: entry_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: entries
foreign_key_column: id
- collection: entry_devices
field: device_id
type: uuid
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: device_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{model}} {{imei}}'
readonly: false
required: true
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: device_id
table: entry_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: devices
foreign_key_column: id
- collection: entry_devices
field: assigned_user_id
type: uuid
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: assigned_user_id
group: null
hidden: false
interface: select-dropdown-m2o
note: >-
Nullable: null = vehicle-mounted (hardwired or backup); set = body-worn
on this crew member (panic button)
options:
template: '{{first_name}} {{last_name}}'
readonly: false
required: false
searchable: true
sort: 4
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: assigned_user_id
table: entry_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: directus_users
foreign_key_column: id
- collection: entry_devices
field: mount_position
type: string
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: mount_position
group: null
hidden: false
interface: input
note: >-
Free-form mount label (e.g. "panic_button_pilot", "hardwired_dash",
"backup_chassis")
options: null
readonly: false
required: false
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: mount_position
table: entry_devices
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_devices
field: date_created
type: timestamp
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: entry_devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: entry_devices
field: date_updated
type: timestamp
meta:
collection: entry_devices
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 7
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: entry_devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: id
type: uuid
meta:
collection: events
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: events
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: organization_id
type: uuid
meta:
collection: events
conditions: null
display: null
display_options: null
field: organization_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Owning org. An event belongs to exactly one org.
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: organization_id
table: events
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: organizations
foreign_key_column: id
- collection: events
field: name
type: string
meta:
collection: events
conditions: null
display: null
display_options: null
field: name
group: null
hidden: false
interface: input
note: Display name (e.g. "Rally Albania 2026")
options: null
readonly: false
required: true
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: name
table: events
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: slug
type: string
meta:
collection: events
conditions: null
display: null
display_options: null
field: slug
group: null
hidden: false
interface: input
note: >-
URL-friendly identifier, unique within the org (composite unique
constraint enforced via db-init/005)
options:
slug: true
trim: true
readonly: false
required: true
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: slug
table: events
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: discipline
type: string
meta:
collection: events
conditions: null
display: null
display_options: null
field: discipline
group: null
hidden: false
interface: select-dropdown
note: 'Drives validation: rally requires vehicle, trail-run/hike does not, etc.'
options:
choices:
- text: Rally
value: rally
- text: Time Trial
value: time-trial
- text: Regatta
value: regatta
- text: Trail Run
value: trail-run
- text: Hike
value: hike
readonly: false
required: true
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: discipline
table: events
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: starts_at
type: timestamp
meta:
collection: events
conditions: null
display: null
display_options: null
field: starts_at
group: null
hidden: false
interface: datetime
note: Event window begin
options: null
readonly: false
required: true
searchable: true
sort: 6
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: starts_at
table: events
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: ends_at
type: timestamp
meta:
collection: events
conditions: null
display: null
display_options: null
field: ends_at
group: null
hidden: false
interface: datetime
note: Event window end
options: null
readonly: false
required: true
searchable: true
sort: 7
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: ends_at
table: events
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: regulation_doc_url
type: string
meta:
collection: events
conditions: null
display: null
display_options: null
field: regulation_doc_url
group: null
hidden: false
interface: input
note: External URL to the rulebook PDF/page
options: null
readonly: false
required: false
searchable: true
sort: 8
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: regulation_doc_url
table: events
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: notes
type: text
meta:
collection: events
conditions: null
display: null
display_options: null
field: notes
group: null
hidden: false
interface: input-multiline
note: Free-form notes
options: null
readonly: false
required: false
searchable: true
sort: 9
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: notes
table: events
data_type: text
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: date_created
type: timestamp
meta:
collection: events
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 10
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: events
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: events
field: date_updated
type: timestamp
meta:
collection: events
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 11
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: events
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_devices
field: id
type: uuid
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: organization_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_devices
field: organization_id
type: uuid
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: organization_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: organization_id
table: organization_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: organizations
foreign_key_column: id
- collection: organization_devices
field: device_id
type: uuid
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: device_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{model}} {{imei}}'
readonly: false
required: true
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: device_id
table: organization_devices
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: devices
foreign_key_column: id
- collection: organization_devices
field: registered_at
type: timestamp
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: registered_at
group: null
hidden: false
interface: datetime
note: When the device was registered with this org
options: null
readonly: false
required: false
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: registered_at
table: organization_devices
data_type: timestamp with time zone
default_value: CURRENT_TIMESTAMP
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_devices
field: date_created
type: timestamp
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 5
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: organization_devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_devices
field: date_updated
type: timestamp
meta:
collection: organization_devices
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: organization_devices
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_users
field: id
type: uuid
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: organization_users
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_users
field: organization_id
type: uuid
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: organization_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Tenant org
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: organization_id
table: organization_users
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: organizations
foreign_key_column: id
- collection: organization_users
field: user_id
type: uuid
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: user_id
group: null
hidden: false
interface: select-dropdown-m2o
note: Directus user
options:
template: '{{first_name}} {{last_name}} ({{email}})'
readonly: false
required: true
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: user_id
table: organization_users
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: directus_users
foreign_key_column: id
- collection: organization_users
field: role
type: string
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: role
group: null
hidden: false
interface: select-dropdown
note: >-
Role for this user in this org. Drives Directus permission policies in
Phase 4.
options:
choices:
- text: Org Admin
value: org-admin
- text: Race Director
value: race-director
- text: Marshal
value: marshal
- text: Timekeeper
value: timekeeper
- text: Participant
value: participant
- text: Viewer
value: viewer
readonly: false
required: true
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: role
table: organization_users
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_users
field: joined_at
type: timestamp
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: joined_at
group: null
hidden: false
interface: datetime
note: When the user joined this org
options: null
readonly: false
required: false
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: joined_at
table: organization_users
data_type: timestamp with time zone
default_value: CURRENT_TIMESTAMP
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_users
field: date_created
type: timestamp
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: organization_users
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_users
field: date_updated
type: timestamp
meta:
collection: organization_users
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 7
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: organization_users
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_vehicles
field: id
type: uuid
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: organization_vehicles
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_vehicles
field: organization_id
type: uuid
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: organization_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{name}}'
readonly: false
required: true
searchable: true
sort: 2
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: organization_id
table: organization_vehicles
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: organizations
foreign_key_column: id
- collection: organization_vehicles
field: vehicle_id
type: uuid
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: vehicle_id
group: null
hidden: false
interface: select-dropdown-m2o
note: null
options:
template: '{{make}} {{model}}'
readonly: false
required: true
searchable: true
sort: 3
special:
- m2o
translations: null
validation: null
validation_message: null
width: half
schema:
name: vehicle_id
table: organization_vehicles
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: vehicles
foreign_key_column: id
- collection: organization_vehicles
field: registered_at
type: timestamp
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: registered_at
group: null
hidden: false
interface: datetime
note: When the vehicle was registered with this org
options: null
readonly: false
required: false
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: registered_at
table: organization_vehicles
data_type: timestamp with time zone
default_value: CURRENT_TIMESTAMP
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_vehicles
field: date_created
type: timestamp
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 5
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: organization_vehicles
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organization_vehicles
field: date_updated
type: timestamp
meta:
collection: organization_vehicles
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 6
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: organization_vehicles
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organizations
field: id
type: uuid
meta:
collection: organizations
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: organizations
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organizations
field: name
type: string
meta:
collection: organizations
conditions: null
display: null
display_options: null
field: name
group: null
hidden: false
interface: input
note: Display name (e.g. "Motorsport Club Albania")
options: null
readonly: false
required: true
searchable: true
sort: 2
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: name
table: organizations
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organizations
field: slug
type: string
meta:
collection: organizations
conditions: null
display: null
display_options: null
field: slug
group: null
hidden: false
interface: input
note: URL-friendly identifier, unique across all orgs
options:
slug: true
trim: true
readonly: false
required: true
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: slug
table: organizations
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organizations
field: date_created
type: timestamp
meta:
collection: organizations
conditions: null
display: datetime
display_options:
relative: true
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 4
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: organizations
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: organizations
field: date_updated
type: timestamp
meta:
collection: organizations
conditions: null
display: datetime
display_options:
relative: true
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 5
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: organizations
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: id
type: uuid
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: id
group: null
hidden: true
interface: input
note: null
options: null
readonly: true
required: false
searchable: true
sort: 1
special:
- uuid
translations: null
validation: null
validation_message: null
width: full
schema:
name: id
table: vehicles
data_type: uuid
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: true
is_indexed: false
is_primary_key: true
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: make
type: string
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: make
group: null
hidden: false
interface: input
note: Manufacturer (e.g. "Toyota")
options: null
readonly: false
required: true
searchable: true
sort: 2
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: make
table: vehicles
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: model
type: string
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: model
group: null
hidden: false
interface: input
note: Model name (e.g. "Land Cruiser 70")
options: null
readonly: false
required: true
searchable: true
sort: 3
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: model
table: vehicles
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: false
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: year
type: integer
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: year
group: null
hidden: false
interface: input
note: Model year
options: null
readonly: false
required: false
searchable: true
sort: 4
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: year
table: vehicles
data_type: integer
default_value: null
max_length: null
numeric_precision: 32
numeric_scale: 0
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: engine_cc
type: integer
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: engine_cc
group: null
hidden: false
interface: input
note: Engine displacement in cc — used for class assignment in rally events
options: null
readonly: false
required: false
searchable: true
sort: 5
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: engine_cc
table: vehicles
data_type: integer
default_value: null
max_length: null
numeric_precision: 32
numeric_scale: 0
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: vin
type: string
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: vin
group: null
hidden: false
interface: input
note: Vehicle Identification Number (optional)
options: null
readonly: false
required: false
searchable: true
sort: 6
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: vin
table: vehicles
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: plate_number
type: string
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: plate_number
group: null
hidden: false
interface: input
note: License plate (optional)
options: null
readonly: false
required: false
searchable: true
sort: 7
special: null
translations: null
validation: null
validation_message: null
width: half
schema:
name: plate_number
table: vehicles
data_type: character varying
default_value: null
max_length: 255
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: notes
type: text
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: notes
group: null
hidden: false
interface: input-multiline
note: Free-form notes
options: null
readonly: false
required: false
searchable: true
sort: 8
special: null
translations: null
validation: null
validation_message: null
width: full
schema:
name: notes
table: vehicles
data_type: text
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: date_created
type: timestamp
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: date_created
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 9
special:
- date-created
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_created
table: vehicles
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
- collection: vehicles
field: date_updated
type: timestamp
meta:
collection: vehicles
conditions: null
display: null
display_options: null
field: date_updated
group: null
hidden: true
interface: datetime
note: null
options: null
readonly: true
required: false
searchable: true
sort: 10
special:
- date-updated
translations: null
validation: null
validation_message: null
width: half
schema:
name: date_updated
table: vehicles
data_type: timestamp with time zone
default_value: null
max_length: null
numeric_precision: null
numeric_scale: null
is_nullable: true
is_unique: false
is_indexed: false
is_primary_key: false
is_generated: false
generation_expression: null
has_auto_increment: false
foreign_key_table: null
foreign_key_column: null
systemFields:
- collection: directus_activity
field: timestamp
schema:
is_indexed: true
- collection: directus_revisions
field: activity
schema:
is_indexed: true
- collection: directus_revisions
field: parent
schema:
is_indexed: true
relations:
- collection: classes
field: event_id
related_collection: events
meta:
junction_field: null
many_collection: classes
many_field: event_id
one_allowed_collections: null
one_collection: events
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: classes
column: event_id
foreign_key_table: events
foreign_key_column: id
constraint_name: classes_event_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entries
field: event_id
related_collection: events
meta:
junction_field: null
many_collection: entries
many_field: event_id
one_allowed_collections: null
one_collection: events
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entries
column: event_id
foreign_key_table: events
foreign_key_column: id
constraint_name: entries_event_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entries
field: vehicle_id
related_collection: vehicles
meta:
junction_field: null
many_collection: entries
many_field: vehicle_id
one_allowed_collections: null
one_collection: vehicles
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entries
column: vehicle_id
foreign_key_table: vehicles
foreign_key_column: id
constraint_name: entries_vehicle_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entries
field: class_id
related_collection: classes
meta:
junction_field: null
many_collection: entries
many_field: class_id
one_allowed_collections: null
one_collection: classes
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entries
column: class_id
foreign_key_table: classes
foreign_key_column: id
constraint_name: entries_class_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entry_crew
field: entry_id
related_collection: entries
meta:
junction_field: null
many_collection: entry_crew
many_field: entry_id
one_allowed_collections: null
one_collection: entries
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entry_crew
column: entry_id
foreign_key_table: entries
foreign_key_column: id
constraint_name: entry_crew_entry_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entry_crew
field: user_id
related_collection: directus_users
meta:
junction_field: null
many_collection: entry_crew
many_field: user_id
one_allowed_collections: null
one_collection: directus_users
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entry_crew
column: user_id
foreign_key_table: directus_users
foreign_key_column: id
constraint_name: entry_crew_user_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entry_devices
field: entry_id
related_collection: entries
meta:
junction_field: null
many_collection: entry_devices
many_field: entry_id
one_allowed_collections: null
one_collection: entries
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entry_devices
column: entry_id
foreign_key_table: entries
foreign_key_column: id
constraint_name: entry_devices_entry_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entry_devices
field: device_id
related_collection: devices
meta:
junction_field: null
many_collection: entry_devices
many_field: device_id
one_allowed_collections: null
one_collection: devices
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entry_devices
column: device_id
foreign_key_table: devices
foreign_key_column: id
constraint_name: entry_devices_device_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: entry_devices
field: assigned_user_id
related_collection: directus_users
meta:
junction_field: null
many_collection: entry_devices
many_field: assigned_user_id
one_allowed_collections: null
one_collection: directus_users
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: entry_devices
column: assigned_user_id
foreign_key_table: directus_users
foreign_key_column: id
constraint_name: entry_devices_assigned_user_id_foreign
on_update: NO ACTION
on_delete: SET NULL
- collection: events
field: organization_id
related_collection: organizations
meta:
junction_field: null
many_collection: events
many_field: organization_id
one_allowed_collections: null
one_collection: organizations
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: events
column: organization_id
foreign_key_table: organizations
foreign_key_column: id
constraint_name: events_organization_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_devices
field: organization_id
related_collection: organizations
meta:
junction_field: null
many_collection: organization_devices
many_field: organization_id
one_allowed_collections: null
one_collection: organizations
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_devices
column: organization_id
foreign_key_table: organizations
foreign_key_column: id
constraint_name: organization_devices_organization_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_devices
field: device_id
related_collection: devices
meta:
junction_field: null
many_collection: organization_devices
many_field: device_id
one_allowed_collections: null
one_collection: devices
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_devices
column: device_id
foreign_key_table: devices
foreign_key_column: id
constraint_name: organization_devices_device_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_users
field: organization_id
related_collection: organizations
meta:
junction_field: null
many_collection: organization_users
many_field: organization_id
one_allowed_collections: null
one_collection: organizations
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_users
column: organization_id
foreign_key_table: organizations
foreign_key_column: id
constraint_name: organization_users_organization_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_users
field: user_id
related_collection: directus_users
meta:
junction_field: null
many_collection: organization_users
many_field: user_id
one_allowed_collections: null
one_collection: directus_users
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_users
column: user_id
foreign_key_table: directus_users
foreign_key_column: id
constraint_name: organization_users_user_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_vehicles
field: organization_id
related_collection: organizations
meta:
junction_field: null
many_collection: organization_vehicles
many_field: organization_id
one_allowed_collections: null
one_collection: organizations
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_vehicles
column: organization_id
foreign_key_table: organizations
foreign_key_column: id
constraint_name: organization_vehicles_organization_id_foreign
on_update: NO ACTION
on_delete: RESTRICT
- collection: organization_vehicles
field: vehicle_id
related_collection: vehicles
meta:
junction_field: null
many_collection: organization_vehicles
many_field: vehicle_id
one_allowed_collections: null
one_collection: vehicles
one_collection_field: null
one_deselect_action: nullify
one_field: null
sort_field: null
schema:
table: organization_vehicles
column: vehicle_id
foreign_key_table: vehicles
foreign_key_column: id
constraint_name: organization_vehicles_vehicle_id_foreign
on_update: NO ACTION
on_delete: RESTRICT