feat(appliance): initial release of MERICA standalone appliance v1.0.0

This commit is contained in:
2026-10-21 17:16:46 +07:00
commit 851be0cda7
144 changed files with 31135 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
"""Schemas package initialization."""
from app.schemas.pipeline import DeployRequest, DraftRequest, PipelineItem, PipelineListResponse
from app.schemas.connection import ConnectionItem, ConnectionListResponse, CustomConnectionRequest, ConnectionTestRequest
from app.schemas.trino import CatalogItem, CatalogListResponse, SchemaItem, SchemaListResponse, TableItem, TableListResponse
from app.schemas.sitomat import SitomatProvisionRequest, SitomatProvisionResponse, SitomatTriggerRequest, SitomatTriggerResponse
__all__ = [
"DeployRequest",
"DraftRequest",
"PipelineItem",
"PipelineListResponse",
"ConnectionItem",
"ConnectionListResponse",
"CustomConnectionRequest",
"ConnectionTestRequest",
"CatalogItem",
"CatalogListResponse",
"SchemaItem",
"SchemaListResponse",
"TableItem",
"TableListResponse",
"SitomatProvisionRequest",
"SitomatProvisionResponse",
"SitomatTriggerRequest",
"SitomatTriggerResponse",
]
+31
View File
@@ -0,0 +1,31 @@
from typing import Optional, List, Any
from pydantic import BaseModel, model_validator
class ConnectionItem(BaseModel):
conn_id: str
conn_type: str
host: str
class ConnectionListResponse(BaseModel):
connections: List[ConnectionItem]
class CustomConnectionRequest(BaseModel):
conn_id: str
conn_type: str = "postgres"
host: str
port: int = 5432
db_schema: str = "public"
login: str = "postgres"
password: Optional[str] = ""
@model_validator(mode="before")
@classmethod
def handle_schema_alias(cls, data: Any) -> Any:
"""Support both 'schema' and 'db_schema' JSON payload keys safely."""
if isinstance(data, dict):
if "schema" in data and "db_schema" not in data:
data["db_schema"] = data.pop("schema")
return data
class ConnectionTestRequest(BaseModel):
connection_id: str
+64
View File
@@ -0,0 +1,64 @@
from pydantic import BaseModel, Field
from typing import Dict, Any, List, Optional
class DeployRequest(BaseModel):
pipeline_id: str
description: Optional[str] = "Dynamic Lakehouse Pipeline"
schedule: Optional[str] = "0 */1 * * *"
nodes: List[Dict[str, Any]]
edges: List[Dict[str, Any]]
notes: Optional[List[Dict[str, Any]]] = None
spec_yaml: Optional[str] = ""
bundle_name: Optional[str] = "dlh-core-ingestion"
version: Optional[str] = "v1.0.0"
class DraftRequest(BaseModel):
pipeline_id: str
description: Optional[str] = "Dynamic Lakehouse Pipeline Draft"
schedule: Optional[str] = "0 */1 * * *"
nodes: List[Dict[str, Any]]
edges: List[Dict[str, Any]]
notes: Optional[List[Dict[str, Any]]] = None
bundle_name: Optional[str] = "dlh-core-ingestion"
class PublishVersionRequest(BaseModel):
pipeline_id: str
version_tag: str = Field(..., description="Semantic version tag, e.g. v1.0.0, v1.1.0")
changelog: Optional[str] = "Released new pipeline version via MERICA Studio"
bundle_name: Optional[str] = "dlh-core-ingestion"
nodes: Optional[List[Dict[str, Any]]] = None
edges: Optional[List[Dict[str, Any]]] = None
notes: Optional[List[Dict[str, Any]]] = None
class RevertVersionRequest(BaseModel):
version_tag: str
class VersionSnapshotItem(BaseModel):
version: str
pipeline_id: str
bundle_name: str
changelog: str
published_at: str
nodes_count: int
edges_count: int
snapshot_filename: str
class VersionListResponse(BaseModel):
pipeline_id: str
current_version: Optional[str]
bundle_name: str
versions: List[VersionSnapshotItem]
class PipelineItem(BaseModel):
id: str
description: Optional[str] = ""
schedule: Optional[str] = "0 */1 * * *"
nodes: List[Dict[str, Any]] = []
edges: List[Dict[str, Any]] = []
is_draft: bool = False
status: str = "deployed"
bundle_name: Optional[str] = "dlh-core-ingestion"
version: Optional[str] = "v1.0.0"
class PipelineListResponse(BaseModel):
pipelines: List[Dict[str, Any]]
+58
View File
@@ -0,0 +1,58 @@
from pydantic import BaseModel, Field
from typing import Dict, Any, Optional, List
class BundleItem(BaseModel):
name: str
tracking_ref: str
repo_url: str
subdir: str
type: str = "git"
class BundleListResponse(BaseModel):
bundles: List[BundleItem]
class SitomatProvisionRequest(BaseModel):
dataset_id: str
bundle_name: Optional[str] = "dlh-core-ingestion"
source_type: str = Field(..., description="database | gws | api")
connection_id: str
source_config: Dict[str, Any] = Field(default_factory=dict)
bronze_target: Optional[Dict[str, Any]] = Field(default_factory=lambda: {
"s3_bucket": "dlh-landing",
"s3_prefix": "bronze/raw/"
})
dbt_models: Optional[Dict[str, str]] = Field(default_factory=dict)
schedule: Optional[str] = "0 2 * * *"
class SitomatProvisionResponse(BaseModel):
status: str = "provisioned"
dataset_id: str
bundle_name: str
bronze_dag_id: str
transform_dag_id: str
initial_version: str
git_commit_hash: Optional[str] = None
yaml_config_path: Optional[str] = None
class SitomatTriggerRequest(BaseModel):
correlation_id: str
dataset_id: str
target_dag_version: Optional[str] = "latest"
conf: Optional[Dict[str, Any]] = Field(default_factory=dict)
class SitomatTriggerResponse(BaseModel):
status: str = "triggered"
correlation_id: str
dag_id: str
dag_run_id: str
pinned_version: str
class SitomatLedgerCallback(BaseModel):
correlation_id: str
dataset_id: str
dag_id: str
dag_run_id: str
status: str
bronze_ref: Optional[str] = None
record_count: Optional[int] = 0
byte_size: Optional[int] = 0
+28
View File
@@ -0,0 +1,28 @@
from pydantic import BaseModel
from typing import List
class CatalogItem(BaseModel):
id: str
name: str
type: str
class CatalogListResponse(BaseModel):
catalogs: List[CatalogItem]
class SchemaItem(BaseModel):
id: str
name: str
layer: str
class SchemaListResponse(BaseModel):
schemas: List[SchemaItem]
class TableItem(BaseModel):
table_name: str
layer: str
format: str
class TableListResponse(BaseModel):
catalog: str
schema_name: str
tables: List[TableItem]