A coordinator types once. The tag carries the audience and helps scope the encryption. Only matching devices can decrypt.
Four standalone categories, plus a Support family with four sub-types. Each one is color-coded everywhere it appears.
A coordinator picks a type code, a city, and the audience roles. The system handles everything else.
Eight options across two groups. The code sets banner color, priority, and inbox grouping — pick by meaning, not by styling.
One specific city — or ALL to reach every region. The chosen value lands in the tag's CITY= segment.
Tap any combination — sorted alphabetically and joined with _. Empty selection means ALL.
The three chips compile into the tag — and the scope segment is auto-derived from city + roles. The message itself stays human-readable.
The tag isn't just an audience label — combined with a shared app key, it scopes the encryption. Only devices that match can derive the key and decrypt.
Five segments, joined by ::. Versioned at the front — the system can evolve without breaking older messages already in flight.
One of GLOBAL, AREA, ROLE, or ROLE_AREA — chosen by whether city and roles are specific or both ALL. No checkbox to flip.
The body is encrypted with a random per-message AES-GCM key. That key is then sealed using HKDF-SHA256 over a shared app key and the tag — so opening it needs both.
Every broadcast carries a versioned tag — the audience selector and one input to the message's encryption, in the same string.
Three quiet design decisions that make targeted broadcasts trustworthy.
Every broadcast carries a versioned tag — the audience selector and the encryption recipe in the same string.
Each code keeps the same color across compose UI, banners, inbox, and audit log. One glance tells you what kind of message this is.
Broadcasts auto-expire after 300 days. Old messages don't pile up in inboxes, don't haunt new staff, don't bloat storage. The audit log keeps the record; the live feed stays clean.