No description
  • Python 68.6%
  • TypeScript 30.6%
  • Dockerfile 0.3%
  • CSS 0.2%
  • Mako 0.2%
Find a file
root 4dedaf7fa7 Harden AI pipeline migration for existing deployments.
Make the new AI schema migration idempotent by checking existing columns, indexes, and tables before creation so upgrades succeed even when parts of the schema already exist.
2026-06-21 21:38:54 +02:00
backend Harden AI pipeline migration for existing deployments. 2026-06-21 21:38:54 +02:00
frontend Refactor AI pipeline to explicit manual stages. 2026-06-21 21:34:07 +02:00
gateway Bootstrap Deal Finder monorepo foundation. 2026-06-21 19:13:56 +02:00
.env.example Refactor AI pipeline to explicit manual stages. 2026-06-21 21:34:07 +02:00
.gitignore Bootstrap Deal Finder monorepo foundation. 2026-06-21 19:13:56 +02:00
codex-ai-valuation-prompt.md Refactor AI pipeline to explicit manual stages. 2026-06-21 21:34:07 +02:00
deal-finder-mvp.md Bootstrap Deal Finder monorepo foundation. 2026-06-21 19:13:56 +02:00
docker-compose.yml Implement full Deal Finder MVP workflow and UI. 2026-06-21 19:59:56 +02:00
MVP_SPEC.md Add initial Deal Finder MVP specification. 2026-06-21 18:58:45 +02:00
README.md Refactor AI pipeline to explicit manual stages. 2026-06-21 21:34:07 +02:00

Deal Finder MVP

Soukroma webova aplikace pro rucni vyhledavani podhodnocenych pocitacu a komponent na ceskych bazarech.

Zdroj pravdy

  • Hlavni specifikace: deal-finder-mvp.md
  • Archiv predchozi verze: MVP_SPEC.md

Pouzite technologie

  • Frontend: Next.js, React, TypeScript, Tailwind CSS, TanStack Query/Table, React Hook Form + Zod, Recharts
  • Backend: FastAPI, SQLAlchemy 2, Alembic, httpx, selectolax
  • Databaze: PostgreSQL
  • Provoz: Docker Compose + Nginx reverse proxy

Struktura repozitare

  • frontend - web UI
  • backend - API, adaptery, scan workflow, oceneni, SMTP
  • gateway - Nginx konfigurace
  • docker-compose.yml - provozni stack

Instalace a prvni spusteni

  1. Vytvor konfiguraci:

    cp .env.example .env
    
  2. Nastav bezpecne hodnoty:

    • APP_SECRET
    • POSTGRES_PASSWORD
    • SESSION_SECURE_COOKIES=true v produkci pod HTTPS
  3. Spust aplikaci:

    APP_PORT=3017 docker compose up -d --build
    

    Pouzij libovolny volny port; 3000 muze byt obsazeny jinou sluzbou.

  4. Otestuj healthcheck:

    curl -fsS http://127.0.0.1:3017/api/health
    
  5. Otevri UI:

    • http://127.0.0.1:3017/login

Docker Compose provoz

Sluzby:

  • gateway - jediny vystaveny port na hostu
  • frontend - Next.js aplikace
  • backend - FastAPI API (pri startu provadi alembic upgrade head)
  • db - PostgreSQL

Kontejnery bezici stale:

APP_PORT=3017 docker compose ps

Logy:

APP_PORT=3017 docker compose logs -f backend

Migrace databaze

Rucni migrace:

APP_PORT=3017 docker compose exec backend alembic upgrade head

Vytvoreni nove migrace:

APP_PORT=3017 docker compose run --rm -v /home/investment/DealFinder/backend:/app backend alembic revision --autogenerate -m "popis zmeny"

Reverse proxy priklad

