A comprehensive AI-powered finance and restaurant recommendation application built with React, Node.js, and modern AI technologies.
- Modern React Interface: Beautiful, responsive UI built with React 18 and TypeScript
- Real-time Dashboard: Live spending overview with charts and analytics
- Receipt Upload: Drag-and-drop receipt processing with AI-powered data extraction
- Interactive Reports: Visual spending analytics with charts and export options
- User Authentication: Secure login/signup with JWT token management
- Mobile-First Design: Optimized for mobile and desktop experiences
- Progressive Web App: Fast loading with offline capabilities
- Location-based Recommendations: Get personalized restaurant suggestions based on your location using Google Places API
- AI-Powered Analysis: Uses OpenAI GPT-4 and LangChain for intelligent restaurant discovery
- Menu Analysis with History: Upload menu images to get budget-friendly recommendations with user history tracking
- Social Media Integration: Analyze restaurant social media content for insights (Zhongcao)
- Legacy Menu Analysis: Public menu analysis with caching (no authentication required)
- User-Aware Transaction System: All transactions scoped to authenticated users
- Receipt Processing: Upload receipt images for automatic transaction categorization
- Bulk Upload: Process multiple receipts at once
- Transaction Tracking: Comprehensive transaction management with categories and notes
- Voucher System: Digital voucher management with status tracking
- Financial Analytics: Generate personalized insights and statistics from your spending data
- Cross-User Security: Complete data isolation between users
- JWT-Based Authentication: Secure token-based authentication system
- Token Blacklisting: Secure logout functionality that invalidates JWT tokens
- Automatic Token Cleanup: Periodic cleanup of expired blacklisted tokens
- User Session Management: Complete session control with token invalidation
- Cross-User Data Isolation: Complete data separation and access control
- Image Recognition: Extract information from restaurant photos and receipts
- Natural Language Processing: Analyze descriptions and social media content
- Recommendation Engine: AI-powered suggestions based on preferences and budget
- Google Places Integration: Real-time location data and place information
This is a monorepo containing three main packages:
nextai-finance-app-monorepo/
βββ packages/
β βββ client/ # React/Vite frontend application
β βββ schema/ # Shared Zod schemas and TypeScript types
β βββ server/ # Node.js/Express backend API
βββ package.json # Root package configuration
βββ README.md # This file
- Framework: React 18 with TypeScript
- Runtime: Node.js with npm
- Build Tool: Vite with SWC for fast development
- Styling: Tailwind CSS with shadcn/ui components
- State Management: Zustand for global state
- Routing: React Router DOM
- Charts: Recharts for data visualization
- UI Components: Comprehensive shadcn/ui component library
- Development: Hot module replacement with Vite
- Port: Runs on http://localhost:8080
- Purpose: Centralized schema validation and TypeScript types
- Technology: Zod for runtime validation
- Features: Request/response schemas, TypeScript type inference
- Usage: Imported by server package for API validation
- Framework: Express.js with TypeScript and ES modules
- Language: TypeScript with strict type checking
- Database: PostgreSQL with Prisma ORM
- AI Services: OpenAI API (GPT-4, GPT-4o-mini), LangChain, Google Places API
- Authentication: JWT-based authentication with user-aware security
- File Processing: Multer for file uploads, Sharp for image processing
- User Isolation: Complete data separation and access control
- Schema Validation: Direct TypeScript imports from shared schema package
- Development: Hot reload with nodemon and ts-node
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher) - Required for all packages
- npm (v8 or higher) - Package manager for all dependencies
- PostgreSQL database - For data storage
- Git - For version control
-
Clone the repository
git clone <repository-url> cd nextai-finance-app-monorepo
-
Install dependencies
# Install all dependencies (root, server, client, schema) npm install -
Set up environment variables
This project requires three separate .env files for different purposes. Example files are provided - copy and rename them:
# Option 1: Use the setup script (recommended) ./setup-env.sh # Option 2: Copy example files manually cp env.example.root .env cp packages/server/env.example.server packages/server/.env cp packages/client/env.example.client packages/client/.env
Then update each file with your actual API keys and database credentials:
Root
.env(Docker Compose Configuration):# Database Configuration (Production - Neon) DATABASE_URL="postgresql://neondb_owner:npg_***@ep-wild-math-***.aws.neon.tech/neondb?sslmode=require&channel_binding=require" # JWT Configuration JWT_SECRET="your-jwt-secret-key-2024" # API Keys OPENAI_API_KEY=sk-proj-*** GOOGLE_PLACES_API_KEY=AIzaSyD*** # Server Configuration NODE_ENV="production" PORT=5001 HOST=0.0.0.0 CORS_ORIGIN=*
packages/server/.env(Backend Development):# Server Configuration - Local Development PORT=5001 HOST=0.0.0.0 CORS_ORIGIN=* NODE_ENV=development # API Keys (same as root .env) JWT_SECRET="your-jwt-secret-key-2024" OPENAI_API_KEY=sk-proj-*** GOOGLE_PLACES_API_KEY=AIzaSyD*** DATABASE_URL="postgresql://neondb_owner:npg_***@ep-wild-math-***.aws.neon.tech/neondb?sslmode=require&channel_binding=require"
packages/client/.env(Frontend Build):# Backend API URL VITE_API_URL=http://localhost:5001 # Environment NODE_ENV=development
-
Build the schema package
Build the shared schema package to ensure all type definitions are available:
cd packages/schema npm run build -
Set up the database
The application uses a remote Neon PostgreSQL database. Initialize the Prisma client and verify the connection:
cd packages/server npx prisma generate npx prisma db pushNote: Database seeding is not required as the remote database is already deployed with data.
-
Verify environment setup
Ensure all three
.envfiles are properly configured with your API keys and database credentials.
From the root directory, you can start both the client and server simultaneously:
# Start both client and server in parallel
npm run devThis will start:
- Frontend (Client): http://localhost:8080
- Backend (Server): http://localhost:5001
β Success Indicators:
[0] VITE v5.4.19 ready in 529 ms
[0] β Local: http://localhost:8080/
[1] π Server running on http://localhost:5001
[1] π Health check: http://localhost:5001/health
Both services will have hot reload enabled for seamless development!
You can also run packages individually using convenient root-level scripts:
Client only:
# From root directory
npm run dev:client
# Or navigate to client directory
cd packages/client && npm run devServer only:
# From root directory
npm run dev:server
# Or navigate to server directory
cd packages/server && npm run devSchema package (for development):
npm run dev --workspace=schemaAll commands run from the project root directory:
| Command | Description |
|---|---|
npm run dev |
Start both client + server β |
npm run dev:client |
Start client only |
npm run dev:server |
Start server only |
π‘ Tip: Use npm run dev for the full-stack development experience!
Generate Prisma client:
cd packages/server
npx prisma generateRun database migrations:
cd packages/server
npx prisma db pushSeed the database (Optional - Remote database already contains data):
cd packages/server
npm run seedNote: The remote Neon database is already populated with data, so seeding is typically not needed.
Open Prisma Studio:
cd packages/server
npx prisma studio"Prisma client not initialized" error:
cd packages/server
npx prisma generate"Could not resolve ./types/zhongcao" error:
cd packages/schema
npm run buildDatabase connection issues:
- Verify your
DATABASE_URLin.envfiles - Ensure the remote database is accessible
- Check network connectivity to Neon database
Start client development server:
cd packages/client
npm run devBuild client for production:
cd packages/client
# Production build
npm run build
# Development build
npm run build:devRun client tests:
cd packages/client
# Run tests
npm test
# Run tests in watch mode
npm run test:watchCode quality and linting:
cd packages/client
# Lint code
npm run lint
# Type checking
npm run type-check
# Format code
npm run format
# Run all checks (lint + build)
npm run check
# Clean install (removes node_modules and reinstalls)
npm run install:cleanPreview production build:
cd packages/client
npm run previewBuild schema package:
cd packages/schema
npm run buildWatch mode for schema development:
cd packages/schema
npm run devRun all tests:
cd packages/server
npm testRun tests in watch mode:
cd packages/server
npm run test:watchRun tests with coverage:
cd packages/server
npm run test:coverageRun recommendation tests:
cd packages/server
npm run test:recoclient/
βββ src/
β βββ components/ # React components
β β βββ ui/ # shadcn/ui components
β β βββ TopNavigation.tsx
β β βββ BottomNavigation.tsx
β β βββ ProtectedRoute.tsx
β βββ pages/ # Application pages
β β βββ Home.tsx # Dashboard
β β βββ Login.tsx # Authentication
β β βββ AddExpense.tsx # Expense management
β β βββ Reports.tsx # Analytics
β β βββ Recommendations.tsx # Restaurant recommendations
β β βββ Profile.tsx # User settings
β βββ contexts/ # React contexts
β β βββ AuthContext.tsx
β βββ hooks/ # Custom React hooks
β βββ store/ # Zustand state management
β β βββ slices/ # State slices
β βββ utils/ # Utility functions
β βββ assets/ # Static assets
β βββ lib/ # Library configurations
β βββ main.tsx # Application entry point
β βββ App.tsx # Root component
βββ public/ # Public assets
βββ index.html # HTML template
βββ vite.config.ts # Vite configuration
βββ tailwind.config.ts # Tailwind CSS configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Client dependencies
schema/
βββ src/
β βββ types/ # Zod schemas and TypeScript types
β β βββ auth.ts # Authentication schemas
β β βββ transaction.ts # Transaction schemas
β β βββ recommendation.ts # Recommendation schemas
β βββ category.ts # Category schemas
β βββ merchant.ts # Merchant schemas
β βββ index.ts # Main export file
βββ dist/ # Compiled JavaScript output
βββ tsconfig.json # TypeScript configuration
βββ package.json # Schema package dependencies
server/
βββ src/
β βββ config/ # Application configuration
β β βββ app.ts # App configuration (TypeScript)
β β βββ database.ts # Database configuration (TypeScript)
β β βββ openai.ts # OpenAI configuration (TypeScript)
β βββ models/ # Database models and Prisma schema
β β βββ database/ # Prisma schema and migrations
β β β βββ client.ts # Database client (TypeScript)
β β β βββ schema.prisma # Prisma schema
β β β βββ migrations/ # Database migrations
β β βββ entities/ # Database entity models (TypeScript)
β β β βββ Profile.ts
β β β βββ Transaction.ts
β β β βββ Voucher.ts
β β β βββ Restaurant.ts
β β βββ index.ts # Models export (TypeScript)
β βββ routes/ # API route handlers (TypeScript)
β β βββ auth/ # Authentication routes
β β βββ restaurant/ # Restaurant-related routes
β β βββ transaction/ # Transaction management routes
β β βββ insights/ # Financial insights routes
β β βββ middleware/ # Express middleware
β βββ services/ # Business logic services (TypeScript)
β β βββ ai/ # AI service integrations
β β βββ auth/ # Authentication services
β β βββ restaurant/ # Restaurant services
β β βββ transaction/ # Transaction services
β β βββ insights/ # Financial insights services
β βββ utils/ # Utility functions (TypeScript)
β β βββ validation/ # Validation utilities
β β βββ upload/ # File upload utilities
β β βββ cache/ # Caching utilities
β β βββ errors/ # Error handling utilities
β β βββ logging/ # Logging utilities
β βββ server.ts # Express server entry point (TypeScript)
β βββ index.ts # Main application entry (TypeScript)
βββ uploads/ # File upload directory
βββ jest.config.js # Jest configuration
βββ nodemon.json # Nodemon configuration for TypeScript
βββ tsconfig.json # TypeScript configuration
βββ package.json # Server dependencies
Below is a detailed list of all available API endpoints for developers.
Registers a new user.
- Authentication: None
- Request Body:
{ "email": "user@example.com", "password": "a-strong-password", "firstName": "John", "lastName": "Doe" } - Success Response (
201 Created):{ "message": "User registered successfully", "userId": 1, "token": "jwt.token.string" } - Error Responses:
400 Bad Request: If email, password, firstName, or lastName are invalid.409 Conflict: If the email is already registered.
Logs in an existing user.
- Authentication: None
- Request Body:
{ "email": "user@example.com", "password": "a-strong-password" } - Success Response (
200 OK):{ "message": "Login successful", "userId": 1, "token": "jwt.token.string", "profileComplete": true } - Error Responses:
401 Unauthorized: If credentials are invalid.
Logs out the authenticated user by blacklisting their JWT token.
- Authentication: Required (
x-auth-tokenheader) - Request Body:
{ "token": "jwt.token.string" } - Success Response (
200 OK):{ "message": "Logout successful", "success": true } - Error Responses:
400 Bad Request: If token is missing or invalid401 Unauthorized: If authentication token is invalid500 Internal Server Error: If logout process fails
Creates or updates a user's profile.
- Authentication: Required (
x-auth-tokenheader) - Request Body:
{ "monthlyBudget": 2000, "monthlyIncome": 5000, "expensePreferences": { "categories": { "Food": 0.4, "Transport": 0.2, "Shopping": 0.2, "Utilities": 0.1, "Other": 0.1 } }, "savingsGoals": { "goalAmount": 10000, "targetDate": "2026-12-31" }, "lifestylePreferences": { "diningStyle": "Casual", "hobbies": ["Reading", "Hiking"] } } - Success Response (
201 Created):{ "message": "Profile saved successfully", "profileId": "some-uuid", "profileComplete": true } - Error Responses:
400 Bad Request: If required profile fields are missing. Example:{ "message": "Missing required profile fields: monthlyBudget, monthlyIncome" }
Retrieves the authenticated user's profile.
- Authentication: Required (
x-auth-tokenheader) - Success Response (
200 OK):{ "id": "some-uuid", "userId": 1, "name": "John Doe", "preferences": { "cuisine": ["Italian", "Japanese"], "diningStyle": "Casual" }, "budget": { "min": 20, "max": 50 } } - Error Responses:
404 Not Found: If the user does not have a profile.
Retrieves blacklist statistics and cleanup service status.
- Authentication: Required (
x-auth-tokenheader) - Success Response (
200 OK):{ "blacklist": { "totalBlacklisted": 15, "recentBlacklisted": 3, "inMemoryCount": 15 }, "cleanup": { "isRunning": true, "lastCleanup": "2023-10-28T10:00:00.000Z" } }
Manually triggers cleanup of expired blacklisted tokens.
- Authentication: Required (
x-auth-tokenheader) - Success Response (
200 OK):{ "message": "Cleanup completed successfully" }
Starts the automatic cleanup service.
- Authentication: Required (
x-auth-tokenheader) - Request Body (optional):
{ "intervalHours": 24 } - Success Response (
200 OK):{ "message": "Cleanup service started", "intervalHours": 24 }
Stops the automatic cleanup service.
- Authentication: Required (
x-auth-tokenheader) - Success Response (
200 OK):{ "message": "Cleanup service stopped" }
Retrieves a list of transactions for the authenticated user.
- Authentication: Required
- Query Parameters:
category(string, optional): Filter by category.startDate(string, optional): ISO 8601 date.endDate(string, optional): ISO 8601 date.limit(number, optional): Number of records to return.offset(number, optional): Number of records to skip.
- Success Response (
200 OK):{ "transactions": [ { "id": 1, "user_id": 1, "amount": 50.0, "category": "Food", "date": "2023-10-27T12:00:00.000Z", "merchant": "Restaurant" } ], "count": 1, "userId": 1 }
Creates a new manual transaction.
- Authentication: Required
- Request Body:
{ "amount": 75.5, "category": "Shopping", "date": "2023-10-28", "merchant": "Mall", "source": "manual" } - Success Response (
201 Created):{ "message": "Transaction created successfully", "transaction": { ... } // Transaction object } - Error Responses:
400 Bad Request: If required fields are missing. Example:{ "error": "Missing required field: source" }
Retrieves a single transaction by its ID.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
200 OK):{ "transaction": { ... } // Transaction object } - Error Responses:
404 Not Found: If transaction with that ID doesn't exist or doesn't belong to the user.
Updates a transaction.
- Authentication: Required
- URL Parameters:
id(number) - Request Body: Any subset of transaction fields.
{ "amount": 85.0, "category": "Food", "merchant": "Updated Restaurant Name" } - Success Response (
200 OK):{ "message": "Transaction updated successfully", "transaction": { ... } // Updated transaction object }
Deletes a transaction.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
200 OK):{ "message": "Transaction deleted successfully" }
Retrieves statistics for the user's transactions.
- Authentication: Required
- Query Parameters:
startDate(string, optional)endDate(string, optional)
- Success Response (
200 OK):{ "stats": { "totalTransactions": 10, "totalSpent": 1234.56, "averageTransaction": 123.45 } }
Retrieves a list of all available transaction categories.
- Authentication: None
- Success Response (
200 OK):{ "categories": ["Food", "Transport", "Shopping", ...] }
Uploads a single receipt image for processing.
- Authentication: Required
- Request Body:
multipart/form-datawith a single file field namedreceipt. - Success Response (
201 Created):{ "message": "Receipt uploaded and processed successfully", "voucher": { ... }, "transaction": { ... }, "parsedData": { ... } } - Error Responses:
400 Bad Request: If no file is uploaded or the file type is invalid.422 Unprocessable Entity: If the AI successfully processes the image but cannot find the required fields (e.g., merchant, total_amount).500 Internal Server Error: If an unexpected error occurs during processing, such as a failure to communicate with the AI service.
Uploads multiple receipt images (up to 10) for processing.
- Authentication: Required
- Request Body:
multipart/form-datawith a file field namedreceipts. - Success Response (
201 Created):{ "message": "Processed 9 receipts successfully, 1 failed", "summary": { "successful": 9, "failed": 1, "total": 10 }, "results": [ ... ], "errors": [ ... ] }
Get personalized restaurant recommendations based on location.
- Authentication: Required
- Query Parameters:
location(string, required): Location to search for restaurants
- Success Response (
200 OK):{ "message": "Personalized restaurant recommendations", "location": "downtown Los Angeles", "personalized": true, "recommendations": [ { "name": "Bestia", "address": "2121 E 7th Pl, Los Angeles, CA 90021", "phone": "(213) 514-5724", "website": "bestiala.com", "googleMapsLink": "https://www.google.com/maps/...", "reason": "Great for seafood lovers like you", "cuisine": "Italian", "priceRange": "$$$", "rating": "4.5" } ] }
Analyzes a menu image and provides budget-based recommendations with user history tracking.
- Authentication: Required (
x-auth-tokenheader) - Request Body:
multipart/form-datawith fields:image(file): The menu image.budget(number): The budget for the meal.userNote(string, optional): Additional notes for the AI.
- Success Response (
200 OK):{ "message": "Menu analysis completed successfully", "cached": false, "menuInfo": { "currency": "$", "items": [ { "name": "THE GREEK ANGEL", "price": 24.95, "description": "spaghettini, tomato sauce, fresh herbs", "category": "Pasta" } ] }, "recommendation": { ... } }
Get user's menu analysis history.
- Authentication: Required
- Query Parameters:
limit(number, optional): Number of records to return (default: 50)offset(number, optional): Number of records to skip (default: 0)includeUser(boolean, optional): Include user data in response
- Success Response (
200 OK):{ "message": "Menu analysis history retrieved successfully", "analyses": [ ... ], "count": 10 }
Get specific menu analysis by ID.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
200 OK):{ "message": "Menu analysis retrieved successfully", "analysis": { ... } } - Error Responses:
404 Not Found: Menu analysis not found or access denied
Update menu analysis notes or budget.
- Authentication: Required
- URL Parameters:
id(number) - Request Body:
{ "userNote": "Updated note about this menu analysis", "budget": 30 } - Success Response (
200 OK):{ "message": "Menu analysis updated successfully", "analysis": { ... } }
Delete menu analysis from history.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
204 No Content)
Get user's menu analysis statistics.
- Authentication: Required
- Success Response (
200 OK):{ "message": "Menu analysis statistics retrieved successfully", "stats": { "totalAnalyses": 15, "fallbackAnalyses": 2, "successfulAnalyses": 13, "averageBudget": 27.5, "recentAnalyses": 8, "successRate": "86.7" } }
Analyzes a restaurant image from social media to extract details.
- Authentication: Required (
x-auth-tokenheader) - Request Body:
multipart/form-datawith a single file field namedimage. - Success Response (
201 Created):{ "message": "Image processed successfully", "result": { ... }, // The created database record "extractedInfo": { ... } // The raw data from AI }
Get all zhongcao results for authenticated user.
- Authentication: Required
- Success Response (
200 OK):[ { "id": 1, "user_id": 4, "restaurantName": "Sample Restaurant", "dishName": "Special Dish", "address": "123 Main St", "description": "Great restaurant experience", "socialMediaHandle": "@restaurant_handle", "createdAt": "2025-08-30T06:38:26.081Z" } ]
Get specific zhongcao result by ID.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
200 OK):{ "id": 1, "user_id": 4, "restaurantName": "Sample Restaurant" // ... other fields } - Error Responses:
404 Not Found: Zhongcao result not found or access denied
Update zhongcao result.
- Authentication: Required
- URL Parameters:
id(number) - Request Body:
{ "restaurantName": "Updated Restaurant Name", "dishName": "Updated Dish Name", "address": "Updated Address", "description": "Updated description", "socialMediaHandle": "@updated_handle" } - Success Response (
200 OK):{ "id": 1, "user_id": 4, "restaurantName": "Updated Restaurant Name" // ... updated fields }
Delete zhongcao result.
- Authentication: Required
- URL Parameters:
id(number) - Success Response (
204 No Content)
Get last cached recommendation.
- Authentication: None
- Success Response (
200 OK):{ "menuInfo": { ... }, "recommendation": { ... }, "budget": 25, "timestamp": "2025-08-30T06:38:26.081Z" }
Re-recommend with new budget using cached menu.
- Authentication: None
- Request Body:
{ "budget": 30, "note": "Updated budget preferences" } - Success Response (
200 OK):{ "menuInfo": { ... }, "recommendation": { ... } }
Get spending summary for authenticated user.
- Authentication: Required
- Query Parameters:
period(string, optional): Time period (monthly, yearly, etc.)category(string, optional): Filter by categorystartDate(string, optional): Start date (ISO 8601)endDate(string, optional): End date (ISO 8601)
- Success Response (
200 OK):{ "success": true, "data": { "userId": 4, "period": "monthly", "summary": { "totalTransactions": 9, "totalAmount": 721.76, "averageAmount": 80.20 }, "periodBreakdown": [ ... ] } }
Get category analysis for authenticated user.
- Authentication: Required
- Query Parameters:
startDate(string, optional): Start dateendDate(string, optional): End datelimit(number, optional): Number of categories to return
- Success Response (
200 OK):{ "success": true, "data": { "categories": [ ... ], "totalAmount": 1234.56 } }
Get merchant analysis for authenticated user.
- Authentication: Required
- Query Parameters: Same as categories
- Success Response (
200 OK):{ "success": true, "data": { "merchants": [ ... ], "totalAmount": 1234.56 } }
Get spending trends for authenticated user.
- Authentication: Required
- Query Parameters:
period(string, optional): Time period for trendsperiods(number, optional): Number of periods to analyze
- Success Response (
200 OK):{ "success": true, "data": { "trends": [ ... ], "period": "monthly" } }
Get budget analysis for authenticated user.
- Authentication: Required
- Query Parameters:
monthlyBudget(number, required): Monthly budget amountmonth(string, optional): Specific month to analyze
- Success Response (
200 OK):{ "success": true, "data": { "budgetAnalysis": { ... }, "monthlyBudget": 2000 } }
Get comprehensive dashboard data for authenticated user.
- Authentication: Required
- Query Parameters:
monthlyBudget(number, optional): Monthly budget for budget analysis
- Success Response (
200 OK):{ "success": true, "data": { "summary": { ... }, "topCategories": [ ... ], "trends": [ ... ], "budget": { ... } } }
Your project requires three separate .env files because each serves a different purpose:
- Purpose: Used by Docker Compose for container orchestration
- Location:
/.env - Contains: Database URLs, API keys, Docker-specific variables
- Purpose: Server-specific runtime configuration
- Location:
/packages/server/.env - Contains: Server host/port, CORS settings, API keys, database connection
- Purpose: Vite build-time environment variables
- Location:
/packages/client/.env - Contains:
VITE_*prefixed variables for frontend build
To get started quickly, use the provided example files:
# Copy example files and rename them
cp env.example.root .env
cp packages/server/env.example.server packages/server/.env
cp packages/client/env.example.client packages/client/.env
# Then edit each file with your actual values:
# - Database URL from Neon (https://neon.tech/)
# - OpenAI API key (https://platform.openai.com/api-keys)
# - Google Places API key (https://developers.google.com/maps/documentation/places/web-service/get-api-key)# Database Configuration (Production - Neon)
DATABASE_URL="postgresql://neondb_owner:npg_***@ep-wild-math-***.aws.neon.tech/neondb?sslmode=require&channel_binding=require"
# JWT Configuration
JWT_SECRET="your-jwt-secret-key-2024"
# API Keys
OPENAI_API_KEY=sk-proj-***
GOOGLE_PLACES_API_KEY=AIzaSyD***
# Server Configuration
NODE_ENV="production"
PORT=5001
HOST=0.0.0.0
CORS_ORIGIN=*
# For Docker Compose - PostgreSQL (local database alternative)
POSTGRES_DB="nextai_finance"
POSTGRES_USER="nextai_user"
POSTGRES_PASSWORD="nextai_password"# Server Configuration - Local Development
PORT=5001
HOST=0.0.0.0
CORS_ORIGIN=*
NODE_ENV=development
# API Keys (same as root .env)
JWT_SECRET="your-jwt-secret-key-2024"
OPENAI_API_KEY=sk-proj-***
GOOGLE_PLACES_API_KEY=AIzaSyD***
DATABASE_URL="postgresql://neondb_owner:npg_***@ep-wild-math-***.aws.neon.tech/neondb?sslmode=require&channel_binding=require"# Backend API URL
VITE_API_URL=http://localhost:5001
# Environment
NODE_ENV=development- Update
VITE_API_URLto your production server URL - Set
NODE_ENV=productionin appropriate files - Ensure all sensitive keys are properly secured
- Use
localhostURLs for local development - Set
NODE_ENV=developmentfor better debugging
- Never commit .env files to version control (already in .gitignore)
- API keys are currently visible - consider using environment variable injection for production
- Database credentials should be rotated regularly
- Server IP changes: Update
VITE_API_URLin client .env - Database migration: Update
DATABASE_URLin root and server .env - API key rotation: Update keys in root and server .env
- Environment changes: Update
NODE_ENVappropriately
A comprehensive Postman collection is available at /postman/NextAI_Finance_App.postman_collection.json with all endpoints pre-configured:
- Import the collection into Postman
- Set environment variables:
baseUrl:http://localhost:5001authToken: Your JWT token from login/register
- Test all endpoints including:
- Authentication (register, login, profile)
- Transactions with full CRUD operations
- Financial insights and analytics
- Restaurant recommendations (with/without auth)
- Menu analysis with history tracking
- Zhongcao social media analysis
- Legacy menu analysis endpoints
cd packages/server
npm run test:recocd packages/server
npm testcd packages/schema
npm run buildcd packages/server
npm start- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow the existing code style and structure
- Add appropriate error handling
- Include comments for complex logic
- Test your changes thoroughly
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
If you encounter any issues or have questions:
- Check the existing issues in the repository
- Create a new issue with detailed information
- Include error messages, steps to reproduce, and environment details
-
v3.0.0 - TypeScript Conversion & Optimization
- β Complete backend conversion from JavaScript to TypeScript
- β Direct schema imports without build process
- β Enhanced type safety across entire codebase
- β Improved developer experience with IntelliSense and compile-time error detection
- β Streamlined development workflow with npm-only setup
- β Updated project structure and documentation
- β Hot reload support with TypeScript development server
-
v2.0.0 - Major User-Aware Refactor
- β Complete user-aware authentication system implemented
- β All transactions, menu analyses, and zhongcao results scoped to authenticated users
- β Menu analysis history tracking with full CRUD operations
- β Financial insights with user isolation and personalization
- β Enhanced error handling with proper HTTP status codes
- β Comprehensive API documentation and Postman collection
- β Cross-user security and data isolation
- β Database migrations for user relationships
- β Legacy endpoints maintained for backward compatibility
-
v1.0.0 - Initial release with restaurant recommendations and transaction management
- OpenAI for AI capabilities
- Google Places API for location services
- Prisma for database management
- React and Express.js communities
Note: Make sure to replace placeholder values (API keys, database URLs) with your actual credentials before running the application.