96 lines
4.0 KiB
Markdown
96 lines
4.0 KiB
Markdown
# 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`
|