@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 +1 -1
- package/src/constants/menus.ts +202 -601
- package/src/utils/apiProxy.ts +155 -0
- package/src/utils/httpClient.ts +34 -27
package/package.json
CHANGED
package/src/constants/menus.ts
CHANGED
|
@@ -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: '
|
|
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: '
|
|
75
|
-
{ key: '
|
|
76
|
-
{ key: '
|
|
77
|
-
{ key: '
|
|
78
|
-
|
|
79
|
-
{ key: '
|
|
80
|
-
{ key: '
|
|
81
|
-
{ key: '
|
|
82
|
-
{ key: '
|
|
83
|
-
{ key: '
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{ key: '
|
|
87
|
-
{ key: '
|
|
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: '
|
|
131
|
-
{ key: '
|
|
132
|
-
{ key: '
|
|
133
|
-
{ key: 'sales__pos', label: 'POS
|
|
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
|
-
|
|
138
|
-
{ key: '
|
|
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
|
-
// ──
|
|
149
|
-
{ key: '
|
|
150
|
-
{ key: '
|
|
151
|
-
{ key: '
|
|
152
|
-
{ key: '
|
|
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
|
-
// ──
|
|
155
|
-
{ key: '
|
|
156
|
-
{ key: '
|
|
157
|
-
{ key: '
|
|
158
|
-
{ key: '
|
|
159
|
-
{ key: '
|
|
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: '
|
|
163
|
-
{ key: '
|
|
164
|
-
{ key: '
|
|
165
|
-
{ key: '
|
|
166
|
-
{ key: '
|
|
167
|
-
{ key: '
|
|
168
|
-
{ key: '
|
|
169
|
-
{ key: '
|
|
170
|
-
{ key: '
|
|
171
|
-
{ key: '
|
|
172
|
-
{ key: '
|
|
173
|
-
{ key: '
|
|
174
|
-
{ key: '
|
|
175
|
-
{ key: '
|
|
176
|
-
{ key: '
|
|
177
|
-
{ key: '
|
|
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: '
|
|
273
|
-
description: '
|
|
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
|
-
'
|
|
291
|
-
'
|
|
292
|
-
'
|
|
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
|
-
'
|
|
303
|
-
'
|
|
304
|
-
'
|
|
305
|
-
'
|
|
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
|
-
'
|
|
410
|
-
'
|
|
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: '
|
|
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
|
-
'
|
|
445
|
-
'
|
|
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: '
|
|
457
|
-
label: '
|
|
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
|
-
'
|
|
512
|
-
'
|
|
513
|
-
'
|
|
514
|
-
'
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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",
|
|
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",
|
|
335
|
+
iconName: "Package",
|
|
631
336
|
groups: [
|
|
632
337
|
{
|
|
633
|
-
id: "
|
|
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: "
|
|
639
|
-
{ id: "
|
|
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: "
|
|
655
|
-
label: "
|
|
348
|
+
id: "inventory_stock",
|
|
349
|
+
label: "Stock",
|
|
656
350
|
items: [
|
|
657
|
-
{ id: "
|
|
658
|
-
{ id: "
|
|
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: "
|
|
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: "
|
|
674
|
-
{ id: "
|
|
675
|
-
{ id: "
|
|
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: "
|
|
696
|
-
label: "
|
|
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: "
|
|
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: "
|
|
735
|
-
label: "
|
|
379
|
+
id: "sales_orders",
|
|
380
|
+
label: "Orders",
|
|
736
381
|
items: [
|
|
737
|
-
{ id: "
|
|
738
|
-
{ id: "
|
|
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: "
|
|
743
|
-
label: "
|
|
387
|
+
id: "sales_fulfillment",
|
|
388
|
+
label: "Fulfillment",
|
|
744
389
|
items: [
|
|
745
|
-
{ id: "
|
|
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: "
|
|
753
|
-
label: "
|
|
394
|
+
id: "sales_post_sales",
|
|
395
|
+
label: "Post-Sales",
|
|
754
396
|
items: [
|
|
755
|
-
{ id: "
|
|
756
|
-
{ id: "
|
|
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: "
|
|
761
|
-
label: "
|
|
402
|
+
id: "sales_pos",
|
|
403
|
+
label: "POS",
|
|
762
404
|
items: [
|
|
763
|
-
{ id: "
|
|
764
|
-
{ id: "
|
|
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: "
|
|
769
|
-
label: "
|
|
410
|
+
id: "sales_analytics",
|
|
411
|
+
label: "Analytics",
|
|
770
412
|
items: [
|
|
771
|
-
{ id: "
|
|
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: "
|
|
779
|
-
label: "
|
|
424
|
+
id: "procurement_orders",
|
|
425
|
+
label: "Orders",
|
|
780
426
|
items: [
|
|
781
|
-
{ id: "
|
|
427
|
+
{ id: "purchase_orders", label: "Purchase Orders", path: "/procurement/orders" },
|
|
782
428
|
],
|
|
783
429
|
},
|
|
784
430
|
{
|
|
785
|
-
id: "
|
|
786
|
-
label: "
|
|
431
|
+
id: "procurement_receiving",
|
|
432
|
+
label: "Receiving",
|
|
787
433
|
items: [
|
|
788
|
-
{ id: "
|
|
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: "
|
|
794
|
-
label: "
|
|
438
|
+
id: "procurement_finance",
|
|
439
|
+
label: "Finance",
|
|
795
440
|
items: [
|
|
796
|
-
{ id: "
|
|
797
|
-
{ id: "
|
|
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: "
|
|
807
|
-
label: "
|
|
808
|
-
iconName: "
|
|
448
|
+
id: "finance",
|
|
449
|
+
label: "Finance",
|
|
450
|
+
iconName: "Wallet",
|
|
809
451
|
groups: [
|
|
810
452
|
{
|
|
811
|
-
id: "
|
|
812
|
-
label: "
|
|
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: "
|
|
829
|
-
{ id: "
|
|
456
|
+
{ id: "invoices", label: "Invoices", path: "/finance/invoices" },
|
|
457
|
+
{ id: "payments", label: "Payments", path: "/finance/payments" },
|
|
830
458
|
],
|
|
831
459
|
},
|
|
832
460
|
{
|
|
833
|
-
id: "
|
|
834
|
-
label: "
|
|
461
|
+
id: "finance_accounting",
|
|
462
|
+
label: "Accounting",
|
|
835
463
|
items: [
|
|
836
|
-
{ id: "
|
|
837
|
-
{ id: "
|
|
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: "
|
|
842
|
-
label: "
|
|
470
|
+
id: "finance_reports",
|
|
471
|
+
label: "Reports",
|
|
843
472
|
items: [
|
|
844
|
-
{ id: "
|
|
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: "
|
|
849
|
-
label: "
|
|
480
|
+
id: "finance_settings",
|
|
481
|
+
label: "Settings",
|
|
850
482
|
items: [
|
|
851
|
-
{ id: "
|
|
852
|
-
{ id: "
|
|
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: "
|
|
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: "
|
|
884
|
-
{ id: "
|
|
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: "
|
|
890
|
-
label: "
|
|
504
|
+
id: "jewelry_master_data",
|
|
505
|
+
label: "Master Data",
|
|
891
506
|
items: [
|
|
892
|
-
{ id: "
|
|
893
|
-
{ id: "
|
|
894
|
-
{ id: "
|
|
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: "
|
|
900
|
-
label: "
|
|
513
|
+
id: "jewelry_procurement",
|
|
514
|
+
label: "Procurement",
|
|
901
515
|
items: [
|
|
902
|
-
{ id: "
|
|
903
|
-
{ id: "
|
|
904
|
-
{ id: "
|
|
905
|
-
{ id: "
|
|
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: "
|
|
910
|
-
label: "
|
|
523
|
+
id: "jewelry_buying",
|
|
524
|
+
label: "Buying",
|
|
911
525
|
items: [
|
|
912
|
-
{ id: "
|
|
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: "
|
|
922
|
-
label: "Sales
|
|
530
|
+
id: "jewelry_sales",
|
|
531
|
+
label: "Sales",
|
|
923
532
|
items: [
|
|
924
|
-
{ id: "
|
|
925
|
-
{ id: "
|
|
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: "
|
|
935
|
-
label: "
|
|
538
|
+
id: "jewelry_stock",
|
|
539
|
+
label: "Stock",
|
|
936
540
|
items: [
|
|
937
|
-
{ id: "
|
|
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: "
|
|
942
|
-
label: "
|
|
546
|
+
id: "jewelry_karigar",
|
|
547
|
+
label: "Karigar",
|
|
943
548
|
items: [
|
|
944
|
-
{ id: "
|
|
549
|
+
{ id: "party_transactions", label: "Party Transactions", path: "/jewelry/party-transactions" },
|
|
945
550
|
],
|
|
946
551
|
},
|
|
947
552
|
{
|
|
948
|
-
id: "
|
|
949
|
-
label: "
|
|
553
|
+
id: "jewelry_configuration",
|
|
554
|
+
label: "Configuration",
|
|
950
555
|
items: [
|
|
951
|
-
{ id: "
|
|
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
|
+
}
|
package/src/utils/httpClient.ts
CHANGED
|
@@ -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
|
|
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
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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 {
|