Каркас Laravel-приложения: Breeze+Sanctum, схема БД, модели, Docker
Laravel 13 в laravel-app/, Breeze (Blade) для сессионного логина + Sanctum для API-токенов (задел под Vue/Flutter на этапе 3). Схема Postgres перенесена из сырого SQL в Laravel-миграции (владелец схемы теперь Laravel, Go-сервисы как читали/писали эти таблицы, так и продолжают). Роли/категории/ операторы условий — закрытые PHP-enum'ы (UserRole, DeviceCategory, ConditionOperator); action_type правил намеренно остаётся строкой — открытый, управляемый данными список, а не код. Сидер device_types с growbox-типами как пример данных, не бизнес-логика. Docker: один контейнер (php-fpm + nginx через supervisord, multi-stage сборка vendor/assets). Образ пока не --no-dev — сидер использует fake() для демо-аккаунта. Проверено: миграции применяются на реальном Postgres (в докере и локально), дефолтные тесты Breeze проходят (25/25), Breeze-логин подтверждён вживую через браузер, Sanctum корректно отдаёт 401 на защищённый /api/user без токена.
This commit is contained in:
@@ -1,59 +0,0 @@
|
||||
-- Core platform schema: users, zones, device types, devices, automation rules.
|
||||
-- Deliberately generic — no growbox-specific tables or columns. A "growbox"
|
||||
-- is just a row in zones with device_types like light/pump/fan attached to it.
|
||||
|
||||
CREATE TABLE users (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'owner' CHECK (role IN ('owner', 'viewer')),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE zones (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE device_types (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
code TEXT NOT NULL UNIQUE, -- light, pump, fan, sensor_temp_humidity, vacuum, ...
|
||||
category TEXT NOT NULL CHECK (category IN ('actuator', 'sensor')),
|
||||
capabilities JSONB NOT NULL DEFAULT '[]' -- e.g. ["turn_on","turn_off","set_level"]
|
||||
);
|
||||
|
||||
CREATE TABLE devices (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
zone_id BIGINT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
|
||||
device_type_id BIGINT NOT NULL REFERENCES device_types(id),
|
||||
name TEXT NOT NULL,
|
||||
external_id TEXT NOT NULL UNIQUE, -- physical device id (ESP32 chip id, etc.)
|
||||
protocol TEXT NOT NULL DEFAULT 'mqtt',
|
||||
status TEXT NOT NULL DEFAULT 'offline' CHECK (status IN ('online', 'offline')),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX devices_zone_id_idx ON devices(zone_id);
|
||||
CREATE INDEX devices_external_id_idx ON devices(external_id);
|
||||
|
||||
CREATE TABLE automation_rules (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
zone_id BIGINT NOT NULL REFERENCES zones(id) ON DELETE CASCADE,
|
||||
target_device_id BIGINT NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
||||
condition_source_device_id BIGINT NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
||||
condition_sensor_type TEXT NOT NULL,
|
||||
condition_operator TEXT NOT NULL CHECK (condition_operator IN ('>', '<', '>=', '<=', '=', '!=')),
|
||||
condition_value DOUBLE PRECISION NOT NULL,
|
||||
action_type TEXT NOT NULL, -- e.g. turn_on, turn_off, set_level
|
||||
action_params JSONB NOT NULL DEFAULT '{}',
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX automation_rules_zone_id_idx ON automation_rules(zone_id);
|
||||
CREATE INDEX automation_rules_active_idx ON automation_rules(is_active) WHERE is_active;
|
||||
Reference in New Issue
Block a user