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/notificationsin 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_categoriesleaf keys (NOT the legacypreferred_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_preferencesshape) — 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.