@apptimate/core-lib 1.1.0 → 1.2.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": "@apptimate/core-lib",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "main": "src/index.ts",
5
5
  "types": "src/index.ts",
6
6
  "publishConfig": {
@@ -62,142 +62,78 @@ export const MENU_ITEM_REGISTRY: RegistryItem[] = [
62
62
  { key: 'core__users', label: 'Users', path: '/users', module: 'Core', defaultGroup: 'User Management' },
63
63
  { key: 'core__roles', label: 'Roles', path: '/roles', module: 'Core', defaultGroup: 'User Management' },
64
64
  { key: 'core__organizations', label: 'Organizations', path: '/organizations', module: 'Core', defaultGroup: 'User Management' },
65
- { key: 'core__design_system', label: 'Design System', path: '/design-system', module: 'Core', defaultGroup: 'Temporary' },
65
+ { key: 'core__parties', label: 'Parties', path: '/parties', module: 'Core', defaultGroup: 'User Management' },
66
66
  { key: 'core__activity_logs', label: 'Activity Logs', path: '/activity-logs', module: 'Core', defaultGroup: 'System Auditing' },
67
67
  { key: 'core__api_requests', label: 'API Requests', path: '/system/api-requests', module: 'Core', defaultGroup: 'System Auditing' },
68
68
  { key: 'core__feature_access_logs', label: 'Feature Access Logs', path: '/system/feature-access-logs', module: 'Core', defaultGroup: 'System Auditing' },
69
69
  { key: 'core__issue_logs', label: 'Issue Logs', path: '/system/issue-logs', module: 'Core', defaultGroup: 'System Auditing' },
70
70
  { key: 'core__feature_registry', label: 'Feature Registry', path: '/system/features', module: 'Core', defaultGroup: 'System Auditing' },
71
71
  { key: 'core__menu_config', label: 'Menu Configuration', path: '/menu-config', module: 'Core', defaultGroup: 'System' },
72
+ { key: 'core__printables', label: 'Printable Templates', path: '/system/printables', module: 'Core', defaultGroup: 'System' },
73
+ { key: 'core__warehouses', label: 'Warehouses', path: '/warehouses', module: 'Core', defaultGroup: 'Resources' },
74
+ { key: 'core__terminals', label: 'Terminals', path: '/terminals', module: 'Core', defaultGroup: 'Resources' },
72
75
 
73
76
  // ── Inventory Module ──
74
- { key: 'inv__items', label: 'Items', path: '/inventory/items', module: 'Inventory', defaultGroup: 'Catalog' },
75
- { key: 'inv__categories', label: 'Categories', path: '/inventory/categories', module: 'Inventory', defaultGroup: 'Catalog' },
76
- { key: 'inv__units', label: 'Units', path: '/inventory/units', module: 'Inventory', defaultGroup: 'Catalog' },
77
- { key: 'inv__supplier_items', label: 'Supplier Items', path: '/inventory/supplier-items', module: 'Inventory', defaultGroup: 'Catalog' },
78
- { key: 'inv__documents', label: 'Stock Documents', path: '/inventory/documents', module: 'Inventory', defaultGroup: 'Stock Control' },
79
- { key: 'inv__warehouses', label: 'Warehouses', path: '/inventory/warehouses', module: 'Inventory', defaultGroup: 'Stock Control' },
80
- { key: 'inv__lots', label: 'Lots & Serials', path: '/inventory/lots', module: 'Inventory', defaultGroup: 'Stock Control' },
81
- { key: 'inv__stock_counts', label: 'Stock Counts', path: '/inventory/stock-counts', module: 'Inventory', defaultGroup: 'Stock Control' },
82
- { key: 'inv__reservations', label: 'Reservations', path: '/inventory/reservations', module: 'Inventory', defaultGroup: 'Stock Control' },
83
- { key: 'inv__inspection', label: 'Inspection', path: '/inventory/inspection', module: 'Inventory', defaultGroup: 'Quality & Alerts' },
84
- { key: 'inv__alerts', label: 'Stock Alerts', path: '/inventory/alerts', module: 'Inventory', defaultGroup: 'Quality & Alerts' },
85
- { key: 'inv__opening_balances', label: 'Opening Balances', path: '/inventory/opening-balances', module: 'Inventory', defaultGroup: 'Operations' },
86
- { key: 'inv__transfer_requests', label: 'Transfer Requests', path: '/inventory/transfer-requests', module: 'Inventory', defaultGroup: 'Transfers' },
87
- { key: 'inv__transfer_orders', label: 'Transfer Orders', path: '/inventory/transfer-orders', module: 'Inventory', defaultGroup: 'Transfers' },
88
- { key: 'inv__consignment', label: 'Consignment', path: '/inventory/consignment', module: 'Inventory', defaultGroup: 'Operations' },
89
- { key: 'inv__write_offs', label: 'Write-Offs', path: '/inventory/write-offs', module: 'Inventory', defaultGroup: 'Operations' },
90
- { key: 'inv__dashboard', label: 'Dashboard', path: '/inventory/dashboard', module: 'Inventory', defaultGroup: 'Reports' },
91
- { key: 'inv__balances', label: 'Stock Balances', path: '/inventory/balances', module: 'Inventory', defaultGroup: 'Reports' },
92
- { key: 'inv__reports', label: 'All Reports', path: '/inventory/reports', module: 'Inventory', defaultGroup: 'Reports' },
93
-
94
- // ── Sales Module: POS channel (current implementation) ──
95
- { key: 'pos__dashboard', label: 'POS Dashboard', path: '/pos', module: 'Sales', defaultGroup: 'POS Overview' },
96
- { key: 'pos__sell', label: 'Sell Screen', path: '/pos/sell', module: 'Sales', defaultGroup: 'POS Overview' },
97
- { key: 'pos__quick_sell', label: 'Quick Sell', path: '/pos/quick-sell', module: 'Sales', defaultGroup: 'POS Overview' },
98
- { key: 'pos__terminals', label: 'Terminals', path: '/pos/terminals', module: 'Sales', defaultGroup: 'POS Configuration' },
99
- { key: 'pos__sessions', label: 'Sessions', path: '/pos/sessions', module: 'Sales', defaultGroup: 'POS Operations' },
100
- { key: 'pos__invoices', label: 'Invoices', path: '/pos/invoices', module: 'Sales', defaultGroup: 'POS Transactions' },
101
- { key: 'pos__returns', label: 'Returns', path: '/pos/returns', module: 'Sales', defaultGroup: 'POS Transactions' },
102
- { key: 'pos__reports', label: 'Sales Reports', path: '/pos/reports', module: 'Sales', defaultGroup: 'POS Reports' },
103
-
104
- // ── Finance Module ──
105
- { key: 'fin__dashboard', label: 'Dashboard', path: '/finance', module: 'Finance', defaultGroup: 'Overview' },
106
- { key: 'fin__settings', label: 'Settings', path: '/finance/settings', module: 'Finance', defaultGroup: 'Setup' },
107
- { key: 'fin__chart_of_accounts', label: 'Chart of Accounts', path: '/finance/accounts', module: 'Finance', defaultGroup: 'General Ledger' },
108
- { key: 'fin__fiscal_periods', label: 'Fiscal Periods', path: '/finance/fiscal-periods', module: 'Finance', defaultGroup: 'General Ledger' },
109
- { key: 'fin__journal_entries', label: 'Journal Entries', path: '/finance/journals', module: 'Finance', defaultGroup: 'General Ledger' },
110
- { key: 'fin__gl_transactions', label: 'GL Transactions', path: '/finance/gl-transactions', module: 'Finance', defaultGroup: 'General Ledger' },
111
- { key: 'fin__receipts', label: 'Receipts', path: '/finance/receipts', module: 'Finance', defaultGroup: 'Receivables' },
112
- { key: 'fin__customers', label: 'Customers (AR)', path: '/finance/customers', module: 'Finance', defaultGroup: 'Receivables' },
113
- { key: 'fin__payments', label: 'Payments', path: '/finance/payments', module: 'Finance', defaultGroup: 'Payables' },
114
- { key: 'fin__vendors', label: 'Vendors (AP)', path: '/finance/vendors', module: 'Finance', defaultGroup: 'Payables' },
115
- { key: 'fin__bank_accounts', label: 'Bank Accounts', path: '/finance/bank/accounts', module: 'Finance', defaultGroup: 'Banking' },
116
- { key: 'fin__bank_transactions', label: 'Bank Transactions', path: '/finance/bank/transactions', module: 'Finance', defaultGroup: 'Banking' },
117
- { key: 'fin__bank_reconciliation', label: 'Bank Reconciliation', path: '/finance/bank/reconciliation', module: 'Finance', defaultGroup: 'Banking' },
118
- { key: 'fin__cheques', label: 'Cheque Management', path: '/finance/cheques', module: 'Finance', defaultGroup: 'Banking' },
119
- { key: 'fin__expense_income', label: 'Expense / Income', path: '/finance/expense-income', module: 'Finance', defaultGroup: 'Expense & Income' },
120
- { key: 'fin__tax_codes', label: 'Tax Codes', path: '/finance/tax/codes', module: 'Finance', defaultGroup: 'Tax' },
121
- { key: 'fin__tax_returns', label: 'Tax Returns', path: '/finance/tax/returns', module: 'Finance', defaultGroup: 'Tax' },
122
- { key: 'fin__events', label: 'Accounting Events', path: '/finance/events', module: 'Finance', defaultGroup: 'System' },
123
- { key: 'fin__reports', label: 'Reports', path: '/finance/reports', module: 'Finance', defaultGroup: 'Reports' },
124
- { key: 'fin__assets', label: 'Fixed Assets', path: '/finance/assets', module: 'Finance', defaultGroup: 'Assets' },
125
- { key: 'fin__budgets', label: 'Budgets', path: '/finance/budgets', module: 'Finance', defaultGroup: 'Budgets' },
126
- { key: 'fin__period_close', label: 'Period Close', path: '/finance/period-close', module: 'Finance', defaultGroup: 'System' },
127
-
128
- // ── Sales Module (umbrella / back-office) ──
77
+ { key: 'inventory__items', label: 'Items', path: '/inventory/items', module: 'Inventory', defaultGroup: 'Catalog' },
78
+ { key: 'inventory__categories', label: 'Categories', path: '/inventory/categories', module: 'Inventory', defaultGroup: 'Catalog' },
79
+ { key: 'inventory__brands', label: 'Brands', path: '/inventory/brands', module: 'Inventory', defaultGroup: 'Catalog' },
80
+ { key: 'inventory__uom', label: 'Units of Measure', path: '/inventory/uom', module: 'Inventory', defaultGroup: 'Catalog' },
81
+
82
+ { key: 'inventory__stock', label: 'Stock Overview', path: '/inventory/stock', module: 'Inventory', defaultGroup: 'Stock' },
83
+ { key: 'inventory__ledger', label: 'Stock Movements', path: '/inventory/ledger', module: 'Inventory', defaultGroup: 'Stock' },
84
+ { key: 'inventory__adjustments', label: 'Adjustments', path: '/inventory/adjustments', module: 'Inventory', defaultGroup: 'Operations' },
85
+ { key: 'inventory__transfers', label: 'Transfers', path: '/inventory/transfers', module: 'Inventory', defaultGroup: 'Operations' },
86
+ { key: 'inventory__serials', label: 'Serial Numbers', path: '/inventory/serials', module: 'Inventory', defaultGroup: 'Operations' },
87
+
88
+ // ── Sales Module ──
89
+ { key: 'sales__price_lists', label: 'Price Lists', path: '/sales/price-lists', module: 'Sales', defaultGroup: 'Master Data' },
90
+ { key: 'sales__quotations', label: 'Quotations', path: '/sales/quotations', module: 'Sales', defaultGroup: 'Orders' },
129
91
  { key: 'sales__orders', label: 'Sales Orders', path: '/sales/orders', module: 'Sales', defaultGroup: 'Orders' },
130
- { key: 'sales__invoices', label: 'Sales Invoices', path: '/sales/invoices', module: 'Sales', defaultGroup: 'Billing' },
131
- { key: 'sales__customers', label: 'Customers', path: '/sales/customers', module: 'Sales', defaultGroup: 'Customers' },
132
- { key: 'sales__quotations', label: 'Quotations', path: '/sales/quotations', module: 'Sales', defaultGroup: 'Pre-Sales' },
133
- { key: 'sales__pos', label: 'POS Workspace', path: '/pos', module: 'Sales', defaultGroup: 'Channels' },
134
- { key: 'sales__returns', label: 'Returns', path: '/sales/returns', module: 'Sales', defaultGroup: 'Returns' },
135
- { key: 'sales__reports', label: 'Sales Reports', path: '/sales/reports', module: 'Sales', defaultGroup: 'Reports' },
92
+ { key: 'sales__goods_issue_notes', label: 'Goods Issue Notes', path: '/sales/delivery-notes', module: 'Sales', defaultGroup: 'Fulfillment' },
93
+ { key: 'sales__returns', label: 'Sales Returns', path: '/sales/returns', module: 'Sales', defaultGroup: 'Post-Sales' },
94
+ { key: 'sales__credit_notes', label: 'Credit Notes', path: '/sales/credit-notes', module: 'Sales', defaultGroup: 'Post-Sales' },
95
+ { key: 'sales__pos', label: 'POS Terminal', path: '/sales/pos', module: 'Sales', defaultGroup: 'POS' },
136
96
 
137
- // ── Procurement Module ──
138
- { key: 'purch__dashboard', label: 'Dashboard', path: '/procurement', module: 'Procurement', defaultGroup: 'Overview' },
139
- { key: 'purch__suppliers', label: 'Suppliers', path: '/procurement/suppliers', module: 'Procurement', defaultGroup: 'Suppliers' },
140
- { key: 'purch__requisitions', label: 'Requisitions', path: '/procurement/requisitions', module: 'Procurement', defaultGroup: 'Purchasing' },
141
- { key: 'purch__orders', label: 'Purchase Orders', path: '/procurement/purchase-orders', module: 'Procurement', defaultGroup: 'Purchasing' },
142
- { key: 'purch__grn', label: 'Goods Receipts (GRN)', path: '/procurement/grns', module: 'Procurement', defaultGroup: 'Receiving' },
143
- { key: 'purch__returns', label: 'Purchase Returns', path: '/procurement/returns', module: 'Procurement', defaultGroup: 'Receiving' },
144
- { key: 'purch__invoices', label: 'Supplier Invoices', path: '/procurement/invoices', module: 'Procurement', defaultGroup: 'Invoicing' },
145
- { key: 'purch__consignment', label: 'Consignment', path: '/procurement/consignment', module: 'Procurement', defaultGroup: 'Consignment' },
146
- { key: 'purch__settlements', label: 'Settlements', path: '/procurement/consignment/settlements', module: 'Procurement', defaultGroup: 'Consignment' },
97
+ { key: 'sales__pos_sessions', label: 'Terminal Sessions', path: '/sales/pos/sessions', module: 'Sales', defaultGroup: 'POS' },
98
+ { key: 'sales__reports', label: 'Sales Reports', path: '/sales/reports', module: 'Sales', defaultGroup: 'Analytics' },
147
99
 
148
- // ── Manufacturing Module (future) ──
149
- { key: 'mfg__bom', label: 'Bill of Materials', path: '/manufacturing/bom', module: 'Manufacturing', defaultGroup: 'Engineering' },
150
- { key: 'mfg__work_orders', label: 'Work Orders', path: '/manufacturing/work-orders', module: 'Manufacturing', defaultGroup: 'Production' },
151
- { key: 'mfg__routing', label: 'Routing', path: '/manufacturing/routing', module: 'Manufacturing', defaultGroup: 'Engineering' },
152
- { key: 'mfg__reports', label: 'Production Reports', path: '/manufacturing/reports', module: 'Manufacturing', defaultGroup: 'Reports' },
100
+ // ── Procurement Module ──
101
+ { key: 'procurement__orders', label: 'Purchase Orders', path: '/procurement/orders', module: 'Procurement', defaultGroup: 'Orders' },
102
+ { key: 'procurement__grn', label: 'Goods Receipt', path: '/procurement/grns', module: 'Procurement', defaultGroup: 'Receiving' },
103
+ { key: 'procurement__invoices', label: 'Invoices', path: '/finance/invoices', module: 'Procurement', defaultGroup: 'Finance' },
104
+ { key: 'procurement__payments', label: 'Payments', path: '/finance/payments', module: 'Procurement', defaultGroup: 'Finance' },
153
105
 
154
- // ── HR Module (future) ──
155
- { key: 'hr__employees', label: 'Employees', path: '/hr/employees', module: 'HR', defaultGroup: 'Workforce' },
156
- { key: 'hr__attendance', label: 'Attendance', path: '/hr/attendance', module: 'HR', defaultGroup: 'Workforce' },
157
- { key: 'hr__payroll', label: 'Payroll', path: '/hr/payroll', module: 'HR', defaultGroup: 'Compensation' },
158
- { key: 'hr__leave', label: 'Leave Management', path: '/hr/leave', module: 'HR', defaultGroup: 'Workforce' },
159
- { key: 'hr__reports', label: 'HR Reports', path: '/hr/reports', module: 'HR', defaultGroup: 'Reports' },
106
+ // ── Finance Module ──
107
+ { key: 'finance__invoices', label: 'Invoices', path: '/finance/invoices', module: 'Finance', defaultGroup: 'Transactions' },
108
+ { key: 'finance__payments', label: 'Payments', path: '/finance/payments', module: 'Finance', defaultGroup: 'Transactions' },
109
+ { key: 'finance__chart_of_accounts', label: 'Chart of Accounts', path: '/finance/chart-of-accounts', module: 'Finance', defaultGroup: 'Accounting' },
110
+ { key: 'finance__journal_entries', label: 'Journal Entries', path: '/finance/journal-entries', module: 'Finance', defaultGroup: 'Accounting' },
111
+ { key: 'finance__fiscal_years', label: 'Fiscal Years', path: '/finance/fiscal-years', module: 'Finance', defaultGroup: 'Accounting' },
112
+ { key: 'finance__trial_balance', label: 'Trial Balance', path: '/finance/reports/trial-balance', module: 'Finance', defaultGroup: 'Reports' },
113
+ { key: 'finance__profit_loss', label: 'Profit & Loss', path: '/finance/reports/profit-loss', module: 'Finance', defaultGroup: 'Reports' },
114
+ { key: 'finance__balance_sheet', label: 'Balance Sheet', path: '/finance/reports/balance-sheet', module: 'Finance', defaultGroup: 'Reports' },
115
+ { key: 'finance__account_ledger', label: 'Account Ledger', path: '/finance/reports/account-ledger', module: 'Finance', defaultGroup: 'Reports' },
116
+ { key: 'finance__payment_modes', label: 'Payment Modes', path: '/finance/payment-modes', module: 'Finance', defaultGroup: 'Settings' },
117
+ { key: 'finance__bank_accounts', label: 'Bank Accounts', path: '/finance/bank-accounts', module: 'Finance', defaultGroup: 'Settings' },
118
+ { key: 'finance__account_mappings', label: 'Account Mappings', path: '/finance/account-mappings', module: 'Finance', defaultGroup: 'Settings' },
160
119
 
161
120
  // ── Jewelry Module ──
162
- { key: 'jwl__dashboard', label: 'Dashboard', path: '/jewelry', module: 'Jewelry', defaultGroup: 'Overview' },
163
- { key: 'jwl__metal_rates', label: 'Metal Rates', path: '/jewelry/metal-rates', module: 'Jewelry', defaultGroup: 'Setup' },
164
- { key: 'jwl__master_metals', label: 'Metal Types', path: '/jewelry/master/metals', module: 'Jewelry', defaultGroup: 'Setup' },
165
- { key: 'jwl__master_purities', label: 'Purity Master', path: '/jewelry/master/purities', module: 'Jewelry', defaultGroup: 'Setup' },
166
- { key: 'jwl__items', label: 'Jewelry Items', path: '/jewelry/items', module: 'Jewelry', defaultGroup: 'Catalog' },
167
- { key: 'jwl__stones', label: 'Loose Stones', path: '/jewelry/stones', module: 'Jewelry', defaultGroup: 'Catalog' },
168
- { key: 'jwl__certifications', label: 'Certifications', path: '/jewelry/certifications', module: 'Jewelry', defaultGroup: 'Catalog' },
169
- { key: 'jwl__karigars', label: 'Karigars', path: '/jewelry/karigars', module: 'Jewelry', defaultGroup: 'Operations' },
170
- { key: 'jwl__custom_orders', label: 'Custom Orders', path: '/jewelry/custom-orders', module: 'Jewelry', defaultGroup: 'Operations' },
171
- { key: 'jwl__repairs', label: 'Repairs', path: '/jewelry/repairs', module: 'Jewelry', defaultGroup: 'Operations' },
172
- { key: 'jwl__melting', label: 'Old Gold / Melting', path: '/jewelry/melting', module: 'Jewelry', defaultGroup: 'Operations' },
173
- { key: 'jwl__tags', label: 'Tag Printing', path: '/jewelry/tags', module: 'Jewelry', defaultGroup: 'Operations' },
174
- { key: 'jwl__refinery', label: 'Refinery Batches', path: '/jewelry/refinery', module: 'Jewelry', defaultGroup: 'Manufacturing' },
175
- { key: 'jwl__metal_issues', label: 'Metal Issues', path: '/jewelry/metal-issues', module: 'Jewelry', defaultGroup: 'Manufacturing' },
176
- { key: 'jwl__designs', label: 'Design Library', path: '/jewelry/designs', module: 'Jewelry', defaultGroup: 'Manufacturing' },
177
- { key: 'jwl__dealers', label: 'Wholesale Dealers', path: '/jewelry/dealers', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
178
- { key: 'jwl__installments', label: 'Installments', path: '/jewelry/installments', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
179
- { key: 'jwl__vouchers', label: 'Gift Vouchers', path: '/jewelry/vouchers', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
180
- { key: 'jwl__reservations', label: 'Reservations', path: '/jewelry/reservations', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
181
- { key: 'jwl__warranties', label: 'Warranties', path: '/jewelry/warranties', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
182
- { key: 'jwl__notifications', label: 'Notifications Queue', path: '/jewelry/notifications', module: 'Jewelry', defaultGroup: 'System' },
183
- { key: 'jwl__reports', label: 'Reports', path: '/jewelry/reports', module: 'Jewelry', defaultGroup: 'Reports' },
184
- { key: 'jwl__pos_sell', label: 'POS Sell', path: '/jewelry/pos/sell', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
185
- { key: 'jwl__pos_sales', label: 'View Sales', path: '/jewelry/pos/sales', module: 'Jewelry', defaultGroup: 'Sales & Billing' },
186
- { key: 'jwl__stone_procurement', label: 'Stone Procurement', path: '/jewelry/stone-procurement', module: 'Jewelry', defaultGroup: 'Procurement' },
187
- { key: 'jwl__consignment', label: 'Consignment Stock', path: '/jewelry/consignment', module: 'Jewelry', defaultGroup: 'Procurement' },
188
- { key: 'jwl__procurement', label: 'Purchase Orders', path: '/jewelry/procurement', module: 'Jewelry', defaultGroup: 'Procurement' },
189
- { key: 'jwl__purchase_pos', label: 'Purchase POS', path: '/jewelry/purchases', module: 'Jewelry', defaultGroup: 'Procurement' },
190
- { key: 'jwl__processing', label: 'Inventory Processing', path: '/jewelry/purchases/processing', module: 'Jewelry', defaultGroup: 'Procurement' },
191
- { key: 'jwl__purchase_returns', label: 'Purchase Returns', path: '/jewelry/purchases/returns', module: 'Jewelry', defaultGroup: 'Procurement' },
192
- { key: 'jwl__repositories', label: 'Metal Repositories', path: '/jewelry/repositories', module: 'Jewelry', defaultGroup: 'Operations' },
193
- { key: 'jwl__repository_settings', label: 'Repository Settings', path: '/jewelry/repository-settings', module: 'Jewelry', defaultGroup: 'Setup' },
194
-
195
- // ── AI Intelligence Module ──
196
- { key: 'ai__recommendations', label: 'Recommendations', path: '/jewelry/ai/recommendations', module: 'AI', defaultGroup: 'Intelligence' },
197
- { key: 'ai__reports', label: 'AI Reports', path: '/jewelry/ai/reports', module: 'AI', defaultGroup: 'Intelligence' },
198
- { key: 'ai__anomalies', label: 'Anomalies', path: '/jewelry/ai/anomalies', module: 'AI', defaultGroup: 'Intelligence' },
199
- { key: 'ai__predictions', label: 'Predictions', path: '/jewelry/ai/predictions', module: 'AI', defaultGroup: 'Intelligence' },
200
- { key: 'ai__usage', label: 'Usage', path: '/jewelry/ai/usage', module: 'AI', defaultGroup: 'Intelligence' },
121
+ { key: 'jewelry__items', label: 'Jewelry Items', path: '/jewelry/items', module: 'Jewelry', defaultGroup: 'Catalog' },
122
+ { key: 'jewelry__categories', label: 'Categories', path: '/jewelry/categories', module: 'Jewelry', defaultGroup: 'Catalog' },
123
+ { key: 'jewelry__material_types', label: 'Material Types', path: '/jewelry/material-types', module: 'Jewelry', defaultGroup: 'Master Data' },
124
+ { key: 'jewelry__purities', label: 'Purities', path: '/jewelry/purities', module: 'Jewelry', defaultGroup: 'Master Data' },
125
+ { key: 'jewelry__metal_rates', label: 'Metal Rates', path: '/jewelry/metal-rates', module: 'Jewelry', defaultGroup: 'Master Data' },
126
+ { key: 'jewelry__purchase_orders', label: 'Purchase Orders', path: '/jewelry/procurement/orders', module: 'Jewelry', defaultGroup: 'Procurement' },
127
+ { key: 'jewelry__grn', label: 'Goods Receipt', path: '/jewelry/procurement/grn', module: 'Jewelry', defaultGroup: 'Procurement' },
128
+ { key: 'jewelry__custom_orders', label: 'Custom Orders', path: '/jewelry/custom-orders', module: 'Jewelry', defaultGroup: 'Procurement' },
129
+ { key: 'jewelry__transformations', label: 'Transformations', path: '/jewelry/procurement/transformations', module: 'Jewelry', defaultGroup: 'Procurement' },
130
+ { key: 'jewelry__old_gold_purchases', label: 'Old Material Purchases', path: '/jewelry/old-gold-purchases', module: 'Jewelry', defaultGroup: 'Buying' },
131
+ { key: 'jewelry__sales', label: 'Sales', path: '/jewelry/sales', module: 'Jewelry', defaultGroup: 'Sales' },
132
+ { key: 'jewelry__sales_orders', label: 'Sales Orders', path: '/jewelry/sales/orders', module: 'Jewelry', defaultGroup: 'Sales' },
133
+ { key: 'jewelry__stock_balances', label: 'Stock Balances', path: '/jewelry/stock/balances', module: 'Jewelry', defaultGroup: 'Stock' },
134
+ { key: 'jewelry__stock_movements', label: 'Stock Movements', path: '/jewelry/stock/movements', module: 'Jewelry', defaultGroup: 'Stock' },
135
+ { key: 'jewelry__party_transactions', label: 'Party Transactions', path: '/jewelry/party-transactions', module: 'Jewelry', defaultGroup: 'Karigar' },
136
+ { key: 'jewelry__settings', label: 'Settings', path: '/jewelry/settings', module: 'Jewelry', defaultGroup: 'Configuration' },
201
137
  ];
202
138
 
203
139
  /**
@@ -269,17 +205,19 @@ export interface MenuPreset {
269
205
  export const MENU_PRESETS: MenuPreset[] = [
270
206
  {
271
207
  id: 'default_full',
272
- label: 'Full ERP',
273
- description: 'All modules visible — suitable for large enterprises',
208
+ label: 'Core Only',
209
+ description: 'System modules only',
274
210
  primaryMenus: [
275
211
  {
276
212
  id: 'core',
277
213
  label: 'Core',
278
214
  iconName: 'Settings',
279
215
  secondaryItems: [
280
- 'core__users', 'core__roles', 'core__organizations',
216
+ 'core__users', 'core__roles', 'core__organizations', 'core__parties',
217
+ 'core__warehouses', 'core__terminals',
281
218
  'core__activity_logs', 'core__api_requests', 'core__feature_access_logs',
282
219
  'core__issue_logs', 'core__feature_registry', 'core__menu_config',
220
+ 'core__printables',
283
221
  ],
284
222
  },
285
223
  {
@@ -287,11 +225,9 @@ export const MENU_PRESETS: MenuPreset[] = [
287
225
  label: 'Inventory',
288
226
  iconName: 'Package',
289
227
  secondaryItems: [
290
- 'inv__items', 'inv__categories', 'inv__units', 'inv__supplier_items',
291
- 'inv__documents', 'inv__warehouses', 'inv__lots', 'inv__stock_counts', 'inv__reservations',
292
- 'inv__inspection', 'inv__alerts',
293
- 'inv__opening_balances',
294
- 'inv__dashboard', 'inv__balances', 'inv__reports',
228
+ 'inventory__items', 'inventory__categories', 'inventory__brands', 'inventory__uom',
229
+ 'inventory__stock', 'inventory__ledger',
230
+ 'inventory__adjustments', 'inventory__transfers', 'inventory__serials',
295
231
  ],
296
232
  },
297
233
  {
@@ -299,106 +235,10 @@ export const MENU_PRESETS: MenuPreset[] = [
299
235
  label: 'Sales',
300
236
  iconName: 'ShoppingCart',
301
237
  secondaryItems: [
302
- 'pos__dashboard', 'pos__sell',
303
- 'pos__terminals', 'pos__sessions',
304
- 'pos__invoices', 'pos__returns',
305
- 'pos__reports',
306
- ],
307
- },
308
- {
309
- id: 'finance',
310
- label: 'Finance',
311
- iconName: 'Landmark',
312
- secondaryItems: [
313
- 'fin__dashboard', 'fin__settings',
314
- 'fin__chart_of_accounts', 'fin__fiscal_periods', 'fin__journal_entries', 'fin__gl_transactions',
315
- 'fin__customers', 'fin__vendors',
316
- 'fin__bank_accounts', 'fin__tax_codes',
317
- ],
318
- },
319
- {
320
- id: 'procurement',
321
- label: 'Procurement',
322
- iconName: 'Truck',
323
- secondaryItems: [
324
- 'purch__dashboard', 'purch__suppliers',
325
- 'purch__requisitions', 'purch__orders',
326
- 'purch__grn', 'purch__returns',
327
- 'purch__invoices',
328
- 'purch__consignment', 'purch__settlements',
329
- ],
330
- },
331
- ],
332
- },
333
- {
334
- id: 'small_retail',
335
- label: 'Small Retail / Jewelry Shop',
336
- description: 'Sales, stock, finance — simplified for small retail businesses',
337
- primaryMenus: [
338
- {
339
- id: 'sales',
340
- label: 'Sales',
341
- iconName: 'ShoppingCart',
342
- secondaryItems: [
343
- 'sales__orders', 'sales__invoices', 'sales__customers',
344
- 'sales__returns', 'sales__reports',
345
- 'pos__dashboard', 'pos__sell',
346
- 'pos__terminals', 'pos__sessions',
347
- 'pos__invoices', 'pos__returns',
348
- 'pos__reports',
349
- ],
350
- },
351
- {
352
- id: 'stock',
353
- label: 'Stock',
354
- iconName: 'Package',
355
- secondaryItems: [
356
- 'inv__items', 'inv__categories',
357
- 'inv__documents', 'inv__warehouses',
358
- 'inv__alerts', 'inv__balances',
359
- ],
360
- },
361
- {
362
- id: 'purchases',
363
- label: 'Purchases',
364
- iconName: 'Truck',
365
- secondaryItems: [
366
- 'purch__orders', 'purch__grn', 'purch__suppliers', 'purch__reports',
367
- ],
368
- },
369
- {
370
- id: 'finance',
371
- label: 'Finance',
372
- iconName: 'Landmark',
373
- secondaryItems: [
374
- 'fin__chart_of_accounts', 'fin__journal_entries',
375
- 'fin__invoices', 'fin__payments', 'fin__reports',
376
- ],
377
- },
378
- {
379
- id: 'settings',
380
- label: 'Settings',
381
- iconName: 'Settings',
382
- secondaryItems: [
383
- 'core__users', 'core__roles', 'core__organizations', 'core__menu_config',
384
- ],
385
- },
386
- ],
387
- },
388
- {
389
- id: 'enterprise_mfg',
390
- label: 'Enterprise / Manufacturing',
391
- description: 'Full modules with procurement, manufacturing, and inventory',
392
- primaryMenus: [
393
- {
394
- id: 'inventory',
395
- label: 'Inventory',
396
- iconName: 'Warehouse',
397
- secondaryItems: [
398
- 'inv__items', 'inv__categories', 'inv__units', 'inv__supplier_items',
399
- 'inv__documents', 'inv__warehouses', 'inv__lots', 'inv__stock_counts', 'inv__reservations',
400
- 'inv__inspection', 'inv__alerts', 'inv__opening_balances',
401
- 'inv__dashboard', 'inv__balances', 'inv__reports',
238
+ 'sales__price_lists',
239
+ 'sales__quotations', 'sales__orders', 'sales__goods_issue_notes',
240
+ 'sales__returns', 'sales__credit_notes',
241
+ 'sales__pos', 'sales__pos_sessions', 'sales__reports',
402
242
  ],
403
243
  },
404
244
  {
@@ -406,179 +246,34 @@ export const MENU_PRESETS: MenuPreset[] = [
406
246
  label: 'Procurement',
407
247
  iconName: 'Truck',
408
248
  secondaryItems: [
409
- 'purch__requisitions', 'purch__orders', 'purch__grn',
410
- 'purch__suppliers', 'purch__contracts', 'purch__reports',
411
- ],
412
- },
413
- {
414
- id: 'manufacturing',
415
- label: 'Manufacturing',
416
- iconName: 'Factory',
417
- secondaryItems: [
418
- 'mfg__bom', 'mfg__work_orders', 'mfg__routing', 'mfg__reports',
249
+ 'procurement__orders', 'procurement__grn',
250
+ 'procurement__invoices', 'procurement__payments',
419
251
  ],
420
252
  },
421
253
  {
422
254
  id: 'finance',
423
255
  label: 'Finance',
424
- iconName: 'Landmark',
425
- secondaryItems: [
426
- 'fin__chart_of_accounts', 'fin__journal_entries',
427
- 'fin__bank_accounts', 'fin__reconciliation',
428
- 'fin__invoices', 'fin__payments', 'fin__reports',
429
- ],
430
- },
431
- {
432
- id: 'hr',
433
- label: 'HR',
434
- iconName: 'Users',
435
- secondaryItems: [
436
- 'hr__employees', 'hr__attendance', 'hr__payroll', 'hr__leave', 'hr__reports',
437
- ],
438
- },
439
- {
440
- id: 'admin',
441
- label: 'Admin',
442
- iconName: 'Settings',
256
+ iconName: 'Wallet',
443
257
  secondaryItems: [
444
- 'core__users', 'core__roles', 'core__organizations',
445
- 'core__activity_logs', 'core__menu_config',
258
+ 'finance__invoices', 'finance__payments',
259
+ 'finance__chart_of_accounts', 'finance__journal_entries', 'finance__fiscal_years',
260
+ 'finance__trial_balance', 'finance__profit_loss', 'finance__balance_sheet', 'finance__account_ledger',
261
+ 'finance__payment_modes', 'finance__bank_accounts', 'finance__account_mappings',
446
262
  ],
447
263
  },
448
- ],
449
- },
450
- {
451
- id: 'services_company',
452
- label: 'Services Company',
453
- description: 'HR, finance, and client management for service businesses',
454
- primaryMenus: [
455
264
  {
456
- id: 'clients',
457
- label: 'Clients',
458
- iconName: 'Handshake',
459
- secondaryItems: [
460
- 'sales__customers', 'sales__quotations', 'sales__orders',
461
- 'sales__invoices', 'sales__reports',
462
- ],
463
- },
464
- {
465
- id: 'team',
466
- label: 'Team',
467
- iconName: 'Users',
468
- secondaryItems: [
469
- 'hr__employees', 'hr__attendance', 'hr__leave', 'hr__payroll', 'hr__reports',
470
- ],
471
- },
472
- {
473
- id: 'finance',
474
- label: 'Finance',
475
- iconName: 'Landmark',
476
- secondaryItems: [
477
- 'fin__chart_of_accounts', 'fin__journal_entries',
478
- 'fin__invoices', 'fin__payments', 'fin__reports',
479
- ],
480
- },
481
- {
482
- id: 'settings',
483
- label: 'Settings',
484
- iconName: 'Settings',
485
- secondaryItems: [
486
- 'core__users', 'core__roles', 'core__organizations', 'core__menu_config',
487
- ],
488
- },
489
- ],
490
- },
491
- {
492
- id: 'jewelry_shop',
493
- label: 'Jewelry Shop',
494
- description: 'Specialized for jewelry retail with metal rates, stones, karigars, and custom orders',
495
- primaryMenus: [
496
- {
497
- id: 'dashboard',
498
- label: 'Dashboard',
499
- iconName: 'LayoutDashboard',
500
- secondaryItems: [
501
- 'jwl__dashboard', 'jwl__metal_rates',
502
- 'jwl__reports', 'jwl__notifications',
503
- 'ai__recommendations', 'ai__reports', 'ai__anomalies', 'ai__predictions', 'ai__usage',
504
- ],
505
- },
506
- {
507
- id: 'catalog',
508
- label: 'Catalog',
265
+ id: 'jewelry',
266
+ label: 'Jewelry',
509
267
  iconName: 'Gem',
510
268
  secondaryItems: [
511
- 'jwl__items', 'jwl__stones', 'jwl__certifications',
512
- 'jwl__master_metals', 'jwl__master_purities',
513
- 'jwl__tags', 'jwl__designs',
514
- 'inv__categories', 'inv__units',
515
- ],
516
- },
517
- {
518
- id: 'sales',
519
- label: 'Sales & POS',
520
- iconName: 'ShoppingCart',
521
- secondaryItems: [
522
- 'jwl__pos_sell', 'jwl__pos_sales',
523
- 'jwl__dealers', 'jwl__installments',
524
- 'jwl__vouchers', 'jwl__reservations',
525
- 'jwl__warranties', 'jwl__melting',
526
- ],
527
- },
528
- {
529
- id: 'orders',
530
- label: 'Orders',
531
- iconName: 'ClipboardList',
532
- secondaryItems: [
533
- 'jwl__custom_orders', 'jwl__repairs',
534
- 'jwl__karigars',
535
- ],
536
- },
537
- {
538
- id: 'manufacturing',
539
- label: 'Manufacturing',
540
- iconName: 'Factory',
541
- secondaryItems: [
542
- 'jwl__refinery', 'jwl__metal_issues', 'jwl__repositories',
543
- ],
544
- },
545
- {
546
- id: 'procurement',
547
- label: 'Procurement',
548
- iconName: 'Truck',
549
- secondaryItems: [
550
- 'jwl__purchase_pos', 'jwl__processing', 'jwl__purchase_returns',
551
- 'jwl__stone_procurement', 'jwl__consignment', 'jwl__procurement',
552
- 'purch__suppliers', 'purch__orders', 'purch__grn',
553
- 'purch__consignment', 'purch__settlements',
554
- ],
555
- },
556
- {
557
- id: 'stock',
558
- label: 'Stock',
559
- iconName: 'Package',
560
- secondaryItems: [
561
- 'inv__items', 'inv__documents', 'inv__warehouses', 'inv__lots',
562
- 'inv__alerts', 'inv__balances', 'inv__reports',
563
- ],
564
- },
565
- {
566
- id: 'finance',
567
- label: 'Finance',
568
- iconName: 'Landmark',
569
- secondaryItems: [
570
- 'fin__chart_of_accounts', 'fin__journal_entries',
571
- 'fin__customers', 'fin__vendors',
572
- 'fin__bank_accounts', 'fin__tax_codes',
573
- ],
574
- },
575
- {
576
- id: 'settings',
577
- label: 'Settings',
578
- iconName: 'Settings',
579
- secondaryItems: [
580
- 'core__users', 'core__roles', 'core__organizations', 'core__menu_config',
581
- 'jwl__repository_settings',
269
+ 'jewelry__items', 'jewelry__categories',
270
+ 'jewelry__material_types', 'jewelry__purities', 'jewelry__metal_rates',
271
+ 'jewelry__purchase_orders', 'jewelry__grn', 'jewelry__custom_orders', 'jewelry__transformations',
272
+ 'jewelry__old_gold_purchases',
273
+ 'jewelry__sales', 'jewelry__sales_orders',
274
+ 'jewelry__stock_balances', 'jewelry__stock_movements',
275
+ 'jewelry__party_transactions',
276
+ 'jewelry__settings',
582
277
  ],
583
278
  },
584
279
  ],
@@ -593,7 +288,7 @@ export const APP_MENUS: MainMenuItem[] = [
593
288
  {
594
289
  id: "core",
595
290
  label: "Core",
596
- iconName: "Settings", // Translates to Settings icon from lucide-react
291
+ iconName: "Settings",
597
292
  groups: [
598
293
  {
599
294
  id: "core_users",
@@ -602,6 +297,7 @@ export const APP_MENUS: MainMenuItem[] = [
602
297
  { id: "users", label: "Users", path: "/users" },
603
298
  { id: "roles", label: "Roles", path: "/roles" },
604
299
  { id: "organizations", label: "Organizations", path: "/organizations" },
300
+ { id: "parties", label: "Parties", path: "/parties" },
605
301
  ],
606
302
  },
607
303
  {
@@ -609,6 +305,15 @@ export const APP_MENUS: MainMenuItem[] = [
609
305
  label: "System",
610
306
  items: [
611
307
  { id: "menu_config", label: "Menu Configuration", path: "/menu-config" },
308
+ { id: "printables", label: "Printable Templates", path: "/system/printables" },
309
+ ],
310
+ },
311
+ {
312
+ id: "core_resources",
313
+ label: "Resources",
314
+ items: [
315
+ { id: "warehouses", label: "Warehouses", path: "/warehouses" },
316
+ { id: "terminals", label: "Terminals", path: "/terminals" },
612
317
  ],
613
318
  },
614
319
  {
@@ -627,61 +332,33 @@ export const APP_MENUS: MainMenuItem[] = [
627
332
  {
628
333
  id: "inventory",
629
334
  label: "Inventory",
630
- iconName: "Package", // Translates to Package icon from lucide-react
335
+ iconName: "Package",
631
336
  groups: [
632
337
  {
633
- id: "inv_catalog",
338
+ id: "inventory_catalog",
634
339
  label: "Catalog",
635
340
  items: [
636
341
  { id: "items", label: "Items", path: "/inventory/items" },
637
342
  { id: "categories", label: "Categories", path: "/inventory/categories" },
638
- { id: "units", label: "Units", path: "/inventory/units" },
639
- { id: "supplier_items", label: "Supplier Items", path: "/inventory/supplier-items" },
640
- ],
641
- },
642
- {
643
- id: "inv_stock",
644
- label: "Stock Control",
645
- items: [
646
- { id: "documents", label: "Stock Documents", path: "/inventory/documents" },
647
- { id: "warehouses", label: "Warehouses", path: "/inventory/warehouses" },
648
- { id: "lots", label: "Lots & Serials", path: "/inventory/lots" },
649
- { id: "stock_counts", label: "Stock Counts", path: "/inventory/stock-counts" },
650
- { id: "reservations", label: "Reservations", path: "/inventory/reservations" },
343
+ { id: "brands", label: "Brands", path: "/inventory/brands" },
344
+ { id: "uom", label: "Units of Measure", path: "/inventory/uom" },
651
345
  ],
652
346
  },
653
347
  {
654
- id: "inv_transfers",
655
- label: "Transfers",
348
+ id: "inventory_stock",
349
+ label: "Stock",
656
350
  items: [
657
- { id: "transfer_requests", label: "Transfer Requests", path: "/inventory/transfer-requests" },
658
- { id: "transfer_orders", label: "Transfer Orders", path: "/inventory/transfer-orders" },
351
+ { id: "stock", label: "Stock Overview", path: "/inventory/stock" },
352
+ { id: "ledger", label: "Stock Movements", path: "/inventory/ledger" },
659
353
  ],
660
354
  },
661
355
  {
662
- id: "inv_quality",
663
- label: "Quality & Alerts",
664
- items: [
665
- { id: "inspection", label: "Inspection", path: "/inventory/inspection" },
666
- { id: "alerts", label: "Stock Alerts", path: "/inventory/alerts" },
667
- ],
668
- },
669
- {
670
- id: "inv_operations",
356
+ id: "inventory_operations",
671
357
  label: "Operations",
672
358
  items: [
673
- { id: "opening_balances", label: "Opening Balances", path: "/inventory/opening-balances" },
674
- { id: "write_offs", label: "Write-Offs", path: "/inventory/write-offs" },
675
- { id: "consignment", label: "Consignment", path: "/inventory/consignment" },
676
- ],
677
- },
678
- {
679
- id: "inv_reports",
680
- label: "Reports",
681
- items: [
682
- { id: "dashboard", label: "Dashboard", path: "/inventory/dashboard" },
683
- { id: "balances", label: "Stock Balances", path: "/inventory/balances" },
684
- { id: "reports", label: "All Reports", path: "/inventory/reports" },
359
+ { id: "adjustments", label: "Adjustments", path: "/inventory/adjustments" },
360
+ { id: "transfers", label: "Transfers", path: "/inventory/transfers" },
361
+ { id: "serials", label: "Serial Numbers", path: "/inventory/serials" },
685
362
  ],
686
363
  },
687
364
  ],
@@ -692,164 +369,120 @@ export const APP_MENUS: MainMenuItem[] = [
692
369
  iconName: "ShoppingCart",
693
370
  groups: [
694
371
  {
695
- id: "sales_pos_overview",
696
- label: "POS Overview",
697
- items: [
698
- { id: "pos_dashboard", label: "POS Dashboard", path: "/pos" },
699
- { id: "pos_sell", label: "Sell Screen", path: "/pos/sell" },
700
- { id: "pos_quick_sell", label: "Quick Sell", path: "/pos/quick-sell" },
701
- ],
702
- },
703
- {
704
- id: "sales_pos_ops",
705
- label: "POS Operations",
706
- items: [
707
- { id: "pos_terminals", label: "Terminals", path: "/pos/terminals" },
708
- { id: "pos_sessions", label: "Sessions", path: "/pos/sessions" },
709
- ],
710
- },
711
- {
712
- id: "sales_pos_transactions",
713
- label: "POS Transactions",
714
- items: [
715
- { id: "pos_invoices", label: "Invoices", path: "/pos/invoices" },
716
- { id: "pos_returns", label: "Returns", path: "/pos/returns" },
717
- ],
718
- },
719
- {
720
- id: "sales_pos_reports",
721
- label: "POS Reports",
372
+ id: "sales_master_data",
373
+ label: "Master Data",
722
374
  items: [
723
- { id: "pos_reports", label: "Sales Reports", path: "/pos/reports" },
375
+ { id: "price_lists", label: "Price Lists", path: "/sales/price-lists" },
724
376
  ],
725
377
  },
726
- ],
727
- },
728
- {
729
- id: "finance",
730
- label: "Finance",
731
- iconName: "Landmark",
732
- groups: [
733
378
  {
734
- id: "fin_overview",
735
- label: "Overview",
379
+ id: "sales_orders",
380
+ label: "Orders",
736
381
  items: [
737
- { id: "fin_dashboard", label: "Dashboard", path: "/finance" },
738
- { id: "fin_settings", label: "Settings", path: "/finance/settings" },
382
+ { id: "quotations", label: "Quotations", path: "/sales/quotations" },
383
+ { id: "sales_orders", label: "Sales Orders", path: "/sales/orders" },
739
384
  ],
740
385
  },
741
386
  {
742
- id: "fin_gl",
743
- label: "General Ledger",
387
+ id: "sales_fulfillment",
388
+ label: "Fulfillment",
744
389
  items: [
745
- { id: "chart_of_accounts", label: "Chart of Accounts", path: "/finance/accounts" },
746
- { id: "fiscal_periods", label: "Fiscal Periods", path: "/finance/fiscal-periods" },
747
- { id: "journals", label: "Journal Entries", path: "/finance/journals" },
748
- { id: "gl_transactions", label: "GL Transactions", path: "/finance/gl-transactions" },
390
+ { id: "goods_issue_notes", label: "Goods Issue Notes", path: "/sales/delivery-notes" },
749
391
  ],
750
392
  },
751
393
  {
752
- id: "fin_receivables",
753
- label: "Receivables (AR)",
394
+ id: "sales_post_sales",
395
+ label: "Post-Sales",
754
396
  items: [
755
- { id: "receipts", label: "Receipts", path: "/finance/receipts" },
756
- { id: "customers", label: "Customers", path: "/finance/customers" },
397
+ { id: "returns", label: "Sales Returns", path: "/sales/returns" },
398
+ { id: "credit_notes", label: "Credit Notes", path: "/sales/credit-notes" },
757
399
  ],
758
400
  },
759
401
  {
760
- id: "fin_payables",
761
- label: "Payables (AP)",
402
+ id: "sales_pos",
403
+ label: "POS",
762
404
  items: [
763
- { id: "payments", label: "Payments", path: "/finance/payments" },
764
- { id: "vendors", label: "Vendors", path: "/finance/vendors" },
405
+ { id: "pos_terminal", label: "POS Terminal", path: "/sales/pos" },
406
+ { id: "pos_sessions", label: "Terminal Sessions", path: "/sales/pos/sessions" },
765
407
  ],
766
408
  },
767
409
  {
768
- id: "fin_banking",
769
- label: "Banking",
410
+ id: "sales_analytics",
411
+ label: "Analytics",
770
412
  items: [
771
- { id: "bank_accounts", label: "Bank Accounts", path: "/finance/bank/accounts" },
772
- { id: "bank_transactions", label: "Bank Transactions", path: "/finance/bank/transactions" },
773
- { id: "bank_reconciliation", label: "Reconciliation", path: "/finance/bank/reconciliation" },
774
- { id: "cheques", label: "Cheque Management", path: "/finance/cheques" },
413
+ { id: "sales_reports", label: "Sales Reports", path: "/sales/reports" },
775
414
  ],
776
415
  },
416
+ ],
417
+ },
418
+ {
419
+ id: "procurement",
420
+ label: "Procurement",
421
+ iconName: "Truck",
422
+ groups: [
777
423
  {
778
- id: "fin_expense_income",
779
- label: "Expense & Income",
424
+ id: "procurement_orders",
425
+ label: "Orders",
780
426
  items: [
781
- { id: "expense_income", label: "Categories & Transactions", path: "/finance/expense-income" },
427
+ { id: "purchase_orders", label: "Purchase Orders", path: "/procurement/orders" },
782
428
  ],
783
429
  },
784
430
  {
785
- id: "fin_tax",
786
- label: "Tax",
431
+ id: "procurement_receiving",
432
+ label: "Receiving",
787
433
  items: [
788
- { id: "tax_codes", label: "Tax Codes", path: "/finance/tax/codes" },
789
- { id: "tax_returns", label: "Tax Returns", path: "/finance/tax/returns" },
434
+ { id: "goods_receipt", label: "Goods Receipt", path: "/procurement/grns" },
790
435
  ],
791
436
  },
792
437
  {
793
- id: "fin_advanced",
794
- label: "Advanced",
438
+ id: "procurement_finance",
439
+ label: "Finance",
795
440
  items: [
796
- { id: "assets", label: "Fixed Assets", path: "/finance/assets" },
797
- { id: "budgets", label: "Budgets", path: "/finance/budgets" },
798
- { id: "events", label: "Accounting Events", path: "/finance/events" },
799
- { id: "reports", label: "Reports", path: "/finance/reports" },
800
- { id: "period_close", label: "Period Close", path: "/finance/period-close" },
441
+ { id: "ap_invoices", label: "Invoices", path: "/finance/invoices" },
442
+ { id: "outgoing_payments", label: "Payments", path: "/finance/payments" },
801
443
  ],
802
444
  },
803
445
  ],
804
446
  },
805
447
  {
806
- id: "procurement",
807
- label: "Procurement",
808
- iconName: "Truck",
448
+ id: "finance",
449
+ label: "Finance",
450
+ iconName: "Wallet",
809
451
  groups: [
810
452
  {
811
- id: "purch_overview",
812
- label: "Overview",
813
- items: [
814
- { id: "purch_dashboard", label: "Dashboard", path: "/procurement" },
815
- ],
816
- },
817
- {
818
- id: "purch_suppliers",
819
- label: "Suppliers",
820
- items: [
821
- { id: "suppliers", label: "Suppliers", path: "/procurement/suppliers" },
822
- ],
823
- },
824
- {
825
- id: "purch_purchasing",
826
- label: "Purchasing",
453
+ id: "finance_transactions",
454
+ label: "Transactions",
827
455
  items: [
828
- { id: "requisitions", label: "Requisitions", path: "/procurement/requisitions" },
829
- { id: "purchase_orders", label: "Purchase Orders", path: "/procurement/purchase-orders" },
456
+ { id: "invoices", label: "Invoices", path: "/finance/invoices" },
457
+ { id: "payments", label: "Payments", path: "/finance/payments" },
830
458
  ],
831
459
  },
832
460
  {
833
- id: "purch_receiving",
834
- label: "Receiving",
461
+ id: "finance_accounting",
462
+ label: "Accounting",
835
463
  items: [
836
- { id: "grns", label: "Goods Receipts (GRN)", path: "/procurement/grns" },
837
- { id: "returns", label: "Purchase Returns", path: "/procurement/returns" },
464
+ { id: "chart_of_accounts", label: "Chart of Accounts", path: "/finance/chart-of-accounts" },
465
+ { id: "journal_entries", label: "Journal Entries", path: "/finance/journal-entries" },
466
+ { id: "fiscal_years", label: "Fiscal Years", path: "/finance/fiscal-years" },
838
467
  ],
839
468
  },
840
469
  {
841
- id: "purch_invoicing",
842
- label: "Invoicing",
470
+ id: "finance_reports",
471
+ label: "Reports",
843
472
  items: [
844
- { id: "invoices", label: "Supplier Invoices", path: "/procurement/invoices" },
473
+ { id: "trial_balance", label: "Trial Balance", path: "/finance/reports/trial-balance" },
474
+ { id: "profit_loss", label: "Profit & Loss", path: "/finance/reports/profit-loss" },
475
+ { id: "balance_sheet", label: "Balance Sheet", path: "/finance/reports/balance-sheet" },
476
+ { id: "account_ledger", label: "Account Ledger", path: "/finance/reports/account-ledger" },
845
477
  ],
846
478
  },
847
479
  {
848
- id: "purch_consignment",
849
- label: "Consignment",
480
+ id: "finance_settings",
481
+ label: "Settings",
850
482
  items: [
851
- { id: "consignment", label: "Agreements", path: "/procurement/consignment" },
852
- { id: "settlements", label: "Settlements", path: "/procurement/consignment/settlements" },
483
+ { id: "payment_modes", label: "Payment Modes", path: "/finance/payment-modes" },
484
+ { id: "bank_accounts", label: "Bank Accounts", path: "/finance/bank-accounts" },
485
+ { id: "account_mappings", label: "Account Mappings", path: "/finance/account-mappings" },
853
486
  ],
854
487
  },
855
488
  ],
@@ -860,99 +493,67 @@ export const APP_MENUS: MainMenuItem[] = [
860
493
  iconName: "Gem",
861
494
  groups: [
862
495
  {
863
- id: "jwl_overview",
864
- label: "Overview",
865
- items: [
866
- { id: "jwl_dashboard", label: "Dashboard", path: "/jewelry" },
867
- { id: "jwl_metal_rates", label: "Metal Rates", path: "/jewelry/metal-rates" },
868
- ],
869
- },
870
- {
871
- id: "jwl_setup",
872
- label: "Master Data",
873
- items: [
874
- { id: "jwl_master_metals", label: "Metal Types", path: "/jewelry/master/metals" },
875
- { id: "jwl_master_purities", label: "Purity Master", path: "/jewelry/master/purities" },
876
- { id: "jwl_repo_settings", label: "Repository Settings", path: "/jewelry/repository-settings" },
877
- ],
878
- },
879
- {
880
- id: "jwl_catalog",
496
+ id: "jewelry_catalog",
881
497
  label: "Catalog",
882
498
  items: [
883
- { id: "jwl_items", label: "Jewelry Items", path: "/jewelry/items" },
884
- { id: "jwl_stones", label: "Loose Stones", path: "/jewelry/stones" },
885
- { id: "jwl_certifications", label: "Certifications", path: "/jewelry/certifications" },
499
+ { id: "jewelry_items", label: "Jewelry Items", path: "/jewelry/items" },
500
+ { id: "jewelry_categories", label: "Categories", path: "/jewelry/categories" },
886
501
  ],
887
502
  },
888
503
  {
889
- id: "jwl_operations",
890
- label: "Operations",
504
+ id: "jewelry_master_data",
505
+ label: "Master Data",
891
506
  items: [
892
- { id: "jwl_karigars", label: "Karigars", path: "/jewelry/karigars" },
893
- { id: "jwl_custom_orders", label: "Custom Orders", path: "/jewelry/custom-orders" },
894
- { id: "jwl_repairs", label: "Repairs", path: "/jewelry/repairs" },
895
- { id: "jwl_melting", label: "Old Gold / Melting", path: "/jewelry/melting" },
507
+ { id: "material_types", label: "Material Types", path: "/jewelry/material-types" },
508
+ { id: "purities", label: "Purities", path: "/jewelry/purities" },
509
+ { id: "metal_rates", label: "Metal Rates", path: "/jewelry/metal-rates" },
896
510
  ],
897
511
  },
898
512
  {
899
- id: "jwl_manufacturing",
900
- label: "Manufacturing",
513
+ id: "jewelry_procurement",
514
+ label: "Procurement",
901
515
  items: [
902
- { id: "jwl_refinery", label: "Refinery Batches", path: "/jewelry/refinery" },
903
- { id: "jwl_metal_issues", label: "Metal Issues", path: "/jewelry/metal-issues" },
904
- { id: "jwl_designs", label: "Design Library", path: "/jewelry/designs" },
905
- { id: "jwl_repositories", label: "Metal Repositories", path: "/jewelry/repositories" },
516
+ { id: "purchase_orders", label: "Purchase Orders", path: "/jewelry/procurement/orders" },
517
+ { id: "goods_receipt", label: "Goods Receipt", path: "/jewelry/procurement/grn" },
518
+ { id: "custom_orders", label: "Custom Orders", path: "/jewelry/custom-orders" },
519
+ { id: "transformations", label: "Transformations", path: "/jewelry/procurement/transformations" },
906
520
  ],
907
521
  },
908
522
  {
909
- id: "jwl_procurement",
910
- label: "Procurement",
523
+ id: "jewelry_buying",
524
+ label: "Buying",
911
525
  items: [
912
- { id: "jwl_purchase_pos", label: "Purchase POS", path: "/jewelry/purchases" },
913
- { id: "jwl_processing", label: "Inventory Processing", path: "/jewelry/purchases/processing" },
914
- { id: "jwl_purchase_returns", label: "Purchase Returns", path: "/jewelry/purchases/returns" },
915
- { id: "jwl_stone_procurement", label: "Stone Procurement", path: "/jewelry/stone-procurement" },
916
- { id: "jwl_consignment", label: "Consignment Stock", path: "/jewelry/consignment" },
917
- { id: "jwl_procurement_orders", label: "Purchase Orders", path: "/jewelry/procurement" },
526
+ { id: "old_gold_purchases", label: "Old Material Purchases", path: "/jewelry/old-gold-purchases" },
918
527
  ],
919
528
  },
920
529
  {
921
- id: "jwl_sales_billing",
922
- label: "Sales & Billing",
530
+ id: "jewelry_sales",
531
+ label: "Sales",
923
532
  items: [
924
- { id: "jwl_pos_sell", label: "POS Sell", path: "/jewelry/pos/sell" },
925
- { id: "jwl_pos_sales", label: "View Sales", path: "/jewelry/pos/sales" },
926
- { id: "jwl_dealers", label: "Wholesale Dealers", path: "/jewelry/dealers" },
927
- { id: "jwl_installments", label: "Installments", path: "/jewelry/installments" },
928
- { id: "jwl_vouchers", label: "Gift Vouchers", path: "/jewelry/vouchers" },
929
- { id: "jwl_reservations", label: "Reservations", path: "/jewelry/reservations" },
930
- { id: "jwl_warranties", label: "Warranties", path: "/jewelry/warranties" },
533
+ { id: "jewelry_sales_main", label: "Sales", path: "/jewelry/sales" },
534
+ { id: "sales_orders", label: "Sales Orders", path: "/jewelry/sales/orders" },
931
535
  ],
932
536
  },
933
537
  {
934
- id: "jwl_reports",
935
- label: "Reports",
538
+ id: "jewelry_stock",
539
+ label: "Stock",
936
540
  items: [
937
- { id: "jwl_reports", label: "Reports & Analytics", path: "/jewelry/reports" },
541
+ { id: "stock_balances", label: "Stock Balances", path: "/jewelry/stock/balances" },
542
+ { id: "stock_movements", label: "Stock Movements", path: "/jewelry/stock/movements" },
938
543
  ],
939
544
  },
940
545
  {
941
- id: "jwl_system",
942
- label: "System",
546
+ id: "jewelry_karigar",
547
+ label: "Karigar",
943
548
  items: [
944
- { id: "jwl_notifications", label: "Notifications Queue", path: "/jewelry/notifications" },
549
+ { id: "party_transactions", label: "Party Transactions", path: "/jewelry/party-transactions" },
945
550
  ],
946
551
  },
947
552
  {
948
- id: "jwl_ai",
949
- label: "AI Intelligence",
553
+ id: "jewelry_configuration",
554
+ label: "Configuration",
950
555
  items: [
951
- { id: "ai_recommendations", label: "Recommendations", path: "/jewelry/ai/recommendations" },
952
- { id: "ai_reports", label: "AI Reports", path: "/jewelry/ai/reports" },
953
- { id: "ai_anomalies", label: "Anomalies", path: "/jewelry/ai/anomalies" },
954
- { id: "ai_predictions", label: "Predictions", path: "/jewelry/ai/predictions" },
955
- { id: "ai_usage", label: "Usage", path: "/jewelry/ai/usage" },
556
+ { id: "jewelry_settings", label: "Settings", path: "/jewelry/settings" },
956
557
  ],
957
558
  },
958
559
  ],
@@ -0,0 +1,155 @@
1
+ import { cookie } from "../constants/storageKeys";
2
+ import { decode } from "./commonService";
3
+
4
+ const HOP_BY_HOP_HEADERS = new Set([
5
+ "connection",
6
+ "content-length",
7
+ "content-encoding",
8
+ "keep-alive",
9
+ "proxy-authenticate",
10
+ "proxy-authorization",
11
+ "te",
12
+ "trailer",
13
+ "transfer-encoding",
14
+ "upgrade",
15
+ ]);
16
+
17
+ function parseCookieHeader(header: string | null): Record<string, string> {
18
+ if (!header) {
19
+ return {};
20
+ }
21
+
22
+ return header.split(";").reduce<Record<string, string>>((acc, part) => {
23
+ const [rawName, ...valueParts] = part.trim().split("=");
24
+ if (!rawName) {
25
+ return acc;
26
+ }
27
+
28
+ acc[rawName] = decodeURIComponent(valueParts.join("=") || "");
29
+ return acc;
30
+ }, {});
31
+ }
32
+
33
+ function getCookieValue(cookies: Record<string, string>, name: string): string | null {
34
+ return cookies[name] ?? null;
35
+ }
36
+
37
+ function getAccessToken(cookies: Record<string, string>): string | null {
38
+ const cookieNames = [
39
+ cookie.access_token.encrypted ? cookie.access_token.secretName : cookie.access_token.name,
40
+ cookie.access_token.name,
41
+ cookie.access_token.secretName,
42
+ ];
43
+
44
+ for (const name of cookieNames) {
45
+ const value = getCookieValue(cookies, name);
46
+ if (!value) {
47
+ continue;
48
+ }
49
+
50
+ return cookie.access_token.encrypted ? decode(value) : value;
51
+ }
52
+
53
+ return null;
54
+ }
55
+
56
+ function buildCookieHeader(name: string, options?: { httpOnly?: boolean }): string {
57
+ const parts = [
58
+ `${name}=`,
59
+ "Path=/",
60
+ "Max-Age=0",
61
+ "Expires=Thu, 01 Jan 1970 00:00:00 GMT",
62
+ "SameSite=Lax",
63
+ ];
64
+
65
+ if (options?.httpOnly) {
66
+ parts.push("HttpOnly");
67
+ }
68
+
69
+ if (process.env.NODE_ENV === "production") {
70
+ parts.push("Secure");
71
+ }
72
+
73
+ return parts.join("; ");
74
+ }
75
+
76
+ export function createSessionLogoutResponse(): Response {
77
+ const headers = new Headers({ "content-type": "application/json" });
78
+ headers.append("set-cookie", buildCookieHeader(cookie.access_token.name, { httpOnly: true }));
79
+ headers.append("set-cookie", buildCookieHeader(cookie.access_token.secretName, { httpOnly: true }));
80
+ headers.append("set-cookie", buildCookieHeader("selected_organization_id"));
81
+
82
+ return new Response(JSON.stringify({ cleared: true }), {
83
+ status: 200,
84
+ headers,
85
+ });
86
+ }
87
+
88
+ export async function forwardApiProxyRequest(request: Request, pathSegments: string[]): Promise<Response> {
89
+ const apiBaseUrl = process.env.NEXT_PUBLIC_API_URL;
90
+
91
+ if (!apiBaseUrl) {
92
+ return new Response(JSON.stringify({
93
+ is_success: false,
94
+ message: "NEXT_PUBLIC_API_URL is not configured.",
95
+ result: null,
96
+ system_code: "api_proxy_not_configured",
97
+ }), {
98
+ status: 500,
99
+ headers: { "content-type": "application/json" },
100
+ });
101
+ }
102
+
103
+ const incomingUrl = new URL(request.url);
104
+ const upstreamPath = pathSegments.join("/");
105
+ const upstreamUrl = new URL(upstreamPath, `${apiBaseUrl.replace(/\/$/, "")}/`);
106
+ upstreamUrl.search = incomingUrl.search;
107
+
108
+ const cookies = parseCookieHeader(request.headers.get("cookie"));
109
+ const token = getAccessToken(cookies);
110
+ const selectedOrganizationId = getCookieValue(cookies, "selected_organization_id");
111
+
112
+ const headers = new Headers();
113
+ const accept = request.headers.get("accept");
114
+ const contentType = request.headers.get("content-type");
115
+ const organizationId = request.headers.get("x-organization-id") ?? selectedOrganizationId;
116
+
117
+ if (accept) {
118
+ headers.set("accept", accept);
119
+ }
120
+
121
+ if (contentType) {
122
+ headers.set("content-type", contentType);
123
+ }
124
+
125
+ if (organizationId) {
126
+ headers.set("x-organization-id", organizationId);
127
+ }
128
+
129
+ if (token) {
130
+ headers.set("authorization", `Bearer ${token}`);
131
+ }
132
+
133
+ const hasBody = !["GET", "HEAD"].includes(request.method.toUpperCase());
134
+ const body = hasBody ? await request.arrayBuffer() : undefined;
135
+
136
+ const upstreamResponse = await fetch(upstreamUrl.toString(), {
137
+ method: request.method,
138
+ headers,
139
+ body,
140
+ cache: "no-store",
141
+ redirect: "manual",
142
+ });
143
+
144
+ const responseHeaders = new Headers();
145
+ upstreamResponse.headers.forEach((value, key) => {
146
+ if (!HOP_BY_HOP_HEADERS.has(key.toLowerCase())) {
147
+ responseHeaders.set(key, value);
148
+ }
149
+ });
150
+
151
+ return new Response(upstreamResponse.body, {
152
+ status: upstreamResponse.status,
153
+ headers: responseHeaders,
154
+ });
155
+ }
@@ -1,19 +1,21 @@
1
1
  import { IApiResponse } from "../common/interfaces/ICommon";
2
- import Cookies from 'js-cookie';
3
- import { cookie } from '../constants/storageKeys';
4
- import { decrypt, replacePlaceholders } from './commonService';
5
2
 
6
3
  /**
7
4
  * Handles 401 Unauthorized responses globally.
8
- * Clears the auth cookie and localStorage, then redirects to the login page.
5
+ * Clears the server-managed session and app-owned local state, then redirects
6
+ * to the login page.
9
7
  */
10
8
  export function handleUnauthorized(): void {
11
- // Clear auth cookie explicitly to avoid clearing cookies from other apps on localhost
12
- const cookieName = replacePlaceholders(
13
- cookie.access_token.encrypted ? cookie.access_token.secretName : cookie.access_token.name,
14
- {}
15
- );
16
- Cookies.remove(cookieName, { path: '/' });
9
+ // Best-effort server-side cookie clear for HttpOnly auth cookies.
10
+ if (typeof window !== 'undefined') {
11
+ fetch('/api/session/logout', {
12
+ method: 'POST',
13
+ credentials: 'same-origin',
14
+ keepalive: true,
15
+ }).catch(() => {
16
+ // Ignore logout cleanup failures and proceed with client-side reset.
17
+ });
18
+ }
17
19
 
18
20
  // Clear only app-owned localStorage keys instead of wiping the entire origin
19
21
  if (typeof window !== 'undefined') {
@@ -49,6 +51,25 @@ export interface ClientResponse<T = any> {
49
51
  responseData: IApiResponse<T>;
50
52
  }
51
53
 
54
+ function buildBrowserProxyUrl(rawUrl: string): string {
55
+ if (typeof window === 'undefined') {
56
+ return rawUrl;
57
+ }
58
+
59
+ try {
60
+ const parsedUrl = new URL(rawUrl, window.location.origin);
61
+
62
+ if (parsedUrl.origin === window.location.origin) {
63
+ return parsedUrl.toString();
64
+ }
65
+
66
+ const proxyPath = parsedUrl.pathname.replace(/^\/+/, '');
67
+ return `/api/proxy/${proxyPath}${parsedUrl.search}`;
68
+ } catch {
69
+ return rawUrl;
70
+ }
71
+ }
72
+
52
73
  export async function sendRequest<T = any>({ url, method, data, params, headers, signal }: RequestOptions): Promise<ClientResponse<T>> {
53
74
  const defaultHeaders: Record<string, string> = {
54
75
  'Accept': 'application/json',
@@ -69,24 +90,10 @@ export async function sendRequest<T = any>({ url, method, data, params, headers,
69
90
  }
70
91
  }
71
92
 
72
- // Automatically add Authorization header on the client side
93
+ // Client-side requests are routed through a same-origin proxy so the
94
+ // browser never needs direct access to the bearer token.
73
95
  if (typeof window !== 'undefined') {
74
- const name = replacePlaceholders(
75
- cookie.access_token.encrypted ? cookie.access_token.secretName : cookie.access_token.name,
76
- {}
77
- );
78
- const tokenValue = Cookies.get(name);
79
-
80
- if (tokenValue) {
81
- try {
82
- const token = cookie.access_token.encrypted ? decrypt(tokenValue) : tokenValue;
83
- if (token) {
84
- defaultHeaders['Authorization'] = `Bearer ${token}`;
85
- }
86
- } catch (error) {
87
- console.error("Failed to process auth token:", error);
88
- }
89
- }
96
+ finalUrl = buildBrowserProxyUrl(finalUrl);
90
97
 
91
98
  // Automatically inject selected organization ID into every request
92
99
  try {