Corp/backend/commerce/README.md
2026-08-17 18:38:22 +03:00

52 lines
2.0 KiB
Markdown

# Commerce analytics core
`commerce` is the product-centric analytics boundary of EUSRR. It does not
replace an operational CRM or warehouse. External and future internal systems
all supply records to the same canonical product model.
## Stable model
- `Product` is one sellable or stockable SKU. `parent` groups variants.
- `SourceRecord` retains the latest raw payload with source provenance.
- `ProductBinding` maps a source product/offer identifier to `Product`.
- `Sale` and `SaleLine` contain normalized product-level sales facts.
- `Cost` contains commissions, delivery, advertising and other expenses.
- `StockSnapshot` contains point-in-time stock observations by source and
warehouse.
Money is never aggregated across currencies. Returns are represented as a
`Sale` with `event_type="return"`; line values remain positive and analytics
applies the sign.
## Integration contract
An adapter subclasses `commerce.integrations.SourceAdapter`, handles API
pagination internally and yields `ExternalRecord` objects. Register it in
`adapter_registry`, then invoke the Celery task `commerce.sync_source`.
Adapters must not store credentials in `SourceSystem.metadata`; secrets belong
in environment-backed configuration or a dedicated encrypted credential
store.
Source-specific code must not create alternative product models. It stores the
raw payload first and then resolves a product through `ProductBinding` or
`commerce.services.match_product` before writing normalized facts.
## API
The authenticated API is mounted at `/api/v1/commerce/`:
- `products/`
- `products/{id}/analytics/`
- `sources/`
- `product-bindings/`
- `sales/`
- `sale-lines/`
- `costs/`
- `stock-snapshots/`
All employees may read. Writes require staff status or the corresponding
Django model permission. The frontend management screen can bootstrap and
correct normalized records manually; integrations should still write them
through application services so raw provenance and idempotency are preserved.