DEV Community

rishabh-hasija
rishabh-hasija

Posted on AI-assisted

StockEntry Guard: Local Gemma-Powered Product Onboarding for Small Retailers

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission πŸ’Έ

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Adding products to an inventory sounds simple until catalogs grow. The same item often gets entered multiple times with slightly different names, pack sizes, or variants.

StockEntry Guard uses local Gemma 3 vision to extract product details, detect possible duplicates, and keep final inventory decisions with the retailer.

StockEntry Guard duplicate review

For example:

  • Coca-Cola Zero 330ml
  • Coke Zero Sugar 330 ml
  • Coca-Cola Zero 500ml

A normal product-entry form will happily create three unrelated records unless someone notices the duplication.

StockEntry Guard helps a retailer to:

  1. Import an existing inventory CSV.
  2. Upload a product photo.
  3. Extract product details locally with Gemma 3.
  4. Review and edit the extracted fields.
  5. Compare the product against the existing catalog.
  6. See whether there is no match, a possible match, or likely a duplicate.
  7. Create a new product or update an existing one only after explicit human approval.
  8. Export the updated inventory back to CSV.

The target user is a small retailer, independent shop, reseller, or anyone maintaining product data without a large inventory-management system.

How a retailer would use it

The current hackathon MVP runs locally and stores the retailer's catalog in a SQLite database.

A retailer imports their existing catalog once using CSV. After the import, the products are stored locally and remain available between application sessions.

From then on, new products can be added through the image workflow without re-importing the CSV.

The intended production experience is a Windows installer:

  1. Install StockEntry Guard.
  2. Launch the desktop shortcut.
  3. Import an existing inventory CSV, or download the sample template.
  4. Add future products by photographing them.
  5. Export the catalog whenever needed.

For the hackathon MVP, the application still requires the local Python/Ollama setup described in the repository. Packaging it as a one-click Windows installer is the next deployment step.

The value is simple: reduce repetitive data entry and prevent messy catalogs from accumulating duplicate products.

Demo

Video demo:

https://drive.google.com/file/d/1GFhMoctpGnEdRfjUzeXzUT5H6zm5rnn3/view?usp=sharing

StockEntry Guard currently runs locally through Streamlit and uses Gemma 3 4B through Ollama for product-image extraction.

The demo shows the complete retailer workflow:

  1. Import an existing inventory CSV.
  2. Upload a product image.
  3. Extract structured product details locally with Gemma.
  4. Review and edit the extracted fields.
  5. Check the product against the existing inventory for possible duplicates.
  6. Approve the product.
  7. Save it into the local inventory database.
  8. Export the updated inventory back to CSV.

For the demo, I used a Hershey's Milk Chocolate bar.

The product image contains clear packaging information including the Hershey's brand, Milk Chocolate product type, and visible package weight.

Gemma analyzes the image locally and returns structured candidate data such as:

  • product name
  • brand
  • category
  • variant
  • size
  • SKU
  • barcode
  • description
  • confidence
  • uncertain fields

The extracted result is never written directly to inventory.

The retailer reviews the fields first, then runs StockEntry Guard's deterministic duplicate check.

The duplicate engine compares the candidate against existing inventory using product name, brand, variant, size, category, barcode, and SKU evidence.

The UI translates the result into simple messages such as:

  • No matching product found
  • Possible match found
  • Likely already in inventory

The retailer then explicitly chooses whether to create a new product, update an existing one, or discard the result.

After approval, the product is stored in the local SQLite inventory database and stays available in future application sessions.

The retailer can export the updated inventory back to CSV at any time.

This demonstrates the main goal of StockEntry Guard:

Use local AI to reduce manual product entry while keeping duplicate prevention and final inventory decisions under human control.

Video demo:

https://drive.google.com/file/d/1GFhMoctpGnEdRfjUzeXzUT5H6zm5rnn3/view?usp=sharing

Code

GitHub repository:

https://github.com/rishabh-hasija/stockentry-guard

