# Module: usermgmt (`b2g_usermgmt/`)
Purpose: registration, login/JWT issuance, users/roles, subscriptions & payments, consultant/auditor hubs, dashboards, Zoho + BGI Bridge sync. Owner: Sanjay.
Entry points: `modules/lng/controllers/LoginController.php` + `controllers/AuthController.php` (mint JWTs); `modules/reg/controllers/RegistrationController.php` (~6.6k lines); `modules/apium/{controllers/UmController.php,components/UmComponent.php}` (~5k/4k lines); `modules/subm/` (subscriptions, invoice/receipt PDFs); `modules/{conshub,audithub,sectorpartner,dashboard,digi,drv,BuyerRegistration}`; console `commands/` (Cron, Zohosync, QuarterwiseEmission, Nibereg) + `cron/*.bat`. Kong: `/usermg/web` (:80), `/api` (:81).
Data: `bgi_b2g_reg_*` — key tables: `usermst_tbl`, `membercompanymst_tbl`, `memberregistrationmst_tbl`, `rolemst_tbl`, `rolemappingdtls_tbl`, `memcompinvoicedtls_tbl`, `memcomppymtinfodtls_tbl`, `quarterwiseemissiondtls_tbl`. Master tables (`designationmst_tbl`, `basemodulemst_tbl`, `stkholderaccessmst_tbl` …) live in `bgi_b2g_master_*` and are fetched from micro, never SQL-joined.
Calls: micro (`MICRO_BASE_URL` → `masterServiceUrl`, most-used), mail (`MAIL_BASE_URL`), gmarketapi (`GMARKETAPI_BASE_URL`), digitall (`DIGITALL_BASE_URL`), zohoapi (`ZOHOAPI_BASE_URL`), filemst (`FILEMST_BASE_URL`/`FILEMST_PUBLIC_URL`), subpayment checkout (`SUBPAYMENT_BASE_URL`), fe-b2g assets for mPDF (`FE_B2G_BASE_URL`); external BGI Bridge (`BRIDGE_BASE_URL`, `modules/reg/components/Bridge.php`) — all merged in `config/params-{env}.php`.
Env selection: `APP_ENV` first, else `HTTP_HOST` (demo/prod domains, else local) — see `config/web.php`.
Invariants:
- `jwtSecret` must match every sibling backend; this service mints the tokens they verify.
- `user.enableSession=false` must stay (JWT-only; a PHP session lock serializes a browser's concurrent requests).
- App-to-app endpoints (`apium/filesync`, zoho sync) authenticate with an `X-Sync-Secret` shared secret, not a JWT.
- Never add a cross-DB SQL join to master or digitall tables — go through the owning service's API.
Gotchas:
- Files over the curl-timeout baseline (`ci/curl-timeout-baseline.txt`): `UmController`, `SubscriptionManagementController`, `reg/components/Bridge.php`, `RegistrationController`s — counts may only go down.
- Without `ZOHOAPI_BASE_URL`/`SUBPAYMENT_BASE_URL` the `$host`-based defaults point back at usermgmt itself (404s seen on demo).
- `controllers/testRegistrationController.php` also declares `app\controllers\RegistrationController` — dead duplicate, don't route to it (verify).
- Root holds scratch/test scripts (`test_*.php`, `scratch/`) — not served (docroot is `web/`/`api/`), but don't extend them.
- Log mirroring is still `FileTarget` → `/proc/self/fd/2`; confirm StderrLogTarget fix status (verify). `api/index.php` hardcodes `YII_DEBUG=true`.
- `vendor/` not committed; Dockerfile installs it.
Prod debugging: CloudWatch `/ecs/b2g-prod/usermgmt` (demo: `/ecs/b2g-demo/usermgmt`); health `GET /healthz` on :80; ECS service `usermgmt`, task family `b2g-usermgmt` / `b2g-demo-usermgmt`. Runbooks: `docs/runbooks/`.
