BuyingAgent/README.md
Lars b276758ee1
All checks were successful
Deploy Development / deploy (push) Successful in 1m19s
Test Suite / pytest-backend (push) Successful in 31s
Test Suite / smoke-dev (push) Successful in 0s
Test Suite / frontend-checks (push) Successful in 28s
Stelle den Frontend-MVP und die v0.3-API auf develop bereit, damit Dev API und PWA zusammen deployen.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 13:04:59 +02:00

96 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# BuyingAgent
Backend für einen generischen Buying-/Deal-Agenten. Das System bewertet, wie gut eine Produktvariante zu einem Profil passt und wie attraktiv ein konkretes Angebot preislich ist. Es kauft nicht.
v0.1 ist ein Walking Skeleton: Profil → Produkt → Variante → Angebot → Preisbeobachtungen → Evaluation. Notebooks sind der erste Anwendungsfall, nicht das Datenmodell.
**Vorgaben:** `docs/buying-agent-v0.1-spec-v1.1.md` (fachlich) und `docs/buying-agent-architecture-addendum-v1.md` (Architektur, hat Vorrang bei Strukturfragen).
## Monorepo
```text
backend/ System of Record: Domain, Scoring, Persistenz, /api/v1
frontend/ Platzhalter — keine UI in v0.1
docs/ Spezifikationen und Deployment
docker-compose.yml
```
Entwicklung auf `develop`. Push nach `develop` baut Dev auf dem Raspberry Pi. Merge `--no-ff` nach `main` deployt Production. Details: `docs/DEPLOYMENT.md`.
## Stack
Python 3.13, FastAPI, Pydantic 2, SQLAlchemy 2 (sync, psycopg 3), Alembic, PostgreSQL 17, pytest, Docker Compose. Build-Tool: uv 0.10.11.
Abhängigkeiten: HTTP → Services → Domain/Scoring → Repositories → PostgreSQL. `domain` und `scoring` importieren weder FastAPI noch SQLAlchemy.
## Lokal starten
```powershell
Copy-Item .env.example .env
docker compose up --build -d
docker compose exec api python -m scripts.demo
```
```sh
cp .env.example .env
docker compose up --build -d
docker compose exec api python -m scripts.demo
```
API: `http://127.0.0.1:8000`
OpenAPI: `http://127.0.0.1:8000/docs`
Live: `GET /health/live`
Ready: `GET /health/ready`
Die Demo legt Definitionen, Profil und die Fälle A–D über HTTP an und wertet sie mit `as_of=2026-10-03T12:00:00Z` aus. Wiederholter Lauf erzeugt keine Duplikate.
## Tests
Lokal, isolierter Stack (tmpfs, kein Dev-/Prod-Volume):
```sh
docker compose -f docker-compose.test.yml up --build --abort-on-container-exit --exit-code-from api
```
Nur Unit-Tests (ohne PostgreSQL), im Verzeichnis `backend/`:
```sh
pytest tests/unit -ra --tb=short
```
Auf dem Server nach Dev-Deploy (Gitea `test.yml`): pytest gegen `buyingagent_test` auf dem Dev-Postgres plus Smoke gegen `http://192.168.2.49:8095/health/ready`.
## Datenmodell (global)
Product, ProductVariant, Offer, PriceObservation, AttributeDefinition und Source sind **systemweit** und haben keine `user_id`/`workspace_id`. Workspace, BuyingProject und Benutzer kommen später und dürfen diese Daten nicht duplizieren.
Profile und Evaluationen können bereits parallel existieren; es gibt kein globales „aktuelles Kaufvorhaben“.
## Scoring `generic-v1`
- Preference-Strategie nur `numeric_linear`. Unbekannte Strategien werden beim Profil abgewiesen.
- `product_eligibility`, `offer_eligibility` und `overall_eligibility` sind getrennt.
- PriceScore ist eine reine Funktion über `current_price`, `reference_history` und `budget`. v0.1 setzt `price_reference_scope=offer`.
- DealScore nur bei `overall_eligibility=ELIGIBLE` und vorhandenem PriceScore.
- Klassifikation am **ungerundeten** DealScore; Anzeige auf zwei Dezimalen, `ROUND_HALF_UP`.
- Geld intern `Decimal`/`NUMERIC(12,2)`, in der API als Dezimalstring.
Referenzfall A (synthetisch): ProductScore 90.21, PriceScore 98.24, DealScore 93.42, `EXCEPTIONAL`. Das ist keine Marktaussage.
## Fehler
Einheitliches Format `{error: {code, message, details}}`. 404 fehlende ID, 409 Konflikt/abweichender Wiederholungsimport, 422 ungültige Payload. Eine fachlich negative Evaluation ist HTTP 201.
## Grenzen von v0.1
Keine Web-UI, keine Authentifizierung, keine Workspaces, kein BuyingProject, kein n8n, keine externen Quellen, keine Auto-Discovery, keine Wechselkurse, keine Variant-/Market-Level-Preisaggregation, keine Plugin-Infrastruktur.
## Server
| Umgebung | Branch | Verzeichnis | API |
|---|---|---|---|
| Development | `develop` | `~/docker/buyingagent-dev` | `http://192.168.2.49:8095` |
| Production | `main` | `~/docker/buyingagent` | `http://192.168.2.49:8006` |
Repo: `http://192.168.2.144:3000/Lars/BuyingAgent.git`