Add migration 002: missing updated_at columns + auto-update triggers + indexes

Tables fixed:
- rooms              → added updated_at
- housekeeping_tasks → added updated_at
- channels           → added created_at + updated_at

Trigger function set_updated_at() attached to all 6 tables (hotels, users,
rooms, bookings, housekeeping_tasks, channels) — updated_at now auto-sets
on every UPDATE via BEFORE UPDATE trigger.

Indexes added for archiving / range queries:
- bookings(hotel_id, created_at), bookings(hotel_id, updated_at)
- housekeeping_tasks(hotel_id, created_at)
- rooms(hotel_id, updated_at)
- channels(hotel_id, updated_at)

Also patched 001_schema.sql so fresh installs start correct.
Migration runner is idempotent — skips already applied files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 12:09:53 +03:00
parent 39aeafe276
commit 6010531114
2 changed files with 80 additions and 1 deletions

View File

@@ -43,6 +43,7 @@ CREATE TABLE IF NOT EXISTS rooms (
amenities TEXT[] NOT NULL DEFAULT '{}', amenities TEXT[] NOT NULL DEFAULT '{}',
notes TEXT, notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(hotel_id, number) UNIQUE(hotel_id, number)
); );
@@ -84,7 +85,8 @@ CREATE TABLE IF NOT EXISTS housekeeping_tasks (
notes TEXT, notes TEXT,
due_date DATE, due_date DATE,
completed_at TIMESTAMPTZ, completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
); );
-- ── Channels ─────────────────────────────────────────────────────────────── -- ── Channels ───────────────────────────────────────────────────────────────
@@ -97,6 +99,8 @@ CREATE TABLE IF NOT EXISTS channels (
api_key_encrypted TEXT, api_key_encrypted TEXT,
hotel_external_id VARCHAR(255), hotel_external_id VARCHAR(255),
last_synced_at TIMESTAMPTZ, last_synced_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(hotel_id, name) UNIQUE(hotel_id, name)
); );

View File

@@ -0,0 +1,75 @@
-- Migration 002 — Add missing updated_at columns and auto-update trigger
-- ─────────────────────────────────────────────────────────────────────────────
-- Tables audit:
-- hotels ✅ created_at ✅ updated_at
-- users ✅ created_at ✅ updated_at
-- rooms ✅ created_at ❌ updated_at ← add
-- bookings ✅ created_at ✅ updated_at
-- housekeeping_tasks ✅ created_at ❌ updated_at ← add
-- channels ❌ created_at ❌ updated_at ← add both
-- ─────────────────────────────────────────────────────────────────────────────
-- ── 1. Add missing columns ──────────────────────────────────────────────────
ALTER TABLE rooms
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
ALTER TABLE housekeeping_tasks
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
ALTER TABLE channels
ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
-- ── 2. Trigger function: auto-set updated_at = NOW() on every UPDATE ────────
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- ── 3. Attach trigger to every table that has updated_at ────────────────────
-- Using DROP IF EXISTS + CREATE so the migration is idempotent.
DROP TRIGGER IF EXISTS trg_hotels_updated_at ON hotels;
DROP TRIGGER IF EXISTS trg_users_updated_at ON users;
DROP TRIGGER IF EXISTS trg_rooms_updated_at ON rooms;
DROP TRIGGER IF EXISTS trg_bookings_updated_at ON bookings;
DROP TRIGGER IF EXISTS trg_housekeeping_tasks_updated_at ON housekeeping_tasks;
DROP TRIGGER IF EXISTS trg_channels_updated_at ON channels;
CREATE TRIGGER trg_hotels_updated_at
BEFORE UPDATE ON hotels
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
CREATE TRIGGER trg_users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
CREATE TRIGGER trg_rooms_updated_at
BEFORE UPDATE ON rooms
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
CREATE TRIGGER trg_bookings_updated_at
BEFORE UPDATE ON bookings
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
CREATE TRIGGER trg_housekeeping_tasks_updated_at
BEFORE UPDATE ON housekeeping_tasks
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
CREATE TRIGGER trg_channels_updated_at
BEFORE UPDATE ON channels
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
-- ── 4. Indexes on created_at for archiving / range queries ──────────────────
-- Нужны чтобы запрос "дай все записи старше 6 месяцев" работал быстро.
CREATE INDEX IF NOT EXISTS idx_bookings_created_at ON bookings(hotel_id, created_at);
CREATE INDEX IF NOT EXISTS idx_bookings_updated_at ON bookings(hotel_id, updated_at);
CREATE INDEX IF NOT EXISTS idx_housekeeping_tasks_created_at ON housekeeping_tasks(hotel_id, created_at);
CREATE INDEX IF NOT EXISTS idx_rooms_updated_at ON rooms(hotel_id, updated_at);
CREATE INDEX IF NOT EXISTS idx_channels_updated_at ON channels(hotel_id, updated_at);