/** * The back-office menu tree (09-UX §2). Editions gate visibility: locked pages * render as discoverable upsells, never hidden (09-UX §5.5). This is data on * purpose — in production it comes from the DB with role filtering applied. */ export type Edition = 'L' | 'S' | 'P' | 'E' export interface NavPage { path: string label: string edition: Edition } export interface NavModule { key: string label: string icon: string pages: NavPage[] } export const NAV: NavModule[] = [ { key: 'dashboard', label: 'Dashboard', icon: '◧', pages: [{ path: '/', label: 'Overview', edition: 'L' }], }, { key: 'catalog', label: 'Catalog', icon: '⌘', pages: [ { path: '/catalog/items', label: 'Items', edition: 'L' }, { path: '/catalog/categories', label: 'Categories', edition: 'L' }, { path: '/catalog/price-lists', label: 'Price Lists', edition: 'S' }, { path: '/catalog/schemes', label: 'Schemes & Offers', edition: 'S' }, { path: '/catalog/labels', label: 'Label Printing', edition: 'S' }, ], }, { key: 'sales', label: 'Sales', icon: '₹', pages: [ { path: '/sales/bills', label: 'Bills', edition: 'L' }, { path: '/sales/returns', label: 'Returns & Credit Notes', edition: 'L' }, { path: '/sales/customers', label: 'Customers', edition: 'L' }, { path: '/sales/khata', label: 'Khata & Collections', edition: 'L' }, { path: '/sales/loyalty', label: 'Loyalty', edition: 'P' }, ], }, { key: 'purchases', label: 'Purchases', icon: '⇩', pages: [ { path: '/purchases/list', label: 'Purchase List', edition: 'L' }, { path: '/purchases/entry', label: 'Purchase Entry', edition: 'L' }, { path: '/purchases/inbox', label: 'Purchase Inbox', edition: 'P' }, { path: '/purchases/suppliers', label: 'Suppliers', edition: 'L' }, { path: '/purchases/gstr2b', label: 'GSTR-2B Reconciliation', edition: 'P' }, ], }, { key: 'inventory', label: 'Inventory', icon: '▤', pages: [ { path: '/inventory/stock', label: 'Stock', edition: 'L' }, { path: '/inventory/adjustments', label: 'Adjustments', edition: 'L' }, { path: '/inventory/transfers', label: 'Transfers', edition: 'E' }, { path: '/inventory/stock-take', label: 'Stock Take', edition: 'P' }, { path: '/inventory/expiry', label: 'Expiry Dashboard', edition: 'P' }, ], }, { key: 'accounting', label: 'Accounting', icon: '≡', pages: [ { path: '/accounting/vouchers', label: 'Vouchers', edition: 'S' }, { path: '/accounting/ledgers', label: 'Ledgers', edition: 'L' }, { path: '/accounting/day-book', label: 'Day Book', edition: 'S' }, { path: '/accounting/pnl', label: 'P&L / Balance Sheet', edition: 'P' }, { path: '/accounting/tally', label: 'Tally Export', edition: 'S' }, ], }, { key: 'gst', label: 'GST', icon: '§', pages: [ { path: '/gst/gstr1', label: 'GSTR-1', edition: 'S' }, { path: '/gst/gstr3b', label: 'GSTR-3B', edition: 'S' }, { path: '/gst/einvoice', label: 'e-Invoice Queue', edition: 'P' }, { path: '/gst/eway', label: 'e-Way Bills', edition: 'P' }, { path: '/gst/hsn', label: 'HSN Summary', edition: 'L' }, ], }, { key: 'reports', label: 'Reports', icon: '◔', pages: [ { path: '/reports/sales', label: 'Sales Reports', edition: 'L' }, { path: '/reports/margins', label: 'Margins', edition: 'S' }, { path: '/reports/stock-aging', label: 'Stock Aging', edition: 'S' }, { path: '/reports/day-end', label: 'Day-End Digest', edition: 'L' }, ], }, { key: 'admin', label: 'Admin', icon: '⚙', pages: [ { path: '/admin/users', label: 'Users & Roles', edition: 'S' }, { path: '/admin/stores', label: 'Stores & Counters', edition: 'L' }, { path: '/admin/settings', label: 'Settings', edition: 'L' }, { path: '/admin/templates', label: 'Print Templates', edition: 'L' }, { path: '/admin/integrations', label: 'Integrations', edition: 'L' }, { path: '/admin/subscription', label: 'Subscription & Plan', edition: 'L' }, { path: '/admin/audit', label: 'Audit Log', edition: 'S' }, { path: '/admin/sync', label: 'Sync & Devices', edition: 'L' }, { path: '/admin/backups', label: 'Backups', edition: 'L' }, { path: '/admin/import', label: 'Data Import', edition: 'L' }, ], }, ] /** The wireframe tenant runs Pro; Enterprise pages render as upsells. */ export const CURRENT_EDITION: Edition = 'P' export const EDITION_ORDER: Edition[] = ['L', 'S', 'P', 'E'] export function isLocked(page: NavPage): boolean { return EDITION_ORDER.indexOf(page.edition) > EDITION_ORDER.indexOf(CURRENT_EDITION) }