# DEPLOY — 5 September 2026

Two pieces of work. **No new table, no new column.** The migration below is a
proof-and-settings run, not a schema change.

---

## 1 · NEW FILES — upload these

| File | What it is |
|---|---|
| `includes/kyc_checkout.php` | The checkout-KYC engine: what the basket needs, the form, the save, the lock |
| `includes/pipeline.php` | The activity pipeline — the ladder, the desks, per-person access |
| `admin/login.php` | **NEW** — the staff door |
| `admin/includes/user_list_engine.php` | **NEW** — the user list itself, now shared |
| `admin/users_all.php` · `users_free.php` · `users_pro.php` · `users_seller.php` · `users_employee.php` · `users_deleted.php` | **NEW** — six front doors, three lines each |
| `kycsmsmigration.php` | **root** — run once in a browser, then delete |

## 2 · MODIFIED FILES — replace these

| File | What changed |
|---|---|
| `includes/shares.php` | Admin approval is no longer a purchase gate; the gate now reports `collect` |
| `includes/kyc.php` | A saved KYC line can never be re-edited by the member; name / email / phone are written from the account |
| `includes/sms.php` | Reads the gateway's reply whatever its shape; new `sms_dlr()` delivery check |
| `checkout.php` | Verification form on step 1, contact boxes locked, KYC saved before the order is placed |
| `category.php` | Buy Now instead of "KYC Required" — it goes to the checkout page |
| `product.php` | Same, plus an amber note that details will be asked at checkout |
| `cart.php` | Missing KYC no longer blocks the basket |
| `kyc_extra.php` | An answered extra question is locked |
| `admin/sms_settings.php` | The approved-DLT-wording button, and the delivery-report check |
| `register.php` | The User ID / referral card is no longer shown on the success screen |
| `admin/activity_task.php` | **Rewritten** — the pipeline screen. The old 1572-line page is in `_to_delete/activity_task.php.old.bak` |
| `admin/includes/sidebar.php` | Activity & Task now lists All Tasks, KYC Requests, Seller Requests and Office; User Management points at the six new pages |
| `admin/user_list.php` | Now three lines — the engine does the work, and `?role=` still works so old links do not break |
| `includes/acl.php` | Five new permissions: `users.view_free`, `view_pro`, `view_seller`, `view_employee`, `view_deleted` |
| every other file in `admin/` | 52 sign-in redirects now go to the staff door instead of the member login |

## 3 · DO NOT UPLOAD

`smsconfig.php` was a one-time local tool. It has been moved to
`_to_delete/smsconfig.php.bak`. Everything it did now lives on the admin screen,
behind the admin login and the `website.sms` permission.

---

## 4 · ORDER OF DEPLOYMENT

1. Upload the two new files and the nine modified ones.
2. Open **`https://wbmcz.online/kycsmsmigration.php`** — it should say
   *Migration completed successfully*.
3. **Delete `kycsmsmigration.php` from the server.**
4. Open **Admin → Website Settings → SMS & OTP**, press **Send a test SMS**.
5. As a member, buy one KYC-gated service and check the verification form on the
   checkout page.

---

---

## 4b · ACTIVITY & TASK — REBUILT

The old screen asked an administrator to write criteria, look at "matching
people", and hand out tasks by hand. The new one is a line with four steps and
one desk:

    Lead  ->  KYC  ->  Refer
                   ->  Order          plus the KYC Pending Request desk

**Nobody moves anybody along.** The goal of a step is a fact about the member —
subscribed, KYC approved, has a referral, has an order — so the moment that fact
becomes true the step completes itself and the next one opens. A member who
subscribes leaves Lead on their own; a KYC that is approved opens Refer and
Order together.

**Staff record an outcome, not a status.** Interested · Follow up (with a date
and a remark) · Free user · Not interested. Dropping somebody needs a reason,
and a follow-up needs a date, or it is only a note.

**Two things float to the top by themselves** — a call-back due today or
overdue, and somebody nobody has been given yet.

**Not interested** leaves the list but is still counted on the tile above it,
and one click brings those rows back.

**Access is per person.** A tick opens one step for one member of staff, set
either while handing work over or from **Team access** in the header. Within a
step they still only see the people they hold. The owner account holds
everything.

**Where the rows come from.** Nothing is imported. A pass over `users` opens
every step that should be open and closes every one that has got what it wanted;
it runs when somebody opens the screen (at most once a minute) and on
**Refresh the line**. Up to 300 people are seeded per pass, so a first fill of a
large member list settles over a few page loads.

### The ladder

Under **User** and **Seller** the tabs are simply how far somebody has got:

    Lead  ->  Free User  ->  Subscription  ->  KYC  ->  Refer  ->  Order

**One person, one row**, and it climbs on its own. Five of the six rungs are
facts about the account — subscribed, KYC approved, has referred somebody, has
ordered — so the moment a fact becomes true the person appears under the next
tab. The sixth, **Free User**, is the one thing staff decide: mark somebody a
free user on the Update panel and they move there until they subscribe.

Because it is the same row all the way up, the remark, the call-back date and
the whole history travel with the person instead of being stranded on a task
nobody opens again. Each tab counts how many have **moved up from it**, which is
what a member of staff actually achieved.

The rung is worked out top-down — the highest true one wins — so nobody can be
in two places at once, and a first run merges the duplicate rows an earlier
design left behind.

### The six tabs

