File size: 3,095 Bytes
bf8519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | """Deep links into the app β ?page=<key>&entity=<kind>:<id>&src=<source>.
The app (app.py) consumes these params once per session right after login and routes to the page,
opening the entity drawer when an entity is present. Digest/alert/mention emails build their links
here so every emailed number lands the reader on the exact row it came from. `src` tags where the
click came from (digest / alert / mention) β the app logs it as the click-through read receipt.
"""
import os
import sys
from urllib.parse import quote
#: β THE ONE HOST LITERAL LEFT IN THE RUNTIME PATH, and it is a MIGRATION HAZARD β named here
#: rather than buried in a default argument, because the day we change hosts this is what silently
#: keeps mailing customers a link to the DEAD one. Found by `ops/verify_portability.py` on its
#: first run (2026-07-30).
#:
#: Why it is still here instead of raising: `deeplink()` has exactly one family of callers
#: (`modules/digest.py`, 7 sites, all building email hrefs), `DIGEST_ENABLED` defaults to ON, and
#: no deploy sets `APP_BASE_URL` today β so refusing to guess would break a LIVE feature to fix a
#: latent one. Instead: both deploy scripts now push `APP_BASE_URL`, which makes the fallback
#: unreachable in a deployed environment, and reaching it prints an operator warning.
#:
#: β EXIT CONDITION for this constant: once a deploy has set `APP_BASE_URL` and it is confirmed
#: present in the running environment, delete the fallback and let `deeplink()` raise instead. It
#: is declared in the portability gate's RESIDUALS so the gate reports it honestly rather than
#: reporting green over it.
_LEGACY_HF_FALLBACK = 'https://royal-imports-cfo-os.hf.space'
BASE_URL = (os.environ.get('APP_BASE_URL') or _LEGACY_HF_FALLBACK).rstrip('/')
#: Warned LAZILY and ONCE β at the first link actually built, not at import. An import-time print
#: fires in every gate, every subprocess and every unit test that so much as touches `core`, which
#: is how a real warning becomes noise nobody reads.
_WARNED = [False]
def _warn_once_if_defaulted():
if _WARNED[0] or os.environ.get('APP_BASE_URL'):
return
_WARNED[0] = True
print(f"[links] APP_BASE_URL is not set - emailed deep links will point at "
f"{_LEGACY_HF_FALLBACK}, which is correct ONLY while that is where the app lives. "
f"Set APP_BASE_URL in the deployed environment.", file=sys.stderr)
# entity kinds the URL scheme supports (must stay in sync with app.py's _desc_from_param)
LINK_KINDS = ('customer', 'sku', 'agent', 'account')
def deeplink(page=None, kind=None, ident=None, src=None):
"""An absolute app URL. deeplink('customer_data', 'customer', 1234, src='digest')."""
_warn_once_if_defaulted()
parts = []
if page:
parts.append(f"page={quote(str(page), safe='')}")
if kind in LINK_KINDS and ident not in (None, ''):
parts.append(f"entity={quote(f'{kind}:{ident}', safe=':')}")
if src:
parts.append(f"src={quote(str(src), safe='')}")
return BASE_URL + ('/?' + '&'.join(parts) if parts else '/')
|