Files
shokuninmarche/migrate.js
Fullstack Developer e003c7146d Initial fullstack scaffold: Events, Guests, Budget, Bookings
- Express backend with PostgreSQL (JWT auth, full CRUD)
- React + Vite + TailwindCSS frontend in Hebrew (RTL)
- Features: Digital Booking System, Guest Management, Smart Budget Management
- Docker Compose with postgres healthcheck
- Auto-runs migrations on startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 18:28:03 +00:00

82 lines
2.7 KiB
JavaScript

const pool = require('./db');
const migrations = [
`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`,
`CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
)`,
`CREATE TABLE IF NOT EXISTS events (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
date TIMESTAMP NOT NULL,
location VARCHAR(500),
event_type VARCHAR(100) DEFAULT 'general',
budget DECIMAL(12,2) DEFAULT 0,
status VARCHAR(50) DEFAULT 'planned',
notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
)`,
`CREATE TABLE IF NOT EXISTS guests (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
event_id UUID REFERENCES events(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
phone VARCHAR(50),
email VARCHAR(255),
rsvp_status VARCHAR(50) DEFAULT 'pending',
table_number INTEGER,
seat_number INTEGER,
dietary_restriction VARCHAR(255),
notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
)`,
`CREATE TABLE IF NOT EXISTS budget_items (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
event_id UUID REFERENCES events(id) ON DELETE CASCADE,
category VARCHAR(100) NOT NULL,
description VARCHAR(500),
estimated_cost DECIMAL(12,2) DEFAULT 0,
actual_cost DECIMAL(12,2),
status VARCHAR(50) DEFAULT 'planned',
created_at TIMESTAMP DEFAULT NOW()
)`,
`CREATE TABLE IF NOT EXISTS bookings (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
event_id UUID REFERENCES events(id) ON DELETE CASCADE,
supplier_name VARCHAR(255) NOT NULL,
supplier_type VARCHAR(100),
contact_info VARCHAR(255),
cost DECIMAL(12,2) DEFAULT 0,
status VARCHAR(50) DEFAULT 'pending',
notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
)`,
`CREATE INDEX IF NOT EXISTS idx_events_user_id ON events(user_id)`,
`CREATE INDEX IF NOT EXISTS idx_guests_event_id ON guests(event_id)`,
`CREATE INDEX IF NOT EXISTS idx_budget_items_event_id ON budget_items(event_id)`,
`CREATE INDEX IF NOT EXISTS idx_bookings_event_id ON bookings(event_id)`,
];
async function runMigrations() {
const client = await pool.connect();
try {
for (const sql of migrations) {
await client.query(sql);
console.log('Migration OK:', sql.substring(0, 60) + '...');
}
console.log('All migrations completed successfully');
} catch (err) {
console.error('Migration failed:', err);
process.exit(1);
} finally {
client.release();
await pool.end();
}
}
runMigrations();