# Safe test fixtures (A1 isolation) Use this when writing tests, Postman, scripts, mock-llm, or i18n checks. **Do not clutter the A1 customer tenant.** Canonical identity details: [demo-user.md](demo-user.md). Mock LLM: [mock-llm.md](mock-llm.md). ## Safe identity (default for QA / CI / mock-llm / i18n) | Field | Value | |-------|--------| | Email | `demo@descrybe.local` (alias `demo@descrybe.test`) | | Password | `DemoPass123!` | | Company | **Platform Demo** | | Plan | **Platform Demo** (custom, high credits, all gates ON) | | API key | `dk_demo_local_descrybe_test_key_v1` → **Platform Demo only** (`seed-demo`) | Rules: 1. Login / session / BYOK / Content Language / UI locale → **demo@** + **Platform Demo**. 2. Public `/api/v1` smoke with the demo key → **Platform Demo** catalog only. 3. Integration tests that need a `users.id` → resolve **exact** `demo@descrybe.local` (then `.test`). Never `LIKE '%a1%'` and never “any recent user”. 4. Ephemeral companies in tests (e.g. `pipeline-llm-mock-co`) are fine; still attach jobs to the demo user id when a FK is required. ## A1 customer identity (explicit only) | Field | Value | |-------|--------| | Email | `a1-primary@descrybe.local` | | Password | `DemoPass123!` | | Company | **A1 Slovenija** (`604f23a8-b66e-4b21-8b45-0d72b68f4790`) | | Legacy MySQL id | `97e1a309-3d23-4aa2-b518-8e8d7afdfec7` | | API key | Create under A1 (Settings → API keys while switched to A1). **Never** reuse `dk_demo_local_descrybe_test_key_v1`. | Use A1 only for dump-faithful billing, legacy nav, or seed-a1 catalog/job recovery. Prefer Admin → Users → Switch to user rather than binding demo into A1. ## Cohort detection (code) `billing.IsA1CohortCompany(legacyCompanyID, companyName)` — **exact** matches only: - `legacy_company_id` = `97e1a309-3d23-4aa2-b518-8e8d7afdfec7` - company name EqualFold: `A1 Slovenija`, `Local Demo Co` (old rename), `A1` **Never** `LIKE '%a1%'` / substring email filters (false positives). Covered by `TestIsA1CohortCompany`. `Local Demo Co` is treated as an A1 cohort **alias**, not as the staff sandbox. The staff sandbox name is **Platform Demo**. ## Postman | Collection | Tenant | Key | |------------|--------|-----| | `Descrybe-v2-Demo-A1-all-v1.postman_collection.json` (Platform Demo surface) | Platform Demo | `dk_demo_local_descrybe_test_key_v1` | | `Descrybe-v2-A1-two-EANs.postman_collection.json` | A1 Slovenija | `REPLACE_WITH_A1_SCOPED_API_KEY` | Platform Demo collection vars ship as `RESOLVE_FROM_PLATFORM_DEMO` — resolve feeds/products/export tokens after `seed-demo` before mutate calls. Never paste A1/Elkotex UUIDs into the Demo collection. ## Seed commands | Command | Effect on A1 | |---------|----------------| | `go run ./cmd/seed-demo` | Ensures Platform Demo; binds demo users **only** there as **admin**; demo API key on Platform Demo; does **not** overwrite A1 wallet/plan | | `go run ./cmd/migrator -list-member-memberships` | Read-only inventory of active `role=member` rows (prints `a1=…`). Demo already admin → usually absent | | `go run ./cmd/migrator -promote-company-admins` | Promote non-A1 `member`→`admin` (`-email` / `-user-id` / `-company-id` + `-dry-run` or `-confirm`). **Never** promotes `a1=true` | | `go run ./cmd/seed-demo -purge-smoke-eans` | Hard-deletes process-smoke EANs (`8700999...`) from **Platform Demo only** (refuses A1). No product soft-delete API — see also `scripts/cleanup-process-smoke-eans.sql` | | `npm run seed:a1` / `cmd/seed-a1` | Explicit A1 reimport — intentional customer data | | `cmd/seed-a1-reset-processing` | Clears A1 processing history only | | `-claim-richest` on seed-demo | Opt-in; can touch richest catalog — leave **false** for isolation | ## Quick anti-patterns | Do not | Do instead | |--------|------------| | Process / enhance under A1 for mock-llm | Platform Demo + mock-llm | | Demo API key + A1 `companyId` / Elkotex IDs | Matching tenant for key and IDs | | `WHERE email NOT LIKE '%a1%'` | Exact `demo@descrybe.local` / `.test` | | Bind `demo@` memberships to A1 | `bindDemoUserToCompanyOnly` / seed-demo | | Rename A1 → Local Demo Co | Keep dump name **A1 Slovenija** |