Inspiration
Independent bookstores carry inventory that sells slowly, and their options are usually to wait, discount, or promote on intuition. Discounts cut into thin margins, and arbitrary bundles often fail to attract customers. Large retailers use merchandising analysts and pricing software, but a small shop usually has neither the data infrastructure nor the specialist time.
We asked a different question from "what should we mark down?": what is the cheapest, safest experiment this shop could run to move this book, and how will it know whether it worked?
What it does
StockRescue is an agentic inventory-recovery platform for independent bookstores. It combines three kinds of reasoning:
| Layer | Question it answers | Who is the authority |
|---|---|---|
| Cultural | Which authors, films, themes, or books are associated with this title? | Qloo API (retrieved evidence) |
| Commercial | Can the shop actually do this, within stock, margin, discount, and budget limits? | Deterministic Python |
| Experimental | Did the action work, and what are the limits of that conclusion? | The retailer's recorded outcomes |
The LLM is optional and only explains facts it is given.
The workflow
- Import and validate. CSV rows are checked for types, negative values, and suspicious prices. Blank optional fields (such as sales history) stay unknown, not zero.
- Diagnose. A dashboard flags products with named rules (for example, no recorded sales in 30 days, long days in stock, high cost tied up relative to velocity). Every metric states its formula and period.
- Resolve. The selected book is resolved to a Qloo entity as a strong match, ambiguous match, or no match.
- Explore. Qloo Insights are retrieved and matched against books the shop actually stocks.
- Generate and check. Candidate bundles, repositioning ideas, and controlled promotions are produced, then filtered by hard constraints.
- Rank and explain. Feasible options are scored by an explainable model. Rejected options stay visible with the reason.
- Approve, run, measure. The owner approves before anything runs. Nothing is published or repriced automatically. Real results are entered afterward and compared with a baseline.
Competitive and market analysis
Independent bookstores sit in a gap between existing tool categories. This table is a category-level comparison, not a feature audit of specific products.
| Approach | Typical strength | Gap for a small bookstore |
|---|---|---|
| Bookstore POS / inventory systems | Accurate stock, sales records, reorder tools | Report what happened. They don't propose or test merchandising experiments. |
| Enterprise markdown / price-optimization software | Sophisticated pricing models at scale | Aimed at large chains with large data volumes. Their primary lever is price, which is the margin-eroding lever we want to use last. |
| Generic recommenders ("customers also bought") | Work well with transaction history | Need purchase data small shops often lack. They recommend to a customer, not a plan for a product the shop is stuck with. |
| General-purpose LLM chat | Fast ideation | Can invent connections, can't check stock or margin, and leave no evidence trail or outcome record. |
| StockRescue | Cultural evidence + hard business constraints + measured outcomes | Currently single-niche, single-retailer demo [adjust if this changes]. |
Our differentiators
- Discount last, not first. Non-discount actions (reposition, bundle) are evaluated before markdowns. Discounts are allowed but must pass the margin and budget checks.
- Provenance on every suggestion. Each Qloo-informed proposal links to the matched entity, the returned results, and the raw response. Assumptions are labelled as assumptions.
- Honesty about limits. Qloo coverage gaps, API failures, and thin evidence are disclosed. The product can say "not enough evidence to rank confidently."
- A measurement loop. Each recommendation is stored as a testable hypothesis with a baseline, an outcome record, and stated limitations.
What we deliberately don't claim
We don't forecast sales uplift or conversion rates, and we don't show confidence badges, because no model has been trained or validated for that on this data. Qloo associations are treated as hypotheses, not as demand predictions.
Analytics methodology
All calculations live in one tested deterministic layer. The LLM never computes money.
Inventory metrics
$$\text{Cost tied up} = q \times c \qquad \text{Retail value} = q \times p$$
Unit and bundle economics. For selling price $p$, unit cost $c$, and a bundle of $n$ items with bundle price $P$:
$$\text{Gross margin \%} = \frac{p - c}{p} \times 100 \qquad \text{Bundle margin \%} = \frac{P - \sum_{i=1}^{n} c_i}{P} \times 100$$
Zero or invalid prices are rejected to prevent division errors.
Experiment profit (direct costs only):
$$\text{Gross profit} = \sum_i u_i\,(p_i - c_i) - \text{direct campaign costs}$$
We state which costs are included (labor, packaging, and platform fees are [included / excluded, confirm]) and revenue is never reported as profit.
Baseline comparison, normalized per day so periods of different length are comparable:
$$r_{\text{base}} = \frac{u_{\text{base}}}{d_{\text{base}}} \qquad r_{\text{exp}} = \frac{u_{\text{exp}}}{d_{\text{exp}}} \qquad \Delta\% = \frac{r_{\text{exp}} - r_{\text{base}}}{r_{\text{base}}} \times 100$$
The percentage is calculated only when $r_{\text{base}} > 0$. Where an optional control product is recorded, it is shown alongside. A before/after difference is not presented as causal proof, and the result lists likely confounders (seasonality, events, stock-outs).
Transparent ranking. Feasible actions are scored on commercial feasibility, strength of available Qloo evidence, operational simplicity, test cost, and measurement quality, using configurable weights [document your actual weights here]. Each ranked option explains its position, and when evidence is too thin the system says so.
Real vs. simulated. Outcomes carry an is_simulated flag, so demo data never mixes with real results.
How we built it
Architecture
- Frontend: Next.js, React, TypeScript, Tailwind. Pages for Dashboard, Rescue Lab (evidence plus rejected options), and Experiments (approval and recorded outcomes).
- Backend: Python, FastAPI, Pydantic, HTTPX, SQLAlchemy, split into an inventory module (CSV validation and metrics), a rescue engine, an experiments module, and a Qloo layer.
- Data: six tables (
products,qloo_entity_mappings,qloo_evidence,rescue_plans,rescue_experiments,experiment_outcomes). SQLite locally and PostgreSQL-ready. Tables are created at startup, and migrations are not implemented yet. - Security and scope: API keys stay on the backend. The demo uses a single demo retailer with no authentication.
Qloo integration
- Entity resolution through search, with strong, ambiguous, and no-match outcomes. The first result is never auto-selected.
- Insights retrieval through the documented Qloo Insights API, with results matched against the shop's actual stock.
- A 15-second timeout, up to 3 attempts, in-memory caching, and typed errors.
- Raw responses are stored alongside each plan, so every suggestion can be traced to what Qloo returned.
- If Qloo is down, times out, or has no match, the plan continues using retailer data only and discloses the coverage gap.
Rescue engine and LLM guardrails
- Pipeline: generate candidates → hard-constraint checks (stock, valid prices, minimum margin, maximum discount, budget) → rank → build test plan.
- Rejected options are kept with reasons instead of being silently dropped.
- The optional LLM explains supplied facts only. Any number it introduces that we didn't supply is rejected, and if the LLM is unavailable the plan returns in rule-based order without AI text.
- Any failed stage yields a partial plan, not an error screen.
Experiment lifecycle
proposed → approved → running → completed, with rejected and cancelled paths. Edits are allowed only while proposed, and an experiment must be approved before it can start.
Quality
A backend pytest suite [confirm count] with Qloo and LLM test doubles, run in GitHub Actions CI. Mocks are used only in tests, never in the demo.
Challenges we ran into
- Entity ambiguity. Book titles match multiple entities, so we built explicit match states and a human-confirmation path in the backend.
- Resisting invented numbers. Forecasts and confidence scores would have looked impressive, but we showed only retrieved evidence, calculated values, and labelled hypotheses.
- Low-data reality. Small shops often lack sales history, so the system works in a low-data mode and distinguishes verified facts, missing information, cultural signals, and assumptions.
- Constraining the LLM. We gave it an explanation-only role with an output guard, so a model failure can't corrupt the financials.
- Scope under time pressure. [Add your own, e.g. what you cut and why.]
Accomplishments that we're proud of
- A real Qloo integration with provenance stored for every proposal.
- Deterministic, tested economics that the AI cannot override.
- An experiment tracker that separates real and simulated results and states its own limitations.
- A product that is willing to say "insufficient evidence."
What we learned
- Cultural signals are good at generating ideas, but only the retailer's own recorded outcomes can show what works.
- Separating what the data says, what we calculated, and what the model wrote makes the product easier to trust and debug.
- For small retailers, a product that is honest about uncertainty is more useful than a confident forecast.
What's next for StockRescue
- Frontend gaps: CSV upload UI, ambiguous-match picker, evidence explorer, and price editor [remove any you finish].
- Agent depth: a bounded tool-calling loop on top of the deterministic pipeline.
- Evaluation: compare rule-based, LLM-only, and Qloo-informed strategies on identical inventory and constraints, judged on proposals and evidence, not claimed sales.
- Learning loop: retailer feedback on usefulness and feasibility, kept separate from measured sales.
- Measurement: control groups and longer test windows. We won't train a sales-prediction model on tiny samples.
- Platform: authentication, multi-retailer support, migrations, and expansion to stationery, gifts, and hobby retail.
Built with
nextjs react typescript tailwindcss python fastapi pydantic sqlalchemy postgresql sqlite httpx qloo-api pytest github-actions
Built With
- actions
- api
- css
- fastapi
- github
- httpx
- next.js
- postgresql
- pydantic
- pytest
- python
- qloo
- react
- rest
- sqlalchemy
- sqlite
- tailwind
- typescript
- uvicorn
Log in or sign up for Devpost to join the conversation.