Skip to main content
Glama

Chicken Business Management MCP Server

by PSYGER02
aiAssistant.ts18.3 kB
/** * AI Assistant Service * Smart AI that proposes actions with human approval workflow * This is the "write-approved" AI that suggests changes but doesn't execute them */ import { supabase } from '../src/supabaseConfig'; import { geminiAPIManager } from './geminiAPIManager'; import { offlineDB } from './offlineService'; interface AIProposal { id: string; type: 'expense_categorization' | 'stock_adjustment' | 'price_optimization' | 'reorder_suggestion' | 'process_improvement'; title: string; description: string; proposed_action: any; confidence: number; reasoning: string; data_source: any; status: 'pending' | 'approved' | 'rejected' | 'expired'; created_at: string; created_by: 'ai_assistant'; expires_at: string; } interface ApprovalRequest { proposal_id: string; human_decision: 'approve' | 'reject'; human_notes?: string; approved_by: string; approved_at: string; } class AIAssistantService { /** * Main AI Assistant - analyzes data and proposes helpful actions * This is the cool part - AI that actually helps your business! */ async analyzeAndPropose(): Promise<AIProposal[]> { console.log('🤖 AI Assistant analyzing business data for improvement opportunities...'); const proposals: AIProposal[] = []; try { // Check for uncategorized expenses const expenseProposals = await this.proposeExpenseCategorization(); proposals.push(...expenseProposals); // Check for stock issues const stockProposals = await this.proposeStockAdjustments(); proposals.push(...stockProposals); // Check for pricing opportunities const priceProposals = await this.proposePriceOptimizations(); proposals.push(...priceProposals); // Check for process improvements const processProposals = await this.proposeProcessImprovements(); proposals.push(...processProposals); // Store all proposals for human review await this.storeProposals(proposals); console.log(`✅ AI Assistant generated ${proposals.length} improvement proposals`); return proposals; } catch (error) { console.error('❌ AI Assistant analysis failed:', error); return []; } } /** * Propose expense categorization for uncategorized items */ async proposeExpenseCategorization(): Promise<AIProposal[]> { const proposals: AIProposal[] = []; try { // Get uncategorized expenses const { data: uncategorizedExpenses } = await supabase .from('expenses') .select('*') .or('category.is.null,category.eq.""') .limit(10); if (!uncategorizedExpenses || uncategorizedExpenses.length === 0) { return proposals; } for (const expense of uncategorizedExpenses) { const categorization = await this.suggestExpenseCategory(expense); if (categorization && categorization.confidence > 70) { proposals.push({ id: `exp_cat_${expense.id}_${Date.now()}`, type: 'expense_categorization', title: `Categorize "${expense.description}"`, description: `AI suggests categorizing this ₱${expense.amount} expense as "${categorization.category}"`, proposed_action: { expense_id: expense.id, new_category: categorization.category, confidence: categorization.confidence }, confidence: categorization.confidence, reasoning: categorization.reasoning, data_source: expense, status: 'pending', created_at: new Date().toISOString(), created_by: 'ai_assistant', expires_at: this.getExpiryDate(7) // Expires in 7 days }); } } return proposals; } catch (error) { console.warn('Expense categorization proposals failed:', error); return []; } } /** * Suggest stock adjustments based on sales patterns */ async proposeStockAdjustments(): Promise<AIProposal[]> { const proposals: AIProposal[] = []; try { // Get current stock levels const { data: products } = await supabase .from('products') .select('*'); if (!products) return proposals; // Get recent sales data for analysis const { data: recentSales } = await supabase .from('sales') .select('*') .gte('date', this.getDaysAgo(30)) .order('date', { ascending: false }); const stockAnalysis = await this.analyzeStockNeeds(products, recentSales || []); for (const suggestion of stockAnalysis.suggestions) { if (suggestion.confidence > 75) { proposals.push({ id: `stock_adj_${suggestion.product_id}_${Date.now()}`, type: 'stock_adjustment', title: `${suggestion.action} for ${suggestion.product_name}`, description: suggestion.description, proposed_action: { product_id: suggestion.product_id, action_type: suggestion.action, recommended_quantity: suggestion.recommended_quantity, current_quantity: suggestion.current_quantity, reasoning: suggestion.reasoning }, confidence: suggestion.confidence, reasoning: suggestion.reasoning, data_source: { product: suggestion.product_data, sales: recentSales }, status: 'pending', created_at: new Date().toISOString(), created_by: 'ai_assistant', expires_at: this.getExpiryDate(5) }); } } return proposals; } catch (error) { console.warn('Stock adjustment proposals failed:', error); return []; } } /** * Propose price optimizations based on sales performance */ async proposePriceOptimizations(): Promise<AIProposal[]> { const proposals: AIProposal[] = []; try { // Get products with sales data const { data: productsWithSales } = await supabase .from('sales') .select('product_name, price, quantity, total, date') .gte('date', this.getDaysAgo(30)); if (!productsWithSales || productsWithSales.length === 0) { return proposals; } const priceAnalysis = await this.analyzePricingOpportunities(productsWithSales); for (const opportunity of priceAnalysis.opportunities) { if (opportunity.confidence > 70) { proposals.push({ id: `price_opt_${opportunity.product_name}_${Date.now()}`, type: 'price_optimization', title: `Price optimization for ${opportunity.product_name}`, description: opportunity.description, proposed_action: { product_name: opportunity.product_name, current_price: opportunity.current_price, suggested_price: opportunity.suggested_price, expected_impact: opportunity.expected_impact }, confidence: opportunity.confidence, reasoning: opportunity.reasoning, data_source: productsWithSales, status: 'pending', created_at: new Date().toISOString(), created_by: 'ai_assistant', expires_at: this.getExpiryDate(14) }); } } return proposals; } catch (error) { console.warn('Price optimization proposals failed:', error); return []; } } /** * Propose process improvements based on patterns */ async proposeProcessImprovements(): Promise<AIProposal[]> { const proposals: AIProposal[] = []; try { // Analyze recent business operations const businessPatterns = await this.analyzeBusinessPatterns(); const improvementSuggestions = await this.generateProcessImprovements(businessPatterns); for (const suggestion of improvementSuggestions) { if (suggestion.confidence > 60) { proposals.push({ id: `process_imp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, type: 'process_improvement', title: suggestion.title, description: suggestion.description, proposed_action: { improvement_type: suggestion.type, implementation_steps: suggestion.steps, expected_benefit: suggestion.benefit }, confidence: suggestion.confidence, reasoning: suggestion.reasoning, data_source: businessPatterns, status: 'pending', created_at: new Date().toISOString(), created_by: 'ai_assistant', expires_at: this.getExpiryDate(30) }); } } return proposals; } catch (error) { console.warn('Process improvement proposals failed:', error); return []; } } /** * Human approval workflow - approve or reject AI proposals */ async processHumanDecision(approval: ApprovalRequest): Promise<{ success: boolean; message: string }> { try { // Get the proposal const { data: proposal } = await supabase .from('ai_proposals') .select('*') .eq('id', approval.proposal_id) .single(); if (!proposal) { return { success: false, message: 'Proposal not found' }; } if (proposal.status !== 'pending') { return { success: false, message: 'Proposal already processed' }; } // Update proposal status const { error: updateError } = await supabase .from('ai_proposals') .update({ status: approval.human_decision === 'approve' ? 'approved' : 'rejected', human_notes: approval.human_notes, approved_by: approval.approved_by, approved_at: approval.approved_at }) .eq('id', approval.proposal_id); if (updateError) { return { success: false, message: 'Failed to update proposal' }; } // If approved, execute the action if (approval.human_decision === 'approve') { const executionResult = await this.executeApprovedAction(proposal); return { success: executionResult.success, message: `Proposal approved and ${executionResult.success ? 'executed successfully' : 'execution failed'}` }; } return { success: true, message: 'Proposal rejected by human' }; } catch (error) { console.error('Human decision processing failed:', error); return { success: false, message: 'Failed to process decision' }; } } /** * Execute approved AI actions safely */ async executeApprovedAction(proposal: AIProposal): Promise<{ success: boolean; message: string }> { try { switch (proposal.type) { case 'expense_categorization': return await this.executeExpenseCategorization(proposal.proposed_action); case 'stock_adjustment': return await this.executeStockAdjustment(proposal.proposed_action); case 'price_optimization': return await this.executePriceOptimization(proposal.proposed_action); default: return { success: false, message: 'Unknown action type' }; } } catch (error) { console.error('Action execution failed:', error); return { success: false, message: 'Execution failed' }; } } // AI Analysis Methods (the smart parts!) private async suggestExpenseCategory(expense: any) { try { const prompt = ` Categorize this chicken business expense: Description: "${expense.description}" Amount: ₱${expense.amount} Date: ${expense.date} Common categories: Feed, Supplies, Utilities, Transportation, Equipment, Marketing, Labor, Other Return JSON: { "category": "suggested_category", "confidence": 0-100, "reasoning": "why this category fits" } `; const response = await geminiAPIManager.makeRequest( { type: 'text', complexity: 'simple', priority: 'normal', requiresStructuredOutput: true }, prompt ); return JSON.parse(response.text); } catch (error) { console.warn('Category suggestion failed:', error); return null; } } private async analyzeStockNeeds(products: any[], sales: any[]) { try { const prompt = ` Analyze stock needs for chicken business: Current Products: ${JSON.stringify(products.slice(0, 5))} Recent Sales: ${JSON.stringify(sales.slice(0, 10))} For each product, determine if we need to: 1. Reorder (running low) 2. Reduce stock (slow moving) 3. Maintain current levels Return JSON: { "suggestions": [ { "product_id": "id", "product_name": "name", "action": "reorder|reduce|maintain", "current_quantity": number, "recommended_quantity": number, "confidence": 0-100, "reasoning": "explanation" } ] } `; const response = await geminiAPIManager.makeRequest( { type: 'text', complexity: 'medium', priority: 'normal', requiresStructuredOutput: true }, prompt ); return JSON.parse(response.text); } catch (error) { console.warn('Stock analysis failed:', error); return { suggestions: [] }; } } private async analyzePricingOpportunities(salesData: any[]) { try { const prompt = ` Analyze pricing opportunities for chicken business: Sales Data: ${JSON.stringify(salesData.slice(0, 15))} Look for: 1. Products selling very fast (can increase price) 2. Products selling slowly (may need price reduction) 3. Optimal pricing based on demand patterns Return JSON: { "opportunities": [ { "product_name": "name", "current_price": number, "suggested_price": number, "confidence": 0-100, "reasoning": "explanation", "expected_impact": "increase/decrease revenue" } ] } `; const response = await geminiAPIManager.makeRequest( { type: 'text', complexity: 'medium', priority: 'normal', requiresStructuredOutput: true }, prompt ); return JSON.parse(response.text); } catch (error) { console.warn('Pricing analysis failed:', error); return { opportunities: [] }; } } private async analyzeBusinessPatterns() { // Get recent business data for pattern analysis const { data: recentNotes } = await supabase .from('notes') .select('*') .gte('created_at', this.getDaysAgo(30)) .order('created_at', { ascending: false }) .limit(50); return { notes: recentNotes || [], note_count: recentNotes?.length || 0, analysis_date: new Date().toISOString() }; } private async generateProcessImprovements(patterns: any) { try { const prompt = ` Based on chicken business patterns, suggest process improvements: Recent Activity: ${patterns.note_count} business notes Pattern Data: ${JSON.stringify(patterns).substring(0, 1000)} Suggest 1-3 process improvements that could: 1. Save time 2. Reduce costs 3. Improve quality 4. Increase revenue Return JSON array: [ { "title": "improvement title", "description": "what to improve", "type": "efficiency|cost|quality|revenue", "confidence": 0-100, "reasoning": "why this helps", "steps": ["step1", "step2"], "benefit": "expected benefit" } ] `; const response = await geminiAPIManager.makeRequest( { type: 'text', complexity: 'medium', priority: 'normal', requiresStructuredOutput: true }, prompt ); return JSON.parse(response.text); } catch (error) { console.warn('Process improvement generation failed:', error); return []; } } // Execution methods private async executeExpenseCategorization(action: any) { try { const { error } = await supabase .from('expenses') .update({ category: action.new_category }) .eq('id', action.expense_id); return { success: !error, message: error ? error.message : 'Expense categorized successfully' }; } catch (error) { return { success: false, message: 'Categorization failed' }; } } private async executeStockAdjustment(action: any) { try { const { error } = await supabase .from('products') .update({ quantity: action.recommended_quantity, updated_at: new Date().toISOString() }) .eq('id', action.product_id); return { success: !error, message: error ? error.message : 'Stock adjusted successfully' }; } catch (error) { return { success: false, message: 'Stock adjustment failed' }; } } private async executePriceOptimization(action: any) { try { // In a real system, you'd update product prices // For now, just log the suggestion console.log('Price optimization executed:', action); return { success: true, message: 'Price optimization noted' }; } catch (error) { return { success: false, message: 'Price optimization failed' }; } } // Helper methods private async storeProposals(proposals: AIProposal[]) { if (proposals.length === 0) return; try { const { error } = await supabase .from('ai_proposals') .insert(proposals); if (error) { console.warn('Failed to store AI proposals:', error); } } catch (error) { console.warn('Proposal storage failed:', error); } } private getExpiryDate(days: number): string { const expiry = new Date(); expiry.setDate(expiry.getDate() + days); return expiry.toISOString(); } private getDaysAgo(days: number): string { const date = new Date(); date.setDate(date.getDate() - days); return date.toISOString(); } } // Export singleton instance export const aiAssistant = new AIAssistantService(); // Export types export type { AIProposal, ApprovalRequest };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PSYGER02/mcpserver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server