Files
iistwin/migrations/0069_gps_tracking.sql

107 lines
4.7 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- GPS-мониторинг: объекты (транспорт/люди), треки, геозоны, события, группы, подписки.
-- Интеграция с Traccar (forward позиций на /api/gps/ingest) и приём геолокации из PWA.
-- Объекты мониторинга (машины, люди с трекерами)
CREATE TABLE IF NOT EXISTS gps_assets (
id SERIAL PRIMARY KEY,
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
name TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'vehicle',
user_id INTEGER REFERENCES users(id),
external_id TEXT,
color TEXT DEFAULT '#3b82f6',
is_active BOOLEAN DEFAULT TRUE,
is_online BOOLEAN DEFAULT FALSE,
last_lat DOUBLE PRECISION,
last_lng DOUBLE PRECISION,
last_speed DOUBLE PRECISION,
last_course DOUBLE PRECISION,
last_seen_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS gps_assets_org_idx ON gps_assets(organization_id);
-- IMEI/идентификатор трекера уникален в рамках организации (только для заполненных)
CREATE UNIQUE INDEX IF NOT EXISTS gps_assets_org_external_idx
ON gps_assets(organization_id, external_id) WHERE external_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS gps_assets_user_idx ON gps_assets(user_id);
-- История позиций (треки)
CREATE TABLE IF NOT EXISTS gps_positions (
id BIGSERIAL PRIMARY KEY,
asset_id INTEGER NOT NULL REFERENCES gps_assets(id) ON DELETE CASCADE,
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
lat DOUBLE PRECISION NOT NULL,
lng DOUBLE PRECISION NOT NULL,
speed DOUBLE PRECISION,
course DOUBLE PRECISION,
accuracy DOUBLE PRECISION,
recorded_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS gps_positions_asset_recorded_idx ON gps_positions(asset_id, recorded_at);
CREATE INDEX IF NOT EXISTS gps_positions_org_recorded_idx ON gps_positions(organization_id, recorded_at);
-- Геозоны (полигоны)
CREATE TABLE IF NOT EXISTS gps_geozones (
id SERIAL PRIMARY KEY,
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
name TEXT NOT NULL,
polygon JSONB NOT NULL,
color TEXT DEFAULT '#f59e0b',
notify_enter BOOLEAN DEFAULT TRUE,
notify_exit BOOLEAN DEFAULT TRUE,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS gps_geozones_org_idx ON gps_geozones(organization_id);
-- События входа/выхода из геозон
CREATE TABLE IF NOT EXISTS gps_geozone_events (
id BIGSERIAL PRIMARY KEY,
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
geozone_id INTEGER NOT NULL REFERENCES gps_geozones(id) ON DELETE CASCADE,
asset_id INTEGER NOT NULL REFERENCES gps_assets(id) ON DELETE CASCADE,
event TEXT NOT NULL,
lat DOUBLE PRECISION,
lng DOUBLE PRECISION,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS gps_geozone_events_asset_idx ON gps_geozone_events(asset_id, created_at);
CREATE INDEX IF NOT EXISTS gps_geozone_events_org_idx ON gps_geozone_events(organization_id, created_at);
-- Текущее состояние «объект внутри геозоны» (для детекта входа/выхода)
CREATE TABLE IF NOT EXISTS gps_geozone_states (
asset_id INTEGER NOT NULL REFERENCES gps_assets(id) ON DELETE CASCADE,
geozone_id INTEGER NOT NULL REFERENCES gps_geozones(id) ON DELETE CASCADE,
inside BOOLEAN NOT NULL,
updated_at TIMESTAMP DEFAULT NOW(),
PRIMARY KEY (asset_id, geozone_id)
);
-- Группы объектов (для фильтров на карте)
CREATE TABLE IF NOT EXISTS gps_groups (
id SERIAL PRIMARY KEY,
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS gps_groups_org_idx ON gps_groups(organization_id);
-- Связь групп и объектов (многие-ко-многим)
CREATE TABLE IF NOT EXISTS gps_group_assets (
group_id INTEGER NOT NULL REFERENCES gps_groups(id) ON DELETE CASCADE,
asset_id INTEGER NOT NULL REFERENCES gps_assets(id) ON DELETE CASCADE,
PRIMARY KEY (group_id, asset_id)
);
-- Подписчики на события объекта (уведомления о входе/выходе/офлайне)
CREATE TABLE IF NOT EXISTS gps_asset_subscribers (
id SERIAL PRIMARY KEY,
asset_id INTEGER NOT NULL REFERENCES gps_assets(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
on_enter BOOLEAN DEFAULT TRUE,
on_exit BOOLEAN DEFAULT TRUE,
on_offline BOOLEAN DEFAULT FALSE,
UNIQUE (asset_id, user_id)
);