dts-universal-report-module 1.0.3 → 1.0.4

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.
Files changed (4) hide show
  1. package/README.md +652 -11
  2. package/dist/index.esm.js +8029 -6404
  3. package/dist/index.js +25 -25
  4. package/package.json +78 -49
package/README.md CHANGED
@@ -1,11 +1,652 @@
1
-
2
- # URM (V1) (Copy)
3
-
4
- This is a code bundle for URM (V1) (Copy). The original project is available at https://www.figma.com/design/DiMA63ToXMUuUqMhmLNobr/URM--V1---Copy-.
5
-
6
- ## Running the code
7
-
8
- Run `npm i` to install the dependencies.
9
-
10
- Run `npm run dev` to start the development server.
11
-
1
+ # Universal Report Module (URM)
2
+
3
+ > A fully featured, embeddable React reporting component for Digital Twin Solutions applications.
4
+ > Drop it into any MERN-stack host app and get a complete data table with filtering, sorting,
5
+ > grouping, views, presets, export, audit history, and scheduled reports — out of the box.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ - [Overview](#overview)
12
+ - [Features](#features)
13
+ - [Tech Stack](#tech-stack)
14
+ - [Architecture](#architecture)
15
+ - [Folder Structure](#folder-structure)
16
+ - [Prerequisites](#prerequisites)
17
+ - [Installation & Setup](#installation--setup)
18
+ - [Running the Development Server](#running-the-development-server)
19
+ - [Building the Library](#building-the-library)
20
+ - [Environment Configuration](#environment-configuration)
21
+ - [Usage — Integrating URM into a Host App](#usage--integrating-urm-into-a-host-app)
22
+ - [Data Source Options](#data-source-options)
23
+ - [Public API Reference](#public-api-reference)
24
+ - [Branching Strategy](#branching-strategy)
25
+ - [Commit Message Format](#commit-message-format)
26
+ - [Code Standards](#code-standards)
27
+ - [Developer Notes](#developer-notes)
28
+
29
+ ---
30
+
31
+ ## Overview
32
+
33
+ The **Universal Report Module (URM)** is a reusable React + TypeScript npm package built for
34
+ Digital Twin Solutions. It provides two primary surfaces:
35
+
36
+ - **`URMBuilder`** — A full report creation and management interface. Users can upload JSON data,
37
+ define column schemas, apply filters, sort, group, manage saved views, create presets, export
38
+ data, and review a complete audit history.
39
+
40
+ - **`URMViewer`** — A read-optimised embedded viewer for host applications that already have data.
41
+ It accepts data directly via props or an API source and renders the full table experience
42
+ without the upload or report-creation workflow.
43
+
44
+ Both surfaces are backed by the same core engine (`UseReportEngine`) and can be configured,
45
+ themed, and extended by the host application.
46
+
47
+ ---
48
+
49
+ ## Features
50
+
51
+ ### Data Ingestion
52
+ - JSON file upload with automatic schema detection
53
+ - Inline data via props (`data={myArray}`)
54
+ - API source with optional auto-refresh (`dataSource={{ type: 'api', url: '...' }}`)
55
+ - Async callback source (`dataSource={{ type: 'callback', fetch: async () => data }}`)
56
+ - Schema conflict detection and resolution UI
57
+
58
+ ### Table & Display
59
+ - Resizable, reorderable columns via drag-and-drop
60
+ - Card grid view toggle (alternative to table rows)
61
+ - Sticky header and frozen column support
62
+ - Row selection (single, range, select-all)
63
+ - Inline row detail, edit, and delete modals
64
+ - Favourited rows and favourites-only filter toggle
65
+ - Empty state and error state components
66
+
67
+ ### Filtering
68
+ - Multi-column filter panel
69
+ - Operators: equals, contains, startsWith, endsWith, gt, lt, gte, lte, isTrue, isFalse, NULL, NOT_NULL
70
+ - Per-column filter clear
71
+ - Filter conflict detection with user warnings
72
+
73
+ ### Sorting
74
+ - Multi-level sort stack (unlimited sort rules)
75
+ - Drag-to-reorder sort priority
76
+ - Column header click cycling (asc → desc → clear)
77
+ - Sort panel with full rule management
78
+
79
+ ### Grouping
80
+ - Multi-level row grouping (up to N levels)
81
+ - Collapsible group rows
82
+ - Group aggregate display (count, sum, min, max)
83
+ - Drag-to-reorder group levels
84
+
85
+ ### Views
86
+ - Named, saved view snapshots (filters + sort + columns + grouping)
87
+ - Default view designation
88
+ - Favourite views
89
+ - Dirty-state detection with diff summary modal
90
+ - View restore and permanent delete
91
+
92
+ ### Presets & Sharing
93
+ - Named saved presets (configuration snapshots)
94
+ - Shareable preset links via URL encoding
95
+ - Preset management panel (apply, delete, copy link)
96
+ - Active preset badge
97
+
98
+ ### Export
99
+ - Export to CSV, Excel (`.xlsx`), and JSON
100
+ - Configurable export options (selected rows, full data, current view)
101
+ - Dirty-view export warning
102
+ - Bulk export for selected rows
103
+
104
+ ### Scheduled Reports
105
+ - Schedule-based auto-export (daily, weekly, monthly)
106
+ - Email notification integration
107
+ - Scheduler management modal
108
+
109
+ ### Audit & History
110
+ - Full audit trail of all user actions (filters, sorts, views, presets, exports)
111
+ - Audit history panel with collapsible timeline
112
+ - Audit events written to report state
113
+
114
+ ### Search
115
+ - Global search across all visible columns
116
+ - Search history with favourites
117
+ - Persistent search history per report
118
+
119
+ ### Pagination
120
+ - Configurable page size (10, 25, 50, 100, all)
121
+ - Page navigation controls
122
+ - Total row count display
123
+
124
+ ### Permissions
125
+ - Role-based access: `owner`, `editor`, `viewer`
126
+ - Configurable permission gates per action
127
+ - View-only mode badge
128
+
129
+ ### Developer Tools
130
+ - Hidden dev config panel (Ctrl+Shift+D or `?devpanel=true`)
131
+ - Feature flags: audit, presets, export, permissions
132
+ - Default filter/sort/column overrides for testing
133
+
134
+ ---
135
+
136
+ ## Tech Stack
137
+
138
+ | Layer | Technology | Version |
139
+ |---|---|---|
140
+ | UI Framework | React | `^18.3.1` |
141
+ | Language | TypeScript | via `@types/react ^18.3.18` |
142
+ | Component Library | Material UI (MUI) | `>=5` |
143
+ | Styling | MUI `sx` prop + Emotion | `>=11` |
144
+ | Drag & Drop | react-dnd + HTML5Backend | `16.0.1` |
145
+ | Export | xlsx (SheetJS) | `^0.18.5` |
146
+ | Build Tool | Vite | `^6.4.2` |
147
+ | Linting | ESLint + TypeScript plugin | — |
148
+ | Formatting | Prettier | — |
149
+ | Git Hooks | Husky + lint-staged | — |
150
+
151
+ **Peer dependencies required in the host app:**
152
+ - `react >= 18`
153
+ - `react-dom >= 18`
154
+ - `@mui/material >= 5`
155
+ - `@emotion/react >= 11`
156
+ - `@emotion/styled >= 11`
157
+
158
+ ---
159
+
160
+ ## Architecture
161
+
162
+ URM follows a **layered core engine** architecture. All business logic lives in the `core/`
163
+ directory as custom hooks. Components in `app/components/` are purely presentational — they
164
+ receive state and handlers from the engine via React Context, and never manage business logic
165
+ directly.
166
+
167
+ ```
168
+ ┌─────────────────────────────────────────────────────────────┐
169
+ │ Host Application │
170
+ │ │
171
+ │ <URMBuilder /> or <URMViewer /> or <URMProvider /> │
172
+ └───────────────────────┬─────────────────────────────────────┘
173
+
174
+ ┌───────────────────────▼─────────────────────────────────────┐
175
+ │ ReportProvider (Context) │
176
+ │ Owns all state. Exposes engine via useReportContext(). │
177
+ └───────────────────────┬─────────────────────────────────────┘
178
+
179
+ ┌───────────────────────▼─────────────────────────────────────┐
180
+ │ UseReportEngine │
181
+ │ Master hook — orchestrates all sub-engines below. │
182
+ │ │
183
+ │ ┌──────────────┐ ┌─────────────┐ ┌───────────────────────┐ │
184
+ │ │UseFilterEngine│ │UseSortEngine│ │ UseGroupingEngine │ │
185
+ │ └──────────────┘ └─────────────┘ └───────────────────────┘ │
186
+ │ ┌──────────────┐ ┌─────────────┐ ┌───────────────────────┐ │
187
+ │ │UseColumnEngine│ │UseViewEngine│ │ UseSearchEngine │ │
188
+ │ └──────────────┘ └─────────────┘ └───────────────────────┘ │
189
+ │ ┌──────────────┐ ┌─────────────┐ │
190
+ │ │UseTableEngine│ │UsePagination│ │
191
+ │ └──────────────┘ └─────────────┘ │
192
+ └───────────────────────┬─────────────────────────────────────┘
193
+
194
+ ┌───────────────────────▼─────────────────────────────────────┐
195
+ │ UI Components (src/app/components/) │
196
+ │ Pure presentation. No local business logic. │
197
+ │ Read state from context. Call handlers from engine. │
198
+ └─────────────────────────────────────────────────────────────┘
199
+ ```
200
+
201
+ **Data flow:**
202
+ ```
203
+ Host provides data → ReportProvider → UseReportEngine processes →
204
+ Context updated → Components re-render with new state
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Folder Structure
210
+
211
+ ```
212
+ universal-report-module/
213
+ ├── src/
214
+ │ ├── index.ts # Public package API — only export from here
215
+ │ ├── main.tsx # Dev-only entry point (not included in build)
216
+ │ │
217
+ │ ├── app/
218
+ │ │ ├── app.tsx # Dev-only root with URL-based mode routing
219
+ │ │ │
220
+ │ │ ├── components/ # All UI components (44 files)
221
+ │ │ │ ├── data-table.tsx # Core table with all interaction features
222
+ │ │ │ ├── report-viewer.tsx # Orchestrator — renders panels and modals
223
+ │ │ │ ├── filter-panel.tsx # Filter rule management
224
+ │ │ │ ├── sort-panel.tsx # Sort stack management
225
+ │ │ │ ├── group-panel.tsx # Grouping level management
226
+ │ │ │ ├── manage-columns-panel.tsx
227
+ │ │ │ ├── manage-views-panel.tsx
228
+ │ │ │ ├── manage-presets-panel.tsx
229
+ │ │ │ ├── export-config-modal.tsx
230
+ │ │ │ ├── scheduled-reports-modal.tsx
231
+ │ │ │ ├── audit-history-panel.tsx
232
+ │ │ │ ├── error-boundary.tsx
233
+ │ │ │ └── ... # 32 additional focused components
234
+ │ │ │
235
+ │ │ ├── devconfig/ # Developer configuration panel (hidden)
236
+ │ │ │ ├── dev-config-context.ts
237
+ │ │ │ ├── dev-config-modal.tsx
238
+ │ │ │ └── urm-dev-config.ts
239
+ │ │ │
240
+ │ │ ├── modules/ # Public-facing entry surfaces
241
+ │ │ │ ├── builder/
242
+ │ │ │ │ ├── index.tsx # URMBuilder — default export with provider wrap
243
+ │ │ │ │ └── builder.tsx # Builder UI (requires context to be provided)
244
+ │ │ │ └── viewer/
245
+ │ │ │ ├── index.tsx # URMViewer — default export with provider wrap
246
+ │ │ │ ├── viewer.tsx # Viewer UI (requires context to be provided)
247
+ │ │ │ └── urm-viewer.tsx # Alternative viewer export
248
+ │ │ │
249
+ │ │ ├── types/ # TypeScript interfaces and types
250
+ │ │ │ ├── report.ts # Report, View, Filter, SortRule, ColumnSchema, etc.
251
+ │ │ │ ├── data-source.ts # DataSourceConfig, DataLoadState
252
+ │ │ │ ├── grouping.ts # GroupNode (for group tree traversal)
253
+ │ │ │ └── scheduler.ts # ScheduledReport, ScheduleFrequency
254
+ │ │ │
255
+ │ │ └── utils/ # Pure utility functions (no React)
256
+ │ │ ├── logger.ts # Centralised logging (replaces console.*)
257
+ │ │ ├── error-handling.ts # Error classification and recovery logic
258
+ │ │ ├── export.ts # CSV, Excel, JSON export helpers
259
+ │ │ ├── filtering.ts # Filter application logic
260
+ │ │ ├── sorting.ts # Multi-level sort comparators
261
+ │ │ ├── grouping.ts # Data grouping and aggregate calculation
262
+ │ │ ├── schema-detector.ts # JSON schema inference
263
+ │ │ ├── view-helpers.ts # View state diff and snapshot helpers
264
+ │ │ ├── presets.ts # Preset capture, apply, share-link encoding
265
+ │ │ ├── persistence.ts # localStorage read/write for report state
266
+ │ │ ├── audit.ts # Audit event creation and appending
267
+ │ │ ├── use-scheduler-engine.ts # Scheduled report execution hook
268
+ │ │ └── ... # 9 additional utility modules
269
+ │ │
270
+ │ ├── core/ # Engine layer — all business logic hooks
271
+ │ │ ├── index.ts # Core exports
272
+ │ │ ├── report-context.tsx # React Context + Provider
273
+ │ │ ├── use-report-engine.ts # Master orchestration hook (~2000 lines)
274
+ │ │ ├── use-filter-engine.ts
275
+ │ │ ├── use-sort-engine.ts
276
+ │ │ ├── use-grouping-engine.ts
277
+ │ │ ├── use-column-engine.ts
278
+ │ │ ├── use-view-engine.ts
279
+ │ │ ├── use-search-engine.ts
280
+ │ │ ├── use-table-engine.ts
281
+ │ │ └── use-pagination-engine.ts
282
+ │ │
283
+ │ └── styles/
284
+ │ ├── globals.css # Base CSS resets
285
+ │ └── index.css # Entry CSS
286
+
287
+ ├── eslint.config.js # ESLint rules (TypeScript + React)
288
+ ├── .prettierrc # Prettier formatting config
289
+ ├── tsconfig.json # TypeScript compiler config (strict mode)
290
+ ├── vite.config.ts # Vite build config (lib mode + dev mode)
291
+ ├── package.json # Package metadata, scripts, lint-staged
292
+ ├── global.d.ts # Global type declarations
293
+ ├── index.html # Dev-only HTML entry
294
+ └── .gitignore
295
+ ```
296
+
297
+ ---
298
+
299
+ ## Prerequisites
300
+
301
+ | Requirement | Minimum Version |
302
+ |---|---|
303
+ | Node.js | `>= 18.x` |
304
+ | npm | `>= 9.x` |
305
+ | Git | any recent version |
306
+
307
+ ---
308
+
309
+ ## Installation & Setup
310
+
311
+ ### 1. Clone the repository
312
+
313
+ ```bash
314
+ git clone https://github.com/Digital-Twin-Operations/universal-report-module.git
315
+ cd universal-report-module
316
+ ```
317
+
318
+ ### 2. Switch to the develop branch
319
+
320
+ All active development happens on `develop`. Never work directly on `main`.
321
+
322
+ ```bash
323
+ git checkout develop
324
+ git pull origin develop
325
+ ```
326
+
327
+ ### 3. Install dependencies
328
+
329
+ ```bash
330
+ npm install
331
+ ```
332
+
333
+ ### 4. Set up environment (if needed)
334
+
335
+ There are no required environment variables for local development of this library.
336
+ If you add one in future, copy `.env.example` and fill values locally:
337
+
338
+ ```bash
339
+ cp .env.example .env
340
+ ```
341
+
342
+ Never commit `.env` — it is in `.gitignore`.
343
+
344
+ ---
345
+
346
+ ## Running the Development Server
347
+
348
+ The project includes a `main.tsx` and `app.tsx` for local development and testing of
349
+ components without needing a host application.
350
+
351
+ ```bash
352
+ npm run dev
353
+ ```
354
+
355
+ Open [http://localhost:5173](http://localhost:5173) in your browser.
356
+
357
+ **URL parameters for switching modes:**
358
+
359
+ | URL | What it shows |
360
+ |---|---|
361
+ | `http://localhost:5173` | Builder surface (default) |
362
+ | `http://localhost:5173?mode=viewer` | Viewer surface |
363
+ | `http://localhost:5173?devpanel=true` | Builder + dev config gear icon visible |
364
+
365
+ **Hidden developer panel keyboard shortcut:**
366
+ `Ctrl + Shift + D` — opens the dev config panel in any mode.
367
+
368
+ ---
369
+
370
+ ## Building the Library
371
+
372
+ ```bash
373
+ npm run build
374
+ ```
375
+
376
+ This produces the distributable package in `dist/`:
377
+
378
+ ```
379
+ dist/
380
+ ├── index.js # CommonJS build
381
+ ├── index.esm.js # ES module build
382
+ └── index.d.ts # TypeScript declarations
383
+ ```
384
+
385
+ The build is configured in `vite.config.ts` in library mode. All peer dependencies
386
+ (`react`, `@mui/material`, `@emotion/*`) are externalized and not bundled.
387
+
388
+ ---
389
+
390
+ ## Environment Configuration
391
+
392
+ | Variable | Description | Example |
393
+ |---|---|---|
394
+ | _(none required)_ | This library has no required env vars | — |
395
+
396
+ If you add environment variables in future:
397
+ - Prefix with `VITE_` for client-side access
398
+ - Document them here and in `.env.example`
399
+ - Never hardcode values in source files
400
+
401
+ ---
402
+
403
+ ## Usage — Integrating URM into a Host App
404
+
405
+ ### Install the package
406
+
407
+ ```bash
408
+ npm install dts-universal-report-module
409
+ ```
410
+
411
+ ### Option 1 — Builder (full report creation UI)
412
+
413
+ ```tsx
414
+ import { URMBuilder } from 'dts-universal-report-module';
415
+
416
+ function MyPage() {
417
+ return <URMBuilder />;
418
+ }
419
+ ```
420
+
421
+ ### Option 2 — Builder with inline data (skip upload)
422
+
423
+ ```tsx
424
+ import { URMBuilder } from 'dts-universal-report-module';
425
+
426
+ function MyPage() {
427
+ const data = [
428
+ { id: 1, name: 'Device A', status: 'online', temperature: 72.4 },
429
+ { id: 2, name: 'Device B', status: 'offline', temperature: 68.1 },
430
+ ];
431
+
432
+ return <URMBuilder data={data} reportName="Device Status" />;
433
+ }
434
+ ```
435
+
436
+ ### Option 3 — Builder with API data source
437
+
438
+ ```tsx
439
+ import { URMBuilder } from 'dts-universal-report-module';
440
+
441
+ function MyPage() {
442
+ return (
443
+ <URMBuilder
444
+ dataSource={{
445
+ type: 'api',
446
+ url: '/api/v1/devices/readings',
447
+ headers: { Authorization: `Bearer ${token}` },
448
+ refreshInterval: 30000, // auto-refresh every 30 seconds
449
+ }}
450
+ reportName="Live Device Readings"
451
+ />
452
+ );
453
+ }
454
+ ```
455
+
456
+ ### Option 4 — Viewer (read-only, data from host)
457
+
458
+ ```tsx
459
+ import { URMViewer } from 'dts-universal-report-module';
460
+
461
+ function Dashboard() {
462
+ const data = useSelector(selectDeviceData);
463
+
464
+ return <URMViewer data={data} />;
465
+ }
466
+ ```
467
+
468
+ ### Option 5 — Custom layout with URMProvider
469
+
470
+ For full control over the layout, use the provider directly:
471
+
472
+ ```tsx
473
+ import { URMProvider, useURMContext } from 'dts-universal-report-module';
474
+
475
+ function CustomReport() {
476
+ const engine = useURMContext();
477
+ return (
478
+ <div>
479
+ <MyCustomHeader reportCount={engine.reports.length} />
480
+ {/* render your own layout using engine state */}
481
+ </div>
482
+ );
483
+ }
484
+
485
+ function App() {
486
+ return (
487
+ <URMProvider mode="builder" data={myData}>
488
+ <CustomReport />
489
+ </URMProvider>
490
+ );
491
+ }
492
+ ```
493
+
494
+ ---
495
+
496
+ ## Data Source Options
497
+
498
+ | Type | Props | Auto-refresh |
499
+ |---|---|---|
500
+ | JSON file upload | _(no props needed)_ | No |
501
+ | Inline array | `data={myArray}` | No |
502
+ | API endpoint | `dataSource={{ type: 'api', url: '...' }}` | Yes (optional) |
503
+ | Async callback | `dataSource={{ type: 'callback', fetch: async () => data }}` | Yes (optional) |
504
+
505
+ ---
506
+
507
+ ## Public API Reference
508
+
509
+ All public exports are defined in `src/index.ts`.
510
+
511
+ ### Components
512
+
513
+ | Export | Description |
514
+ |---|---|
515
+ | `URMBuilder` | Full report creation + management surface |
516
+ | `URMViewer` | Embedded read-only viewer |
517
+ | `URMBuilderRaw` | Builder without provider wrap — bring your own `URMProvider` |
518
+ | `URMViewerRaw` | Viewer without provider wrap — bring your own `URMProvider` |
519
+ | `URMProvider` | React context provider — use for custom layouts |
520
+
521
+ ### Hooks
522
+
523
+ | Export | Description |
524
+ |---|---|
525
+ | `useURMContext` | Access full engine state and handlers inside `URMProvider` |
526
+
527
+ ### Types
528
+
529
+ | Export | Description |
530
+ |---|---|
531
+ | `Report` | Full report object shape |
532
+ | `DataSourceConfig` | Union type for API and callback data sources |
533
+ | `DataLoadState` | `'idle' \| 'loading' \| 'ready' \| 'error' \| 'refreshing'` |
534
+
535
+ ---
536
+
537
+ ## Branching Strategy
538
+
539
+ | Branch | Purpose | Rules |
540
+ |---|---|---|
541
+ | `main` | Production-ready builds | Never commit directly. Merge from `develop` only when releasing. |
542
+ | `develop` | Active development | All feature work merges here. Always deployable. |
543
+ | `feature/*` | New features | Branch from `develop`. Merge back to `develop` via PR. |
544
+ | `bugfix/*` | Non-critical bug fixes | Branch from `develop`. Merge back to `develop`. |
545
+ | `hotfix/*` | Urgent production fixes | Branch from `main`. Merge to both `main` and `develop`. |
546
+
547
+ **Creating a feature branch:**
548
+ ```bash
549
+ git checkout develop
550
+ git pull origin develop
551
+ git checkout -b feature/urm-123-short-description
552
+ ```
553
+
554
+ **Merging back to develop:**
555
+ ```bash
556
+ git checkout develop
557
+ git merge feature/urm-123-short-description
558
+ git push origin develop
559
+ ```
560
+
561
+ ---
562
+
563
+ ## Commit Message Format
564
+
565
+ All commits must follow **Conventional Commits** format:
566
+
567
+ ```
568
+ type(scope): short description in imperative mood
569
+ ```
570
+
571
+ | Type | When to use |
572
+ |---|---|
573
+ | `feat` | New feature or capability |
574
+ | `fix` | Bug fix |
575
+ | `refactor` | Code restructure with no behaviour change |
576
+ | `docs` | Documentation only |
577
+ | `chore` | Tooling, dependencies, config |
578
+ | `test` | Tests added or updated |
579
+ | `perf` | Performance improvement |
580
+
581
+ **Examples:**
582
+
583
+ ```bash
584
+ git commit -m "feat(export): add JSON export option to export config modal"
585
+ git commit -m "fix(filter): resolve null crash when filter value is empty string"
586
+ git commit -m "refactor(structure): rename all files to kebab-case convention"
587
+ git commit -m "docs(readme): add complete project overview and developer guide"
588
+ git commit -m "chore(toolchain): add eslint, prettier, and husky configuration"
589
+ ```
590
+
591
+ **Rules:**
592
+ - Subject line max 72 characters
593
+ - Use imperative mood: "add", "fix", "update" — not "added", "fixes"
594
+ - Scope = the module or area affected
595
+
596
+ ---
597
+
598
+ ## Code Standards
599
+
600
+ This project follows the **MERN Engineering Standards v1.0** document.
601
+ Key rules enforced by ESLint and Prettier:
602
+
603
+ - All file names: `kebab-case` (e.g. `data-table.tsx`)
604
+ - All folder names: `kebab-case` (e.g. `modules/builder/`)
605
+ - React component names: `PascalCase` (export name inside the file)
606
+ - Hook names: `camelCase` with `use` prefix
607
+ - No `console.log` — use `logger` from `src/app/utils/logger.ts`
608
+ - No `console.error` or `console.warn` directly — use `logger`
609
+ - No inline `style={{}}` — use MUI `sx` prop
610
+ - No hardcoded colour values — use MUI theme tokens
611
+ - No function longer than 80 lines
612
+ - No commented-out dead code
613
+ - All code through `develop` branch — never commit to `main`
614
+
615
+ ---
616
+
617
+ ## Developer Notes
618
+
619
+ ### Why is UseReportEngine.ts so large?
620
+
621
+ `use-report-engine.ts` (~2,000 lines) is the master orchestration hook. It intentionally
622
+ centralises all state management and handler definitions in one place so that the
623
+ `ReportContext` can expose a single, stable API to all components. This is a known area
624
+ for future decomposition — the sub-engines (`use-filter-engine`, `use-sort-engine`, etc.)
625
+ are already extracted; the remaining work is to move more handler logic into them.
626
+
627
+ ### Why does the build externalise so many dependencies?
628
+
629
+ URM is designed to be embedded in host applications that already have React and MUI installed.
630
+ Bundling them again would cause version conflicts and bloat the package. All peer dependencies
631
+ are listed in `package.json > peerDependencies` and must be present in the host app.
632
+
633
+ ### Dev panel
634
+
635
+ The developer configuration panel is deliberately hidden from production UI. It can be
636
+ accessed via `Ctrl+Shift+D` or the `?devpanel=true` URL parameter. It allows toggling
637
+ feature flags, setting default filter/sort/column configs, and simulating different user roles.
638
+ It is excluded from the published package build.
639
+
640
+ ### Adding a new utility
641
+
642
+ 1. Create the file in `src/app/utils/` with a `kebab-case` name
643
+ 2. Export only what other files need
644
+ 3. Import using relative paths, e.g. `import { myUtil } from '../utils/my-util'`
645
+ 4. If it needs logging, import from `./logger`
646
+
647
+ ### Adding a new component
648
+
649
+ 1. Create the file in `src/app/components/` with a `kebab-case` name
650
+ 2. Export the component as a named export using `PascalCase`
651
+ 3. Do not manage business logic inside components — use `useReportContext()`
652
+ 4. Do not use `style={{}}` — use MUI `sx` prop only