# SKU synchronisation

Apply the new schema before starting workers:

```bash
python manage.py migrate
```

Redis defaults to `redis://localhost:6379`. Override `CELERY_BROKER_URL` and
`CELERY_RESULT_BACKEND` in environments that use a managed Redis service.

Celery Beat uses `task_scheduler.scheduler.DatabaseScheduler`. Periodic
schedule definitions and their last-run state are stored in the
`task_scheduler_periodictask` table through Django's MySQL connection. The
migration seeds the cart, viewed, and never-synchronised schedules. They can
be enabled, disabled, or edited from Django Admin without restarting Beat;
changes are detected within five seconds by default. Override
`CELERY_BEAT_MAX_LOOP_INTERVAL` to change that polling interval.

Run exactly one Beat process. Multiple Beat processes can publish the same
periodic task more than once.

The `Procfile` defines Celery Beat and separate workers with these queues and
concurrency levels:

```text
cart:  8
view:  4
never: 2
```

For a non-Procfile deployment, run the equivalent processes:

```bash
celery -A mama_care_api beat --loglevel=INFO --scheduler task_scheduler.scheduler:DatabaseScheduler
celery -A mama_care_api worker -Q cart --concurrency=8 --loglevel=INFO
celery -A mama_care_api worker -Q view --concurrency=4 --loglevel=INFO
celery -A mama_care_api worker -Q never --concurrency=2 --loglevel=INFO
```

Supplier requests use the country, currency, and language from the latest
successful `AliExpressProductSave` record for the product. Personal benefits
are always excluded from synchronization requests.

The mobile product-detail request must include both `parentId` and
`shoppingAccountId`. It only upserts `ProductView`; synchronization remains a
Beat-owned background operation.

Checkout uses the shopping account store currency and calls the supplier
synchronously. It returns `PRODUCT_VALIDATION_FAILED`, `INSUFFICIENT_STOCK`, or
`PRICE_CHANGED` before creating an order when validation fails.
