Initial commit: site monorepo with API, web, and infra.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
ChangeAction = Literal["upsert", "delete"]
|
||||
ChangeDomain = Literal["global", "report"]
|
||||
EnterpriseRole = Literal["admin", "zootech", "viewer"]
|
||||
ConflictResolution = Literal["keep_orchestrator", "keep_hub"]
|
||||
|
||||
|
||||
class ChangeEventIn(BaseModel):
|
||||
event_id: str
|
||||
seq: int
|
||||
domain: ChangeDomain = "global"
|
||||
table: str = Field(alias="table")
|
||||
record_id: str
|
||||
action: ChangeAction
|
||||
version: int = 1
|
||||
content_hash: str = ""
|
||||
payload: dict[str, Any] = Field(default_factory=dict)
|
||||
emitted_at: datetime
|
||||
origin_site_id: str | None = None
|
||||
|
||||
model_config = {"populate_by_name": True}
|
||||
|
||||
|
||||
class ChangeEventOut(BaseModel):
|
||||
event_id: str
|
||||
seq: int
|
||||
domain: ChangeDomain
|
||||
table: str
|
||||
record_id: str
|
||||
action: ChangeAction
|
||||
version: int
|
||||
content_hash: str
|
||||
payload: dict[str, Any]
|
||||
emitted_at: datetime
|
||||
origin_site_id: str | None = None
|
||||
|
||||
|
||||
class PushChangesRequest(BaseModel):
|
||||
events: list[ChangeEventIn]
|
||||
|
||||
|
||||
class PushChangesResponse(BaseModel):
|
||||
applied_event_ids: list[str]
|
||||
held_event_ids: list[str]
|
||||
conflicts: list[str]
|
||||
|
||||
|
||||
class PullChangesRequest(BaseModel):
|
||||
cursor: int = 0
|
||||
limit: int = 100
|
||||
|
||||
|
||||
class PullChangesResponse(BaseModel):
|
||||
events: list[ChangeEventOut]
|
||||
next_cursor: int
|
||||
|
||||
|
||||
class AckChangesRequest(BaseModel):
|
||||
event_ids: list[str]
|
||||
direction: Literal["inbound", "outbound"] = "inbound"
|
||||
|
||||
|
||||
class AckChangesResponse(BaseModel):
|
||||
last_acked_seq: int
|
||||
|
||||
|
||||
class SyncCapabilitiesResponse(BaseModel):
|
||||
protocol_version: str = "1.0"
|
||||
domains: list[str] = Field(default_factory=lambda: ["global", "report"])
|
||||
|
||||
|
||||
class HeartbeatRequest(BaseModel):
|
||||
wesp_version: str | None = None
|
||||
lag_seconds: int | None = None
|
||||
|
||||
|
||||
class HeartbeatResponse(BaseModel):
|
||||
status: str = "ok"
|
||||
server_time: datetime
|
||||
|
||||
|
||||
class PairStartRequest(BaseModel):
|
||||
enterprise_id: str
|
||||
farm_name: str
|
||||
|
||||
|
||||
class PairStartResponse(BaseModel):
|
||||
session_id: str
|
||||
code: str
|
||||
expires_at: datetime
|
||||
|
||||
|
||||
class PairConfirmRequest(BaseModel):
|
||||
code: str
|
||||
hub_site_id: str
|
||||
hub_name: str | None = None
|
||||
hub_url: str | None = None
|
||||
|
||||
|
||||
class PairConfirmResponse(BaseModel):
|
||||
farm_hub_id: str
|
||||
hub_site_id: str
|
||||
api_key: str
|
||||
enterprise_id: str
|
||||
|
||||
|
||||
class ConflictSummary(BaseModel):
|
||||
id: str
|
||||
table_name: str
|
||||
record_id: str
|
||||
farm_hub_id: str | None
|
||||
status: str
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class ConflictDetail(ConflictSummary):
|
||||
orchestrator_snapshot: dict[str, Any]
|
||||
hub_snapshot: dict[str, Any]
|
||||
held_event_ids: list[str]
|
||||
|
||||
|
||||
class ResolveConflictRequest(BaseModel):
|
||||
resolution: ConflictResolution
|
||||
|
||||
|
||||
class EnterpriseOut(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
slug: str
|
||||
status: str
|
||||
|
||||
|
||||
class FarmHubOut(BaseModel):
|
||||
id: str
|
||||
enterprise_id: str
|
||||
name: str
|
||||
hub_site_id: str
|
||||
url: str | None
|
||||
status: str
|
||||
last_seen: datetime | None
|
||||
wesp_version: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class HubAuthContext:
|
||||
farm_hub_id: str
|
||||
hub_site_id: str
|
||||
enterprise_id: str
|
||||
farm_hub: Any
|
||||
|
||||
|
||||
@dataclass
|
||||
class TenantContext:
|
||||
enterprise_id: str
|
||||
enterprise_role: EnterpriseRole | None
|
||||
user_id: str | None
|
||||
farm_hub_ids: list[str] | None
|
||||
Reference in New Issue
Block a user