/** * Centralised feature keys for the whole application. * * Every gateable thing in the app — module, screen, tab, menu entry, button and * action — has exactly one key here. UI code must never pass a raw string to the * feature service; always reference a member of this enum so renames and typos * are caught by the compiler. * * Keys use dot notation and the hierarchy is encoded in the key itself: * * loans → parent of * loans.apply → parent of * loans.apply.submit * * The feature service derives parent/child relationships from this path, so a * disabled parent automatically disables everything beneath it. Adding a child * key therefore only requires that its parent key also exists. */ export enum FeatureKey { // ---------------------------------------------------------------- Auth ---- AUTH = 'auth', AUTH_LOGIN = 'auth.login', AUTH_LOGIN_USER_ROLE = 'auth.login.userRole', AUTH_LOGIN_AGENT_ROLE = 'auth.login.agentRole', AUTH_LOGIN_BIOMETRIC = 'auth.login.biometric', AUTH_LOGIN_FORGOT_PASSWORD = 'auth.login.forgotPassword', AUTH_REGISTER = 'auth.register', AUTH_LOGIN_CREATE_ACCOUNT = 'auth.login.createAccount', AUTH_LOGOUT = 'auth.logout', // ---------------------------------------------------------------- Home ---- HOME = 'home', HOME_ACCOUNTS = 'home.accounts', HOME_ACCOUNTS_CAROUSEL = 'home.accounts.carousel', HOME_ACCOUNTS_BALANCE_TOGGLE = 'home.accounts.balanceToggle', HOME_ACCOUNTS_MINI_STATEMENT = 'home.accounts.miniStatement', HOME_ACCOUNTS_DETAILS = 'home.accounts.details', HOME_ACCOUNTS_EPASSBOOK = 'home.accounts.ePassbook', HOME_ACCOUNTS_REKYC = 'home.accounts.reKyc', HOME_ACCOUNTS_VIDEO_KYC = 'home.accounts.videoKyc', HOME_ACCOUNTS_MMID = 'home.accounts.mmid', HOME_QUICK_ACTIONS = 'home.quickActions', HOME_QUICK_ACTIONS_TRANSFER = 'home.quickActions.transfer', HOME_QUICK_ACTIONS_BILL_PAY = 'home.quickActions.billPay', HOME_QUICK_ACTIONS_AIRTIME = 'home.quickActions.airtime', HOME_QUICK_ACTIONS_LOANS = 'home.quickActions.loans', HOME_QUICK_ACTIONS_CARDS = 'home.quickActions.cards', HOME_QUICK_ACTIONS_STATS = 'home.quickActions.stats', HOME_SERVICES = 'home.services', HOME_SERVICES_TRANSFER = 'home.services.transfer', HOME_SERVICES_SELF_TRANSFER = 'home.services.selfTransfer', HOME_SERVICES_BILL_PAY = 'home.services.billPay', HOME_SERVICES_COLLECT_REQUEST = 'home.services.collectRequest', HOME_SERVICES_MANAGE_PAYEE = 'home.services.managePayee', HOME_SERVICES_SUPPORT = 'home.services.support', HOME_SERVICES_INSURANCE = 'home.services.insurance', HOME_SERVICES_DEPOSITS = 'home.services.deposits', HOME_SERVICES_GOLD_LOAN = 'home.services.goldLoan', HOME_INSIGHTS = 'home.insights', HOME_PROMO_BANNER = 'home.promoBanner', // -------------------------------------------------------------- Search ---- SEARCH = 'search', SEARCH_GLOBAL = 'search.global', // ------------------------------------------------------- Notifications ---- NOTIFICATIONS = 'notifications', NOTIFICATIONS_LIST = 'notifications.list', NOTIFICATIONS_MARK_READ = 'notifications.markRead', // ------------------------------------------------------------ Payments ---- PAYMENTS = 'payments', PAYMENTS_HUB = 'payments.hub', PAYMENTS_BENEFICIARIES = 'payments.beneficiaries', PAYMENTS_BENEFICIARIES_LIST = 'payments.beneficiaries.list', PAYMENTS_BENEFICIARIES_ADD = 'payments.beneficiaries.add', PAYMENTS_BENEFICIARIES_DELETE = 'payments.beneficiaries.delete', PAYMENTS_TRANSFER = 'payments.transfer', PAYMENTS_TRANSFER_IMPS = 'payments.transfer.imps', PAYMENTS_TRANSFER_NEFT = 'payments.transfer.neft', PAYMENTS_TRANSFER_RTGS = 'payments.transfer.rtgs', PAYMENTS_TRANSFER_INTERNAL = 'payments.transfer.internal', PAYMENTS_TRANSFER_SUBMIT = 'payments.transfer.submit', /** * The three fund-transfer entry points on the payments hub. Each is a * destination in its own right rather than a rail: `mobile` collects a * mobile number and MMID, `account` an account number and IFSC, and `own` * moves money * between the customer's own accounts. The rail keys above still decide how * the resulting transfer settles. */ PAYMENTS_TRANSFER_MOBILE = 'payments.transfer.mobile', PAYMENTS_TRANSFER_ACCOUNT = 'payments.transfer.account', PAYMENTS_TRANSFER_OWN = 'payments.transfer.own', PAYMENTS_UPI = 'payments.upi', PAYMENTS_UPI_SCAN = 'payments.upi.scan', /** This customer's own MMIDs, for receiving money over IMPS. */ PAYMENTS_MMID = 'payments.mmid', PAYMENTS_MMID_CANCEL = 'payments.mmid.cancel', PAYMENTS_MMID_GENERATE = 'payments.mmid.generate', // --------------------------------------------------------------- Cards ---- CARDS = 'cards', CARDS_OVERVIEW = 'cards.overview', CARDS_DETAILS = 'cards.details', CARDS_TRANSACTIONS = 'cards.transactions', CARDS_CONTROLS = 'cards.controls', CARDS_CONTROLS_FREEZE = 'cards.controls.freeze', CARDS_CONTROLS_ONLINE = 'cards.controls.online', CARDS_CONTROLS_INTERNATIONAL = 'cards.controls.international', CARDS_CONTROLS_CONTACTLESS = 'cards.controls.contactless', CARDS_CONTROLS_ATM = 'cards.controls.atm', CARDS_CONTROLS_LIMITS = 'cards.controls.limits', CARDS_CONTROLS_BLOCK = 'cards.controls.block', CARDS_APPLY_CREDIT = 'cards.applyCredit', CARDS_REQUEST_PHYSICAL = 'cards.requestPhysical', // ------------------------------------------------------------ Services ---- SERVICES = 'services', SERVICES_HUB = 'services.hub', SERVICES_DEPOSITS = 'services.deposits', SERVICES_DEPOSITS_OVERVIEW = 'services.deposits.overview', SERVICES_DEPOSITS_DETAILS = 'services.deposits.details', SERVICES_DEPOSITS_OPEN_FD = 'services.deposits.openFd', SERVICES_DEPOSITS_OPEN_RD = 'services.deposits.openRd', SERVICES_DEPOSITS_CALCULATOR = 'services.deposits.calculator', SERVICES_CHEQUE = 'services.cheque', SERVICES_CHEQUE_HUB = 'services.cheque.hub', SERVICES_CHEQUE_BOOK_REQUEST = 'services.cheque.bookRequest', SERVICES_CHEQUE_STOP_PAYMENT = 'services.cheque.stopPayment', SERVICES_CHEQUE_TRACKING = 'services.cheque.tracking', SERVICES_CHEQUE_POSITIVE_PAY = 'services.cheque.positivePay', SERVICES_CERTIFICATES = 'services.certificates', SERVICES_CERTIFICATES_HUB = 'services.certificates.hub', SERVICES_CERTIFICATES_LIST = 'services.certificates.list', SERVICES_CERTIFICATES_BALANCE = 'services.certificates.balance', SERVICES_CERTIFICATES_INTEREST = 'services.certificates.interest', SERVICES_CERTIFICATES_SHARE = 'services.certificates.share', SERVICES_CERTIFICATES_HYPOTHECATION = 'services.certificates.hypothecation', SERVICES_CERTIFICATES_INSURANCE = 'services.certificates.insurance', SERVICES_CERTIFICATES_TAX = 'services.certificates.tax', SERVICES_CERTIFICATES_LOAN = 'services.certificates.loan', SERVICES_REQUESTS = 'services.requests', SERVICES_REQUESTS_HUB = 'services.requests.hub', SERVICES_STANDING_INSTRUCTIONS = 'services.standingInstructions', SERVICES_FORM_15G15H = 'services.form15g15h', SERVICES_NOMINATION = 'services.nomination', SERVICES_BRANCH_LOCATOR = 'services.branchLocator', SERVICES_AWARENESS = 'services.awareness', SERVICES_AWARENESS_LIST = 'services.awareness.list', SERVICES_AWARENESS_DETAIL = 'services.awareness.detail', SERVICES_PROTECTION = 'services.protection', SERVICES_PROTECTION_HUB = 'services.protection.hub', SERVICES_PROTECTION_SCHEME_DETAIL = 'services.protection.schemeDetail', SERVICES_PROTECTION_ENROLLMENT = 'services.protection.enrollment', SERVICES_PROTECTION_DEAF = 'services.protection.deaf', SERVICES_PROTECTION_DEAF_CLAIM = 'services.protection.deafClaim', SERVICES_PROTECTION_DICGC = 'services.protection.dicgc', SERVICES_SUPPORT_CHAT = 'services.supportChat', SERVICES_HELP_CENTER = 'services.helpCenter', /** * Enquiry desk: the entries that answer a question outright, or change a PIN, * rather than opening a journey. * * `mpinChange` and `miniStatement` gate entry points rather than screens — * those screens live in the profile and home stacks and keep their own keys. * Having a key here lets the bank take the tile off the service desk without * also removing the screen from where it already was. */ SERVICES_BALANCE_ENQUIRY = 'services.balanceEnquiry', SERVICES_MINI_STATEMENT = 'services.miniStatement', SERVICES_MPIN_CHANGE = 'services.mpinChange', SERVICES_TPIN_CHANGE = 'services.tpinChange', SERVICES_FATE_OF_CHEQUE = 'services.fateOfCheque', // --------------------------------------------------------------- Loans ---- LOANS = 'loans', LOANS_DASHBOARD = 'loans.dashboard', LOANS_TYPES = 'loans.types', LOANS_ELIGIBILITY = 'loans.eligibility', LOANS_CALCULATOR = 'loans.calculator', LOANS_APPLY = 'loans.apply', LOANS_TRACKING = 'loans.tracking', LOANS_ACTIVE_DETAILS = 'loans.activeDetails', LOANS_EMI_PAYMENT = 'loans.emiPayment', LOANS_FORECLOSURE = 'loans.foreclosure', LOANS_HISTORY = 'loans.history', LOANS_DOCUMENTS = 'loans.documents', // ----------------------------------------------------------- Insurance ---- INSURANCE = 'insurance', INSURANCE_DASHBOARD = 'insurance.dashboard', INSURANCE_BUY = 'insurance.buy', INSURANCE_POLICIES = 'insurance.policies', INSURANCE_POLICY_DETAILS = 'insurance.policyDetails', INSURANCE_RENEWALS = 'insurance.renewals', INSURANCE_CLAIMS = 'insurance.claims', INSURANCE_DOCUMENTS = 'insurance.documents', INSURANCE_CALCULATOR = 'insurance.calculator', INSURANCE_COMPARISON = 'insurance.comparison', INSURANCE_NOTIFICATIONS = 'insurance.notifications', // ------------------------------------------------------------- Profile ---- PROFILE = 'profile', PROFILE_MAIN = 'profile.main', PROFILE_EDIT = 'profile.edit', PROFILE_ACCOUNTS = 'profile.accounts', PROFILE_ACCOUNTS_ADD = 'profile.accounts.add', PROFILE_BENEFICIARIES_SHORTCUT = 'profile.beneficiariesShortcut', PROFILE_STATEMENTS_SHORTCUT = 'profile.statementsShortcut', PROFILE_SETTINGS = 'profile.settings', PROFILE_SETTINGS_LANGUAGE = 'profile.settings.language', PROFILE_SETTINGS_NOTIFICATIONS = 'profile.settings.notifications', PROFILE_SETTINGS_PRIVACY = 'profile.settings.privacy', PROFILE_SECURITY = 'profile.security', PROFILE_SECURITY_CHANGE_PIN = 'profile.security.changePin', PROFILE_SECURITY_CHANGE_PASSWORD = 'profile.security.changePassword', PROFILE_SECURITY_BIOMETRIC = 'profile.security.biometric', PROFILE_SECURITY_TWO_FACTOR = 'profile.security.twoFactor', PROFILE_SECURITY_DEVICES = 'profile.security.devices', PROFILE_SECURITY_LOGOUT_ALL = 'profile.security.logoutAll', PROFILE_SECURITY_HIDE_BALANCE = 'profile.security.hideBalance', PROFILE_SUPPORT = 'profile.support', PROFILE_LEGAL = 'profile.legal', PROFILE_ABOUT = 'profile.about', /** * In-app switchboard for the curated operational features. * * Ships disabled and is meant to be turned on through remote config for the * tenants whose staff need it — so the bank decides which installs expose it, * rather than it being present for every customer. */ PROFILE_FEATURE_FLAGS = 'profile.featureFlags', // --------------------------------------------------------------- Agent ---- AGENT = 'agent', AGENT_DASHBOARD = 'agent.dashboard', AGENT_DASHBOARD_MAIN = 'agent.dashboard.main', AGENT_DASHBOARD_ROUTE = 'agent.dashboard.route', AGENT_CUSTOMERS = 'agent.customers', AGENT_CUSTOMERS_LIST = 'agent.customers.list', AGENT_CUSTOMERS_DETAIL = 'agent.customers.detail', AGENT_CUSTOMERS_CREATE = 'agent.customers.create', AGENT_CUSTOMERS_EDIT = 'agent.customers.edit', AGENT_CUSTOMERS_DELETE = 'agent.customers.delete', AGENT_CUSTOMERS_INSTALLMENT_HISTORY = 'agent.customers.installmentHistory', AGENT_COLLECTIONS = 'agent.collections', AGENT_COLLECTIONS_DAILY = 'agent.collections.daily', AGENT_COLLECTIONS_HISTORY = 'agent.collections.history', AGENT_COLLECTIONS_RECEIPT = 'agent.collections.receipt', AGENT_LOANS = 'agent.loans', AGENT_LOANS_LIST = 'agent.loans.list', AGENT_LOANS_CREATE_REQUEST = 'agent.loans.createRequest', AGENT_LOANS_ACCOUNT_OPENING = 'agent.loans.accountOpening', AGENT_LOANS_COMMISSION = 'agent.loans.commission', AGENT_PROFILE = 'agent.profile', AGENT_PROFILE_MAIN = 'agent.profile.main', AGENT_PROFILE_SMS_HISTORY = 'agent.profile.smsHistory', AGENT_PROFILE_CHANGE_PASSWORD = 'agent.profile.changePassword', } /** Every declared feature key, in declaration order. */ export const ALL_FEATURE_KEYS = Object.values(FeatureKey) as FeatureKey[]; /** Set form, for O(1) membership checks when validating untrusted strings. */ const FEATURE_KEY_SET: ReadonlySet = new Set(ALL_FEATURE_KEYS); /** * Narrows an arbitrary string (remote config, JSON-driven UI, deep link) to a * known FeatureKey. Returns `undefined` when the string is not a declared key, * which callers must treat as "not enabled". */ export const toFeatureKey = (value: string | null | undefined): FeatureKey | undefined => typeof value === 'string' && FEATURE_KEY_SET.has(value) ? (value as FeatureKey) : undefined; /** * Parent key of a feature, derived from its dot path. * `loans.apply.submit` → `loans.apply`; a root key → `undefined`. */ export const getParentFeatureKey = (key: FeatureKey): FeatureKey | undefined => { const lastDot = key.lastIndexOf('.'); if (lastDot === -1) { return undefined; } return toFeatureKey(key.slice(0, lastDot)); }; /** * All ancestors of a key, nearest parent first. * `loans.apply.submit` → [`loans.apply`, `loans`]. */ export const getFeatureAncestors = (key: FeatureKey): FeatureKey[] => { const ancestors: FeatureKey[] = []; let current = getParentFeatureKey(key); while (current) { ancestors.push(current); current = getParentFeatureKey(current); } return ancestors; };