ManualAI is a comprehensive AI-powered restaurant management platform designed to streamline operations for restaurant owners and managers. The platform provides end-to-end solutions for inventory management, order processing, staff hiring, marketing campaigns, and financial tracking—all enhanced with artificial intelligence to provide predictive insights and automation.
- Intelligent Inventory Management: Real-time stock tracking with AI-powered forecasting and automated reordering
- Order Management System: Multi-channel order processing with WhatsApp integration
- Smart Hiring Platform: AI-assisted recruitment with automated candidate screening
- Marketing Automation: Campaign management with AI-generated content and audience targeting
- Financial Dashboard: Comprehensive transaction tracking and financial analytics
- Real-time Notifications: Multi-channel alerts for critical business events
- AI Insights Engine: Predictive analytics for sales, inventory, and operational optimization
- React 19 - Modern UI library with latest features
- TypeScript - Type-safe development
- Vite - Next-generation frontend tooling
- Tailwind CSS 4 - Utility-first styling framework
- Radix UI - Accessible component primitives
- Lucide React - Icon library
- Recharts - Data visualization
- Framer Motion - Animation library
- Convex - Real-time backend-as-a-service with reactive queries
- Clerk - Authentication and user management
- ESLint - Code linting
- Prettier - Code formatting
- TypeScript ESLint - TypeScript-specific linting rules
- Node.js 18+
- npm or yarn package manager
- Convex account
- Clerk account
# Install dependencies
npm install
# Set up environment variables
cp .env.local.example .env.local
# Add your Convex and Clerk credentials
# Start development server
npm run dev
# Start Convex backend (in separate terminal)
npm run convex:devVITE_CONVEX_URL=your_convex_deployment_url
CONVEX_DEPLOYMENT=your_convex_deployment_id
VITE_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_ISSUER_URL=your_clerk_issuer_urlThe platform uses Convex as its real-time database with the following core tables:
Stores user account information and integration settings.
Fields:
name(string) - User's full nameemail(string) - User's email addressexternalId(string) - Clerk authentication IDimageUrl(string, optional) - Profile picture URLintegrations(object, optional) - Third-party service connectionszomato- Zomato integration statusmeta- Meta/Facebook integration status
status(enum) - Account status:active,suspended,blockedcreatedAt(number) - Unix timestampupdatedAt(number) - Unix timestamp
Indexes:
byExternalId- Query users by Clerk IDbyStatus- Filter users by account status
Restaurant profile and configuration data.
Fields:
name(string) - Restaurant nameownerId(id) - Reference to users tableaddress(string) - Physical addressgstNumber(string, optional) - GST registration numberlogoUrl(string, optional) - Restaurant logo URLphone(string) - Contact numberwhatsappNumber(string, optional) - WhatsApp business numberwhatsappVerified(boolean) - WhatsApp verification statusplan(enum) - Subscription tier:starter,professional,enterpriseisActive(boolean) - Restaurant operational statussettings(object) - Notification preferenceslowStockAlert(boolean)newOrderPing(boolean)campaignSummaryEmail(boolean)
Indexes:
by_owner- Query restaurants by owner
Stock management and tracking.
Fields:
restaurantId(id) - Reference to restaurants tablename(string) - Item namesupplierId(id) - Reference to suppliers tablecurrentStock(number) - Current quantityminimumStock(number) - Reorder thresholdunit(string) - Measurement unit (kg, liters, pieces, etc.)status(enum) - Stock level:in-stock,low-stock,out-of-stockautoReorder(boolean) - Enable automatic reorderingpreferredQuantity(number) - Default order quantitylastRestocked(number, optional) - Last restock timestampaiForecasting(object, optional) - AI predictionspredictedRunoutDate(number) - Estimated depletion daterecommendedOrderQuantity(number) - Suggested order amountconfidence(number) - Prediction confidence score (0-1)
Indexes:
by_restaurant- Query inventory by restaurantby_status- Filter by stock status
Customer order management.
Fields:
restaurantId(id) - Reference to restaurants tableorderNumber(string) - Unique order identifierwhatsappId(string, optional) - WhatsApp message IDcustomerName(string) - Customer namecustomerPhone(string) - Contact numberitems(array) - Order itemsname(string) - Item namequantity(number) - Quantity orderedprice(number) - Item pricemodifiers(array, optional) - Customizations
totalAmount(number) - Total order valuestatus(enum) - Order state:new,preparing,ready,completed,cancelledpaymentStatus(enum) - Payment state:paid,cod,pendingorderType(enum) - Service type:dine-in,takeaway,deliverycreatedAt(number) - Order creation timestampupdatedAt(number) - Last update timestampcompletedAt(number, optional) - Completion timestampestimatedTime(number, optional) - Preparation time in minutes
Indexes:
by_restaurant- Query orders by restaurantby_status- Filter by order statusby_date- Sort by creation date
Employee management and records.
Fields:
restaurantId(id) - Reference to restaurants tableuserId(id, optional) - Reference to users table (if registered)name(string) - Employee nameemail(string) - Email addressphone(string) - Contact numberrole(enum) - Position:owner,manager,chef,staffstatus(enum) - Employment status:active,pending,inactive,on-leavehireDate(number) - Employment start datesalary(number, optional) - Compensation amountrating(number, optional) - Performance rating
Indexes:
by_restaurant- Query staff by restaurantby_status- Filter by employment status
Recruitment listings and management.
Fields:
restaurantId(id) - Reference to restaurants tabletitle(string) - Job titledepartment(string) - Department/categorytype(enum) - Employment type:full-time,part-time,contractdescription(string) - Job descriptionrequirements(array) - Required qualificationssalary(string, optional) - Compensation rangestatus(enum) - Posting status:active,paused,closedurgency(enum) - Priority level:high,medium,lowpostedDate(number) - Publication timestampclosedDate(number, optional) - Closure timestampaiOptimized(object, optional) - AI-enhanced contentoptimizedTitle(string) - AI-improved titleoptimizedDescription(string) - AI-enhanced descriptiontargetAudience(array) - Recommended audience segments
Indexes:
by_restaurant- Query postings by restaurantby_status- Filter by posting status
Candidate applications and screening.
Fields:
jobPostingId(id) - Reference to jobPostings tablerestaurantId(id) - Reference to restaurants tableapplicantName(string) - Candidate nameemail(string) - Contact emailphone(string) - Contact numberlocation(string, optional) - Candidate locationexperience(number) - Years of experienceskills(array) - Skill setresume(string, optional) - Resume URLcoverLetter(string, optional) - Cover letter textstatus(enum) - Application state:new,under-review,interview-scheduled,shortlisted,rejected,hiredappliedDate(number) - Application timestampaiScreening(object, optional) - AI evaluationscore(number) - Candidate score (0-100)strengths(array) - Identified strengthsconcerns(array) - Potential concernsrecommendation(string) - AI recommendation
Indexes:
by_job- Query applications by job postingby_restaurant- Query applications by restaurantby_status- Filter by application status
Campaign management and analytics.
Fields:
restaurantId(id) - Reference to restaurants tablename(string) - Campaign namegoal(enum) - Campaign objective:repeat-orders,clear-stock,festive-offer,new-customersaudience(array) - Target audience segmentsmessage(string) - Campaign messagechannel(enum) - Communication channel:whatsapp,sms,emailscheduledDate(number) - Scheduled send timestatus(enum) - Campaign state:draft,scheduled,sent,completed,cancelledstats(object, optional) - Campaign metricssent(number) - Messages sentdelivered(number) - Successful deliveriesread(number) - Messages readclicked(number) - Link clicksconverted(number) - Conversionsrevenue(number) - Generated revenue
aiGenerated(object, optional) - AI-generated contentcontentVariants(array) - Message variationsbestPerformingVariant(string, optional) - Top performeraudienceInsights(string, optional) - Audience analysis
createdAt(number) - Creation timestamp
Indexes:
by_restaurant- Query campaigns by restaurantby_status- Filter by campaign status
Financial records and accounting.
Fields:
restaurantId(id) - Reference to restaurants tabletype(enum) - Transaction type:income,expensecategory(string) - Transaction categorydescription(string) - Transaction detailsamount(number) - Transaction amountdate(number) - Transaction datepaymentMethod(string, optional) - Payment method usedreferenceId(string, optional) - External referenceorderId(id, optional) - Reference to orders tablepurchaseOrderId(id, optional) - Reference to purchaseOrders table
Indexes:
by_restaurant- Query transactions by restaurantby_type- Filter by transaction typeby_date- Sort by transaction date
Predictive analytics and recommendations.
Fields:
restaurantId(id) - Reference to restaurants tabletype(enum) - Insight category:inventory-forecast,sales-prediction,hiring-recommendation,marketing-suggestioninsight(string) - Insight descriptionconfidence(number) - Confidence score (0-1)actionable(boolean) - Whether insight requires actiondata(any) - Supporting datacreatedAt(number) - Generation timestampexpiresAt(number, optional) - Expiration timestamp
Indexes:
by_restaurant- Query insights by restaurantby_type- Filter by insight type
Convex functions are located in the convex/ directory and provide server-side logic for data operations.
- users.ts - User management operations
- restaurants.ts - Restaurant CRUD operations
- inventory.ts - Inventory tracking and forecasting
- orders.ts - Order processing and management
- hiring.ts - Job posting and application management
- marketing.ts - Campaign creation and analytics
- finances.ts - Transaction recording and reporting
- dashboard.ts - Aggregated dashboard data
// Example: Fetching restaurant data
import { useQuery } from "convex/react";
import { api } from "../convex/_generated/api";
const restaurant = useQuery(api.restaurants.get, {
restaurantId: "restaurant_id_here"
});// Example: Creating an order
import { useMutation } from "convex/react";
import { api } from "../convex/_generated/api";
const createOrder = useMutation(api.orders.create);
await createOrder({
restaurantId: "restaurant_id",
customerName: "John Doe",
items: [{ name: "Pizza", quantity: 2, price: 15.99 }],
totalAmount: 31.98,
orderType: "delivery"
});The platform uses Clerk for authentication with the following flow:
- Sign Up → User creates account via Google, Apple, or email/password
- Redirect to Sign In → After signup, user is redirected to sign-in page
- Sign In → User authenticates and is redirected to dashboard
- Session Management → Clerk maintains secure session with JWT tokens
- User Sync → User data is synchronized with Convex database
All routes except /sign-in and /sign-up require authentication. Unauthenticated users are automatically redirected to the sign-in page.
# Start development server
npm run dev
# Start Convex backend
npm run convex:dev
# Build for production
npm run build
# Deploy Convex functions
npm run convex:deploy
# Run linter
npm run lint
# Format code
npm run format
# Check formatting
npm run format:checkManualAI_Frontend/
├── convex/ # Convex backend functions
│ ├── schema.ts # Database schema definition
│ ├── users.ts # User operations
│ ├── restaurants.ts # Restaurant operations
│ ├── inventory.ts # Inventory management
│ ├── orders.ts # Order processing
│ ├── hiring.ts # Recruitment functions
│ ├── marketing.ts # Campaign management
│ ├── finances.ts # Financial operations
│ └── dashboard.ts # Dashboard aggregations
├── src/
│ ├── components/ # React components
│ │ ├── auth/ # Authentication components
│ │ ├── generated/ # Dashboard components
│ │ └── ui/ # Reusable UI components (Radix)
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Utility functions
│ ├── providers/ # Context providers
│ ├── settings/ # App configuration
│ ├── App.tsx # Main application component
│ └── main.tsx # Application entry point
├── package.json # Dependencies and scripts
├── vite.config.ts # Vite configuration
└── tsconfig.json # TypeScript configuration
This project follows standard React and TypeScript best practices. When contributing:
- Follow the existing code style
- Use TypeScript for type safety
- Write descriptive commit messages
- Test changes thoroughly before submitting
- Update documentation for new features
Proprietary - All rights reserved
For technical support or questions, please contact the development team or refer to the internal documentation portal.