Skip to main content

Part 3 — Resident Preferences & Onboarding

Part-DR of Notify-Me (CU-86c1p963g). Produces the resident-side input to Part 4 engine. How a resident says what they want to hear about.

TL;DR

A resident chooses which ontology tags they care about; their choices are stored as leaf keys in users.notify_categories (JSON string[], ) and edited from their profile. The picker is topic-first (Gali's conversational flow: pick topics, then only the relevant follow-ups) and lives inside the resident's real profile. v1 persists interest keys; channels + frequency + per-branch answers are the next persistence step.

Data model ()

  • users.notify_categories?: string[] (apps/user/src/entities/user.entity.ts) — the resident's chosen ontology leaf keys. Nullable/empty = opted-out (no digest), i.e. opt-in semantics.
  • Consent = existing community membership + users.enable_general_notifications (Aviad-approved: v1 needs no new consent screen).

Future persistence (v2)

Beyond notify_categories, the spec's richer model: per-topic branch answers (emergency Type/Severity-threshold/District, event Audience/type, perk type/District), channels (Email/SMS/WhatsApp/Push), and frequency (immediate / daily / weekly). Store as a notification_preferences document/JSON on the user. v1 keeps only the interest keys; channels are client-side for now.

API ( — external-gateway, JwtAuthGuard, @User('userId'))

apps/external-gateway/src/controllers/user/notify-categories.controller.ts, under /api/v2/users:

  • GET /self/notify-categories/options — the active taxonomy (resident picker source).
  • GET /self/notify-categories — the resident's chosen keys (string[]).
  • PUT /self/notify-categories — update ({ categories: string[] }).

Surface

  • /profile/notifications in the consumer (bewith-consumer-frontend): interest picker rendering the 10 categories → concept groups → selectable leaf-tag chips, plus a channels section. Loads current selection, persists on Save. Embedded in the real Yii profile via iframe (?token=&embedded=1, site/dev-login), RTL, under the profile "Notifications" tab.
  • Uses MUI + BeWith DS token values, not literal DS components: the consumer pins DS 2.4.55 + MUI 7 and the DS components crash under MUI 7 (theme.alpha is not a function). Dependency: fixing the DS↔MUI7 incompatibility (a design-system-package task) unblocks native DS components here.

Resident visibility rule

A resident sees the org's categories + the categories of the communities they're subscribed to (with any org/community alias labels applied). The options endpoint returns canonical; alias resolution + scoping-by-membership is the enrichment step.

Decisions locked

  • Consent via existing membership + enable_general_notifications (no new consent screen in v1).
  • Interest stored as notify_categories leaf keys (NOT the legacy preferred_categories).
  • Topic-first conversational onboarding; editable anytime from the profile.
  • Emergencies always immediate regardless of frequency (see Part 4).

Open questions

  • Channels/frequency/branch-answer persistence (the notification_preferences shape) — v2.
  • Empty-column default (all vs none) — resolved to none/opt-in for v1.
  • Per-topic channel routing (SMS for emergencies, email for the rest) — spec OQ7, future.

Testing

  • Load reflects the DB selection; Save writes notify_categories. Acceptance: loading reflects the stored selection and saving persists it.