# Module: digitall (`b2g_digitall/`)
Purpose: ESG/GHG reporting hub — scope 1/2/3 emissions, green surveys, CRIF/Synesgy ESG scoring & PDF reports, Breathe ESG integration, Keycloak SSO, third-party read API. Owner: Sanjay.
Entry points: `modules/esg/controllers/` (`EsgreportingController` ~5.3k lines, `GreensurveyController`, `SsoController`, `SynesgySyncController`, `EsgsyncdataController`); `modules/{sectorpartner,div,configuration,doc,extapi}`; `components/` (`Breathesg`, `BreatheEsgApiService`, `KeycloakService`, `SynesgyTokenService`, `CrifReportService`, `ConfmgmtApiClient`, `PackServiceClient`); console `commands/` (`SynesgyController` ~3k lines, `SyncEmission*`, `Crifreport`, `EsgCompanySync`) driven by root `*.bat` crons. Kong: `/digitall/web` (120s timeouts).
Data: `bgi_b2g_digitall_*` — key tables: `memcompesgscopeonetworeg_tbl`, `memcompscopeoneemissiondata_tbl`/`...two...`/`...three...`, `memcompsurveydtls_tbl`, `memcompsurveyscoredtls_tbl`, `memcompcrifreg_tbl`, `memcompbusinessunitsdtls_tbl`, `sso_session_tbl`. Some models read `bgi_b2g_reg_*` / `bgi_b2g_master_*` cross-schema via `params['regDbSchema']`/`['masterDbSchema']` table prefixes (e.g. `membercompanymst_tbl`, `countrymst_tbl`).
Calls: usermgmt (`USERMGMT_BASE_URL`), micro (`MICRO_BASE_URL`), profilemgmt (`PROFILEMGMT_BASE_URL`), confmgmt (`CONFMGMT_BASE_URL`, via Kong — `ConfmgmtApiClient` appends `/index.php/<route>`); external Breathe ESG, Synesgy/CRIF, Keycloak, GitBook.
Env selection: `APP_ENV` first, else `HTTP_HOST` (demo/prod domains, else local) — see `config/web.php`.
Invariants:
- `regDbSchema`/`masterDbSchema` in `params-{env}.php` must name the same tier's schemas (prod↔prod, demo↔dev). Note `params-local.php` currently points them at `*_prod` while `db-local.php` uses `bgi_b2g_digitall_dev` (verify intent).
- `extapi` is HttpBasicAuth (`params['extApiAuth']`), not JWT; it resolves `mcm_bridgecompid` via confmgmt's internal API (`X-Sync-Secret` = `confmgmtSyncSecret`), never by querying confmgmt tables.
- `jwtSecret` must match siblings (`HttpBearerAuth` + `JwtHelper`).
Gotchas:
- Breathe AI calls are synchronous and slow — Kong route is raised to 120s; ALB idle timeout must be ≥120s too. `Breathesg.php`, `ConfmgmtApiClient.php`, `PackServiceClient.php` are on the curl-timeout baseline.
- CRIF report PDFs are cached on local disk — ephemeral on Fargate (verify storage path).
- Crons are Windows `.bat` wrappers around `php yii ...`; how/if they are scheduled on ECS is unclear (verify).
- Stray files: `modules/esg/controllers/SynesgyS soController.php` (space in name, class `SynesgySsoController`), `*Fixed.php` duplicates of SSO/Keycloak — confirm which are live before editing.
- `encryptionKey` differs from the other services' value (verify whether intended).
- Log mirroring is still `FileTarget` → `/proc/self/fd/2`; confirm StderrLogTarget fix status (verify). `vendor/` not committed.
Prod debugging: CloudWatch `/ecs/b2g-prod/digitall` (demo: `/ecs/b2g-demo/digitall`); health `GET /healthz` on :80; ECS service `digitall`, task family `b2g-digitall` / `b2g-demo-digitall`. Runbooks: `docs/runbooks/`.
