From 6ed88fdb84c7dce39ae42b6467d436b7ae07725b Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Mon, 20 Apr 2026 21:36:18 +0300 Subject: [PATCH] feat(phase1): add photo fields to Item model --- backend/models.py | 9 +++- backend/tests/test_schema.py | 81 ++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 backend/tests/test_schema.py diff --git a/backend/models.py b/backend/models.py index 6f64021d..9bd60d1e 100644 --- a/backend/models.py +++ b/backend/models.py @@ -50,10 +50,15 @@ class Item(Base): quantity = Column(Float, default=0.0) min_quantity = Column(Float, default=1.0) image_url = Column(String, nullable=True) - + + # Photo fields for item onboarding + photo_path = Column(String, nullable=True) + photo_thumbnail_path = Column(String, nullable=True) + photo_upload_date = Column(DateTime, nullable=True) + # Generic box/container association for multi-item OCR scanning box_label = Column(String, index=True, nullable=True) - + # Full AI metadata labels_data = Column(Text, nullable=True) diff --git a/backend/tests/test_schema.py b/backend/tests/test_schema.py new file mode 100644 index 00000000..43ee65d1 --- /dev/null +++ b/backend/tests/test_schema.py @@ -0,0 +1,81 @@ +import pytest +from datetime import datetime +from backend.models import Item + + +class TestItemPhotoFields: + """Test photo fields in Item model.""" + + def test_item_has_photo_fields(self, test_db): + """Test that Item model has three photo fields.""" + from backend.models import Item + from sqlalchemy import inspect + + mapper = inspect(Item) + column_names = [c.name for c in mapper.columns] + + assert "photo_path" in column_names + assert "photo_thumbnail_path" in column_names + assert "photo_upload_date" in column_names + + def test_photo_fields_are_nullable(self, test_db): + """Test that photo fields are nullable and can create item without them.""" + item = Item( + name="Test Item", + category="Electronics", + type="Component", + quantity=5, + barcode="PHOTO-001", + part_number="PN-001" + ) + test_db.add(item) + test_db.commit() + + retrieved = test_db.query(Item).filter_by(id=item.id).first() + assert retrieved.photo_path is None + assert retrieved.photo_thumbnail_path is None + assert retrieved.photo_upload_date is None + + def test_photo_fields_can_store_values(self, test_db): + """Test that photo fields can store string and datetime values.""" + upload_date = datetime(2026, 4, 20, 12, 30, 45) + + item = Item( + name="Test Item", + category="Electronics", + type="Component", + quantity=5, + barcode="PHOTO-002", + part_number="PN-002", + photo_path="/images/items/photo-001.jpg", + photo_thumbnail_path="/images/items/thumbs/photo-001.jpg", + photo_upload_date=upload_date + ) + test_db.add(item) + test_db.commit() + + retrieved = test_db.query(Item).filter_by(id=item.id).first() + assert retrieved.photo_path == "/images/items/photo-001.jpg" + assert retrieved.photo_thumbnail_path == "/images/items/thumbs/photo-001.jpg" + assert retrieved.photo_upload_date == upload_date + + def test_photo_fields_partial_null(self, test_db): + """Test that only some photo fields can be set, others null.""" + item = Item( + name="Test Item", + category="Electronics", + type="Component", + quantity=5, + barcode="PHOTO-003", + part_number="PN-003", + photo_path="/images/items/photo-003.jpg", + photo_thumbnail_path=None, + photo_upload_date=None + ) + test_db.add(item) + test_db.commit() + + retrieved = test_db.query(Item).filter_by(id=item.id).first() + assert retrieved.photo_path == "/images/items/photo-003.jpg" + assert retrieved.photo_thumbnail_path is None + assert retrieved.photo_upload_date is None