refactor: remove convention-based identity field fallback
All checks were successful
build-and-release / build (push) Successful in 2m23s
All checks were successful
build-and-release / build (push) Successful in 2m23s
Pre-fill is now purely schema-driven: only fields explicitly marked identity_shared: true by an admin in the Onboarding Schema Editor are pre-filled when registering a second role. No implicit convention set. SwitchServicesPage now passes the full existing profile to RoleWizard; RoleWizard filters to identity_shared fields using the new role's schema. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1df875ed36
commit
09a5c36310
2 changed files with 17 additions and 44 deletions
|
|
@ -2,7 +2,7 @@ import { For, Show, createSignal, onMount } from 'solid-js';
|
||||||
import { RefreshCw, ArrowLeft } from 'lucide-solid';
|
import { RefreshCw, ArrowLeft } from 'lucide-solid';
|
||||||
import { BTN_GHOST, BTN_PRIMARY, CARD } from '~/components/DashboardShell';
|
import { BTN_GHOST, BTN_PRIMARY, CARD } from '~/components/DashboardShell';
|
||||||
import RoleWizard from '~/components/dashboard/RoleWizard';
|
import RoleWizard from '~/components/dashboard/RoleWizard';
|
||||||
import { roleKeyToPrefix, isIdentityField } from '~/lib/role-utils';
|
import { roleKeyToPrefix } from '~/lib/role-utils';
|
||||||
|
|
||||||
const API = '';
|
const API = '';
|
||||||
const NAVY = '#0D0D2A';
|
const NAVY = '#0D0D2A';
|
||||||
|
|
@ -48,29 +48,23 @@ const REGISTER_OPTIONS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the user's active role profile and extracts doc URLs for fields
|
* Fetches the user's active role profile and returns all string-valued fields.
|
||||||
* that are identity fields (shared across roles). These are passed as
|
* RoleWizard will filter this down to only fields marked `identity_shared: true`
|
||||||
* `prefilledDocs` to RoleWizard so the user doesn't have to re-upload
|
* in the new role's onboarding schema — so the filtering is schema-driven, not
|
||||||
* Aadhaar / PAN / selfie etc. when registering a second role.
|
* convention-based.
|
||||||
*/
|
*/
|
||||||
async function fetchSharedIdentityDocs(activeRoleKey: string): Promise<Record<string, string>> {
|
async function fetchExistingProfile(activeRoleKey: string): Promise<Record<string, string>> {
|
||||||
if (!activeRoleKey) return {};
|
if (!activeRoleKey) return {};
|
||||||
try {
|
try {
|
||||||
const res = await apiFetch(`/api/profile?roleKey=${activeRoleKey}`);
|
const res = await apiFetch(`/api/profile?roleKey=${activeRoleKey}`);
|
||||||
if (!res.ok) return {};
|
if (!res.ok) return {};
|
||||||
const data = await res.json().catch(() => ({}));
|
const data = await res.json().catch(() => ({}));
|
||||||
const profile: Record<string, unknown> = data?.profile_data ?? data ?? {};
|
const profile: Record<string, unknown> = data?.profile_data ?? data ?? {};
|
||||||
|
const result: Record<string, string> = {};
|
||||||
// Keep only string values (URLs / field values) for fields whose key
|
|
||||||
// looks like an identity document — we don't know the schema here, so
|
|
||||||
// we use the convention-based check (adminFlagged = false).
|
|
||||||
const shared: Record<string, string> = {};
|
|
||||||
for (const [key, val] of Object.entries(profile)) {
|
for (const [key, val] of Object.entries(profile)) {
|
||||||
if (typeof val === 'string' && val && isIdentityField(key, false)) {
|
if (typeof val === 'string' && val) result[key] = val;
|
||||||
shared[key] = val;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return shared;
|
return result;
|
||||||
} catch {
|
} catch {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
@ -136,8 +130,8 @@ export default function SwitchServicesPage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch identity docs from the user's current active role to pre-fill
|
// Fetch existing profile — RoleWizard filters to identity_shared fields
|
||||||
const shared = await fetchSharedIdentityDocs(activeRole());
|
const shared = await fetchExistingProfile(activeRole());
|
||||||
setSharedDocs(shared);
|
setSharedDocs(shared);
|
||||||
|
|
||||||
await loadRoles();
|
await loadRoles();
|
||||||
|
|
|
||||||
|
|
@ -22,34 +22,13 @@ export function roleKeyToPrefix(roleKey: string): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Field IDs that are considered "shared identity" documents by convention
|
|
||||||
* when the onboarding schema has not explicitly marked them with
|
|
||||||
* `identity_shared: true`. Admins can use these IDs to get automatic
|
|
||||||
* pre-fill from the user's active role — or they can mark any field with
|
|
||||||
* `identity_shared: true` to opt into pre-fill explicitly.
|
|
||||||
*/
|
|
||||||
export const CONVENTION_IDENTITY_FIELD_IDS = new Set([
|
|
||||||
"aadhaar",
|
|
||||||
"aadhaar_card",
|
|
||||||
"aadhaar_number",
|
|
||||||
"aadhar",
|
|
||||||
"pan",
|
|
||||||
"pan_card",
|
|
||||||
"pan_number",
|
|
||||||
"passport",
|
|
||||||
"passport_number",
|
|
||||||
"selfie",
|
|
||||||
"profile_photo",
|
|
||||||
"photo_id",
|
|
||||||
"address_proof",
|
|
||||||
"government_id",
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true when a field should be pre-filled from the user's existing
|
* Returns true when a field should be pre-filled from the user's existing
|
||||||
* profile across roles (either admin-flagged or matched by convention).
|
* profile across roles. Only fields explicitly marked `identity_shared: true`
|
||||||
|
* in the onboarding schema (by an admin in the Schema Editor) qualify —
|
||||||
|
* there is no convention-based fallback so behaviour is always explicit and
|
||||||
|
* auditable.
|
||||||
*/
|
*/
|
||||||
export function isIdentityField(fieldId: string, adminFlagged: boolean): boolean {
|
export function isIdentityField(_fieldId: string, adminFlagged: boolean): boolean {
|
||||||
return adminFlagged || CONVENTION_IDENTITY_FIELD_IDS.has(fieldId);
|
return adminFlagged;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue