Prompt
We are starting a completely new implementation of an AI-powered crop disease diagnosis system called LeafDoctor AI.

Forget all previous project architecture, interfaces, factories, dependency injection, repositories, and service layers.

We are building a WORKING MVP first.

After the MVP is complete, we will refactor into a production architecture.

==================================================
PROJECT GOAL
==================================================

Implement a complete working pipeline.

Farmer uploads leaf image

↓

Image is stored inside uploads/

↓

Google Gemini Vision diagnoses the image

↓

Gemini returns

- Crop
- Problem Label
- Confidence

↓

Lookup PostgreSQL database

↓

Retrieve

- Class_ID
- Treatment
- Chemical
- Dosage
- SMS
- etc.

↓

Store diagnosis history

↓

Return JSON response

==================================================
IMPORTANT BUSINESS RULES
==================================================

Gemini is ONLY responsible for diagnosis.

Gemini NEVER generates

- recommendation
- treatment
- dosage
- chemical
- SMS

Those always come from PostgreSQL.

==================================================
AVAILABLE DATA
==================================================

I already have these datasets.

1.

crop_protection_labels.csv

Contains

Class_ID

Label_Name

Primary_Category

This is the master label table.

2.

normalized_class_treatment_mapping.csv

Contains approximately 3090 records.

Columns include

Class_ID

Master_Label_Name

Crop

Type of Problem

Chemical & Formulation

Chemical Type

Revised Dosages

SMS : Growth Stage 1

This is the recommendation database.

These CSVs have already been generated by Gemini as a mapping layer.

You should analyze these files before deciding how Gemini should respond.

==================================================
VERY IMPORTANT
==================================================

Do NOT assume Gemini should return Class_ID.

First analyze the uploaded CSVs.

If returning Label_Name is more reliable than returning Class_ID, then redesign the workflow accordingly.

Accuracy is much more important than elegance.

==================================================
DATABASE
==================================================

Use PostgreSQL.

Use SQLAlchemy ORM.

Do NOT use SQLite.

CSV/XLSX files will be imported only once.

After import,

PostgreSQL becomes the single source of truth.

==================================================
IMAGE STORAGE
==================================================

Every uploaded image must be stored inside

uploads/

using a unique filename.

Example

uploads/20260708153022.jpg

These images will later be used for training our own AI model.

==================================================
FASTAPI
==================================================

Create

POST /diagnose

Workflow

1.

Receive uploaded image

2.

Validate image

3.

Save image inside uploads/

4.

Call Gemini Vision

5.

Receive diagnosis

6.

Lookup PostgreSQL

7.

Store diagnosis history

8.

Return JSON

==================================================
PROJECT STRUCTURE
==================================================

Keep everything SIMPLE.

leafdoctor/

app.py

config.py

database.py

models.py

gemini.py

service.py

import_data.py

uploads/

data/

requirements.txt

.env

No repositories.

No interfaces.

No dependency injection.

No factories.

No enterprise architecture.

==================================================
DEVELOPMENT RULES
==================================================

1.

Implement ONE file at a time.

2.

Every file must be COMPLETE.

3.

Never generate placeholders.

4.

Never generate TODOs.

5.

Never generate pseudo code.

6.

Every file must run.

7.

Wait for my confirmation before generating the next file.

==================================================
VERY IMPORTANT INSTRUCTION
==================================================

Before writing any code, carefully analyze the uploaded CSV/XLSX files.

I want the MOST RELIABLE solution, not the most beautiful architecture.

If you discover a better workflow than the one described above based on my datasets, explain it first before writing code.

Do not blindly follow my assumptions if the data suggests a better approach.

==================================================
FIRST TASK
==================================================

First analyze all uploaded datasets and propose the final database schema and complete end-to-end workflow.

Do not write any code yet.

After I approve the workflow, start implementing the project beginning with database.py.


leafdoctor/
│
├── app.py
├── config.py
├── database.py
├── models.py
├── gemini.py
├── service.py
├── import_data.py
├── uploads/
├── data/
├── requirements.txt
└── .env


# LeafDoctor AI – MVP Development Context

We are building a **completely new AI-powered crop disease diagnosis system** called **LeafDoctor AI**.

This is a **working MVP**, not a production architecture.

**Golden Rule**

Do NOT redesign the architecture.

Do NOT introduce Repository Pattern.

Do NOT introduce Dependency Injection.

Do NOT introduce Factories.

Do NOT introduce Interfaces.

Do NOT introduce Enterprise Architecture.

The goal is to build a **working end-to-end system first**. We will refactor later after the MVP is complete.

---

# Technology Stack

Backend

* Python 3.11+
* FastAPI
* SQLAlchemy ORM
* PostgreSQL
* Google Gemini Vision (`google-genai`)
* Pydantic v2
* pydantic-settings

Image

* Pillow

CSV Import

* pandas
* openpyxl

---

# Folder Structure

```text
leafdoctor/

app.py
config.py
database.py
models.py
gemini.py
service.py

import_data.py
import_utils.py

uploads/
data/

requirements.txt
.env
```

---

# Project Workflow

Farmer uploads image

↓

Image stored inside

uploads/

↓

Gemini Vision diagnoses image

↓

Gemini returns ONLY

* crop
* label
* confidence

↓

Backend validates result

↓

Lookup PostgreSQL

