Интегрирован wesp в сайт
CI / quality (push) Canceled after 0s

This commit is contained in:
влад
2026-07-17 12:57:18 +03:00
parent 5dfa06ddbe
commit 355c0ef9f1
883 changed files with 194576 additions and 177 deletions
+118
View File
@@ -0,0 +1,118 @@
from sqlalchemy import Boolean, Column, DateTime, Integer, String, Text, UniqueConstraint
from app import db
from .base import SoftDeleteMixin, TimestampMixin, default_uuid
class SyncMetadata(db.Model, TimestampMixin, SoftDeleteMixin):
"""Метаданные синхронизации (паспорт узла)."""
__tablename__ = "sync_metadata"
id = Column(String(36), primary_key=True, default=default_uuid)
node_id = Column(String(36), nullable=False, unique=True)
node_type = Column(String(20), nullable=False) # 'server' | 'client'
node_name = Column(String(100), nullable=True)
node_status = Column(String(20), default="active")
last_heartbeat = Column(DateTime, nullable=True)
last_sync = Column(DateTime, nullable=True)
sync_status = Column(String(20), default="idle")
is_enabled = Column(Boolean, default=True)
class SyncClient(db.Model, TimestampMixin, SoftDeleteMixin):
"""Реестр клиентов синхронизации."""
__tablename__ = "sync_clients"
id = Column(String(36), primary_key=True, default=default_uuid)
node_id = Column(String(36), nullable=False, unique=True)
client_name = Column(String(100), nullable=False)
ip_address = Column(String(45), nullable=True)
port = Column(Integer, default=80)
status = Column(String(20), default="active")
last_seen = Column(DateTime, nullable=True)
total_syncs = Column(Integer, default=0)
last_error = Column(Text, nullable=True)
is_enabled = Column(Boolean, default=True)
personal_snapshot_completed_at = Column(DateTime, nullable=True)
personal_snapshot_cursor = Column(Integer, nullable=False, default=0)
class SyncEngineState(db.Model, TimestampMixin, SoftDeleteMixin):
"""Durable flags/cursors for sync engine bootstrap."""
__tablename__ = "sync_engine_state"
id = Column(Integer, primary_key=True, default=1)
universal_bootstrap_completed_at = Column(DateTime, nullable=True)
universal_bootstrap_cursor = Column(Integer, nullable=False, default=0)
universal_bootstrap_last_error = Column(Text, nullable=True)
class SyncClientDisplayName(db.Model):
"""Привязка клиента к отображаемому имени (для UI)."""
__tablename__ = "sync_client_display_name"
node_id = Column(String(36), primary_key=True)
display_name = Column(String(100), nullable=False)
updated_at = Column(DateTime, nullable=False)
class SyncQueue(db.Model, TimestampMixin, SoftDeleteMixin):
"""Очередь задач синхронизации."""
__tablename__ = "sync_queue"
__table_args__ = (
UniqueConstraint(
"table_name",
"record_id",
"action",
"target_node_id",
name="uq_sync_queue_task",
),
)
id = Column(String(36), primary_key=True, default=default_uuid)
table_name = Column(String(50), nullable=False)
record_id = Column(String(36), nullable=False)
action = Column(String(20), nullable=False) # 'create' | 'update' | 'delete'
status = Column(String(20), default="pending") # pending|processing|completed|failed
target_node_id = Column(String(36), nullable=True)
source_node_id = Column(String(36), nullable=True)
priority = Column(Integer, default=1)
retry_count = Column(Integer, default=0)
max_retries = Column(Integer, default=3)
error_message = Column(Text, nullable=True)
created_at = Column(DateTime, nullable=False)
processed_at = Column(DateTime, nullable=True)
completed_at = Column(DateTime, nullable=True)
class SyncDelivery(db.Model, TimestampMixin, SoftDeleteMixin):
"""Фиксация доставки универсальных задач до клиентов."""
__tablename__ = "sync_delivery"
id = Column(String(36), primary_key=True, default=default_uuid)
client_id = Column(String(36), nullable=False, index=True)
task_id = Column(String(36), nullable=False, index=True)
delivered_at = Column(DateTime, nullable=False)
class SyncConflict(db.Model, TimestampMixin, SoftDeleteMixin):
"""Конфликты синхронизации."""
__tablename__ = "sync_conflicts"
id = Column(String(36), primary_key=True, default=default_uuid)
table_name = Column(String(50), nullable=False)
record_id = Column(String(36), nullable=False)
conflict_type = Column(String(20), nullable=False)
local_data = Column(Text, nullable=True)
remote_data = Column(Text, nullable=True)
resolution = Column(String(20), nullable=True)
resolved_by = Column(String(50), nullable=True)
resolved_at = Column(DateTime, nullable=True)