@i4e/invest4edu-access-core 0.39.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i4e/invest4edu-access-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Shared access-control primitives for NeoFindesk: tenant keystone, role capabilities, reportee tree, entity/role vocabulary, mobile app identity, feature flags, and the unified access engine (registry schema, snapshot resolver, visibleWhen).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -124,6 +124,15 @@ export const DEFAULT_CLIENT_PROFILE_SETTINGS = deepFreeze({
|
|
|
124
124
|
change_request: {
|
|
125
125
|
ttl_minutes: 10,
|
|
126
126
|
},
|
|
127
|
+
corrections: {
|
|
128
|
+
// Details a client cannot change in the app; asking sends their RM a WhatsApp and an email.
|
|
129
|
+
fields: ["client_name", "pan_card_no", "primary_mobile"],
|
|
130
|
+
},
|
|
131
|
+
ucc_followup: {
|
|
132
|
+
// A client's app edit to one of this product's UCC fields is never pushed to BSE by the client:
|
|
133
|
+
// the profile is flagged for backoffice / the RM to run the UCC update (uccfieldrules).
|
|
134
|
+
product_code: "mf",
|
|
135
|
+
},
|
|
127
136
|
goals: {
|
|
128
137
|
partner_goal_requires_approval: true,
|
|
129
138
|
corporate_goals_stay_with_corporate: true,
|
|
@@ -138,6 +147,8 @@ export const DEFAULT_CLIENT_PROFILE_SETTINGS = deepFreeze({
|
|
|
138
147
|
goal_rejected: "client.goal.rejected",
|
|
139
148
|
goal_share_requested: "client.goal.share_requested",
|
|
140
149
|
goals_share_requested: "client.goals.share_requested",
|
|
150
|
+
profile_correction_requested: "client.profile.correction_requested",
|
|
151
|
+
ucc_update_pending: "client.profile.ucc_update_pending",
|
|
141
152
|
goal_shared: "client.goal.shared",
|
|
142
153
|
goal_share_revoked: "client.goal.revoked",
|
|
143
154
|
relationship_attached: "client.relationship.attached",
|
|
@@ -202,6 +213,8 @@ export const CLIENT_PROFILE_SETTING_DESCRIPTIONS = Object.freeze({
|
|
|
202
213
|
"field_lock.lock_requires_kyc_verified": "The personal lock starts only once KYC is verified.",
|
|
203
214
|
"field_lock.lock_requires_ucc": "The personal lock starts only once a UCC exists.",
|
|
204
215
|
"change_request.ttl_minutes": "Minutes a corporate change request waits for the client's OTP.",
|
|
216
|
+
"corrections.fields": "Details a client asks their RM to correct (WhatsApp + email to the RM), never edits in the app.",
|
|
217
|
+
"ucc_followup.product_code": "Product whose UCC field rules (uccfieldrules) decide which client edits flag the profile for a UCC update.",
|
|
205
218
|
"goals.partner_goal_requires_approval": "Goals added by partners or employees wait for the client's approval.",
|
|
206
219
|
"goals.corporate_goals_stay_with_corporate": "Corporate-profile goals are never shown to main-profile partners.",
|
|
207
220
|
"events.profile_change_requested": "Event name: a corporate change was sent to the client.",
|
|
@@ -212,6 +225,8 @@ export const CLIENT_PROFILE_SETTING_DESCRIPTIONS = Object.freeze({
|
|
|
212
225
|
"events.goal_approved": "Event name: the client approved a goal.",
|
|
213
226
|
"events.goal_rejected": "Event name: the client rejected a goal.",
|
|
214
227
|
"events.goal_share_requested": "Event name: a partner asked to see a goal.",
|
|
228
|
+
"events.profile_correction_requested": "Event name: a client asked their RM to correct a detail they cannot edit.",
|
|
229
|
+
"events.ucc_update_pending": "Event name: a client changed UCC details in the app; backoffice / the RM must run the UCC update.",
|
|
215
230
|
"events.goals_share_requested": "Event name: a partner asked the client to share their goals (no goal named — R16).",
|
|
216
231
|
"events.goal_shared": "Event name: the client shared a goal with a partner.",
|
|
217
232
|
"events.goal_share_revoked": "Event name: the client stopped sharing a goal.",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UCC follow-up — which of a client's own app edits leave their UCC (BSE) out of date.
|
|
3
|
+
*
|
|
4
|
+
* A client never pushes to BSE from the app. When they change a detail the product's UCC field
|
|
5
|
+
* rules (`uccfieldrules`, one document per product) mark as synced to the UCC, the profile is
|
|
6
|
+
* flagged instead, and backoffice or the RM runs the UCC update from the web.
|
|
7
|
+
*
|
|
8
|
+
* Pure: the backend loads the rules document and applies the result.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The rules name a client's contact lists by their UCC meaning; the client record by its field.
|
|
13
|
+
* A data-model fact, not configuration — the two names never diverge per environment.
|
|
14
|
+
*/
|
|
15
|
+
export const UCC_RULE_NAME_OF_CLIENT_FIELD = Object.freeze({
|
|
16
|
+
phone_list: "mobile",
|
|
17
|
+
email_list: "email",
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
/** Rule names a client edit can leave out of date: warn-locked fields synced to the UCC, and
|
|
21
|
+
* collections (bank, nominees) whose tagged entries warn on edit. */
|
|
22
|
+
export function uccSyncedRuleNames(rules) {
|
|
23
|
+
if (!rules || rules.is_active === false) return [];
|
|
24
|
+
const fields = Object.entries(rules.fields ?? {})
|
|
25
|
+
.filter(([, rule]) => rule && rule.lock === "warn" && rule.syncEndpoint)
|
|
26
|
+
.map(([name]) => name);
|
|
27
|
+
const collections = Object.entries(rules.collections ?? {})
|
|
28
|
+
.filter(([, rule]) => rule && rule.edit_tagged === "warn")
|
|
29
|
+
.map(([name]) => name);
|
|
30
|
+
return [...new Set([...fields, ...collections])];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Of the client fields an edit touched, the ones that leave the UCC out of date — by the rule
|
|
35
|
+
* name backoffice will recognise ("mobile", not "phone_list").
|
|
36
|
+
*/
|
|
37
|
+
export function uccFieldsTouched(touchedClientFields, rules) {
|
|
38
|
+
const synced = new Set(uccSyncedRuleNames(rules));
|
|
39
|
+
const out = new Set();
|
|
40
|
+
for (const field of touchedClientFields ?? []) {
|
|
41
|
+
const ruleName = UCC_RULE_NAME_OF_CLIENT_FIELD[field] ?? field;
|
|
42
|
+
if (synced.has(ruleName)) out.add(ruleName);
|
|
43
|
+
}
|
|
44
|
+
return [...out];
|
|
45
|
+
}
|