# Scheme Display API - Documentation ## Overview This document describes the new API endpoints for displaying government schemes on the frontend with filtering, pagination, and search capabilities. --- ## 🎯 New API Endpoints ### 1. **GET /schemes/all** - Get All Schemes with Filtering Retrieves a paginated list of schemes with optional filtering. #### Request Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `page` | integer | No | 1 | Page number (starts from 1) | | `page_size` | integer | No | 10 | Number of schemes per page (max: 100) | | `state` | string | No | null | Filter by state name | | `category` | string | No | null | Filter by scheme category | | `level` | string | No | null | Filter by level (Central/State) | | `search` | string | No | null | Search text (searches in name, details, benefits, tags) | #### Response Format ```json { "total": 3402, "page": 1, "page_size": 10, "total_pages": 341, "schemes": [ { "scheme_name": "Scheme Name", "slug": "scheme-slug", "details": "Detailed description...", "benefits": "Benefits offered...", "eligibility": "Eligibility criteria...", "application": "How to apply...", "documents": "Required documents...", "level": "State/Central", "scheme_category": "Category name", "tags": "tag1, tag2" } ] } ``` #### Example Requests ```bash # Get first page of all schemes GET http://127.0.0.1:8000/schemes/all # Get schemes for specific state GET http://127.0.0.1:8000/schemes/all?state=Karnataka&page=1&page_size=20 # Filter by category GET http://127.0.0.1:8000/schemes/all?category=Agriculture # Filter by level GET http://127.0.0.1:8000/schemes/all?level=Central # Search with text GET http://127.0.0.1:8000/schemes/all?search=farmer # Combined filters GET http://127.0.0.1:8000/schemes/all?state=Maharashtra&category=Education&page=1&page_size=15 ``` --- ### 2. **GET /schemes/{slug}** - Get Scheme Details by Slug Retrieves detailed information about a specific scheme. #### Request Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `slug` | string | Yes | - | Unique scheme identifier | | `language` | string | No | "en" | Language code for translation | #### Response Format ```json { "scheme_name": "Scheme Name", "slug": "scheme-slug", "details": "Full details...", "benefits": "Complete benefits...", "eligibility": "Full eligibility criteria...", "application": "Complete application process...", "documents": "All required documents...", "level": "State/Central", "scheme_category": "Category", "tags": "tags" } ``` #### Example Requests ```bash # Get scheme in English GET http://127.0.0.1:8000/schemes/astpss # Get scheme in Hindi GET http://127.0.0.1:8000/schemes/astpss?language=hi # Get scheme in Telugu GET http://127.0.0.1:8000/schemes/pmsfbcs?language=te ``` --- ### 3. **GET /schemes/categories** - Get All Categories Retrieves all unique scheme categories. #### Response Format ```json { "categories": [ "Agriculture,Rural & Environment", "Business & Entrepreneurship", "Education & Learning", "Health & Wellness", "Social welfare & Empowerment", "Women and Child" ] } ``` #### Example Request ```bash GET http://127.0.0.1:8000/schemes/categories ``` --- ### 4. **GET /schemes/stats** - Get Scheme Statistics Retrieves statistics about all schemes. #### Response Format ```json { "total_schemes": 3402, "by_level": { "State": 2850, "Central": 552 }, "by_category": { "Social welfare & Empowerment": 856, "Business & Entrepreneurship": 642, "Education & Learning": 432, "Agriculture,Rural & Environment": 389, "Health & Wellness": 267 }, "total_categories": 24 } ``` #### Example Request ```bash GET http://127.0.0.1:8000/schemes/stats ``` --- ## 🎨 Frontend Implementation Examples ### React/Next.js Example ```javascript // Fetch schemes with filters const fetchSchemes = async (filters) => { const params = new URLSearchParams({ page: filters.page || 1, page_size: filters.pageSize || 10, ...(filters.state && { state: filters.state }), ...(filters.category && { category: filters.category }), ...(filters.level && { level: filters.level }), ...(filters.search && { search: filters.search }) }); const response = await fetch( `http://127.0.0.1:8000/schemes/all?${params}` ); return await response.json(); }; // Fetch single scheme const fetchScheme = async (slug, language = 'en') => { const response = await fetch( `http://127.0.0.1:8000/schemes/${slug}?language=${language}` ); return await response.json(); }; // Usage in component const SchemesList = () => { const [schemes, setSchemes] = useState([]); const [filters, setFilters] = useState({ page: 1, pageSize: 10, state: '', category: '', search: '' }); useEffect(() => { fetchSchemes(filters).then(data => { setSchemes(data.schemes); }); }, [filters]); return (
{/* Filter UI */} {/* Scheme cards */}
); }; ``` --- ## 🔍 Search & Filter Recommendations ### **RECOMMENDATION: Implement Filters on BACKEND** #### ✅ Why Backend Filtering is Better: 1. **Performance** - Only sends required data over network - Reduces bandwidth usage - Faster page loads (10 schemes vs 3402 schemes) 2. **Scalability** - Database can grow without affecting frontend performance - Efficient pagination - Optimized queries 3. **Consistency** - Same filtering logic across all platforms (web, mobile, etc.) - Centralized business logic - Easier to maintain 4. **User Experience** - Faster search results - Real-time filtering without loading all data - Better mobile experience 5. **SEO Benefits** - Server-side rendering possible - Better indexing of individual scheme pages - Faster initial page load #### ❌ Why Avoid Frontend Filtering: 1. **Performance Issues** - Loading 3402+ schemes slows down initial page load - Memory consumption on client devices - Poor mobile performance 2. **Network Overhead** - Large JSON payload on every page load - Wasted bandwidth for unused data 3. **Maintenance** - Duplicate filtering logic on frontend and backend - Harder to debug issues --- ## 📊 Backend Filtering Implementation ### Current Implementation Features: #### 1. **State Filtering** ```python # Searches in details and eligibility fields if state and state != "All States": filtered_df = filtered_df[ filtered_df['details'].str.contains(state, case=False, na=False) | filtered_df['eligibility'].str.contains(state, case=False, na=False) ] ``` #### 2. **Category Filtering** ```python # Case-insensitive partial matching if category: filtered_df = filtered_df[ filtered_df['schemeCategory'].str.contains(category, case=False, na=False) ] ``` #### 3. **Level Filtering** ```python # Exact match for Central/State if level: filtered_df = filtered_df[ filtered_df['level'].str.lower() == level.lower() ] ``` #### 4. **Text Search** ```python # Searches across multiple fields if search: search_mask = ( filtered_df['scheme_name'].str.contains(search, case=False, na=False) | filtered_df['details'].str.contains(search, case=False, na=False) | filtered_df['benefits'].str.contains(search, case=False, na=False) | filtered_df['tags'].str.contains(search, case=False, na=False) ) ``` #### 5. **Pagination** ```python # Efficient slicing start_idx = (page - 1) * page_size end_idx = start_idx + page_size paginated_df = filtered_df.iloc[start_idx:end_idx] ``` --- ## 🎯 Recommended Frontend Architecture ### Option 1: Server-Side Rendering (SSR) - **Best for SEO** ```javascript // Next.js Example export async function getServerSideProps(context) { const { page, state, category } = context.query; const response = await fetch( `http://127.0.0.1:8000/schemes/all?page=${page || 1}&state=${state || ''}&category=${category || ''}` ); const data = await response.json(); return { props: { schemes: data } }; } ``` ### Option 2: Client-Side with Debouncing - **Good UX** ```javascript // React Hook for debounced search import { useState, useEffect } from 'react'; import { debounce } from 'lodash'; const useSchemeSearch = () => { const [filters, setFilters] = useState({}); const [schemes, setSchemes] = useState([]); const [loading, setLoading] = useState(false); const debouncedSearch = debounce(async (filters) => { setLoading(true); const data = await fetchSchemes(filters); setSchemes(data.schemes); setLoading(false); }, 500); // Wait 500ms after user stops typing useEffect(() => { debouncedSearch(filters); }, [filters]); return { schemes, loading, setFilters }; }; ``` ### Option 3: Hybrid Approach - **Balanced** ```javascript // Initial load: Server-side // Filters: Client-side API calls // Search: Debounced backend calls const SchemeList = ({ initialSchemes }) => { const [schemes, setSchemes] = useState(initialSchemes); const handleFilterChange = async (newFilters) => { const data = await fetchSchemes(newFilters); setSchemes(data.schemes); }; return (
); }; ``` --- ## 🚀 Performance Optimization Tips ### 1. **Caching** ```javascript // Frontend caching with React Query import { useQuery } from '@tanstack/react-query'; const useSchemes = (filters) => { return useQuery({ queryKey: ['schemes', filters], queryFn: () => fetchSchemes(filters), staleTime: 5 * 60 * 1000, // Cache for 5 minutes }); }; ``` ### 2. **Lazy Loading** ```javascript // Load more schemes on scroll const SchemeList = () => { const [page, setPage] = useState(1); const handleScroll = () => { if (/* bottom of page */) { setPage(prev => prev + 1); } }; // Fetch next page and append }; ``` ### 3. **Virtual Scrolling** ```javascript // Use react-window for large lists import { FixedSizeList } from 'react-window'; {SchemeCard} ``` --- ## 📱 Mobile Optimization ### Recommended Approach for Mobile: 1. **Smaller Page Size**: Use `page_size=5` or `page_size=10` on mobile 2. **Lazy Loading**: Load more on scroll instead of pagination buttons 3. **Simplified Filters**: Show essential filters only 4. **Backend Filtering**: Critical for mobile performance ```javascript // Detect device and adjust const isMobile = window.innerWidth < 768; const pageSize = isMobile ? 5 : 10; fetchSchemes({ page: 1, page_size: pageSize }); ``` --- ## 🔐 Error Handling ### Backend Errors ```javascript const fetchSchemes = async (filters) => { try { const response = await fetch(`/schemes/all?${params}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error('Failed to fetch schemes:', error); // Show error toast/message to user return { schemes: [], total: 0 }; } }; ``` --- ## 📈 Testing the API ### Using cURL ```bash # Get all schemes curl http://127.0.0.1:8000/schemes/all # Filter by state curl "http://127.0.0.1:8000/schemes/all?state=Karnataka" # Search curl "http://127.0.0.1:8000/schemes/all?search=farmer" # Get specific scheme curl http://127.0.0.1:8000/schemes/astpss # Get statistics curl http://127.0.0.1:8000/schemes/stats ``` ### Using Python ```python import requests # Get schemes response = requests.get( 'http://127.0.0.1:8000/schemes/all', params={ 'page': 1, 'page_size': 10, 'state': 'Karnataka', 'category': 'Agriculture' } ) data = response.json() print(f"Found {data['total']} schemes") ``` --- ## 📝 Summary ### ✅ What We Built: 1. **4 new API endpoints** for scheme management 2. **Backend filtering** (state, category, level, search) 3. **Pagination** support 4. **Multi-language** scheme details 5. **Statistics** endpoint ### ✅ Recommendations: 1. **Use BACKEND filtering** - Better performance, scalability, UX 2. **Implement pagination** - Don't load all 3402 schemes at once 3. **Add debouncing** - For search input (500ms delay) 4. **Cache results** - Use React Query or SWR 5. **Lazy load** - For mobile and infinite scroll ### 🎯 Best Practice: **Backend handles filtering → Frontend displays results → User gets fast, smooth experience** --- ## 🆘 Support For API documentation and interactive testing: - Swagger UI: http://127.0.0.1:8000/docs - ReDoc: http://127.0.0.1:8000/redoc