← back to Animals

migrations/006_owner_pets.sql

69 lines

-- Owner-uploaded pet profiles + photos — Steve's Bowie, Humphrey, Madison
-- (and any future user uploads).
--
-- Distinct from `breed_images` (which is the public PD/CC library) and
-- `shelter_animals` (Petfinder-style adoption feeds). These are personal
-- pets attached to an `app_users` account, with full attribution to that
-- user. They render on the user's profile and (with the user's consent)
-- can appear in the breed page as community-uploaded examples.

BEGIN;

CREATE TABLE IF NOT EXISTS owner_pets (
  id              BIGSERIAL PRIMARY KEY,
  app_user_id     BIGINT REFERENCES app_users(id) ON DELETE SET NULL,
  name            TEXT NOT NULL,
  species_id      BIGINT REFERENCES species(id),
  breed_id        BIGINT REFERENCES breeds(id),
  breed_text      TEXT,                              -- free-text if no breed match
  sex             TEXT CHECK (sex IN ('m','f','unknown')),
  birth_year      INTEGER,
  death_year      INTEGER,
  bio             TEXT,
  hero_image_url  TEXT,
  share_publicly  BOOLEAN NOT NULL DEFAULT FALSE,    -- if TRUE, can show in breed gallery
  source          TEXT NOT NULL DEFAULT 'owner_upload', -- 'owner_upload' | 'gdrive_import' | 'manual'
  created_at      TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_owner_pets_user   ON owner_pets(app_user_id);
CREATE INDEX IF NOT EXISTS idx_owner_pets_breed  ON owner_pets(breed_id);

CREATE TABLE IF NOT EXISTS owner_pet_photos (
  id              BIGSERIAL PRIMARY KEY,
  pet_id          BIGINT NOT NULL REFERENCES owner_pets(id) ON DELETE CASCADE,
  image_url       TEXT NOT NULL,            -- where the file lives now (local path or CDN)
  thumb_url       TEXT,
  source          TEXT NOT NULL,            -- 'gdrive' | 'photos.app' | 'upload' | 'icloud'
  source_ref      TEXT,                     -- the file ID at the source (e.g., gdrive file id)
  filename        TEXT,
  caption         TEXT,
  taken_at        TIMESTAMPTZ,
  width           INTEGER,
  height          INTEGER,
  is_hero         BOOLEAN NOT NULL DEFAULT FALSE,
  share_publicly  BOOLEAN NOT NULL DEFAULT FALSE,
  ingested_at     TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  UNIQUE (pet_id, source_ref)
);
CREATE INDEX IF NOT EXISTS idx_owner_pet_photos_pet ON owner_pet_photos(pet_id);

-- Ensure Steve's known pets have stub rows even before any photo arrives,
-- so the import script just writes photos against existing IDs.
-- (Linked to his admin app_user once it exists. Idempotent.)
INSERT INTO owner_pets (name, species_id, breed_text, source, share_publicly)
  SELECT 'Bowie',    (SELECT id FROM species WHERE name='dog'), NULL, 'manual', FALSE
   WHERE NOT EXISTS (SELECT 1 FROM owner_pets WHERE name='Bowie' AND species_id=(SELECT id FROM species WHERE name='dog'));
INSERT INTO owner_pets (name, species_id, breed_text, source, share_publicly)
  SELECT 'Humphrey', (SELECT id FROM species WHERE name='dog'), NULL, 'manual', FALSE
   WHERE NOT EXISTS (SELECT 1 FROM owner_pets WHERE name='Humphrey' AND species_id=(SELECT id FROM species WHERE name='dog'));
INSERT INTO owner_pets (name, species_id, breed_text, source, share_publicly)
  SELECT 'Madison',  (SELECT id FROM species WHERE name='dog'), NULL, 'manual', FALSE
   WHERE NOT EXISTS (SELECT 1 FROM owner_pets WHERE name='Madison' AND species_id=(SELECT id FROM species WHERE name='dog'));

-- Attach to Steve's admin account if it exists
UPDATE owner_pets SET app_user_id = (SELECT id FROM app_users WHERE email = 'steve@designerwallcoverings.com' LIMIT 1)
  WHERE name IN ('Bowie','Humphrey','Madison') AND app_user_id IS NULL;

COMMIT;