# TechTitans POS — One-Page New IPTV Connection

**Branch:** `techtitans/iptv-i2`. Replaces the 4-step New IPTV Subscription wizard with one compact,
responsive page. Reuses the existing I1/I2 backend (customer search/create, provider/plan catalogues,
renewal calc, encrypted credentials, idempotent create) — **no backend rebuild**. Not pushed.

## Task 1 — Inspected (reused, not rebuilt)

Existing form (`NewIptvPage.tsx` wizard), `iptvApi`/`customersApi`, `StoreIptvSubscriptionRequest`
validation, `IptvSubscriptionService::create` (idempotent + encrypted credential + MAC dedup),
`RenewalCalculator`, and the I1/I2 reports. All logic reused.

## Task 2 — One-page form (4 grouped sections)

`frontend/src/pages/iptv/NewIptvPage.tsx` — a single page, no step navigation:

- **A · Customer** — debounced search (name/phone/email), select, **inline "New customer" modal**
  (`customersApi.create`), selected-customer summary, Change (keeps other fields).
- **B · Connection details** — User login, Actual user, MAC id, Box model, **Provider / Portal** (select),
  **Subcontractor** (select), account credentials (masked password, encrypted server-side), Internal notes.
  **Inline "Add provider / Add subcontractor"** shown only with `iptv.configure`. Reference values come
  from the tenant catalogues (not hard-coded).
- **C · Subscription & pricing** — Plan (filtered by provider), Start date, **Service expiry** (auto-calc,
  overridable), Monthly charge (defaults to plan price), One-time box price, Status. The plan's selling
  price + tax class are shown read-only; no conflicting duplicate pricing fields are introduced
  (`monthly_charge_minor` = recurring override, `unit_price_minor` = one-time box, plan price = reference).
  A hint distinguishes **service expiry** (when IPTV ends, advanced by renewals) from payment due dates.
- **D · Notifications** — Send welcome email / SMS (default from the tenant settings), with a clear
  "no messages are sent in development" note.

## Task 3 — Reduced scrolling

Responsive two-column field grids, compact section headers (`A·/B·/C·/D·`), a **sticky Save/Cancel action
bar**, consistent TechTitans styling, and mobile/tablet-friendly single-column collapse. Inline-add blocks
appear only when permitted (collapsed otherwise).

## Task 4 — Smart input behaviour

- Customer search/select + inline create without leaving the page.
- Provider → **applicable plans filtered**; plan + start → **suggested expiry auto-calculated**
  (calendar-safe preview; the server derives it authoritatively when not overridden).
- Monthly charge **defaults to the plan price**; manual edits are preserved (a "touched" flag stops async
  loads / plan changes from overwriting entered values).
- **MAC duplicates** rejected by the backend (422 → inline field error); inline validation on required
  fields.
- Reference loads only populate their own dropdowns — typed values are never clobbered.

## Task 5 — Save confirmation

"Create connection" validates (customer + provider + user login required), then opens an **on-page confirm
summary modal** (customer, login, provider/portal, plan, expiry, monthly charge, credential set?,
notification choices) with **Back to edit** / **Confirm & create**. Nothing is saved until confirm; the
create is **idempotent** (one stable `X-Request-Id` per page). On success it navigates to the new account
detail page.

## Task 6 — Compatibility + the one additive backend change

Existing I1/I2 subscriptions, CRM links, encrypted credentials, provider/plan config, renewal history,
permissions and expiry calc are all preserved (I1 20 + I2 11 backend tests still green). The only legacy
field not yet backed was the **per-connection welcome choice** (legacy `mail_flag`/`sms_flag`): added
additively — `StoreIptvSubscriptionRequest` accepts `send_welcome_email`/`send_welcome_sms`, and
`IptvSubscriptionService` records welcome **eligibility** per chosen channel in `iptv_notification_log`
(real persistence, dedup-safe, **no send in dev**). No new table/column; no frontend-only faking.

## Task 7 — Tests

- **Backend** `IptvOperationsTest` — **11 passed** incl. the new "per-connection welcome choice records
  eligibility without sending". Full IPTV + catalog suite **37 passed** (no regression).
- **Frontend** `IptvPages.test.tsx` — **7 passed** incl. the one-page flow (search→select customer,
  provider→plan filter, user login + credential, **confirm summary → Confirm & create**, single idempotent
  POST) and a "does not submit until confirm" guard. `tsc` ✓, `eslint` ✓; customers suite green.
- **Browser** (Playwright, real servers, techtitans) `e2e/iptv-onepage.spec.ts` — **passed**: filled the
  single page, auto-calc expiry (2026-12-10) + auto-filled charge (CA$15.00), opened the confirm summary,
  created, and **reopened the saved account confirming the login + MAC persisted** (per-run unique
  account/MAC avoids the dedup rule). Screenshots in `frontend/test-results/iptv-onepage/`: `form.png`,
  `confirm.png`, `created-detail.png`.

## Changed files

- Frontend: `pages/iptv/NewIptvPage.tsx` (rewritten one-page form), `pages/iptv/iptv.css` (sections +
  sticky bar + summary + checks), `lib/api/iptv.ts` (welcome flags on the create body),
  `pages/iptv/IptvPages.test.tsx` (one-page tests), `e2e/iptv-onepage.spec.ts` (new).
- Backend: `Http/Requests/Api/V1/Iptv/StoreIptvSubscriptionRequest.php`,
  `Iptv/IptvSubscriptionService.php` (welcome-channel eligibility), `tests/Feature/Iptv/IptvOperationsTest.php`.

## Known limitations

- The provider/subcontractor inline-add uses a compact add box (not a full searchable combobox with
  type-ahead create) — adequate for the small catalogues; a richer type-ahead is a later polish.
- Welcome notifications record eligibility only; real email/SMS delivery is a later increment (off by
  default). Plan tax is applied by the money pipeline when billing is enabled (I2 boundary).

## Commit hashes (branch `techtitans/iptv-i2`, not pushed)

- Backend + report: see the latest `techtitans/iptv-i2` backend commit.
- Frontend: see the latest `techtitans/iptv-i2` frontend commit.
