This document describes the IDS API server with product management and AI-powered chat functionality using vector embeddings.
IDS (Israel Defense Store API) is a tactical gear e-commerce API server that provides:
- Vector-based semantic product search using OpenAI embeddings
- AI-powered chat assistant for product recommendations
- Email conversation import and context enhancement (NEW!)
- Health monitoring endpoints
- Swagger/OpenAPI documentation
- Static web interface for customer support
The API includes comprehensive Swagger/OpenAPI documentation that can be accessed at:
Swagger UI: http://localhost:8080/swagger/index.html
- GET
/- Static UI (AI Assistant chatbot interface) - GET
/swagger/- Swagger UI documentation
- GET
/api/- Root API endpoint with service information - GET
/api/healthz- Basic health check - GET
/api/healthz/db- Database health check - POST
/api/chat- Chat with AI assistant using enhanced vector search (products + email conversation context)
- Go 1.25.0 or higher
- MariaDB/MySQL database
- OpenAI API key (for chat functionality)
-
Clone the repository
-
Copy
.env.exampleto.envand configure:cp .env.example .env
-
Update the
.envfile with your configuration:DATABASE_URL=mysql://username:password@localhost:3306/database_name OPENAI_API_KEY=your_openai_api_key_here PORT=8080
-
Build and run:
# Build the server make build # Run the server make run # Or run in development mode make dev
-
Initialize embeddings (required for vector search):
# Build the embeddings initialization tool make build-embeddings # Run it to generate embeddings for all products ./bin/init-embeddings-write
To regenerate the Swagger documentation:
# Install swag tool (if not already installed)
make install-tools
# Generate documentation
make swaggerOr use the script directly:
./scripts/generate-swagger.shThe Dockerfile automatically generates Swagger documentation during the build process:
# Build Docker image (Swagger docs generated automatically)
make docker-build
# Or build with pre-generated Swagger docs
make docker-build-with-swagger
# Or use Docker directly
docker build -t ids-api .The Docker build process:
- Installs the
swagtool - Generates fresh Swagger documentation
- Builds the application with the generated docs
- Creates a production-ready image
The IDS API uses OpenAI's text embeddings to provide intelligent, semantic product search. This enables the AI assistant to understand user queries and recommend the most relevant products based on meaning rather than just keywords.
- Embedding Generation: Product information (title, description, tags, prices) is converted into vector embeddings using OpenAI's
text-embedding-3-smallmodel - Storage: Embeddings are stored in the
product_embeddingstable in MariaDB - Semantic Search: User queries are converted to embeddings and compared using cosine similarity
- Smart Ranking: Products are ranked by similarity score, with in-stock items prioritized
- Context-Aware Responses: The top 15 most relevant products are provided to the AI for generating responses
The init-embeddings-write command generates and stores embeddings for all products in the database:
# Build the embeddings tool
make build-embeddings
# Run embedding generation
./bin/init-embeddings-writeThis command:
- Creates the
product_embeddingstable if it doesn't exist - Fetches all published and private products from the database
- Generates embeddings in batches of 100 products
- Stores embeddings in JSON format
- Can be run on-demand or scheduled (includes built-in daily execution mode)
Note: The command requires write access to the database and will create the necessary tables automatically.
The system can import email conversations (EML and MBOX files) and use them to enhance chat responses. The AI learns from past customer interactions to provide better, more contextual answers.
- Parse Email Files: Import individual EML files or entire MBOX archives
- Thread Detection: Automatically groups related emails into conversations
- Vector Embeddings: Generate semantic embeddings for intelligent search
- Enhanced Chat: Chat responses enhanced with insights from similar past conversations
- Dual Search: Searches both products AND relevant email history
# Build the email import tool
make build-import-emails
# Import EML files from a directory
./bin/import-emails -eml /path/to/emails/directory
# Import MBOX file (e.g., Gmail export)
./bin/import-emails -mbox /path/to/mailbox.mbox
# Import without generating embeddings (faster)
./bin/import-emails -eml /path/to/emails -embeddings=falseThe chat endpoint combines product search with email context:
curl -X POST http://localhost:8080/api/chat \
-H "Content-Type: application/json" \
-d '{
"conversation": [
{
"role": "user",
"message": "I need an OWB holster for Glock 19"
}
]
}'The AI will:
- Find similar products using vector search
- Find similar past email conversations
- Use insights from past successful interactions
- Provide better, more contextual responses
For production deployments, use Azure Blob Storage + Kubernetes Jobs:
# 1. Upload emails to Azure Blob Storage
az storage blob upload-batch \
--account-name prodstorage1234 \
--source /path/to/emails \
--destination email-imports
# 2. Trigger import job via API
curl -X POST http://your-backend-url/api/admin/trigger-email-import
# 3. Monitor job status
kubectl get jobs -l app=email-import -w --context=jshipsterAdmin API Endpoints:
POST /api/admin/trigger-email-import- Create Kubernetes job to import emailsGET /api/admin/email-import-status/:jobName- Get job status
- Azure Import: See docs/AZURE_EMAIL_QUICK_START.md (Quick Start)
- Azure Full Guide: See docs/AZURE_BLOB_EMAIL_IMPORT.md
- Local Import: See docs/EMAIL_IMPORT_GUIDE.md
- Examples: See docs/EMAIL_EXAMPLE.md
- Terraform Setup: See ../terraform/STORAGE_SETUP.md
- Better Answers: AI learns from past successful interactions
- Consistency: Similar questions get consistent, proven answers
- Knowledge Capture: Institutional knowledge from email support preserved
- Faster Resolution: Common issues resolved using known solutions
- Scalable: Azure Blob Storage + Kubernetes Jobs for production-grade imports
The chatbot API endpoint provides an AI-powered assistant that uses vector embeddings to find and recommend tactical gear products. The assistant understands natural language queries and provides contextual product recommendations based on semantic similarity.
POST /api/chat
The chat endpoint uses enhanced vector search with:
- Product Search: Uses embeddings for semantic product search when the
product_embeddingstable exists and contains data - Email Context: Enhances responses with insights from similar past customer conversations when email embeddings are available
The endpoint accepts a JSON payload with the following structure:
{
"conversation": [
{
"role": "user",
"message": "Hello, I am looking for holsters for Glock 19."
},
{
"role": "assistant",
"message": "Hello! I would be happy to help you find holsters."
},
{
"role": "user",
"message": "What do you have for right-handed use?"
}
]
}conversation(array, required): Array of conversation messagesrole(string, required): Role of the message sender ("user" or "assistant")message(string, required): The actual message content
The system automatically determines if a message is from a user or assistant based on the role field:
- Messages with
rolecontaining "assistant", "bot", or "ai" are treated as assistant messages - All other messages are treated as user messages
{
"response": "Based on our product database, I can see we have several holsters available...\n\n**Found 5 relevant products** (showing top matches with similarity scores):",
"products": {
"Fobus Standard Holster": "fobus-standard-holster",
"ORPAZ Defense Glock Holster": "orpaz-defense-glock-19-holster"
},
"error": "Optional error message if something went wrong"
}response(string): The AI assistant's response with product recommendationsproducts(object, optional): Map of product names to their slugs/SKUs for creating product linkserror(string, optional): Error message if the request failed
The application supports the following environment variables in your .env file:
# Database Configuration
DATABASE_URL=mysql://username:password@localhost:3306/database_name
# Server Configuration
PORT=8080
VERSION=1.0.0
LOG_LEVEL=info
# OpenAI Configuration
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_TIMEOUT=60 # API timeout in seconds (default: 60)
# Tunnel Configuration (for SSH tunnel scenarios)
WAIT_FOR_TUNNEL=false # Wait for SSH tunnel before connecting to databaseThe chatbot functionality requires:
- OpenAI API key (get one from https://platform.openai.com/)
- Database connection (for product data and embeddings)
- Product embeddings table (created by
init-embeddings-writecommand)
- Query Extraction: The last user message is extracted from the conversation
- Vector Search: The query is converted to an embedding and compared against all product embeddings using cosine similarity
- Filtering: Products are filtered to prioritize in-stock items
- Top Products: The top 20 most similar products are retrieved
- Context Building: The top 15 products are formatted with names, prices, stock status, and similarity scores
- AI Processing: The conversation is sent to OpenAI's
gpt-4o-minimodel with product context - Response: The AI generates recommendations based on the most relevant products
- Product Metadata: Product slugs/SKUs are returned for frontend linking
- General Context: Basic store information is provided to the AI
- Message Processing: Conversation messages are converted to OpenAI's chat format
- AI Processing: The conversation is sent to OpenAI's
gpt-4o-minimodel - Response: The AI provides general tactical gear guidance without specific product recommendations
- Start the server:
make run - Open your browser to
http://localhost:8080 - Use the AI Assistant chatbot interface to interact with the AI
curl -X POST http://localhost:8080/api/chat \
-H "Content-Type: application/json" \
-d '{
"conversation": [
{
"role": "user",
"message": "I need a holster for my Glock 19, right-handed, under $50"
}
]
}'Example response with vector search:
{
"response": "I found several holsters that match your requirements:\n\n**Fobus Standard Holster** - $34.99 - In Stock - Similarity: 0.87\n**ORPAZ Defense Glock 19** - $42.50 - In Stock - Similarity: 0.85\n\n**Found 5 relevant products** (showing top matches with similarity scores):",
"products": {
"Fobus Standard Holster": "fobus-standard-holster",
"ORPAZ Defense Glock 19": "orpaz-defense-glock-19-holster"
}
}The API handles various error conditions:
- 503 Service Unavailable: Database connection not available
- 500 Internal Server Error: OpenAI API key not configured or API error
- 400 Bad Request: Invalid request body, empty conversation, or no user message found
When using vector search mode, the AI assistant has access to:
- Product titles and descriptions
- SKU and pricing information
- Stock status and quantity
- Product tags and categories
- Semantic similarity scores
The assistant uses the top 15 most relevant products (out of 20 retrieved) to provide accurate recommendations.
- Embedding Generation: Initial setup requires generating embeddings for all products
- Search Performance: Vector similarity calculation is performed in-memory for all products
- Result Ranking: Products are sorted by cosine similarity and filtered by stock status
- Context Limits: Top 15 products are included in AI context to avoid token limits
- OpenAI Timeout: Configurable via
OPENAI_TIMEOUT(default: 60 seconds) - Retry Logic: Basic chat mode includes exponential backoff retry (3 attempts)
- Token Limits: Responses limited to 1000-2000 tokens depending on mode
- Temperature: Set to 0.7 for balanced creativity and accuracy
- OpenAI API calls are subject to OpenAI's rate limits
- Vector search queries all products but limits results to top 20
- Request timeout configurable via
OPENAI_TIMEOUTenvironment variable - Batch embedding generation uses 100 products per batch
The embeddings table is automatically created by the init-embeddings-write command:
CREATE TABLE product_embeddings (
product_id INT PRIMARY KEY,
embedding JSON NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci- product_id: Foreign key to wpjr_posts.ID
- embedding: JSON array of 1536 float values (OpenAI text-embedding-3-small dimensions)
- created_at: Timestamp of when the embedding was first created
- updated_at: Timestamp of the last update
# Build the server
make build
# Run in development mode (auto-reload)
make dev
# Run tests
make test
# Run tests with coverage
make test-coverage
# Format code
make fmt
# Lint code
make lint
# Generate Swagger docs
make swagger
# Build embeddings tool
make build-embeddings
# Format, lint, and build embeddings tool
make embeddings
# Build email import tool
make build-import-emails
# Database management (Docker)
make db-start # Start MariaDB container
make db-stop # Stop MariaDB container
make db-restart # Restart MariaDB container
make db-status # Check container status
make db-logs # View container logsThe application includes language detection capabilities for the following languages:
- English (en)
- Hebrew (עברית / he)
- Arabic (العربية / ar)
- Russian (Русский / ru)
- Chinese (中文 / zh)
- Japanese (日本語 / ja)
- Korean (한국어 / ko)
Note: Currently, the chat handlers are configured to always respond in English. Language detection is implemented in the internal/utils/language.go module but not yet integrated into the active chat flow. Future updates can enable automatic language detection from user queries.
- Language Detection: Language detection is implemented but not currently active in chat handlers
- In-Memory Vector Search: All embeddings are loaded into memory for similarity calculation
- No Pagination: Vector search returns top N results without pagination support
- Basic Retry Logic: Only basic chat mode has retry logic with exponential backoff
- Vector Database: Use a dedicated vector database (e.g., Pinecone, Weaviate) for scalable similarity search
- Incremental Updates: Support updating individual product embeddings without regenerating all
- Multi-Language Chat: Enable automatic language detection and response in the user's language
- Advanced Filtering: Add filters for price range, categories, and other product attributes
- Hybrid Search: Combine vector similarity with traditional keyword search
- Caching: Add caching for frequent queries to reduce OpenAI API calls
Problem: The chat endpoint provides general tactical gear information without specific product recommendations.
Solution:
- Ensure the
product_embeddingstable exists in your database - Run the embeddings initialization command:
./bin/init-embeddings-write - Verify embeddings were generated successfully in the database
- Restart the server to initialize the embedding service
Problem: Server starts but shows "Database connection not available" warnings.
Solution:
- Verify your
DATABASE_URLin the.envfile is correct - Ensure the database server is running
- Check database credentials and network connectivity
- If using SSH tunnel, ensure
WAIT_FOR_TUNNEL=trueis set
Problem: Chat requests fail with OpenAI API errors.
Solution:
- Verify your
OPENAI_API_KEYis valid and active - Check your OpenAI account has sufficient credits/quota
- Increase
OPENAI_TIMEOUTif requests are timing out - Review OpenAI API status page for service disruptions
Problem: init-embeddings-write command fails or times out.
Solution:
- Ensure you have write access to the database
- Verify the database connection string includes write permissions
- Check that you have sufficient OpenAI API quota for batch processing
- Review the console output for specific error messages
- The command processes products in batches of 100 - partial failures may require manual cleanup
Problem: Server fails to start or exits immediately.
Solution:
- Check the
.envfile exists and has proper configuration - Ensure port 8080 (or configured port) is not already in use
- Review server logs for specific error messages
- Verify Go version is 1.25.0 or higher
- Keep your OpenAI API key secure and never commit it to version control
- The API key is loaded from environment variables
- Database embeddings are stored in JSON format and can be large
- Consider implementing authentication for production use
- The API includes CORS configuration that allows all origins for development
- The
init-embeddings-writecommand requires write access to the database - Use environment variables for all sensitive configuration
- Review and restrict CORS settings before deploying to production
For issues, questions, or contributions, please refer to the repository's issue tracker.