diff --git a/crates/db/migrations/0003_object.sql b/crates/db/migrations/0003_object.sql new file mode 100644 index 0000000..a5c8047 --- /dev/null +++ b/crates/db/migrations/0003_object.sql @@ -0,0 +1,18 @@ +-- Catalogue objects (the inventory-minimum core). One row = one object or a group. +CREATE TABLE object ( + id UUID PRIMARY KEY, + object_number TEXT NOT NULL UNIQUE, + object_name TEXT NOT NULL, + number_of_objects INTEGER NOT NULL DEFAULT 1 CHECK (number_of_objects >= 1), + brief_description TEXT, + current_location TEXT, + current_owner TEXT, + recorder TEXT, + recording_date DATE, + visibility TEXT NOT NULL DEFAULT 'draft' + CHECK (visibility IN ('draft', 'internal', 'public')), + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX object_visibility_idx ON object (visibility); diff --git a/crates/db/tests/migrate.rs b/crates/db/tests/migrate.rs index 74d3227..5588e37 100644 --- a/crates/db/tests/migrate.rs +++ b/crates/db/tests/migrate.rs @@ -19,6 +19,18 @@ async fn migrate_is_idempotent_and_creates_audit_log(pool: PgPool) { assert_eq!(regclass.as_deref(), Some("audit_log")); } +#[sqlx::test] +async fn migrate_creates_object_table(pool: PgPool) { + let db = Db::from_pool(pool); + + let regclass: Option = sqlx::query_scalar("SELECT to_regclass('public.object')::text") + .fetch_one(db.pool()) + .await + .unwrap(); + + assert_eq!(regclass.as_deref(), Some("object")); +} + #[sqlx::test] async fn migrate_creates_vocabulary_and_authority_tables(pool: PgPool) { let db = Db::from_pool(pool);