CI / backend (pull_request) Canceled after 0s
CI / shell (pull_request) Canceled after 0s
CI / frontend (pull_request) Canceled after 0s
CI / arm64-smoke (pull_request) Canceled after 0s
CI / backend (push) Canceled after 0s
CI / shell (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / arm64-smoke (push) Canceled after 0s
226 lines
10 KiB
Python
226 lines
10 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import JSON, Boolean, DateTime, Integer, String, Text
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.models.base import Base
|
|
|
|
|
|
def utc_now() -> datetime:
|
|
return datetime.now(UTC)
|
|
|
|
|
|
class User(Base):
|
|
__tablename__ = "users"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
username: Mapped[str] = mapped_column(String(100), unique=True, index=True)
|
|
password_hash: Mapped[str] = mapped_column(String(255))
|
|
role: Mapped[str] = mapped_column(String(30), default="administrator")
|
|
disabled: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class SessionRecord(Base):
|
|
__tablename__ = "sessions"
|
|
|
|
id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
user_id: Mapped[int] = mapped_column(Integer, index=True)
|
|
csrf_token: Mapped[str] = mapped_column(String(64))
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True))
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class ApiToken(Base):
|
|
__tablename__ = "api_tokens"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
label: Mapped[str] = mapped_column(String(120))
|
|
token_hash: Mapped[str] = mapped_column(String(255))
|
|
role: Mapped[str] = mapped_column(String(30), default="operator")
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
|
|
|
|
class Setting(Base):
|
|
__tablename__ = "settings"
|
|
|
|
key: Mapped[str] = mapped_column(String(120), primary_key=True)
|
|
value: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class FixtureSource(Base):
|
|
__tablename__ = "fixture_sources"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
manufacturer_key: Mapped[str] = mapped_column(String(100))
|
|
fixture_key: Mapped[str] = mapped_column(String(150))
|
|
schema_ref: Mapped[str] = mapped_column(String(255))
|
|
source_url: Mapped[str] = mapped_column(String(255))
|
|
payload: Mapped[dict[str, object]] = mapped_column(JSON)
|
|
payload_hash: Mapped[str] = mapped_column(String(64))
|
|
imported_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class FixtureDefinition(Base):
|
|
__tablename__ = "fixture_definitions"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
slug: Mapped[str] = mapped_column(String(160), unique=True, index=True)
|
|
manufacturer: Mapped[str] = mapped_column(String(120))
|
|
model: Mapped[str] = mapped_column(String(160))
|
|
short_name: Mapped[str | None] = mapped_column(String(120), nullable=True)
|
|
categories: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
normalized_data: Mapped[dict[str, object]] = mapped_column(JSON)
|
|
source_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class FixtureInstance(Base):
|
|
__tablename__ = "fixture_instances"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
universe: Mapped[int] = mapped_column(Integer, default=1)
|
|
name: Mapped[str] = mapped_column(String(160))
|
|
definition_id: Mapped[int] = mapped_column(Integer, index=True)
|
|
mode_key: Mapped[str] = mapped_column(String(120))
|
|
start_address: Mapped[int] = mapped_column(Integer)
|
|
channel_count: Mapped[int] = mapped_column(Integer)
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
group_names: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
position: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
tags: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class Scene(Base):
|
|
__tablename__ = "scenes"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(160))
|
|
slug: Mapped[str] = mapped_column(String(160), unique=True, index=True)
|
|
color: Mapped[str] = mapped_column(String(20), default="#00e5ff")
|
|
icon: Mapped[str | None] = mapped_column(String(40), nullable=True)
|
|
priority: Mapped[int] = mapped_column(Integer, default=10)
|
|
fade_in_ms: Mapped[int] = mapped_column(Integer, default=500)
|
|
fade_out_ms: Mapped[int] = mapped_column(Integer, default=500)
|
|
hold_ms: Mapped[int] = mapped_column(Integer, default=0)
|
|
master_limit: Mapped[int] = mapped_column(Integer, default=255)
|
|
values: Mapped[list[dict[str, object]]] = mapped_column(JSON, default=list)
|
|
targets: Mapped[list[dict[str, object]]] = mapped_column(JSON, default=list)
|
|
tags: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class Effect(Base):
|
|
__tablename__ = "effects"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(160))
|
|
slug: Mapped[str] = mapped_column(String(160), unique=True, index=True)
|
|
effect_type: Mapped[str] = mapped_column(String(80))
|
|
parameters: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
priority: Mapped[int] = mapped_column(Integer, default=40)
|
|
cooldown_ms: Mapped[int] = mapped_column(Integer, default=0)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class TriggerMapping(Base):
|
|
__tablename__ = "trigger_mappings"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
slug: Mapped[str] = mapped_column(String(160), unique=True, index=True)
|
|
name: Mapped[str] = mapped_column(String(160))
|
|
event_type: Mapped[str] = mapped_column(String(60))
|
|
action_type: Mapped[str] = mapped_column(String(30))
|
|
action_slug: Mapped[str] = mapped_column(String(160))
|
|
config: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
active: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class TriggerEvent(Base):
|
|
__tablename__ = "trigger_events"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
slug: Mapped[str] = mapped_column(String(160), index=True)
|
|
event_id: Mapped[str | None] = mapped_column(String(160), nullable=True)
|
|
status: Mapped[str] = mapped_column(String(30), default="queued")
|
|
payload: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class SystemEvent(Base):
|
|
__tablename__ = "system_events"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
category: Mapped[str] = mapped_column(String(40))
|
|
level: Mapped[str] = mapped_column(String(20))
|
|
message: Mapped[str] = mapped_column(Text)
|
|
payload: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class BackupRecord(Base):
|
|
__tablename__ = "backups"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
label: Mapped[str] = mapped_column(String(160))
|
|
path: Mapped[str] = mapped_column(String(255))
|
|
manifest: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class MidiBridge(Base):
|
|
__tablename__ = "midi_bridges"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
bridge_id: Mapped[str] = mapped_column(String(160), unique=True, index=True)
|
|
device_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
ip_address: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
protocol_version: Mapped[int] = mapped_column(Integer, default=1)
|
|
online: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
last_heartbeat_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
last_event_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
last_event: Mapped[dict[str, object]] = mapped_column(JSON, default=dict)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class MidiBridgeToken(Base):
|
|
__tablename__ = "midi_bridge_tokens"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
label: Mapped[str] = mapped_column(String(120))
|
|
token_hash: Mapped[str] = mapped_column(String(64), unique=True, index=True)
|
|
bridge_id: Mapped[str | None] = mapped_column(String(160), nullable=True)
|
|
scopes: Mapped[list[str]] = mapped_column(JSON, default=list)
|
|
last_used_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
|
|
|
|
class MidiMapping(Base):
|
|
__tablename__ = "midi_mappings"
|
|
|
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(160))
|
|
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
bridge_id: Mapped[str | None] = mapped_column(String(160), nullable=True)
|
|
device_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
|
message_type: Mapped[str] = mapped_column(String(40))
|
|
channel: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
number: Mapped[int] = mapped_column(Integer)
|
|
action: Mapped[str] = mapped_column(String(60))
|
|
target_type: Mapped[str] = mapped_column(String(40))
|
|
target_id: Mapped[str | None] = mapped_column(String(160), nullable=True)
|
|
mode: Mapped[str] = mapped_column(String(40), default="trigger")
|
|
minimum_value: Mapped[int] = mapped_column(Integer, default=0)
|
|
maximum_value: Mapped[int] = mapped_column(Integer, default=127)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
|
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|