diff --git a/app/__init__.py b/app/__init__.py index c8f73cc..21735b6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,4 @@ """NX AI - FastAPI/Python/Postgres/tsvector""" # Current Version -__version__ = "1.0.9" +__version__ = "1.1.0" diff --git a/tests/csv/soho_vapes.csv b/app/api/products/data/big_data.csv similarity index 100% rename from tests/csv/soho_vapes.csv rename to app/api/products/data/big_data.csv diff --git a/app/api/products/start_data.csv b/app/api/products/data/seed.csv similarity index 100% rename from app/api/products/start_data.csv rename to app/api/products/data/seed.csv diff --git a/app/api/products/seed.py b/app/api/products/seed.py index 53fee19..231d7b5 100644 --- a/app/api/products/seed.py +++ b/app/api/products/seed.py @@ -6,8 +6,7 @@ router = APIRouter() -CSV_PATH = os.path.join(os.path.dirname(__file__), 'start_data.csv') -CSV_PATH = os.path.abspath(CSV_PATH) +CSV_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), 'data/seed.csv')) @router.get("/products/seed", status_code=status.HTTP_200_OK) def seed_products() -> dict: @@ -61,6 +60,20 @@ def seed_products() -> dict: """, row ) + # Add tsvector column for full-text search + cur.execute(''' + ALTER TABLE product + ADD COLUMN IF NOT EXISTS search_vector tsvector; + ''') + # Populate tsvector column (example: combine title, Pack_Description, Hierarchy1-3) + cur.execute(''' + UPDATE product SET search_vector = + to_tsvector('english', coalesce(title,'') || ' ' || coalesce(Pack_Description,'') || ' ' || coalesce(Hierarchy1,'') || ' ' || coalesce(Hierarchy2,'') || ' ' || coalesce(Hierarchy3,'')); + ''') + # Create GIN index for fast search + cur.execute(''' + CREATE INDEX IF NOT EXISTS idx_product_search_vector ON product USING GIN(search_vector); + ''') conn.commit() cur.execute('SELECT * FROM product;') if cur.description is None: diff --git a/app/api/root.py b/app/api/root.py index 2c89a22..20a45aa 100644 --- a/app/api/root.py +++ b/app/api/root.py @@ -14,7 +14,7 @@ def root() -> dict: epoch = int(time.time() * 1000) meta = { "severity": "success", - "title": "NX-AI says hi", + "title": "How can NX-AI help?", "version": __version__, "base_url": base_url, "time": epoch, @@ -22,6 +22,12 @@ def root() -> dict: endpoints = [ {"name": "docs", "url": f"{base_url}/docs"}, {"name": "health", "url": f"{base_url}/health"}, - {"name": "products", "url": f"{base_url}/products"} + { + "name": "products", + "url": f"{base_url}/products", + "children": [ + {"name": "seed", "url": f"{base_url}/products/seed"} + ] + } ] return {"meta": meta, "data": endpoints} diff --git a/app/main.py b/app/main.py index 96bc379..cb8a86a 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,4 @@ from app import __version__ -"""NX-AI Open Source, production ready Python FastAPI/Postgres app for NX""" - from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles diff --git a/tests/test_routes.py b/tests/test_routes.py index 3437436..b9f1672 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -1,15 +1,12 @@ """Unit and integration tests for NX AI routes.""" from unittest.mock import MagicMock - from fastapi.testclient import TestClient - from app.api.routes import get_db_connection from app.main import app client = TestClient(app) - def test_root_returns_welcome_message() -> None: """GET / should return a welcome message.""" response = client.get("/") @@ -25,3 +22,13 @@ def test_health_returns_ok() -> None: assert response.status_code == 200 assert response.json() == {"status": "ok"} + +def test_products_returns_list() -> None: + """GET /products should return a list of products (possibly empty).""" + response = client.get("/products") + assert response.status_code == 200 + json_data = response.json() + assert "meta" in json_data + assert "data" in json_data + assert isinstance(json_data["data"], list) +