| Tab | What is under it |
|---|---|
| **User** | The ladder, plus the KYC request desk and Support |
| **Seller** | Seller Requests, then the same ladder, plus the seller KYC desk, Product Requests and Support |
| **Employee / Admin / Super Admin** | What each of them is carrying — open, call-backs due, completed, dropped — and which steps they can reach |
| **Office** | Wallet (withdrawal requests), Payout (approved, waiting for the money to go), Website Requests, and General — the pages that are edited rather than decided on |

### Handing work out

417 people and a page of 25 are not the same thing, so there are three settings:
the rows **ticked on this page**, **all of them on the rung**, or **the first N**
of them — with the count typed in, so work can be shared out in batches. The
order is the one on screen: overdue call-backs first, then people nobody holds.
The **Mine** tile shows what you are holding yourself.

### Rungs and desks

Only two kinds of screen exist under those tabs, and they behave differently on
purpose.

A **rung** is where somebody has got to. It is a fact about them, so they arrive
and leave on their own and nobody ticks "done".

A **desk** is a queue somebody decides on: seller requests, KYC submissions,
product listings, support tickets, withdrawals, payouts, website requests. Every
desk reads and writes the real table — a seller accepted here is a seller
accepted on `admin/upgrade_requests.php`, a product accepted here goes live the
same way `admin/product_management.php` would make it live. Nothing is copied,
so nothing can drift.

Each desk offers **Accept · Hold · Reject** with a remark. Hold is not a verdict:
it leaves the record where it is and keeps the note for us. Two desks bend the
wording to fit — Support reads *Reply &amp; close · Keep open · Close without
action*, and Payout asks for the **UTR number** in the remark before it will let
anything be marked paid.

---

## 4c · THE STAFF DOOR

`admin/login.php` is the way in for the people who run the place. It is **one
door, not three**: an employee, an admin and a super admin sign in with the same
credentials, and the door works out which they are — from `staff_level` if one
is set, otherwise from their role, and the owner account (no role at all) is
always a super admin. Three separate forms would have been three ways of typing
the same password into the same table, and sooner or later somebody picks the
wrong one and thinks their account is broken.

It takes a mobile, an e-mail **or** a staff code. A member who lands there is
sent to their own sign-in with a note, rather than told "wrong password" — their
password is not wrong, the door is.

Every page under `admin/` now sends a signed-out visitor here.

## 4d · USER MANAGEMENT, SPLIT

The list is six pages now — All, Free User, Pro User, Seller, Employees,
Deleted — each with its **own URL and its own permission**, so a member of staff
can be given the Free User list and nothing else.

They are three-line files. The table, the filters, the modals and the CSV export
live once, in `admin/includes/user_list_engine.php`. A column added there appears
on all six; a bug fixed there is fixed on all six.

Two things worth knowing:

* **The audience is set by the page, not the address bar.** `users_free.php` is
  the free-user list and no query string can widen it, which is what makes the
  separate permissions worth having.
* **Each list remembers its own filters.** A search on Sellers does not follow
  you to Free Users.

`user_list.php` still exists and still answers `?role=`, so every link and
bookmark made before the split keeps working.

---

## 5 · WHAT THE MIGRATION DOES

It checks, it sets, and for the pipeline it adds.

**Adds, for the pipeline** — `tasks.outcome`, `tasks.outcome_at`,
`users.task_access` and the small `pipe_reviews` table (accept / hold / reject
decisions), then fills the line for the first time.

**Checks** — that all the files are actually on the server; that
`kyc_details`, `kyc_custom_fields`, `kyc_custom_values`, `otp_codes` and
`sms_log` exist; that all forty columns the checkout form writes to are present
(and adds any that a very old database happens to be missing); that
`uploads/kyc/` and `uploads/kyc_extra/` exist and are writable.

**Sets** — the SMS settings that turn the OTP on:

| Setting | What it does | When it is left alone |
|---|---|---|
| `sms_sender_id` | `GUERAR` | if you have already put a header in |
| `sms_tpl_otp_register` | the approved DLT wording | if you have your own wording there |
| `sms_tpl_otp_reset` | the approved DLT wording | same |
| `sms_welcome_enabled` | `0` — it has no approved template, so it would be billed and dropped | if already off |
| `sms_enabled` | `1` | if already on |
| `sms_test_mode` | `0` | only switched off once the gateway details are complete |

Every decision is printed with its reason. Running it twice changes nothing the
second time.

---

## 6 · WHAT MEMBERS WILL NOTICE

* No more orange **KYC Required** button. Every product a member can buy in their
  area shows **Buy Now**.
* On the checkout page, name / mobile / email are shown greyed out with a lock —
  they are the ones from registration and support has to change them.
* Under them, a **Verification details** block asks for whatever that service
  still needs, grouped the way the KYC wizard groups it. Lines already on the
  record show greyed with *saved*.
* They cannot reach the payment step until every box is filled, so nothing is
  ever charged for an order that would then be rejected.
* After paying, those lines are locked everywhere — on the checkout page, on
  `profile.php#kyc`, and on `kyc_extra.php`. Only the office can correct them.
* Buying no longer waits for an admin to approve the KYC. Admin → KYC Pending
  still shows every submission.
* Service-area blocking is untouched.
* The success screen after signing up no longer shows the User ID as a referral
  code. Referring only pays once a subscription is taken, so handing somebody the
  code the moment they join invites them to share something that earns them
  nothing yet. The ID is unchanged and still on the dashboard and on Refer & Earn.

---

## 7 · STILL OPEN

The OTP text ends with *"This SMS has been sent from GuestRAR"* — that is the
reseller's brand, and members will read it. Sending under your own name needs
your own DLT entity, your own header and your own approved templates. No code
changes for that: only the Sender ID box and the two template boxes on the
admin screen.