The project includes:

  • Python 3.12
  • Streamlit
  • Gemma 3 4B
  • Ollama
  • SQLAlchemy
  • SQLite
  • Alembic
  • Pydantic
  • pytest
  • Ruff
  • mypy

The repository also contains architecture documentation, sample inventory data, automated tests, and a downloadable sample CSV for new users.

How I Built It

I wanted the hackathon MVP to stay small enough to finish, but I did not want the codebase to become a one-file Streamlit prototype that would need to be replaced later.

I used a modular monolith with clear boundaries:

Streamlit UI
     |
Application use cases
     |
Domain + ports
     |
Infrastructure adapters
     |
SQLite / Ollama / CSV / similarity engine
Enter fullscreen mode Exit fullscreen mode

Why Does Open Innovation Matter?

Open-source AI is important to StockEntry Guard because the product is designed for small retailers who may not want product images, barcodes, catalog information, and internal inventory data sent to an external AI service.

StockEntry Guard runs Gemma 3 locally through Ollama.

That gives the retailer several practical benefits.

Product data stays local

Product photographs can contain packaging information, SKUs, barcodes, variants, and internal catalog details.

With local inference, the image can be processed on the retailer's own computer instead of being uploaded to a hosted AI API.

No per-product AI API bill

A retailer may eventually process hundreds or thousands of products.

A local open-weight model removes the need to pay for every image extraction request. The main requirement becomes local computing resources.

The model is replaceable

StockEntry Guard does not make the rest of the application depend directly on Gemma.

The AI layer implements an AIProductExtractor interface.

This means another local vision model could replace Gemma later without rewriting inventory management, duplicate detection, persistence, or the user interface.

I could control the extraction rules

For inventory data, a confident-looking wrong answer is worse than an empty field.

The extraction prompt therefore tells the model:

  • do not guess SKUs
  • do not guess barcodes
  • do not guess unreadable pack sizes
  • distinguish the brand from the product name
  • separate meaningful variants from marketing slogans
  • return null when information is uncertain

Open models and local inference made this combination of privacy, control, and low operating cost practical for the project.

My Agent Session

I used Codex as a development agent throughout the project, but built the application in small, reviewable slices instead of asking the agent to generate the entire project in one pass.

The main development stages were:

  1. system architecture and repository structure
  2. domain model and persistence
  3. Ollama/Gemma image extraction
  4. normalization and duplicate detection
  5. CSV import/export and application workflows
  6. Streamlit UI
  7. retailer-facing UX refinement
  8. regression testing and documentation

One of the most useful parts of this workflow happened during real Gemma testing.

All automated extraction tests were passing, but a real product image failed with:

MissingProductNameError

I tested Gemma directly with the same image and confirmed that its vision capability correctly identified the product as Heineken Lager Beer.

I then inspected the raw structured response produced through the application.

Gemma was returning only:

  • confidence
  • uncertain_fields

The issue was not the model or image.

The generated JSON Schema treated product fields such as name, brand, and variant as optional because they had default None values.

Gemma therefore followed the schema correctly and omitted them.

I changed the schema so every product key is required but nullable.

After the fix, the same real image produced:

  • Name: Heineken Lager Beer
  • Brand: Heineken
  • Category: Beer
  • Variant: City Edition
  • Confidence: 0.95

Unreadable SKU, barcode, and size values remained empty.

This was a useful reminder that passing mocked tests is not enough when integrating an AI model. I repeatedly tested the actual model between implementation slices and used those results to guide the next agent task.

The finished project currently has 238 automated tests covering the domain, persistence, migrations, extraction validation, duplicate detection, CSV workflows, transactions, idempotency, and Streamlit behavior.

My First User

Prize Categories

Best Use of Gemma

StockEntry Guard uses Gemma 3 4B as its local multimodal model.

Gemma analyzes retail product photographs and returns structured candidate information including product name, brand, category, variant, size, SKU, and barcode when those values are visible.

The model runs locally through Ollama.

AI output never writes directly to inventory. The retailer reviews the extracted information, StockEntry Guard independently performs deterministic duplicate detection, and the retailer explicitly approves the final inventory action.

Top comments (0)