gateway/nginx.conf smeruje:

  • /api/* -> backend:8000
  • vse ostatni -> frontend:3000

Minimalni externi reverse proxy (napr. Caddy/Nginx) ma smerovat HTTPS provoz na host port APP_PORT.

SMTP propojeni z Dockeru

Backend pouziva env promenne:

  • SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM, SMTP_TO, SMTP_STARTTLS

V Compose je nastaveno:

extra_hosts:
  - "host.docker.internal:host-gateway"

Dulezite:

  • SMTP naslouchajici jen na 127.0.0.1 hostitele neni z kontejneru dostupne.
  • Bezpecnejsi varianta je naslouchat na Docker bridge IP a omezit firewall na konkretni Docker sit.
  • Pokud SMTP bezi v Dockeru, preferuj sdilenou pojmenovanou Docker sit a host podle DNS jmena SMTP kontejneru.

Zalohovani a obnova PostgreSQL

Zaloha:

APP_PORT=3017 docker compose exec db pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > backup.sql

Obnova:

cat backup.sql | APP_PORT=3017 docker compose exec -T db psql -U "$POSTGRES_USER" "$POSTGRES_DB"

Pridani noveho bazaroveho adapteru

  1. Vytvor novy adapter v backend/app/adapters/<source>.py implementujici:
    • scan(max_price)
    • fetch_listing(url)
  2. Pridat adapter do ALL_ADAPTERS v backend/app/adapters/__init__.py
  3. Pridat fixture HTML testy v backend/tests/fixtures + parser test v backend/tests/test_adapters.py
  4. Udrzet adapterovou logiku uvnitr adapteru (bez rozptyleni selektoru po aplikaci)

Omezeni zdroju

  • Adaptery pouzivaji pouze verejne dostupne stranky.
  • Pri detekci blokace/CAPTCHA vraci vysvetlitelnou chybu zdroje a scan pokracuje.
  • Adaptery neobchazeji technicke ochrany.
  • Aktualni parsery jsou best-effort; pri zmenach HTML je potreba upravit fixture a parser.

Vypocet ceny a jistoty

Implementace v backend/app/valuation.py:

  • minimalne 3 porovnatelne nabidky
  • median porovnatelnych cen
  • konzervativni cena = median * faktor (default 0.85)
  • ocekavany zisk = konzervativni cena - porizovaci naklady - poplatky
  • marze = zisk / porizovaci naklady * 100
  • status Zajimava jen pri splneni limitu ceny, zisku, marze, poctu srovnani a dostatecne jistote

Rucne rizena AI pipeline

AI faze jsou oddelene od scanu a nikdy se nespousti automaticky:

  1. POST /scans pouze bazarovy scan + deterministicky prefiltr + interni oceneni
  2. POST /ai/normalizations/preview a POST /ai/normalizations pouze rucne pro vybrane listing_ids
  3. POST /ai/research/preview a POST /ai/research pouze rucne pro vybrane listing_ids

Automaticke retezeni je zakazane:

  • scan -> normalizace
  • normalizace -> research
  • zmena ceny/popisu -> automaticky rerun
  • otevreni seznamu/detailu -> automaticky AI call

Kazda nabidka ma oddelene stavy:

  • ai_normalization_status
  • ai_research_status

Podporovane stavy: not_requested, queued, running, completed, failed, stale, skipped_budget, skipped_not_eligible.

AI API

  • POST /ai/normalizations/preview
  • POST /ai/normalizations
  • GET /ai/normalizations/{job_id}
  • POST /ai/research/preview
  • POST /ai/research
  • GET /ai/research/{job_id}
  • GET /ai/jobs
  • POST /listings/{id}/mark-ai-stale

Preview endpointy nikdy nevolaji placene AI. Spousteci endpointy vyzaduji explicitni seznam listing_ids a CSRF token.

Spusteni testu

Backend:

APP_PORT=3017 docker compose exec backend pytest

Frontend unit testy:

APP_PORT=3017 docker compose exec frontend npm run test

Frontend e2e smoke:

APP_PORT=3017 docker compose exec frontend npm run test:e2e

Troubleshooting

  • Port conflict: nastav jiny APP_PORT (napr. 3017)
  • 401 po loginu: over SESSION_SECURE_COOKIES vs. HTTP/HTTPS rezim
  • Migrace nesedi: spust alembic upgrade head v backend kontejneru
  • SMTP fail: over reachable host/port z kontejneru a STARTTLS nastaveni
  • Adapter chyby: zkontroluj HTML fixture a parser selektory