from __future__ import annotations from typing import Literal from uuid import UUID from pydantic import Field from .common import ApiEnvelope, RouteContract, SchemaModel HTTP_METHOD = 'POST' ROUTE_PATH = '/api/fertilization/recommend/' class FertilizationRecommendRequest(SchemaModel): farm_uuid: UUID sensor_uuid: UUID | None = None crop_id: str | None = None plant_name: str | None = None growth_stage: str | None = None query: str | None = None class NpkRatio(SchemaModel): n: float p: float k: float label: str class ApplicationMethod(SchemaModel): id: str label: str class ApplicationInterval(SchemaModel): value: int unit: Literal['day', 'week'] label: str class Dosage(SchemaModel): base_amount_per_hectare: float base_amount_per_square_meter: float unit: Literal['kg', 'gram', 'liter', 'milliliter'] label: str calculation_basis: str class PrimaryRecommendation(SchemaModel): fertilizer_code: str fertilizer_name: str display_title: str fertilizer_type: str npk_ratio: NpkRatio application_method: ApplicationMethod application_interval: ApplicationInterval dosage: Dosage reasoning: str summary: str class NutrientItem(SchemaModel): key: str name: str value: float unit: Literal['percent'] description: str | None = None class NutrientAnalysis(SchemaModel): macro: list[NutrientItem] = Field(default_factory=list) micro: list[NutrientItem] = Field(default_factory=list) class ApplicationGuideStep(SchemaModel): step_number: int title: str description: str class ApplicationGuide(SchemaModel): safety_warning: str steps: list[ApplicationGuideStep] = Field(default_factory=list) class AlternativeRecommendation(SchemaModel): fertilizer_code: str fertilizer_name: str fertilizer_type: str usage_method: str description: str class FertilizationSection(SchemaModel): type: Literal['recommendation', 'list', 'warning', 'info'] title: str icon: str | None = None content: str | None = None items: list[str] = Field(default_factory=list) fertilizerType: str | None = None amount: str | None = None applicationMethod: str | None = None timing: str | None = None validityPeriod: str | None = None expandableExplanation: str | None = None class FertilizationRecommendResponseData(SchemaModel): primary_recommendation: PrimaryRecommendation nutrient_analysis: NutrientAnalysis application_guide: ApplicationGuide alternative_recommendations: list[AlternativeRecommendation] = Field(default_factory=list) sections: list[FertilizationSection] = Field(default_factory=list) class FertilizationRecommendResponse(ApiEnvelope[FertilizationRecommendResponseData]): pass CONTRACT = RouteContract( method=HTTP_METHOD, path=ROUTE_PATH, request_model=FertilizationRecommendRequest.__name__, response_model=FertilizationRecommendResponse.__name__, )