Data and analytics

Etsy and Shopify profit and stockout dashboard

Python and DuckDB dashboard merging Etsy and Shopify sales, computing per-product profit after fees and shipping, and forecasting 30-day stockouts.

pythonduckdbstreamlitpytestuv

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add etsy-and-shopify-profit-and-stockout-dashboard-ef2fd7
10 filesDownload zip
CLAUDE.md
# the app

the app is a solo-seller dashboard that merges Etsy and Shopify orders, computes profit per product after platform fees, payment fees and shipping, and predicts which products will stock out within 30 days. It is a personal tool for one seller, not a multi-user app.

@REVIEW.md

## Stack

- Python 3.12, managed with uv
- DuckDB file at `data/shop.duckdb` (never commit it)
- Streamlit UI in `src/the app/app.py`
- pytest, ruff, mypy

## Commands

- Install deps: `uv sync`
- Tests: `uv run pytest -q`
- Lint and format check: `uv run ruff check . && uv run ruff format --check .`
- Types: `uv run mypy src`
- Ingest fixtures: `uv run python -m the app.ingest --source fixtures`
- Run dashboard: `uv run streamlit run src/the app/app.py`
- Full check: the `verify` skill

## Layout

- `src/the app/`: `ingest.py`, `models.py`, `fees.py`, `forecast.py`, `app.py`
- `sql/`: DuckDB view and table SQL, loaded by name
- `tests/`: pytest suite, no network
- `fixtures/`: anonymized sample Etsy and Shopify exports
- `scripts/smoke.py`: end-to-end check into a temp DuckDB
- `SPEC.md` (scope and contracts), `PLAN.md` (phases), `REVIEW.md` (review rules)

## Data model

- Unified tables: `orders`, `order_lines`, `products`, `inventory_snapshots`, `fee_rules`
- Staging tables: `raw_etsy_*` and `raw_shopify_*`, kept as received
- `product_map` links platform listing or SKU IDs to `products`
- Money is stored as integer cents plus a currency code. Never use floats for money.
- Timestamps are normalized to UTC on ingest.
- Ingest is idempotent: upsert on `(platform, order_id, line_id)`.

## Gotchas

- Etsy and Shopify use different SKU and listing IDs. Always go through `product_map`.
- Etsy fees: listing, transaction, payment processing, offsite ads.
- Shopify fees: plan, payment processing, app fees.
- Refunds and partial refunds reduce revenue. Fees are often not refunded, so check the fee rules.
- Shipping cost paid and shipping charged are separate values. Do not net them silently.
- Discounts reduce revenue at the line level before allocation.

## Forecast rule

- Start with trailing-window velocity: a blend of 28-day and 7-day averages, plus lead time and safety stock.
- Output `days_of_cover` and `stockout_date`.
- No ML until a baseline backtest exists and beats the baseline.

## Conventions

- Pure functions for fee and profit math.
- SQL lives in `sql/*.sql` and is loaded by name, not inline in Python.
- Type hints everywhere.
- Tests make no network calls and are deterministic.
- Golden-number tests use hand-verified values. Recompute by hand before changing an expected value.

## Secrets

- Keys come only from env vars: `ETSY_API_KEY`, `SHOPIFY_ACCESS_TOKEN`.
- `.env.example` holds placeholders only: `ETSY_API_KEY=YOUR_API_KEY`, `SHOPIFY_ACCESS_TOKEN=YOUR_ACCESS_TOKEN`.
- Never commit `.env`, `data/`, `*.duckdb`, or real exports.

## Workflow

- Explore, then plan, then code, then run the `verify` skill before saying a task is done.
- Use `/clear` between unrelated tasks and `/compact` at natural breaks.
- Give every change a way to check itself: a test, a golden number, or the smoke run.

## Do not

- Use floats for money.
- Delete `data/shop.duckdb` without asking.
- Make live API calls unless the user asks.
- Commit or push without asking.
- Put real customer names, addresses or emails in fixtures, logs or tests.
Use for my project