# Profiling details

## Base URL (example)

`https://userprofiledev.eatanceapp.com`

OpenAPI / Swagger: `https://userprofiledev.eatanceapp.com/docs`

---

## HTTP API

| Method | Path | Inputs | Body |
|--------|------|--------|------|
| `GET` | `/` | — | none |
| `GET` | `/profile/{user_id}` | `user_id` in path | none |
| `POST` | `/profile/create_profiling` | — | **JSON** (see below) |

---

### `GET /`

- **Example:** `https://userprofiledev.eatanceapp.com/`
- **Response:** Health JSON (includes `docs` path).

---

### `GET /profile/{user_id}`

- **Example:** `https://userprofiledev.eatanceapp.com/profile/12345`
- **Does:** Reads the **stored** published row only—no DB recompute, no LLM.
- **Response:** Parsed `profile_json` (sanitized: metadata, signals, statistics, …) **plus** a top-level **`deep_analysis`** field: markdown string if present, or `null` if not computed yet.
- **404** if there is no stored profile, empty/invalid JSON, or missing usable `metadata`.

---

### `POST /profile/create_profiling`

- **Example:** `https://userprofiledev.eatanceapp.com/profile/create_profiling`
- **Content-Type:** `application/json`
- **Body:**

```json
{
  "user_id": 12345,
  "days": 60
}
```

| Field | Type | Required | Default | Range |
|-------|------|----------|---------|--------|
| `user_id` | integer | yes | — | — |
| `days` | integer | no | `60` | `1`…`180` (lookback for orders / activity) |

- **Does:** Builds the deterministic profile from the DB for that window, runs **deep analysis** (LLM when applicable), upserts **`user_profiling`** (JSON + markdown).
- **Response:** `{ "deep_analysis": "<markdown string>" }`

---

### Other

- **Auth:** not on these routes; protect at network / gateway.
- **CORS:** env `CORS_ORIGINS` (comma-separated); unset → any origin.

---

## Tables (this service writes)

| Table | What we store |
|-------|----------------|
| `dbo.user_profiling` | Published `profile_json` + `deep_analysis_markdown` (one logical row per `user_id` after upsert) |
| `dbo.user_profiling_staging` | Same shape; batch workspace only until publish |
| `dbo.user_profiling_tracker` | `last_completed_at` per `user_id` (batch recency skip; updated on published/API upserts) |

**Order — API (`create_profiling`):** orchestrator persists via published upsert (per internal steps): delete published row(s) for that `user_id` → insert `user_profiling` → insert or update `user_profiling_tracker`.

**Order — scheduled batch:** from a clean start (`last_id` 0, no checkpoint): truncate `user_profiling_staging` → per user upsert staging → after a full successful scan, one transaction: delete published for users in staging → insert from staging into `user_profiling` → merge `user_profiling_tracker` → truncate staging.

*Reads* use operational tables (e.g. `users`, orders, `user_activity_logs`, …); not listed here.
