Update Docker Compose ports to 8081 and add new apps and URL routes for crop zoning, plant simulator, pest detection, irrigation recommendation, fertilization recommendation, and farm AI assistant.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PlantSimulatorConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "plant_simulator"
|
||||
verbose_name = "Plant Simulator"
|
||||
@@ -0,0 +1,176 @@
|
||||
"""
|
||||
Static mock data for Plant Simulator API.
|
||||
Matches PLANT_SIMULATOR_API.md. No database, no dynamic values.
|
||||
Smooth animation: 51 points (0–10s, ~5 frames per second).
|
||||
"""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GET /api/plant-simulator/config (ورود: فقط اسلایدرها)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CONFIG_SLIDERS_ONLY = {
|
||||
"sliders": [
|
||||
{
|
||||
"key": "light",
|
||||
"label": "نور",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"step": 5,
|
||||
"unit_type": "percent",
|
||||
"default_value": 75,
|
||||
"icon": "☀️",
|
||||
},
|
||||
{
|
||||
"key": "water",
|
||||
"label": "آب",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"step": 5,
|
||||
"unit_type": "percent",
|
||||
"default_value": 65,
|
||||
"icon": "💧",
|
||||
},
|
||||
{
|
||||
"key": "soil_ph",
|
||||
"label": "pH خاک",
|
||||
"min": 4,
|
||||
"max": 9,
|
||||
"step": 0.5,
|
||||
"unit_type": "number",
|
||||
"unit": "",
|
||||
"default_value": 6.5,
|
||||
},
|
||||
{
|
||||
"key": "growth_speed",
|
||||
"label": "سرعت رشد",
|
||||
"min": 0.5,
|
||||
"max": 5,
|
||||
"step": 0.5,
|
||||
"unit_type": "number",
|
||||
"unit": "×",
|
||||
"default_value": 1.5,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# POST /api/plant-simulator/start (ثابتها + چارت کانفیگ + plant + progress + chart)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CONSTANTS = {
|
||||
"max_height": 280,
|
||||
"max_leaves": 14,
|
||||
"max_branches": 6,
|
||||
"max_yield": 500,
|
||||
"yield_unit": "g",
|
||||
"yield_rate_unit": "g/s",
|
||||
"height_unit": "px",
|
||||
}
|
||||
|
||||
CHART_CONFIG = {
|
||||
"title": "پیشرفت رشد",
|
||||
"x_axis_label": "زمان (ثانیه)",
|
||||
"series": [
|
||||
{
|
||||
"key": "height",
|
||||
"label": "ارتفاع (px)",
|
||||
"y_axis_id": "yHeight",
|
||||
"min": 0,
|
||||
"max": 280,
|
||||
"unit": "px",
|
||||
},
|
||||
{
|
||||
"key": "leaves",
|
||||
"label": "تعداد برگ",
|
||||
"y_axis_id": "yLeaf",
|
||||
"min": 0,
|
||||
"max": 14,
|
||||
},
|
||||
{
|
||||
"key": "yield",
|
||||
"label": "محصول (g)",
|
||||
"y_axis_id": "yYield",
|
||||
"min": 0,
|
||||
"max": 500,
|
||||
"unit": "g",
|
||||
},
|
||||
{
|
||||
"key": "yield_rate",
|
||||
"label": "نرخ محصول (g/s)",
|
||||
"y_axis_id": "yYieldRate",
|
||||
"min": 0,
|
||||
"unit": "g/s",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# 51 نقطه برای انیمیشن نرم (۰ تا ۱۰ ثانیه، هر ~۰٫۲s)
|
||||
_labels = [f"{i * 0.2:.1f}s" for i in range(51)]
|
||||
_height = [round(142 * (i / 50) ** 0.9) for i in range(51)] # رشد کمی شتابدار
|
||||
_leaf = [min(5, int(i / 10)) for i in range(51)] # 0,0..,1,1..,2,...,5
|
||||
_yield = [round(12.4 * (i / 50) ** 1.2, 1) for i in range(51)] # محصول با شتاب ملایم
|
||||
_yield_rate = [round(0.087 * max(0, (i - 15) / 35), 3) for i in range(51)] # نرخ از ثانیه ~۳
|
||||
|
||||
START_RESPONSE_DATA = {
|
||||
"constants": CONSTANTS,
|
||||
"chart": CHART_CONFIG,
|
||||
"plant": {
|
||||
"height": 142,
|
||||
"leaves_count": 5,
|
||||
"branches_count": 2,
|
||||
"fruits_count": 0,
|
||||
"yield": 12.4,
|
||||
"yield_rate": 0.087,
|
||||
"tick": 520,
|
||||
"is_healthy": True,
|
||||
"can_continue": True,
|
||||
},
|
||||
"progress": {
|
||||
"growth_progress": 50,
|
||||
"light_status": 75,
|
||||
"water_status": 65,
|
||||
"yield_progress": 2.5,
|
||||
"yield_current": 12.4,
|
||||
"yield_rate_current": 0.087,
|
||||
},
|
||||
"chart_history": {
|
||||
"labels": _labels,
|
||||
"height_history": _height,
|
||||
"leaf_history": _leaf,
|
||||
"yield_history": _yield,
|
||||
"yield_rate_history": _yield_rate,
|
||||
},
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GET /api/plant-simulator/state (plant + progress + chart history)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
STATE_RESPONSE_DATA = {
|
||||
"plant": {
|
||||
"height": 142,
|
||||
"leaves_count": 5,
|
||||
"branches_count": 2,
|
||||
"fruits_count": 0,
|
||||
"yield": 12.4,
|
||||
"yield_rate": 0.087,
|
||||
"tick": 520,
|
||||
"is_healthy": True,
|
||||
"can_continue": True,
|
||||
},
|
||||
"progress": {
|
||||
"growth_progress": 50,
|
||||
"light_status": 75,
|
||||
"water_status": 65,
|
||||
"yield_progress": 2.5,
|
||||
"yield_current": 12.4,
|
||||
"yield_rate_current": 0.087,
|
||||
},
|
||||
"chart": {
|
||||
"labels": _labels,
|
||||
"height_history": _height,
|
||||
"leaf_history": _leaf,
|
||||
"yield_history": _yield,
|
||||
"yield_rate_history": _yield_rate,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "Plant Simulator",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"description": "Plant Simulator API. GET config (sliders only), GET state, POST start (body: environment + growth_speed per serializers), stop/reset/environment. Static mock only."
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "Get config (GET)",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"url": "{{baseUrl}}/api/plant-simulator/config/",
|
||||
"description": "ورود: فقط اسلایدرها. Returns sliders only (key, label, min, max, step, unit_type, default_value, icon)."
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"name": "Success",
|
||||
"status": "OK",
|
||||
"code": 200,
|
||||
"body": "{\n \"status\": \"success\",\n \"data\": {\n \"sliders\": [\n {\"key\": \"light\", \"label\": \"نور\", \"min\": 0, \"max\": 100, \"step\": 5, \"unit_type\": \"percent\", \"default_value\": 75, \"icon\": \"☀️\"},\n {\"key\": \"water\", \"label\": \"آب\", \"min\": 0, \"max\": 100, \"step\": 5, \"unit_type\": \"percent\", \"default_value\": 65, \"icon\": \"💧\"},\n {\"key\": \"soil_ph\", \"label\": \"pH خاک\", \"min\": 4, \"max\": 9, \"step\": 0.5, \"unit_type\": \"number\", \"unit\": \"\", \"default_value\": 6.5},\n {\"key\": \"growth_speed\", \"label\": \"سرعت رشد\", \"min\": 0.5, \"max\": 5, \"step\": 0.5, \"unit_type\": \"number\", \"unit\": \"×\", \"default_value\": 1.5}\n ]\n }\n}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Get state (GET)",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"url": "{{baseUrl}}/api/plant-simulator/state/",
|
||||
"description": "Returns static plant state, progress, and chart history (plant, progress, chart)."
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"name": "Success",
|
||||
"status": "OK",
|
||||
"code": 200,
|
||||
"body": "{\n \"status\": \"success\",\n \"data\": {\n \"plant\": {\"height\": 142, \"leaves_count\": 5, \"branches_count\": 2, \"fruits_count\": 0, \"yield\": 12.4, \"yield_rate\": 0.087, \"tick\": 520, \"is_healthy\": true, \"can_continue\": true},\n \"progress\": {\"growth_progress\": 50, \"light_status\": 75, \"water_status\": 65, \"yield_progress\": 2.5, \"yield_current\": 12.4, \"yield_rate_current\": 0.087},\n \"chart\": {\n \"labels\": [\"0s\", \"1s\", \"2s\", \"3s\", \"4s\", \"5s\", \"6s\", \"7s\", \"8s\", \"9s\", \"10s\"],\n \"height_history\": [0, 5, 12, 28, 45, 68, 92, 110, 125, 135, 142],\n \"leaf_history\": [0, 0, 1, 2, 3, 4, 4, 5, 5, 5, 5],\n \"yield_history\": [0, 0, 0, 0.1, 0.5, 1.2, 3.2, 5.8, 8.2, 10.1, 12.4],\n \"yield_rate_history\": [0, 0, 0, 0.01, 0.03, 0.05, 0.06, 0.07, 0.08, 0.085, 0.087]\n }\n }\n}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Start simulation (POST)",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"environment\": {\n \"light\": 75,\n \"water\": 65,\n \"soil_ph\": 6.5\n },\n \"growth_speed\": 1.5\n}"
|
||||
},
|
||||
"url": "{{baseUrl}}/api/plant-simulator/start/",
|
||||
"description": "Body per serializers.START_REQUEST_EXAMPLE_STATIC: environment (light, water, soil_ph) + growth_speed. Returns constants, chart, plant, progress, chart_history."
|
||||
},
|
||||
"response": [
|
||||
{
|
||||
"name": "Success",
|
||||
"status": "OK",
|
||||
"code": 200,
|
||||
"body": "{\n \"status\": \"success\",\n \"data\": {\n \"constants\": {\"max_height\": 280, \"max_leaves\": 14, \"max_branches\": 6, \"max_yield\": 500, \"yield_unit\": \"g\", \"yield_rate_unit\": \"g/s\", \"height_unit\": \"px\"},\n \"chart\": {\"title\": \"پیشرفت رشد\", \"x_axis_label\": \"زمان (ثانیه)\", \"series\": [{\"key\": \"height\", \"label\": \"ارتفاع (px)\", \"y_axis_id\": \"yHeight\", \"min\": 0, \"max\": 280, \"unit\": \"px\"}, {\"key\": \"leaves\", \"label\": \"تعداد برگ\", \"y_axis_id\": \"yLeaf\", \"min\": 0, \"max\": 14}, {\"key\": \"yield\", \"label\": \"محصول (g)\", \"y_axis_id\": \"yYield\", \"min\": 0, \"max\": 500, \"unit\": \"g\"}, {\"key\": \"yield_rate\", \"label\": \"نرخ محصول (g/s)\", \"y_axis_id\": \"yYieldRate\", \"min\": 0, \"unit\": \"g/s\"}]},\n \"plant\": {\"height\": 142, \"leaves_count\": 5, \"branches_count\": 2, \"fruits_count\": 0, \"yield\": 12.4, \"yield_rate\": 0.087, \"tick\": 520, \"is_healthy\": true, \"can_continue\": true},\n \"progress\": {\"growth_progress\": 50, \"light_status\": 75, \"water_status\": 65, \"yield_progress\": 2.5, \"yield_current\": 12.4, \"yield_rate_current\": 0.087},\n \"chart_history\": {\"labels\": [\"0.0s\", \"0.2s\", \"0.4s\", \"1.0s\", \"2.0s\", \"5.0s\", \"10.0s\"], \"height_history\": [0, 2, 5, 18, 45, 110, 142], \"leaf_history\": [0, 0, 0, 0, 0, 1, 5], \"yield_history\": [0, 0, 0, 0.2, 1.5, 6.2, 12.4], \"yield_rate_history\": [0, 0, 0, 0.01, 0.03, 0.06, 0.087]}\n }\n}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Stop simulation (POST)",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"body": {"mode": "raw", "raw": "{}"},
|
||||
"url": "{{baseUrl}}/api/plant-simulator/stop/",
|
||||
"description": "Empty body. Returns success only."
|
||||
},
|
||||
"response": [{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}]
|
||||
},
|
||||
{
|
||||
"name": "Reset simulation (POST)",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"body": {"mode": "raw", "raw": "{}"},
|
||||
"url": "{{baseUrl}}/api/plant-simulator/reset/",
|
||||
"description": "Empty body. Returns success only."
|
||||
},
|
||||
"response": [{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}]
|
||||
},
|
||||
{
|
||||
"name": "Update environment (PATCH)",
|
||||
"request": {
|
||||
"method": "PATCH",
|
||||
"header": [{"key": "Content-Type", "value": "application/json"}],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"environment\": {\n \"light\": 80,\n \"water\": 70,\n \"soil_ph\": 6.5\n },\n \"growth_speed\": 2\n}"
|
||||
},
|
||||
"url": "{{baseUrl}}/api/plant-simulator/environment/",
|
||||
"description": "Body: environment (same keys as sliders) + optional growth_speed. Returns success only."
|
||||
},
|
||||
"response": [{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}]
|
||||
}
|
||||
],
|
||||
"variable": [{"key": "baseUrl", "value": "http://localhost:8000"}]
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
Response serialization for Plant Simulator API.
|
||||
Plain Django; no DRF. Builds response envelope only. All payloads are static mock data.
|
||||
|
||||
Request: on POST /start the client must send a body with keys matching the sliders
|
||||
from config (light, water, soil_ph) plus growth_speed. See START_REQUEST_EXAMPLE.
|
||||
No validation or use of request in response; backend returns static mock only.
|
||||
"""
|
||||
|
||||
from .mock_data import CONFIG_SLIDERS_ONLY
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# POST /start — بدنهای که کلاینت باید ارسال کند (مطابق اسلایدرهای config)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# کلیدهای environment (همان key هر اسلایدر بهجز growth_speed)
|
||||
START_ENVIRONMENT_KEYS = [
|
||||
item["key"]
|
||||
for item in CONFIG_SLIDERS_ONLY["sliders"]
|
||||
if item["key"] != "growth_speed"
|
||||
]
|
||||
|
||||
# مقدار پیشفرض هر اسلایدر برای ساخت نمونه درخواست
|
||||
def _defaults_from_sliders():
|
||||
return {
|
||||
item["key"]: item["default_value"]
|
||||
for item in CONFIG_SLIDERS_ONLY["sliders"]
|
||||
}
|
||||
|
||||
# نمونه بدنه درخواست start که کلاینت باید ارسال کند
|
||||
START_REQUEST_EXAMPLE = {
|
||||
"environment": {
|
||||
k: v for k, v in _defaults_from_sliders().items() if k != "growth_speed"
|
||||
},
|
||||
"growth_speed": _defaults_from_sliders().get("growth_speed", 1.5),
|
||||
}
|
||||
|
||||
# برای سازگاری: همان ساختار به صورت ثابت (بدون وابستگی به محاسبه)
|
||||
START_REQUEST_EXAMPLE_STATIC = {
|
||||
"environment": {
|
||||
"light": 75,
|
||||
"water": 65,
|
||||
"soil_ph": 6.5,
|
||||
},
|
||||
"growth_speed": 1.5,
|
||||
}
|
||||
|
||||
|
||||
def success_response():
|
||||
"""
|
||||
Response when endpoint does not return data.
|
||||
Returns: {"status": "success"}
|
||||
"""
|
||||
return {"status": "success"}
|
||||
|
||||
|
||||
def success_with_data(data):
|
||||
"""
|
||||
Response when endpoint returns data.
|
||||
Returns: {"status": "success", "data": data}
|
||||
"""
|
||||
return {"status": "success", "data": data}
|
||||
@@ -0,0 +1,19 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import (
|
||||
ConfigView,
|
||||
EnvironmentView,
|
||||
ResetView,
|
||||
StartView,
|
||||
StateView,
|
||||
StopView,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path("config/", ConfigView.as_view(), name="plant-simulator-config"),
|
||||
path("state/", StateView.as_view(), name="plant-simulator-state"),
|
||||
path("start/", StartView.as_view(), name="plant-simulator-start"),
|
||||
path("stop/", StopView.as_view(), name="plant-simulator-stop"),
|
||||
path("reset/", ResetView.as_view(), name="plant-simulator-reset"),
|
||||
path("environment/", EnvironmentView.as_view(), name="plant-simulator-environment"),
|
||||
]
|
||||
@@ -0,0 +1,161 @@
|
||||
"""
|
||||
Plant Simulator API views.
|
||||
Plain Django only; no DRF. No database. All responses are static mock data.
|
||||
Response format: {"status": "success"} or {"status": "success", "data": <payload>}. HTTP 200 only.
|
||||
No processing, validation, or use of input parameters in responses.
|
||||
CSRF exempt so frontend (e.g. localhost:3000) can call POST/PATCH without token.
|
||||
"""
|
||||
|
||||
from django.http import JsonResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from .mock_data import CONFIG_SLIDERS_ONLY, START_RESPONSE_DATA, STATE_RESPONSE_DATA
|
||||
from .serializers import success_response, success_with_data
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class ConfigView(View):
|
||||
"""
|
||||
GET endpoint for simulator configuration (ورود).
|
||||
|
||||
Purpose:
|
||||
Returns only sliders (min, max, step, unit, label, default_value, icon).
|
||||
Used when loading/entering the simulator page.
|
||||
|
||||
Input parameters:
|
||||
None. Query parameters, if sent, are not read or used.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
- data: object with key "sliders" (array of slider configs).
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
return JsonResponse(success_with_data(CONFIG_SLIDERS_ONLY), status=200)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class StateView(View):
|
||||
"""
|
||||
GET endpoint for plant state, progress, and chart history.
|
||||
|
||||
Purpose:
|
||||
Returns static plant state (height, leaves_count, branches_count,
|
||||
fruits_count, yield, yield_rate, tick, is_healthy, can_continue),
|
||||
progress (growth_progress, light_status, water_status, yield_progress,
|
||||
yield_current, yield_rate_current), and chart (labels, height_history,
|
||||
leaf_history, yield_history, yield_rate_history). Used during or after
|
||||
simulation for UI and chart.
|
||||
|
||||
Input parameters:
|
||||
None. Query parameters, if sent, are not read or used.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
- data: object with keys "plant", "progress", "chart" per
|
||||
PLANT_SIMULATOR_API.md §3.
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
return JsonResponse(success_with_data(STATE_RESPONSE_DATA), status=200)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class StartView(View):
|
||||
"""
|
||||
POST endpoint to start simulation.
|
||||
|
||||
Purpose:
|
||||
Returns constants, chart config, plant state, progress, and chart
|
||||
history. Body may contain environment and growth_speed; not read or used.
|
||||
|
||||
Input parameters:
|
||||
- body (optional): JSON. May contain "environment" and "growth_speed".
|
||||
Location: body. Not read or validated; not used in response.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
- data: object with "constants", "chart", "plant", "progress", "chart_history".
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def post(self, request):
|
||||
return JsonResponse(success_with_data(START_RESPONSE_DATA), status=200)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class StopView(View):
|
||||
"""
|
||||
POST endpoint to stop simulation.
|
||||
|
||||
Purpose:
|
||||
Accepts stop request. Returns success only. No processing performed.
|
||||
Body may be empty or contain session_id; not read or used.
|
||||
|
||||
Input parameters:
|
||||
- body (optional): JSON or empty. Location: body. Not read or used.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
No "data" field.
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def post(self, request):
|
||||
return JsonResponse(success_response(), status=200)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class ResetView(View):
|
||||
"""
|
||||
POST endpoint to reset simulation.
|
||||
|
||||
Purpose:
|
||||
Accepts reset request. Returns success only. No processing performed.
|
||||
Body may be empty or contain session_id; not read or used.
|
||||
|
||||
Input parameters:
|
||||
- body (optional): JSON or empty. Location: body. Not read or used.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
No "data" field.
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def post(self, request):
|
||||
return JsonResponse(success_response(), status=200)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class EnvironmentView(View):
|
||||
"""
|
||||
PATCH endpoint to update environment (slider values).
|
||||
|
||||
Purpose:
|
||||
Accepts environment update. Returns success only. No processing
|
||||
performed. Body may contain environment and growth_speed; not
|
||||
read or used in the response.
|
||||
|
||||
Input parameters:
|
||||
- body (optional): JSON. May contain "environment" (object)
|
||||
and "growth_speed" (number). Location: body. Not read or used.
|
||||
|
||||
Response structure:
|
||||
- status: string, always "success".
|
||||
No "data" field.
|
||||
|
||||
No processing or validation is performed on inputs.
|
||||
"""
|
||||
|
||||
def patch(self, request):
|
||||
return JsonResponse(success_response(), status=200)
|
||||
Reference in New Issue
Block a user