Initial commit
This commit is contained in:
187
backend/migrations/001_init.sql
Normal file
187
backend/migrations/001_init.sql
Normal file
@@ -0,0 +1,187 @@
|
||||
-- Enable PostGIS extension
|
||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||
|
||||
-- API Keys table
|
||||
CREATE TABLE api_keys (
|
||||
id SERIAL PRIMARY KEY,
|
||||
key VARCHAR(64) UNIQUE NOT NULL,
|
||||
app_name VARCHAR(100) NOT NULL,
|
||||
rate_limit INTEGER DEFAULT 1000,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_used_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- Routes table (маршруты)
|
||||
CREATE TABLE routes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
route_number VARCHAR(10) NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL CHECK (type IN ('bus', 'minibus', 'trolleybus', 'tram')),
|
||||
color VARCHAR(7) DEFAULT '#0066CC',
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Stops table (остановки) with geospatial support
|
||||
CREATE TABLE stops (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
location GEOGRAPHY(Point, 4326) NOT NULL,
|
||||
address VARCHAR(300),
|
||||
description TEXT,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create spatial index for stops
|
||||
CREATE INDEX idx_stops_location ON stops USING GIST(location);
|
||||
|
||||
-- Route stops junction table (связь маршрутов и остановок)
|
||||
CREATE TABLE route_stops (
|
||||
id SERIAL PRIMARY KEY,
|
||||
route_id INTEGER NOT NULL REFERENCES routes(id) ON DELETE CASCADE,
|
||||
stop_id INTEGER NOT NULL REFERENCES stops(id) ON DELETE CASCADE,
|
||||
sequence INTEGER NOT NULL,
|
||||
time_offset_minutes INTEGER NOT NULL DEFAULT 0,
|
||||
UNIQUE(route_id, stop_id, sequence)
|
||||
);
|
||||
|
||||
-- Schedules table (расписание)
|
||||
CREATE TABLE schedules (
|
||||
id SERIAL PRIMARY KEY,
|
||||
route_id INTEGER NOT NULL REFERENCES routes(id) ON DELETE CASCADE,
|
||||
day_type VARCHAR(20) NOT NULL CHECK (day_type IN ('weekday', 'saturday', 'sunday', 'holiday')),
|
||||
departure_times TIME[] NOT NULL,
|
||||
valid_from DATE,
|
||||
valid_until DATE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Vehicles table (транспортные средства)
|
||||
CREATE TABLE vehicles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
vehicle_number VARCHAR(20) NOT NULL,
|
||||
registration VARCHAR(20),
|
||||
type VARCHAR(20) NOT NULL,
|
||||
capacity INTEGER,
|
||||
route_id INTEGER REFERENCES routes(id) ON DELETE SET NULL,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Historical delays table (статистика задержек)
|
||||
CREATE TABLE historical_delays (
|
||||
id SERIAL PRIMARY KEY,
|
||||
route_id INTEGER NOT NULL REFERENCES routes(id) ON DELETE CASCADE,
|
||||
stop_id INTEGER NOT NULL REFERENCES stops(id) ON DELETE CASCADE,
|
||||
hour_of_day INTEGER NOT NULL CHECK (hour_of_day BETWEEN 0 AND 23),
|
||||
day_type VARCHAR(20) NOT NULL,
|
||||
avg_delay_minutes INTEGER NOT NULL,
|
||||
sample_count INTEGER DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(route_id, stop_id, hour_of_day, day_type)
|
||||
);
|
||||
|
||||
-- Alerts table (уведомления и оповещения)
|
||||
CREATE TABLE alerts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
route_id INTEGER REFERENCES routes(id) ON DELETE CASCADE,
|
||||
alert_type VARCHAR(20) NOT NULL CHECK (alert_type IN ('delay', 'cancellation', 'detour', 'info')),
|
||||
title VARCHAR(200) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
start_time TIMESTAMP NOT NULL,
|
||||
end_time TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Sync log table (для offline синхронизации)
|
||||
CREATE TABLE sync_log (
|
||||
id SERIAL PRIMARY KEY,
|
||||
table_name VARCHAR(50) NOT NULL,
|
||||
record_id INTEGER NOT NULL,
|
||||
action VARCHAR(20) NOT NULL CHECK (action IN ('insert', 'update', 'delete')),
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX idx_routes_number ON routes(route_number);
|
||||
CREATE INDEX idx_routes_active ON routes(is_active);
|
||||
CREATE INDEX idx_stops_name ON stops(name);
|
||||
CREATE INDEX idx_route_stops_route ON route_stops(route_id);
|
||||
CREATE INDEX idx_route_stops_stop ON route_stops(stop_id);
|
||||
CREATE INDEX idx_schedules_route ON schedules(route_id);
|
||||
CREATE INDEX idx_vehicles_route ON vehicles(route_id);
|
||||
CREATE INDEX idx_alerts_active ON alerts(is_active, start_time, end_time);
|
||||
CREATE INDEX idx_sync_log_timestamp ON sync_log(timestamp);
|
||||
|
||||
-- Create function to update updated_at timestamp
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Create triggers for updated_at
|
||||
CREATE TRIGGER update_routes_updated_at BEFORE UPDATE ON routes
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_stops_updated_at BEFORE UPDATE ON stops
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_schedules_updated_at BEFORE UPDATE ON schedules
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
CREATE TRIGGER update_vehicles_updated_at BEFORE UPDATE ON vehicles
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Create function to log changes for sync
|
||||
CREATE OR REPLACE FUNCTION log_sync_changes()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF (TG_OP = 'DELETE') THEN
|
||||
INSERT INTO sync_log (table_name, record_id, action)
|
||||
VALUES (TG_TABLE_NAME, OLD.id, 'delete');
|
||||
RETURN OLD;
|
||||
ELSIF (TG_OP = 'UPDATE') THEN
|
||||
INSERT INTO sync_log (table_name, record_id, action)
|
||||
VALUES (TG_TABLE_NAME, NEW.id, 'update');
|
||||
RETURN NEW;
|
||||
ELSIF (TG_OP = 'INSERT') THEN
|
||||
INSERT INTO sync_log (table_name, record_id, action)
|
||||
VALUES (TG_TABLE_NAME, NEW.id, 'insert');
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create sync triggers for main tables
|
||||
CREATE TRIGGER sync_routes AFTER INSERT OR UPDATE OR DELETE ON routes
|
||||
FOR EACH ROW EXECUTE FUNCTION log_sync_changes();
|
||||
|
||||
CREATE TRIGGER sync_stops AFTER INSERT OR UPDATE OR DELETE ON stops
|
||||
FOR EACH ROW EXECUTE FUNCTION log_sync_changes();
|
||||
|
||||
CREATE TRIGGER sync_route_stops AFTER INSERT OR UPDATE OR DELETE ON route_stops
|
||||
FOR EACH ROW EXECUTE FUNCTION log_sync_changes();
|
||||
|
||||
CREATE TRIGGER sync_schedules AFTER INSERT OR UPDATE OR DELETE ON schedules
|
||||
FOR EACH ROW EXECUTE FUNCTION log_sync_changes();
|
||||
|
||||
-- Insert sample API key for development
|
||||
INSERT INTO api_keys (key, app_name, rate_limit)
|
||||
VALUES ('dev_key_12345678', 'Development App', 10000);
|
||||
|
||||
-- Grant permissions
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO transit_admin;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO transit_admin;
|
||||
Reference in New Issue
Block a user