Improve the UI and tests

This commit is contained in:
Urtzi Alfaro
2025-11-15 21:21:06 +01:00
parent 86d704b354
commit 54b7a5e080
44 changed files with 2268 additions and 1414 deletions

View File

@@ -0,0 +1,49 @@
-- ================================================================
-- Performance Indexes Migration for Inventory Service
-- Created: 2025-11-15
-- Purpose: Add indexes to improve dashboard query performance
-- ================================================================
-- Index for ingredients by tenant and ingredient_category
-- Used in: get_stock_by_category, get_business_model_metrics
CREATE INDEX IF NOT EXISTS idx_ingredients_tenant_ing_category
ON ingredients(tenant_id, ingredient_category)
WHERE is_active = true;
-- Index for ingredients by tenant and product_category
-- Used in: get_stock_status_by_category
CREATE INDEX IF NOT EXISTS idx_ingredients_tenant_prod_category
ON ingredients(tenant_id, product_category)
WHERE is_active = true;
-- Index for stock by tenant, ingredient, and availability
-- Used in: get_stock_summary_by_tenant, get_ingredient_stock_levels
CREATE INDEX IF NOT EXISTS idx_stock_tenant_ingredient_available
ON stock(tenant_id, ingredient_id, is_available);
-- Index for food_safety_alerts by tenant, status, and severity
-- Used in: get_alerts_by_severity, get_food_safety_dashboard
CREATE INDEX IF NOT EXISTS idx_alerts_tenant_status_severity
ON food_safety_alerts(tenant_id, status, severity);
-- Index for stock_movements by tenant and movement_date (descending)
-- Used in: get_movements_by_type, get_recent_activity
CREATE INDEX IF NOT EXISTS idx_movements_tenant_date
ON stock_movements(tenant_id, movement_date DESC);
-- Index for stock by tenant and ingredient with quantity
-- Used in: get_live_metrics with stock level calculations
CREATE INDEX IF NOT EXISTS idx_stock_tenant_quantity
ON stock(tenant_id, ingredient_id, quantity_current)
WHERE is_available = true;
-- Index for ingredients by tenant and creation date
-- Used in: get_recent_activity for recently added ingredients
CREATE INDEX IF NOT EXISTS idx_ingredients_tenant_created
ON ingredients(tenant_id, created_at DESC)
WHERE is_active = true;
-- Composite index for stock movements by type and date
-- Used in: get_movements_by_type with date filtering
CREATE INDEX IF NOT EXISTS idx_movements_type_date
ON stock_movements(tenant_id, movement_type, movement_date DESC);

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
Script to apply performance indexes to the inventory database
Usage: python apply_indexes.py
"""
import asyncio
import os
import sys
from pathlib import Path
# Add parent directory to path to import app modules
sys.path.insert(0, str(Path(__file__).parent.parent))
from sqlalchemy import text
from app.core.database import database_manager
import structlog
logger = structlog.get_logger()
async def apply_indexes():
"""Apply performance indexes from SQL file"""
try:
# Read the SQL file
sql_file = Path(__file__).parent / "001_add_performance_indexes.sql"
with open(sql_file, 'r') as f:
sql_content = f.read()
logger.info("Applying performance indexes...")
# Split by semicolons and execute each statement
statements = [s.strip() for s in sql_content.split(';') if s.strip() and not s.strip().startswith('--')]
async with database_manager.get_session() as session:
for statement in statements:
if statement:
logger.info(f"Executing: {statement[:100]}...")
await session.execute(text(statement))
await session.commit()
logger.info(f"Successfully applied {len(statements)} index statements")
return True
except Exception as e:
logger.error(f"Failed to apply indexes: {e}", exc_info=True)
return False
async def verify_indexes():
"""Verify that indexes were created"""
try:
logger.info("Verifying indexes...")
verify_query = """
SELECT
schemaname,
tablename,
indexname,
indexdef
FROM pg_indexes
WHERE indexname LIKE 'idx_%'
AND schemaname = 'public'
ORDER BY tablename, indexname;
"""
async with database_manager.get_session() as session:
result = await session.execute(text(verify_query))
indexes = result.fetchall()
logger.info(f"Found {len(indexes)} indexes:")
for idx in indexes:
logger.info(f" {idx.tablename}.{idx.indexname}")
return True
except Exception as e:
logger.error(f"Failed to verify indexes: {e}", exc_info=True)
return False
async def main():
"""Main entry point"""
logger.info("Starting index migration...")
# Apply indexes
success = await apply_indexes()
if success:
# Verify indexes
await verify_indexes()
logger.info("Index migration completed successfully")
else:
logger.error("Index migration failed")
sys.exit(1)
# Close database connections
await database_manager.close_connections()
if __name__ == "__main__":
asyncio.run(main())