Add .rfflow file export/import support:
- Migration 050: import_metadata JSONB column on trees
- GET /trees/{id}/export?format=json|xml endpoint
- POST /trees/import endpoint (creates draft, resolves categories/tags)
- FlowExportEnvelope, FlowImportRequest/Response schemas
- import_metadata field on TreeResponse
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
55 lines
1.5 KiB
Python
55 lines
1.5 KiB
Python
"""Schemas for .rfflow file export and import."""
|
|
from datetime import datetime
|
|
from typing import Optional, Any, Literal
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.schemas.tree import TreeType
|
|
|
|
|
|
class FlowExportCategory(BaseModel):
|
|
"""Category info embedded in export file."""
|
|
name: str
|
|
slug: str
|
|
|
|
|
|
class FlowExportData(BaseModel):
|
|
"""The flow payload inside an .rfflow file."""
|
|
name: str
|
|
description: Optional[str] = None
|
|
tree_type: TreeType
|
|
version: int = 1
|
|
author_name: Optional[str] = None
|
|
category: Optional[FlowExportCategory] = None
|
|
tags: list[str] = []
|
|
tree_structure: dict[str, Any]
|
|
intake_form: Optional[list[dict[str, Any]]] = None
|
|
|
|
|
|
class FlowExportEnvelope(BaseModel):
|
|
"""Top-level .rfflow file structure."""
|
|
rfflow_version: str = "1.0"
|
|
exported_at: datetime
|
|
source_app: str = "ResolutionFlow"
|
|
format: Literal["json", "xml"] = "json"
|
|
flow: FlowExportData
|
|
|
|
|
|
class FlowImportRequest(BaseModel):
|
|
"""What the frontend sends after parsing a .rfflow file."""
|
|
rfflow_version: str = Field(..., description="Must be '1.0'")
|
|
exported_at: datetime
|
|
source_app: str = "ResolutionFlow"
|
|
format: Literal["json", "xml"] = "json"
|
|
flow: FlowExportData
|
|
|
|
|
|
class FlowImportResponse(BaseModel):
|
|
"""Response after importing a flow."""
|
|
tree_id: str
|
|
name: str
|
|
tree_type: str
|
|
status: str = "draft"
|
|
category_created: bool = False
|
|
tags_created: list[str] = []
|
|
validation_warnings: list[str] = []
|