Files
XC_VM/tests
Divarion_D 559d7347c4 feat(reseller): dashboard location map, live connections and recent media
Dashboard half of Rosmi720/XC_VM@8fa1e67f, which 78d7b232 left out over
tenant scoping. Same three panels, built on the endpoints that already
enforce the reseller's scope instead of on fresh SQL in the controller.

- Connections by Location: world map plus a top-countries breakdown, from
  one `lines_activity` query joined onto `lines`. Gated on
  save_closed_connection + dashboard_map and only ships jsvectormap once
  there is something to paint, mirroring the admin dashboard.
- Live Connections: the ./table?id=live_connections serverSide table the
  Live Connections page uses, five rows, kill button included. Rendered
  only with reseller_client_connection_logs.
- Recently Added: Streams / Movies / Episodes tabs over
  ./table?id=streams|movies|episodes, newest first. Rendered only with
  can_view_vod.
- Recent Activity and Expiring Lines become DataTables (sort, search,
  paging) instead of fixed-height scroll boxes.
- Activity rows: text-dark / text-secondary -> text-body /
  text-body-secondary. The Bootstrap 5.3 `text-dark` is near-black, so
  those links were unreadable on the dark skin.
- Tolerate a request that lost its user: the controller and the shell now
  fall back to '' / 0 instead of fataling on $rUserInfo['username'] and
  ['member_group_id'].

Changed on import:
- No unscoped fallbacks. Upstream re-ran the country, movie and live
  stream queries without the tenant filter whenever the scoped one came
  back empty, and never scoped series or episodes at all, so an empty
  reseller saw the whole panel's data. Empty scope now means empty panel,
  which is what ResellerTableRenderer does everywhere else.
- Drop the hardcoded 'EG' fallback for connections GeoIP could not place;
  those rows are left out of the map instead of being pinned to Egypt.
- $rCanVod reads the can_view_vod permission. Upstream set it to a literal
  true, which showed the media panels to resellers without VOD access.
- No CategoryService::getAll() alias and no category-name resolver: the
  table endpoints already return a resolved category per row.
- No stream_view links. That route is registered for admin only, so the
  per-row links and View buttons upstream added would 404 for a reseller.
  (Seven existing reseller views have the same dead link — separate fix.)
- Only the three strings the panels ask for, not all 138 upstream keys;
  the rest are already present or unreferenced.

Verified: 869 tests, make gates, CRAP gate, PHPStan. Visual layout still
wants a browser pass.

Refs: #148
2026-09-22 22:29:06 +03:00
..