KrishokOS Technical Reference
KrishokOS — My Complete Build Reference
AI-Powered Agricultural Operating System for Bangladesh
This is my consolidated technical reference for KrishokOS — everything from the vision I started with, through the architecture I designed, to what I’ve actually shipped in the MVP. I wrote this so I (or anyone picking this project up later) can read one document and understand not just what the system does, but why I made the decisions I made along the way.
- Current Build: MVP v1.0
- Actual MVP Tech Stack: Next.js 16 · React 19 · TypeScript · Tailwind CSS · Local JSON Database (MVP) · JWT Authentication · Server + Client Components · REST API Architecture
⚠️ A note before I get into it: I wrote my planning documents at different points in the project, and they don’t all agree with each other — for example, one of my early planning docs recommends a React + Vite + Django + PostgreSQL stack, while what I actually shipped is Next.js end-to-end with a local JSON database. Wherever my own sources conflict, I’ve labeled things clearly as “Vision / Planning” vs. “As-Built” so I never present an old idea as if it were current fact.
Table of Contents
- My Product Vision
- My Product Strategy & MVP Philosophy
- My MVP Scope
- My Product Feature Roadmap (All Phases)
- My System Architecture
- My Technology Stack
- My Project Structure (As-Built)
- My Landing Page
- My Landing Page Refactor History
- My Internationalization Setup (Bengali ↔ English)
- My Authentication System
- My Session & Route Security
- My User Entry Points & Navigation Flows
- My Plant Management Module
- My Farm Setup Wizard
- My Farm Analysis Engine
- My Dashboard
- My Personalized Analytics Engine (As-Built)
- My Data Models
- My API Reference
- My Land Conversion Engine
- My Security Architecture
- My Performance Optimizations
- My Developer Setup
- My Current MVP User Journey
- My Future Roadmap
- Things I Still Need to Reconcile
1. My Product Vision
I’m building KrishokOS to become a Bangladesh-focused Agriculture ERP platform — one designed to help farmers produce residue-free, export-quality crops through guided, data-driven farming practices. I wanted it to feel like real digital infrastructure for smart agriculture, not just another form-heavy dashboard, so I made it Bengali-first from day one rather than bolting on translations later.
My vision statement: empower Bangladesh’s agriculture through technology-driven, safe, sustainable, and export-ready farming.
My long-term goal is an integrated operating system for agriculture spanning multiple farming domains:
- Plant Management
- Livestock Management
- Aquaculture Management
My core value proposition for the MVP: enable Bangladeshi farmers to establish and manage residue-free banana farms through guided onboarding, intelligent recommendations, and actionable cultivation insights.
2. My Product Strategy & MVP Philosophy
I made a deliberate decision not to build a full-scale agricultural ERP from day one. Instead, I’m following a focused, iterative approach:
- Solve one problem exceptionally well.
- Support one crop initially.
- Validate the guided farming experience.
- Build reusable architecture for future expansion.
By starting with banana cultivation and decision support, I’m establishing a foundation I can evolve into a full agricultural operating system for Bangladesh, rather than trying to boil the ocean on my first release.
3. My MVP Scope
I focused my MVP on five pillars:
- Authentication System
- Farm Onboarding Wizard
- Plant Management Module
- Personalized Analytics Dashboard
- Multi-language Support (Bangla + English)
✅ What I included in the MVP
- Banana cultivation management
- Guided farm setup experience
- Farm assessment and recommendation engine
- Decision-support dashboard
- Single farm ownership per user
- Authentication and onboarding workflows
❌ What I deliberately excluded from the MVP
- Multiple crop support
- Multiple farm management
- Livestock management
- Aquaculture management
4. My Product Feature Roadmap (All Phases)
This is the full, long-range roadmap I laid out during planning — it spans well beyond what I’ve actually built for the current MVP.
| Phase | Name | Key Features |
|---|---|---|
| 0 | Foundation | Project vision & architecture · Next.js + TypeScript setup · GitHub repo & Vercel deployment · Landing page & design system · Developer documentation |
| 1 | MVP | Authentication · Farm Setup Wizard · Farmer Dashboard · Crop Journey Management · Task Management |
| 2 | Smart Farm Operations | Inventory Management · Irrigation Scheduling · Fertilizer Tracking · Harvest Tracking · Reporting Dashboard |
| 3 | AI-Powered Agriculture | Disease Detection from Images · AI Advisory Assistant · Recommendation Engine |
| 4 | Export Readiness | Residue-Free Compliance · Export Checklist · Traceability System · QR Code Generation |
| 5 | Marketplace Ecosystem | Buyer Marketplace · Input Marketplace · Agricultural Service Marketplace |
| 6 | Enterprise Platform | Multi-Farm Management · Worker Management · Financial Management · Advanced Analytics · API Integrations |
The development sequence I recommend to myself
- Landing Page
- Authentication
- Farm Setup Wizard
- Dashboard
- Crop Journey Timeline
- Task Management
- Inventory
- Harvest Tracking
- Disease Detection
- AI Assistant
- Traceability
- Marketplace
5. My System Architecture
I use a modern, serverless-first architecture optimized for performance and scalability — at least, that’s the plan. What I’ve actually shipped so far is intentionally leaner than that plan, so I’m documenting both here.
5.1 My Planning-Stage Architecture (Vision)
My original architecture blueprint envisioned a heavier, enterprise-style stack:
CLIENT LAYER
------------
Next.js + TypeScript + Tailwind + ShadCN UI
• Landing Page
• Authentication
• Dashboard
• Farm Setup Wizard
• Crop Management
• Advisory Panel
• Reports & Analytics
│
│ HTTPS
▼
APPLICATION LAYER
-----------------
Next.js App Router
• Server Components
• Route Handlers
• Server Actions
• Middleware
┌────────────────┬────────────────────┬──────────────────┐
│ Authentication │ Business Logic │ Notifications │
├────────────────┼────────────────────┼──────────────────┤
│ Clerk/Auth.js │ Farm Setup │ In-App Alerts │
│ RBAC │ Crop Planning │ SMS Gateway │
│ Sessions │ Advisory Engine │ Email Service │
│ │ Task Scheduler │ │
└────────────────┴────────────────────┴──────────────────┘
│
▼
DATA LAYER
----------
PostgreSQL + Prisma
Entities:
• User • Task
• Farm • Inventory
• Field • DiseaseReport
• Crop • IrrigationSchedule
• CropCycle • FertilizerApplication
• Harvest
• ExportCertificate
• Notification
│
▼
EXTERNAL SERVICES
-----------------
• Cloudinary / S3 → Image Storage
• OpenAI / Gemini → AI Advisory
• SMS Provider → Notifications
• Resend / SendGrid → Email Service
• Weather APIs → Forecast Data
• Government APIs → Agricultural Data
The deployment flow I planned:
GitHub → Vercel → Next.js Application
├──▶ PostgreSQL
├──▶ Cloudinary
└──▶ OpenAI / Gemini
5.2 What I Actually Built — As-Built MVP Architecture
What I’ve shipped is deliberately simpler than the plan above — no external auth provider yet, no Postgres yet, no AI services integrated yet:
┌─────────────────────────┐
│ Landing Website │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Authentication System │ (JWT-style, JSON-backed)
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Plant Management Setup │
│ Crop + Farming Method │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Farm Setup Wizard │
│ 11-Step Onboarding │
└────────────┬────────────┘
│
▼
┌─────────────────────────┐
│ Personalized Dashboard │
│ Analytics + Advisories │
└─────────────────────────┘
Here’s how I’m tracking what I’ve built vs. what I still have planned:
| Layer | What I’ve Built (MVP) | What I’ve Planned (Future) |
|---|---|---|
| Client | Next.js 16, React 19, TypeScript, Tailwind | Same, + ShadCN UI, Framer Motion |
| Application | Next.js Route Handlers, Server/Client Components | + Server Actions, Middleware, RBAC |
| Auth | Custom JWT-style tokens + HTTP-only cookies | NextAuth.js with full RBAC |
| Data | Local JSON files (data/*.json) | Supabase PostgreSQL + Prisma |
| Realtime | (not yet integrated) | WebSockets for chat & instant notifications |
| Media | (not yet integrated) | Cloudinary / S3 |
| AI | (not yet integrated) | OpenAI / Gemini |
| Notifications | (not yet integrated) | In-app alerts, SMS gateway, Email service |
| Deployment | (local/dev) | GitHub → Vercel |
How I think about the request flow once I’m on the planned stack: the Next.js App Router is my orchestration layer — the Client Layer renders the UI (Dashboard, Farm Setup, Reports), the Application Layer handles business logic via Server Components, Route Handlers, and Server Actions, and the Data Layer has Prisma talking to Supabase PostgreSQL across entities like User, Farm, Field, CropCycle, Task, Inventory, and DiseaseReport.
6. My Technology Stack
What I’ve actually shipped — Frontend
| Technology | Purpose |
|---|---|
| Next.js 16 | Application Framework |
| React | UI Rendering |
| TypeScript | Type Safety |
| Tailwind CSS | Styling |
next/image | Image Optimization |
useState / useEffect | State Management |
What I’ve actually shipped — Backend
| Technology | Purpose |
|---|---|
| Next.js Route Handlers | API Layer |
| JSON Files | MVP Database |
| JWT Tokens | Authentication |
| PBKDF2 | Password Hashing |
An alternative stack I proposed early on (not what I actually shipped)
In one of my earlier planning documents, I proposed a different frontend/backend pairing. I’m keeping it here for historical context, but the actual MVP uses the Next.js full-stack approach above, not this:
- Frontend: React + Vite, with React Router, Context API, React Hook Form, Zod, TanStack Query
- Backend: Django, Django REST Framework, PostgreSQL
7. My Project Structure (As-Built)
app/
│
├── page.tsx
├── layout.tsx
│
├── auth/
│ ├── signin/
│ ├── signup/
│ ├── verify-email/
│ ├── forgot-password/
│ └── resetpassword/
│
├── dashboard/
│
├── wizard/
│
├── plant-management/
│
└── api/
├── auth/
└── wizard/
components/
│
├── landing/
│ ├── Header.tsx
│ ├── HeroSection.tsx
│ ├── ModuleCards.tsx
│ ├── CropsShowcase.tsx
│ └── LandingPage.tsx
│
├── wizard/
│ ├── WizardLayout.tsx
│ ├── ProgressTracker.tsx
│ ├── SuccessModal.tsx
│ └── steps/
│
└── ui/
└── button.tsx
lib/
│
├── auth.ts
├── wizardDb.ts
├── validation.ts
└── unitConverter.ts
data/
│
├── users.json
├── farmers.json
├── farms.json
├── wizardProgress.json
├── crops.json
└── locations.json
8. My Landing Page
The components I built
Header.tsx
What it’s responsible for:
- Sticky navigation
- Mobile menu
- Language switcher
- Login / Signup CTA
I use useState() for mobile menu management here.
HeroSection.tsx
What it contains:
- Hero title, subtitle, CTA buttons
- KPI statistics
- Advisory preview card
I render all of this data from arrays rather than hardcoding it.
ModuleCards.tsx
What it displays: Plant Management, Financial Management, Advisory System, AI Assistant, Analytics — all rendered via mapped data arrays.
CropsShowcase.tsx
What it displays: the crops I currently support and plan to support — Banana, Papaya, Rice, Mango, Vegetable — using next/image for optimized loading.
The three primary CTAs I designed
My landing page has three CTAs, each with its own journey I mapped out deliberately:
1. Header CTA — “শুরু করুন” (“Get Started”)
Landing Page → Sign Up / Sign In → Dashboard (empty state)
2. Hero CTA — a dashboard-navigation action
Landing Page → Sign Up / Sign In → Dashboard (empty state)
Note to myself: the original label for this CTA got corrupted somewhere in my source documentation and I couldn’t reliably recover it — I need to verify the exact label against my live source code.
3. Hero CTA — “Farm Setup শুরু করুন” (“Start Farm Setup”)
Landing Page → Sign Up / Sign In → 11-Step Farm Setup Wizard → Farm Analysis Engine → Dashboard (active state)
The empty dashboard state I show (after CTAs 1 & 2, before the wizard is completed):
Welcome, [User Name]
You haven't configured your farm yet.
[ Start Farm Setup ]
9. My Landing Page Refactor History
Before: my monolithic Hero.tsx
Originally, my app/page.tsx rendered a single Hero.tsx component that contained the entire landing page: sticky header, hero section, stats/KPIs, advisory panel, module showcase, crop showcase, and mobile nav logic — all crammed into one file.
Supporting files I had at the time:
button.tsx— a reusable button usingclass-variance-authority(CVA)utils.ts— mycn()helper for merging Tailwind classesglobals.css— Tailwind imports, theme variables, base styles
After: the decomposed component architecture I moved to
components/
└── landing/
├── LandingPage.tsx
├── Header.tsx
├── HeroSection.tsx
├── ModuleCards.tsx
└── CropsShowcase.tsx
What I changed, step by step
| # | Change I Made | What It Improved |
|---|---|---|
| 1 | Extracted the header into Header.tsx | Isolated responsibilities; nav items now come from config arrays; mobile nav uses React state instead of DOM manipulation → cleaner code, easier updates, better testability |
| 2 | Extracted the hero into HeroSection.tsx | Content separated from page structure; stats/KPI cards rendered from arrays; hero image migrated to next/image → better performance, less duplication |
| 3 | Extracted the modules into ModuleCards.tsx | Module definitions centralized as data, cards generated via .map() → faster updates, consistent UI, less maintenance |
| 4 | Extracted the crops into CropsShowcase.tsx | Crop data rendered dynamically; optimized image delivery → faster loads, easier content expansion |
| 5 | Created the composition in LandingPage.tsx | Orchestrates Header, Hero, Modules, Crops, cultivation methods, farm setup overview, journey timeline, feature grid, AI assistant panel, CTA section, and footer → centralized page composition, clean separation of concerns |
How I simplified Hero.tsx
Before:
Hero.tsx
└── Entire landing page implementation
After:
Hero.tsx
└── Returns <LandingPage />
Since Hero.tsx now just functions as a passthrough wrapper, I can safely remove it entirely, updating page.tsx to:
import LandingPage from "@/components/landing/LandingPage";
export default function Home() {
return <LandingPage />;
}
How I fixed mobile navigation
What I had before:
document.getElementById(...)
What I moved to:
const [mobileOpen, setMobileOpen] = useState(false);
<button onClick={() => setMobileOpen((prev) => !prev)} />
{mobileOpen && (
<div>...</div>
)}
This aligns with React best practices, eliminates manual DOM manipulation, and makes the behavior much more predictable and maintainable.
The data-driven rendering pattern I adopted
I generate navigation (and similar UI) from config arrays rather than hardcoding JSX:
const navLinks = [
{ href: "#modules", label: "..." }, // localized label
{ href: "#crops", label: "..." }, // localized label
];
<nav>
{navLinks.map((link) => (
<a key={link.href} href={link.href}>
{link.label}
</a>
))}
</nav>
Note to myself: the actual Bengali label strings got corrupted in one of my source documents during export and are omitted here rather than guessed at — I need to pull the real strings from my live codebase.
What this pattern gets me: less repetitive JSX, centralized content updates, easier scaling.
10. My Internationalization Setup (Bengali ↔ English)
I built KrishokOS Bengali-first, with seamless toggling to English.
The languages I support:
type Language = "bn" | "en";
Where I keep the state — LandingPage.tsx:
const [language, setLanguage] = useState<"bn" | "en">("bn");
How I pass it down:
LandingPage
├── Header
├── HeroSection
├── ModuleCards
└── CropsShowcase
Each child component receives language as a prop; Header owns the toggle controls and updates the shared state:
onClick={() => onLanguageChange("bn")}
onClick={() => onLanguageChange("en")}
My translation object pattern:
const heroText = {
bn: {
title: "...", // localized title
},
en: {
title: "Smart Agriculture",
},
};
<h1>{heroText[language].title}</h1>
Keeping the HTML lang attribute in sync:
useEffect(() => {
document.documentElement.lang = language === "en" ? "en" : "bn";
}, [language]);
The result I get: users can switch between Bengali and English and every piece of dynamic content updates instantaneously, without heavy routing overhead or manual DOM manipulation.
Something I still want to do: move my translations into dedicated locale files and adopt full Next.js i18n routing instead of the in-component state pattern I’m using right now.
11. My Authentication System
The features I’ve built
| Feature | Endpoint | Notes |
|---|---|---|
| User Registration | POST /api/auth/signup | Fields: Name, Email, Phone, Password |
| Sign In | POST /api/auth/signin | Supports Email + Password or Phone + Password |
| Email Verification | POST /api/auth/verify-email | Updates { "emailVerified": true } |
| Forgot Password | POST /api/auth/forgot-password | Generates a reset token |
| Reset Password | POST /api/auth/resetpassword | Updates the hashed password |
My user record schema — data/users.json
{
"id": "uuid",
"name": "Farmer Name",
"email": "user@email.com",
"phone": "017XXXXXXXX",
"passwordHash": "...",
"emailVerified": true,
"verificationToken": null,
"resetToken": null,
"createdAt": ""
}
My planned upgrade path: in my original architecture I envisioned swapping this for NextAuth.js with full RBAC — I haven’t implemented that yet in the MVP.
12. My Session & Route Security
I implemented this in lib/auth.ts.
What I built:
- JWT-style tokens
- HTTP-only cookies (so client-side scripts can’t access the token)
- Session persistence
- Protected routes, gated via
requireUser()before rendering
The pages I protect:
/dashboard/wizard/plant-management
13. My User Entry Points & Navigation Flows
I require authentication on all of my primary CTAs.
What happens for an unauthenticated user
CTA Click → Redirect to Authentication
My authentication routes:
/auth/signin
/auth/signup
How I handle post-authentication redirects
I make sure users return to whatever they were originally trying to reach:
| Entry CTA | Redirect Target |
|---|---|
| Header CTA | /dashboard |
| Farm Setup CTA | /wizard |
14. My Plant Management Module
Route: /plant-management
What it’s for: letting the user select a Crop and Farming Method before entering the Farm Setup Wizard.
Crop selection
| Status | Crops |
|---|---|
| I currently support | Banana, Papaya |
| I’ve planned | Rice, Mango, Tomato, Potato, Chili, Onion |
Farming methods I support
- Residue-Free Farming
- Organic Farming
- Chemical Farming
The workflow I built
Select Crop
│
▼
Select Farming Method
│
▼
POST /api/wizard/start
│
▼
Redirect /wizard
15. My Farm Setup Wizard
Route: /wizard · Purpose: create a Farmer Profile and Farm Profile through an 11-step guided wizard.
Where I drew inspiration from: the Plantix onboarding flow, and the Krishok Smart Farm onboarding experience.
What I built into it: cascading location dropdowns (Division → District → Upazila), dynamic unit conversion, and persistent state management across steps.
⚠️ Something I need to reconcile with myself: across two of my own planning documents, I described the 11 steps slightly differently — different ordering and grouping of fields (e.g. one groups District/Upazila/Union as three separate steps, the other groups Division/District/Upazila into a single step). I’ve kept both versions below until I confirm against my live wizard code (
components/wizard/steps/) which one actually shipped.
15.1 The version I documented in my Technical Documentation
| Step | Name | Fields |
|---|---|---|
| 1 | Farmer Identity | Name, Phone, Email, National ID |
| 2 | Farm Information | Farm Name, Farm Type |
| 3 | Soil & Water | Soil Type, Water Source |
| 4 | District | — |
| 5 | Upazila | — |
| 6 | Union | — |
| 7 | Land Measurement | Decimal, Bigha, Katha (includes conversion engine) |
| 8 | Primary Crop | Pre-populated from Plant Management |
| 9 | Secondary Crops | Multi-select |
| 10 | Annual Budget | — |
| 11 | Review & Confirm | Read-only summary |
Important thing to remember: Step 11 is not an input step. My completion threshold is
completedSteps.length >= 10.
15.2 The version I documented in my Banana Farm Setup spec
| Step | Name | Fields |
|---|---|---|
| 1 | Farmer Information | Farmer name, Phone number |
| 2 | Farm Location | Division, District, Upazila |
| 3 | Farm Details | Farm size, Land measurement unit |
| 4 | Previous Land Use | Previous crop, Years of cultivation |
| 5 | Soil Information | Soil type, Soil pH level |
| 6 | Water Source | Irrigation method, Water availability |
| 7 | Budget Planning | Available farming budget |
| 8 | Market Objective | Local / Wholesale / Export market |
| 9 | Export Goal | ”Are you targeting export-quality production?” (Yes/No) |
| 10 | Farming Method | Organic / Conventional (Chemical) / Residue-Free |
| 11 | Banana Cultivation Setup | Variety selection, expected yield target, final review & confirmation |
16. My Farm Analysis Engine
Once someone completes onboarding, my system generates an initial farm assessment automatically.
Example farm profile output
Residue-Free Banana Farm
Rajshahi
2 Acres
The initial recommendations I generate
- Recommended Variety
- Recommended Plant Spacing
- Required Seedling Quantity
The financial estimates I calculate
- Estimated Production Cost
- Expected Revenue
- Projected Profit
The risk assessment I run
- Water Availability Risk
- Soil Suitability Risk
- Climate Considerations
Everything my Farm Analysis Engine generates becomes a widget inside the dashboard.
The data flow I designed (planning doc)
User
↓
Farm
↓
FarmAssessment
↓
CultivationPlan
↓
BananaPlan
↓
Recommendations
↓
Activities
17. My Dashboard
Route: /dashboard — protected, requires an authenticated user.
My dashboard logic
I built the dashboard’s behavior around one condition: has the user completed Farm Setup?
Scenario A — Farm Setup Not Completed → Empty Dashboard
What I display: “No active farms”, “Start your first farm setup”
Primary action: Start Farm Setup
What I keep hidden until onboarding completes:
- Analytics
- Irrigation schedules
- Fertilizer recommendations
- Disease monitoring
- Production timeline
In my actual MVP right now, the empty-state instead shows mock values for early testing rather than a fully blank state — I’m treating this as a known, intentional simplification for now, not the final behavior.
Scenario B — Farm Setup Completed → Active Farm Dashboard
Sections I show:
- Farm Overview (Banana Variety, Farm Size, Farming Method, Expected Harvest Date)
- Today’s Recommendations
- Upcoming Tasks
- Production Timeline
- Alerts
- Recent Activities
18. My Personalized Analytics Engine (As-Built)
Dashboard states in my MVP
| State | Behavior |
|---|---|
| No Farm Setup | Shows mock values — Active Farms: 2, Crops Growing: 2, Alerts: 3 |
| Farm Created | Loads the real farm profile |
What I generate this from
- Crop, Farming Method, Soil Type, Water Source, Land Size, Budget
Farm Profile Overview
I display Farm Name, Crop, Location, Method.
Soil & irrigation advisory (example)
Loamy Soil + Tube Well Water →
- Weekly irrigation schedule
- Drainage recommendation
- Soil nutrient recommendation
Farming method strategy I apply
| Method | Strategy Focus |
|---|---|
| Organic | Certification focus, premium market, organic inputs |
| Residue-Free | Export market, compliance tracking |
| Chemical | Conventional yield optimization |
Financial forecast I calculate
Expected Yield, Expected Revenue, Input Costs, Net Profit, ROI, 75/25 Model Targets.
Daily advisory
I generate dynamic recommendations based on Crop, Season, and Method.
19. My Data Models
What I’ve actually built (JSON files)
FARMER
{
"id": "",
"userId": "",
"name": "",
"phone": "",
"email": ""
}
FARM
{
"id": "",
"farmerId": "",
"farmName": "",
"primaryCrop": "",
"farmingMethod": "",
"soilType": "",
"waterSource": "",
"landSize": 0
}
WIZARDPROGRESS
{
"id": "",
"userId": "",
"currentStep": 1,
"completedSteps": [],
"stepData": {}
}
What I’ve planned for the future (PostgreSQL + Prisma)
- User
- Farm
- Field
- Crop
- CropCycle
- Task
- Inventory
- DiseaseReport
- IrrigationSchedule
- FertilizerApplication
- Harvest
- ExportCertificate
- Notification
20. My API Reference
| Action | Method & Path | Notes |
|---|---|---|
| Start Wizard | POST /api/wizard/start | Body: { "crop": "Banana", "farmingMethod": "Organic" } |
| Save Step | PUT /api/wizard/step/:stepNumber | Persists individual step data |
| Get Progress | GET /api/wizard/progress/:farmerId | Returns current wizard progress |
| Get Locations | GET /api/wizard/locations | Cascading District/Upazila/Union dropdown data |
| Complete Wizard | POST /api/wizard/complete | Creates FARMER and FARM records |
| Sign Up | POST /api/auth/signup | Fields: Name, Email, Phone, Password |
| Sign In | POST /api/auth/signin | Email+Password or Phone+Password |
| Verify Email | POST /api/auth/verify-email | Sets emailVerified: true |
| Forgot Password | POST /api/auth/forgot-password | Issues a reset token |
| Reset Password | POST /api/auth/resetpassword | Updates hashed password |
21. My Land Conversion Engine
Location: lib/unitConverter.ts
Units I support: Decimal, Bigha, Katha
1 Bigha = 33 Decimal
1 Decimal = 3.03 Katha
Where I use it: Wizard Step 7 (Land Measurement / Farm Details).
22. My Security Architecture
| Concern | My Approach |
|---|---|
| Password storage | PBKDF2 hashing — I never store passwords in plain text |
| Session security | HTTP-only cookies — prevents client-side token access |
| Route protection | Protected routes verify requireUser() before rendering |
My planned upgrade: move to NextAuth.js with full RBAC as the platform matures (see §5.2 and §11).
23. My Performance Optimizations
The hero image LCP fix I made
The issue I ran into: Largest Contentful Paint (LCP) warnings, because my hero image sits above the fold.
How I fixed it:
loading="eager"
The result: improved perceived load speed, LCP warnings resolved, and I kept all the Next.js image optimization benefits.
The Next.js config updates I made
Remote image support (next.config.mjs):
images: {
remotePatterns: [
{
hostname: "images.unsplash.com",
},
],
}
Local network dev access:
allowedDevOrigins: ["192.168.56.1"]
This lets my dev resources load correctly when I access the app over my local network.
Validation results I got (at time of refactor)
| Check | Command | Result |
|---|---|---|
| Build | npm run build | ✅ Completed successfully |
| Lint | npm run lint | ✅ No linting issues detected |
| Types | npx tsc --noEmit | ✅ No TypeScript errors identified |
My dev server (at time of refactor)
Local: http://localhost:3000
Network: http://192.168.56.1:3000
24. My Developer Setup
# Install dependencies
npm install
# Run development server
npm run dev
# Type check
npx tsc --noEmit
# Production build
npm run build
# Start production server
npm start
25. My Current MVP User Journey
Landing Page
│
▼
Sign Up
│
▼
Verify Email
│
▼
Sign In
│
▼
Dashboard
│
▼
Plant Management
│
▼
Crop Selection
│
▼
Farming Method Selection
│
▼
11-Step Farm Wizard
│
▼
Create Farm
│
▼
Personalized Analytics Dashboard
│
▼
Future ERP Modules
26. My Future Roadmap
Near-term, from my Banana Farm Setup / Product Development Roadmap
| Phase | Focus |
|---|---|
| 1 | Foundation — Landing page, Authentication system, Empty dashboard experience |
| 2 | Farm Onboarding — 11-step setup wizard, Farm data persistence |
| 3 | Intelligence Layer — Dashboard analytics, Recommendation engine |
| 4 | Operational Management — Banana cultivation workflow, Activity management, Scheduling, Task tracking |
| 5 | Crop Expansion — Papaya cultivation support |
| 6 | Platform Expansion — Livestock management, Aquaculture management |
Long-term, from my Technical Documentation
| Phase | Focus |
|---|---|
| 2 | PlantOS Core — Crop lifecycle management, growth stage tracking, disease tracking, fertilizer planning, irrigation scheduling |
| 3 | AI Advisory — Disease detection, pest detection, yield prediction, image analysis |
| 4 | Marketplace — Input suppliers, buyers, contract farming, logistics |
| 5 | Financial OS — Loans, insurance, subsidy management, farm accounting |
Landing page — things I still want to do
- Extract Farm Setup into its own component.
- Separate Journey Timeline into reusable sections.
- Create dedicated Platform Features components.
- Isolate the AI Assistant panel.
- Move translations into dedicated locale files.
- Implement full Next.js internationalization support.
- Add animation and interaction enhancements.
27. Things I Still Need to Reconcile
Since this reference pulls together several of my own planning documents written at different project stages, a few inconsistencies crept in. I’m listing them here so I remember to resolve them against my live codebase:
- Frontend/backend stack conflict: in my Banana Farm Setup planning doc I recommended React + Vite + Django + PostgreSQL, but my Technical Documentation and Landing Page Refactor notes confirm what I actually built is Next.js full-stack with a local JSON database. The Next.js approach is what’s actually running — the React/Vite/Django idea was an earlier proposal I ended up not using.
- Auth provider conflict: my System Architecture diagram proposes NextAuth.js, but what I’ve actually built for authentication is a custom JWT + PBKDF2 + JSON file implementation. NextAuth.js is a planned future migration, not what’s running today.
- Database conflict: my System Architecture diagram specifies Supabase PostgreSQL + Prisma, but my Technical Documentation and Project Structure confirm the MVP currently persists everything in local JSON files (
data/*.json). Postgres/Prisma is the upgrade path I’ve planned for once the MVP validates the product. - Wizard step ordering conflict: my Technical Documentation and my Banana Farm Setup spec describe different step groupings for the 11-step wizard (see §15.1 vs §15.2). I need to confirm against
components/wizard/steps/which version I actually shipped. - Dashboard empty-state conflict: my Banana Farm Setup spec describes a genuinely empty state (“No active farms”), while my Technical Documentation’s Dashboard State 1 shows mock values (Active Farms: 2, Crops Growing: 2, Alerts: 3) instead. The mock-value version is what I’m actually running in the MVP, used for early testing/demo purposes.
- Garbled Bengali strings: several Bengali-language UI strings (CTA labels, nav link labels, hero translation values) got corrupted somewhere during export from my original source documents, and I couldn’t reliably reconstruct them. I’ve flagged them inline rather than guessing — I’ll pull the real strings from my live source code when I formalize this documentation.