Arrival screen (lock-box reveal)
/p/{token}/arrival is the lock-box code + arrival instructions page.
Three deliberately distinct branches that mirror the T-0 email logic:
States
| When | What renders |
|---|---|
| Before 14:00Z on arrival day | ”Your code will appear on the morning of {date}” — code never visible |
| Arrival day, pre-check-in NOT complete | Red CTA: “Pre-check-in required” with link to /p/{token}/pre-checkin — code still hidden |
| Arrival day, pre-check-in complete | Full reveal: code + arrival_message_body + check-in form CTA |
The 14:00Z cutoff (= 8am MT in MDT) is identical to when the T-0 email
fires from runPreArrivalT0 in pre-arrival-messages.ts. The two
delivery surfaces stay in lock-step intentionally — if we relaxed the
portal gate, we’d defeat the whole “morning of arrival” design.
Why three states (not two)
The middle state — arrival day + pre-check-in incomplete — exists because a guest who skips pre-check-in still has a working portal link from earlier emails. If we only had “before/after arrival day” gating, they’d see the code without ever completing pre-check-in. That breaks the T&Cs + payment-on-file workflow.
Code visibility audit
The code string appears in HTML only inside the
renderArrivalReveal branch. The other two branches assemble HTML
without referencing prop.lock_box_code at all — grep-able for
sanity:
$ grep -n "lock_box_code" src/routes/portal.ts# only inside handleArrivalScreen → renderArrivalRevealResponse sets Cache-Control: no-store to keep the code out of any
intermediary cache.
Template substitution
property_config.arrival_message_body is the per-unit body text
configured by Bill. It supports two substitutions:
{firstName}→ booking guest’s first name{lockBoxCode}→ property’slock_box_codecolumn
The same template is used by renderT0WithCodes so a guest gets the
same text in the email and on the portal screen.
Fallback
If arrival_message_body is empty (property not yet configured),
the portal still shows the code with a minimal “Your lock-box code
is X” sentence. The T-0 email also alerts Bill in that case (see
pre-arrival-messages.ts).
Source
- Route:
src/routes/portal.tshandleArrivalScreen+ the threerenderArrival*helpers - T-0 email parallel:
src/workflows/pre-arrival-messages.tsrenderT0WithCodes/renderT0NoCodesYet - Tests:
test/routes/portal.test.ts— three M4 cases (pre-arrival, arrival-day-no-checkin, arrival-day-w-checkin)