smartfarming / index.html
Abder004's picture
Add 1 files
ce4e1e4 verified
<!DOCTYPE html>
<html>
<head>
<title>AgriChain Backend Documentation</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
pre {
background-color: #f8f8f8;
border-radius: 5px;
padding: 15px;
overflow-x: auto;
}
.endpoint {
border-left: 4px solid #10b981;
padding-left: 1rem;
margin-bottom: 2rem;
}
</style>
</head>
<body class="bg-gray-50 p-8">
<div class="max-w-6xl mx-auto bg-white rounded-lg shadow-lg p-8">
<div class="flex items-center mb-8">
<i class="fas fa-leaf text-emerald-500 text-3xl mr-3"></i>
<h1 class="text-3xl font-bold text-gray-800">AgriChain Backend API</h1>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">System Overview</h2>
<p class="text-gray-600 mb-4">
The AgriChain backend provides RESTful APIs for the smart farming dashboard, handling IoT device data,
blockchain transactions, AI predictions, and user management.
</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div class="bg-emerald-50 p-4 rounded-lg">
<h3 class="font-medium text-emerald-800 mb-2">Tech Stack</h3>
<ul class="text-sm text-gray-700 space-y-1">
<li>Node.js v18+</li>
<li>Express.js</li>
<li>MongoDB (with Mongoose)</li>
<li>JWT Authentication</li>
<li>Web3.js for blockchain</li>
<li>TensorFlow.js for AI</li>
</ul>
</div>
<div class="bg-blue-50 p-4 rounded-lg">
<h3 class="font-medium text-blue-800 mb-2">Key Features</h3>
<ul class="text-sm text-gray-700 space-y-1">
<li>Real-time IoT data processing</li>
<li>Blockchain data integrity</li>
<li>AI prediction models</li>
<li>User authentication</li>
<li>Cloud integration</li>
</ul>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<h3 class="font-medium text-purple-800 mb-2">Deployment</h3>
<ul class="text-sm text-gray-700 space-y-1">
<li>Docker containerization</li>
<li>Kubernetes for orchestration</li>
<li>AWS ECS/EKS</li>
<li>CI/CD with GitHub Actions</li>
</ul>
</div>
</div>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Installation</h2>
<pre><code class="language-bash">
# Clone the repository
git clone https://github.com/agrichain/backend.git
cd backend
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Edit .env with your configuration
# Start the development server
npm run dev
# For production
npm run build
npm start
</code></pre>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">API Endpoints</h2>
<div class="endpoint">
<h3 class="text-lg font-medium text-gray-800 mb-2">Authentication</h3>
<div class="mb-4">
<span class="bg-green-100 text-green-800 text-xs font-medium px-2.5 py-0.5 rounded">POST</span>
<span class="ml-2 font-mono">/api/auth/register</span>
</div>
<pre><code class="language-javascript">
// Request Body
{
"name": "John Farmer",
"email": "john@example.com",
"password": "securepassword123",
"farmName": "Green Valley Farms"
}
// Response
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "507f1f77bcf86cd799439011",
"name": "John Farmer",
"email": "john@example.com",
"farmName": "Green Valley Farms"
}
}
</code></pre>
<div class="mb-4 mt-6">
<span class="bg-green-100 text-green-800 text-xs font-medium px-2.5 py-0.5 rounded">POST</span>
<span class="ml-2 font-mono">/api/auth/login</span>
</div>
<pre><code class="language-javascript">
// Request Body
{
"email": "john@example.com",
"password": "securepassword123"
}
// Response (same structure as register)
</code></pre>
</div>
<div class="endpoint">
<h3 class="text-lg font-medium text-gray-800 mb-2">IoT Device Management</h3>
<div class="mb-4">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded">GET</span>
<span class="ml-2 font-mono">/api/iot/devices</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"devices": [
{
"id": "60d5ec9cfb9d8b3a48fe9a12",
"name": "Soil Moisture Sensor - Field A",
"type": "moisture",
"status": "online",
"batteryLevel": 78,
"signalStrength": 92,
"lastReading": {
"value": 72,
"timestamp": "2023-06-15T08:30:45.000Z"
},
"location": {
"field": "A",
"coordinates": [34.0522, -118.2437]
}
},
// ... more devices
]
}
</code></pre>
<div class="mb-4 mt-6">
<span class="bg-yellow-100 text-yellow-800 text-xs font-medium px-2.5 py-0.5 rounded">POST</span>
<span class="ml-2 font-mono">/api/iot/data</span>
<span class="text-sm text-gray-500 ml-2">(for IoT devices to send data)</span>
</div>
<pre><code class="language-javascript">
// Request Body
{
"deviceId": "60d5ec9cfb9d8b3a48fe9a12",
"secretKey": "device-secret-key",
"readings": [
{
"type": "moisture",
"value": 72,
"timestamp": "2023-06-15T08:30:45.000Z"
}
]
}
// Response
{
"success": true,
"message": "Data received and stored",
"blockchainHash": "a3f8e2d4b5c71f9e8a0b6d5c4f3e2a1b"
}
</code></pre>
</div>
<div class="endpoint">
<h3 class="text-lg font-medium text-gray-800 mb-2">Blockchain</h3>
<div class="mb-4">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded">GET</span>
<span class="ml-2 font-mono">/api/blockchain/blocks</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"blocks": [
{
"index": 4892,
"timestamp": "2023-06-15T08:30:45.000Z",
"data": {
"deviceId": "60d5ec9cfb9d8b3a48fe9a12",
"readingType": "moisture",
"value": 72,
"field": "A"
},
"previousHash": "b5c71f9e8a0b6d5c4f3e2a1ba3f8e2d",
"hash": "a3f8e2d4b5c71f9e8a0b6d5c4f3e2a1b"
},
// ... more blocks
]
}
</code></pre>
<div class="mb-4 mt-6">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded">GET</span>
<span class="ml-2 font-mono">/api/blockchain/validate</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"valid": true,
"invalidBlocks": [],
"message": "Blockchain integrity verified"
}
</code></pre>
</div>
<div class="endpoint">
<h3 class="text-lg font-medium text-gray-800 mb-2">AI Predictions</h3>
<div class="mb-4">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded">GET</span>
<span class="ml-2 font-mono">/api/ai/predictions</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"predictions": [
{
"type": "irrigation",
"field": "A",
"prediction": "Next irrigation in 8 hours",
"confidence": 0.92,
"recommendation": "Delay watering until evening to reduce evaporation"
},
{
"type": "pest",
"field": "B",
"prediction": "Low pest risk (15%)",
"confidence": 0.87,
"recommendation": "Monitor for corn borer, no treatment needed yet"
},
{
"type": "harvest",
"field": "C",
"prediction": "Optimal harvest window: July 15-18",
"confidence": 0.85,
"recommendation": "Prepare workforce and storage for peak yield"
}
]
}
</code></pre>
<div class="mb-4 mt-6">
<span class="bg-yellow-100 text-yellow-800 text-xs font-medium px-2.5 py-0.5 rounded">POST</span>
<span class="ml-2 font-mono">/api/ai/train</span>
<span class="text-sm text-gray-500 ml-2">(Admin only - retrain models)</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"message": "AI models retrained successfully",
"newAccuracy": {
"irrigation": 0.93,
"pest": 0.88,
"harvest": 0.86
}
}
</code></pre>
</div>
<div class="endpoint">
<h3 class="text-lg font-medium text-gray-800 mb-2">Cloud Integration</h3>
<div class="mb-4">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded">GET</span>
<span class="ml-2 font-mono">/api/cloud/status</span>
</div>
<pre><code class="language-javascript">
// Response
{
"success": true,
"services": [
{
"provider": "AWS IoT",
"status": "connected",
"metrics": {
"messages": 1248,
"storage": 2.8,
"rulesProcessed": 56
}
},
{
"provider": "Azure Data Lake",
"status": "syncing",
"metrics": {
"dataStored": 4.2,
"lastSync": "2023-06-15T08:28:12.000Z",
"analyticsJobs": 12
}
},
{
"provider": "Google BigQuery",
"status": "processing",
"metrics": {
"queries": 84,
"mlModels": 3,
"storage": 1.5
}
}
]
}
</code></pre>
</div>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Database Schema</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">User</h3>
<pre><code class="language-javascript">
{
name: String,
email: { type: String, unique: true },
password: String,
farmName: String,
role: { type: String, enum: ['user', 'admin'], default: 'user' },
createdAt: { type: Date, default: Date.now }
}
</code></pre>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">Device</h3>
<pre><code class="language-javascript">
{
name: String,
type: { type: String, enum: ['moisture', 'temperature', 'humidity', 'light', 'ph', 'co2'] },
status: { type: String, enum: ['online', 'offline', 'maintenance'] },
batteryLevel: Number,
signalStrength: Number,
secretKey: String, // For authentication
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
location: {
field: String,
coordinates: [Number] // [longitude, latitude]
}
}
</code></pre>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">Reading</h3>
<pre><code class="language-javascript">
{
deviceId: { type: mongoose.Schema.Types.ObjectId, ref: 'Device' },
type: String,
value: Number,
timestamp: { type: Date, default: Date.now },
field: String,
blockchainHash: String
}
</code></pre>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">Block</h3>
<pre><code class="language-javascript">
{
index: Number,
timestamp: { type: Date, default: Date.now },
data: {
deviceId: { type: mongoose.Schema.Types.ObjectId, ref: 'Device' },
readingType: String,
value: Number,
field: String
},
previousHash: String,
hash: String
}
</code></pre>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">Prediction</h3>
<pre><code class="language-javascript">
{
type: { type: String, enum: ['irrigation', 'pest', 'harvest'] },
field: String,
prediction: String,
confidence: Number,
recommendation: String,
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
createdAt: { type: Date, default: Date.now }
}
</code></pre>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h3 class="font-medium text-gray-800 mb-2">CloudService</h3>
<pre><code class="language-javascript">
{
provider: { type: String, enum: ['aws', 'azure', 'google'] },
status: String,
metrics: {
messages: Number,
storage: Number,
rulesProcessed: Number,
// ... other metrics
},
lastSync: Date,
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}
</code></pre>
</div>
</div>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Example Server Code</h2>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">app.js (Main Server File)</h3>
<pre><code class="language-javascript">
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const { Web3 } = require('web3');
const tf = require('@tensorflow/tfjs-node');
const app = express();
// Database connection
mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.error('MongoDB connection error:', err));
// Middleware
app.use(cors());
app.use(helmet());
app.use(express.json());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
// Blockchain setup
const web3 = new Web3(process.env.BLOCKCHAIN_NODE_URL);
const contract = new web3.eth.Contract(
JSON.parse(process.env.CONTRACT_ABI),
process.env.CONTRACT_ADDRESS
);
// Routes
app.use('/api/auth', require('./routes/auth'));
app.use('/api/iot', require('./routes/iot'));
app.use('/api/blockchain', require('./routes/blockchain'));
app.use('/api/ai', require('./routes/ai'));
app.use('/api/cloud', require('./routes/cloud'));
// Error handling
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
success: false,
message: 'Internal server error'
});
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
module.exports = app;
</code></pre>
</div>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">routes/iot.js (Example Route)</h3>
<pre><code class="language-javascript">
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const Device = require('../models/Device');
const Reading = require('../models/Reading');
const { addBlock } = require('../utils/blockchain');
// @route GET api/iot/devices
// @desc Get all user's IoT devices
// @access Private
router.get('/devices', auth, async (req, res) => {
try {
const devices = await Device.find({ userId: req.user.id });
// Get latest readings for each device
const devicesWithReadings = await Promise.all(devices.map(async device => {
const latestReading = await Reading.findOne({ deviceId: device._id })
.sort({ timestamp: -1 })
.limit(1);
return {
...device.toObject(),
lastReading: latestReading || null
};
}));
res.json({ success: true, devices: devicesWithReadings });
} catch (err) {
console.error(err.message);
res.status(500).json({ success: false, message: 'Server error' });
}
});
// @route POST api/iot/data
// @desc Receive data from IoT device
// @access Private (using device secret key)
router.post('/data', async (req, res) => {
const { deviceId, secretKey, readings } = req.body;
try {
// Verify device
const device = await Device.findOne({ _id: deviceId, secretKey });
if (!device) {
return res.status(401).json({
success: false,
message: 'Invalid device credentials'
});
}
// Save readings
const savedReadings = await Promise.all(readings.map(async reading => {
const newReading = new Reading({
deviceId,
type: reading.type,
value: reading.value,
timestamp: reading.timestamp || Date.now(),
field: device.location.field
});
// Add to blockchain
const blockData = {
deviceId,
readingType: reading.type,
value: reading.value,
field: device.location.field
};
const hash = await addBlock(blockData);
newReading.blockchainHash = hash;
return await newReading.save();
}));
// Update device status and battery if provided
if (readings[0].batteryLevel) {
device.batteryLevel = readings[0].batteryLevel;
await device.save();
}
res.json({
success: true,
message: 'Data received and stored',
blockchainHash: savedReadings[0].blockchainHash
});
} catch (err) {
console.error(err.message);
res.status(500).json({ success: false, message: 'Server error' });
}
});
module.exports = router;
</code></pre>
</div>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">utils/blockchain.js</h3>
<pre><code class="language-javascript">
const Block = require('../models/Block');
const crypto = require('crypto');
// Simple blockchain implementation (in production would use Ethereum or similar)
class Blockchain {
constructor() {
this.chain = [];
this.initializeChain();
}
async initializeChain() {
// Load existing chain from database
const blocks = await Block.find().sort({ index: 1 });
this.chain = blocks;
// If no blocks, create genesis block
if (this.chain.length === 0) {
await this.createGenesisBlock();
}
}
async createGenesisBlock() {
const genesisBlock = new Block({
index: 0,
timestamp: Date.now(),
data: { message: "Genesis block" },
previousHash: "0",
hash: this.calculateHash(0, "0", Date.now(), { message: "Genesis block" })
});
await genesisBlock.save();
this.chain.push(genesisBlock);
}
calculateHash(index, previousHash, timestamp, data) {
return crypto
.createHash('sha256')
.update(index + previousHash + timestamp + JSON.stringify(data))
.digest('hex');
}
async addBlock(data) {
const previousBlock = this.chain[this.chain.length - 1];
const newIndex = previousBlock.index + 1;
const newTimestamp = Date.now();
const newHash = this.calculateHash(newIndex, previousBlock.hash, newTimestamp, data);
const newBlock = new Block({
index: newIndex,
timestamp: newTimestamp,
data,
previousHash: previousBlock.hash,
hash: newHash
});
await newBlock.save();
this.chain.push(newBlock);
return newHash;
}
async validateChain() {
for (let i = 1; i < this.chain.length; i++) {
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
// Check hash
if (currentBlock.hash !== this.calculateHash(
currentBlock.index,
currentBlock.previousHash,
currentBlock.timestamp,
currentBlock.data
)) {
return false;
}
// Check previous hash
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
}
const blockchain = new Blockchain();
// Public functions
const addBlock = async (data) => {
return await blockchain.addBlock(data);
};
const validateChain = async () => {
return await blockchain.validateChain();
};
const getBlocks = async () => {
return blockchain.chain;
};
module.exports = {
addBlock,
validateChain,
getBlocks
};
</code></pre>
</div>
</div>
<div class="mb-8">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Deployment</h2>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">Dockerfile</h3>
<pre><code class="language-dockerfile">
# Use official Node.js image
FROM node:18-alpine
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
# Build the app
RUN npm run build
# Expose the app port
EXPOSE 5000
# Start the app
CMD ["npm", "start"]
</code></pre>
</div>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">docker-compose.yml</h3>
<pre><code class="language-yaml">
version: '3.8'
services:
app:
build: .
ports:
- "5000:5000"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongo:27017/agrichain
- JWT_SECRET=your_jwt_secret
depends_on:
- mongo
restart: unless-stopped
mongo:
image: mongo:6.0
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=example
volumes:
mongodb_data:
</code></pre>
</div>
<div class="mb-6">
<h3 class="font-medium text-gray-800 mb-2">Kubernetes Deployment</h3>
<pre><code class="language-yaml">
apiVersion: apps/v1
kind: Deployment
metadata:
name: agrichain-backend
spec:
replicas: 3
selector:
matchLabels:
app: agrichain-backend
template:
metadata:
labels:
app: agrichain-backend
spec:
containers:
- name: app
image: your-registry/agrichain-backend:latest
ports:
- containerPort: 5000
env:
- name: NODE_ENV
value: production
- name: MONGODB_URI
value: "mongodb://agrichain-mongo:27017/agrichain"
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: agrichain-secrets
key: jwt-secret
- name: mongo
image: mongo:6.0
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: agrichain-secrets
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: agrichain-secrets
key: mongo-root-password
volumeMounts:
- name: mongodb-data
mountPath: /data/db
volumes:
- name: mongodb-data
persistentVolumeClaim:
claimName: mongodb-pvc
---
apiVersion: v1
kind: Service
metadata:
name: agrichain-service
spec:
selector:
app: agrichain-backend
ports:
- protocol: TCP
port: 80
targetPort: 5000
type: LoadBalancer
</code></pre>
</div>
</div>
<div class="bg-emerald-50 p-4 rounded-lg">
<h2 class="text-lg font-medium text-emerald-800 mb-2">Next Steps</h2>
<ul class="list-disc pl-5 text-gray-700 space-y-1">
<li>Set up CI/CD pipeline with GitHub Actions</li>
<li>Configure monitoring with Prometheus and Grafana</li>
<li>Implement WebSocket for real-time updates to frontend</li>
<li>Add more AI models for different crop types</li>
<li>Integrate with weather APIs for enhanced predictions</li>
</ul>
</div>
</div>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Abder004/smartfarming" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>