↓

Retrieve

* Class_ID
* Treatment
* Chemical
* Dosage
* SMS

↓

Save diagnosis history

↓

Return JSON

---

# Business Rule

Gemini NEVER generates

* treatment
* dosage
* recommendation
* chemical
* SMS

Gemini ONLY performs diagnosis.

Everything else comes from PostgreSQL.

---

# Datasets

## Master Labels

crop_protection_labels.csv

Contains

* Class_ID
* Label_Name
* Primary_Category

Approximately 201 labels.

This is the MASTER dataset.

---

## Recommendation Mapping

normalized_class_treatment_mapping.csv

Approximately 3090 records.

Contains

* Class_ID
* Crop
* Type of Problem
* Chemical & Formulation
* Chemical Type
* Revised Dosages
* SMS : Growth Stage 1

This is the recommendation dataset.

---

# Data Analysis Findings

We analyzed both datasets.

Important findings

1.

Master labels are unique.

One Class_ID

↓

One Label

2.

Treatment table contains mapping inconsistencies.

Master_Label_Name is NOT reliable.

There are shifted labels.

Therefore

DO NOT import Master_Label_Name.

Always resolve labels using

Class_ID

↓

protection_labels

3.

PostgreSQL becomes the single source of truth.

CSV files are used only once during import.

---

# Database Design

## protection_labels

id

class_id

label_name_en

label_name_bn

primary_category_en

primary_category_bn

created_at

---

## treatment_mapping

id

class_id

crop_en

crop_bn

problem_type_en

problem_type_bn

chemical

chemical_type

dosage

sms_en

sms_bn

created_at

---

## diagnosis_history

id

image_path

crop_detected

predicted_label

class_id

confidence

treatment_id

gemini_model

raw_response

verified_label

verified_by

verified_at

created_at

---

# Image Storage

All uploaded images are stored.

Example

uploads/

20260708153022_abcd1234.jpg

These images will later be used to train our own AI model.

---

# Import Strategy

import_utils.py

Responsibilities

* Load CSV
* Clean data
* Validate duplicates
* Detect orphan Class_ID
* Detect label mismatch
* Import PostgreSQL
* Generate

data/crop_label_mapping.json

* Generate

data/import_report.json

---

# crop_label_mapping.json

Generated during import.

Example

```json
{
  "Rice": {
    "labels": [
      "Blast",
      "Brown Spot",
      "Leaf Folder"
    ],
    "class_ids": [
      12,
      15,
      18
    ]
  }
}
```

Gemini loads this JSON.

NOT PostgreSQL.

---

# Gemini

Library

google-genai

Model

gemini-2.5-flash

Uses ONE API call.

Not two-stage.

Returns

```json
{
    "crop":"Rice",
    "label":"Blast",
    "confidence":0.98
}
```

Uses

response_schema

with

DiagnosisSchema

NOT regex parsing.

Validation

* crop exists
* label belongs to crop
* confidence between 0 and 1

Returns

DiagnosisResult dataclass.

---

# Service Layer

Workflow

Save uploaded image

↓

Gemini diagnose

↓

Lookup ProtectionLabel

↓

Get Class_ID

↓

Lookup TreatmentMapping

↓

Save DiagnosisHistory

↓

Return JSON

Important fixes already identified

* Case-insensitive label lookup
* Case-insensitive crop lookup
* Rollback database transaction on failure
* Ensure uploads directory exists
* Remove singleton instance at bottom of service.py

---

# App

FastAPI

Endpoints

GET /

GET /health

GET /statistics

GET /history

GET /history/{id}

DELETE /history/{id}

POST /diagnose

POST /diagnose

Accepts multipart UploadFile.

Stores image.

Calls service.

Returns diagnosis.

---

# Configuration

.env contains

APP_NAME

APP_VERSION

DEBUG

LOG_LEVEL

DB_HOST

DB_PORT

DB_NAME

DB_USER

DB_PASSWORD

GEMINI_API_KEY

GEMINI_MODEL

GEMINI_TEMPERATURE

GEMINI_MAX_OUTPUT_TOKENS

UPLOAD_DIR

DATA_DIR

MAX_UPLOAD_SIZE_MB

config.py already exposes

settings

using pydantic-settings.

---

# Current Project Status

Completed

✓ database.py

✓ config.py

✓ models.py

✓ import_utils.py

✓ import_data.py

✓ gemini.py

✓ service.py

✓ app.py

✓ requirements.txt

✓ .env

Some runtime fixes may still be required because the project has not yet been executed end-to-end.

---

# Development Rule

From now on

Do NOT redesign anything.

Do NOT rewrite entire files unless absolutely necessary.

If an error occurs

Fix ONLY that error.

Keep all business logic unchanged.

The objective is to finish the MVP as quickly as possible and stabilize it through testing.


pip install -r requirements.txt
playwright install


python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

To run api for ssh session
uvicorn api_filter:app --reload --port 8000

To run continuously
nohup uvicorn land_api:app --host 0.0.0.0 --port 8900 > app.log 2>&1 &

To kill
sudo lsof -i :8900
sudo kill -9 858138

RUN THIS FILE ALWAYS WHENEVER YOUR DATASET UPGRADED
python import_data.py

ALSO CREATE FOLDER TO SAVE IMAGES
mkdir uploads
