@memberjunction/core-entities 3.4.0 → 4.1.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.
Files changed (78) hide show
  1. package/dist/artifact-extraction/artifact-extract-rules.js +1 -2
  2. package/dist/artifact-extraction/artifact-extract-rules.js.map +1 -1
  3. package/dist/artifact-extraction/artifact-extractor.d.ts +1 -1
  4. package/dist/artifact-extraction/artifact-extractor.js +1 -5
  5. package/dist/artifact-extraction/artifact-extractor.js.map +1 -1
  6. package/dist/custom/ComponentEntityExtended.d.ts +1 -1
  7. package/dist/custom/ComponentEntityExtended.js +8 -11
  8. package/dist/custom/ComponentEntityExtended.js.map +1 -1
  9. package/dist/custom/DashboardEntityExtended.d.ts +1 -1
  10. package/dist/custom/DashboardEntityExtended.js +17 -20
  11. package/dist/custom/DashboardEntityExtended.js.map +1 -1
  12. package/dist/custom/EntityEntityExtended.d.ts +1 -1
  13. package/dist/custom/EntityEntityExtended.js +7 -10
  14. package/dist/custom/EntityEntityExtended.js.map +1 -1
  15. package/dist/custom/EntityFieldEntityExtended.d.ts +1 -1
  16. package/dist/custom/EntityFieldEntityExtended.js +27 -29
  17. package/dist/custom/EntityFieldEntityExtended.js.map +1 -1
  18. package/dist/custom/EnvironmentEntityExtended.d.ts +1 -1
  19. package/dist/custom/EnvironmentEntityExtended.js +7 -10
  20. package/dist/custom/EnvironmentEntityExtended.js.map +1 -1
  21. package/dist/custom/ListDetailEntityExtended.d.ts +1 -1
  22. package/dist/custom/ListDetailEntityExtended.js +14 -17
  23. package/dist/custom/ListDetailEntityExtended.js.map +1 -1
  24. package/dist/custom/ResourcePermissions/ResourceData.js +4 -8
  25. package/dist/custom/ResourcePermissions/ResourceData.js.map +1 -1
  26. package/dist/custom/ResourcePermissions/ResourcePermissionEngine.d.ts +1 -1
  27. package/dist/custom/ResourcePermissions/ResourcePermissionEngine.js +6 -9
  28. package/dist/custom/ResourcePermissions/ResourcePermissionEngine.js.map +1 -1
  29. package/dist/custom/ResourcePermissions/ResourcePermissionSubclass.d.ts +1 -1
  30. package/dist/custom/ResourcePermissions/ResourcePermissionSubclass.js +10 -13
  31. package/dist/custom/ResourcePermissions/ResourcePermissionSubclass.js.map +1 -1
  32. package/dist/custom/ScheduledActionExtended.d.ts +1 -1
  33. package/dist/custom/ScheduledActionExtended.js +7 -10
  34. package/dist/custom/ScheduledActionExtended.js.map +1 -1
  35. package/dist/custom/TemplateEntityExtended.d.ts +1 -1
  36. package/dist/custom/TemplateEntityExtended.js +8 -11
  37. package/dist/custom/TemplateEntityExtended.js.map +1 -1
  38. package/dist/custom/UserViewEntity.d.ts +1 -1
  39. package/dist/custom/UserViewEntity.js +44 -75
  40. package/dist/custom/UserViewEntity.js.map +1 -1
  41. package/dist/engines/EncryptionEngineBase.d.ts +1 -6
  42. package/dist/engines/EncryptionEngineBase.d.ts.map +1 -1
  43. package/dist/engines/EncryptionEngineBase.js +8 -19
  44. package/dist/engines/EncryptionEngineBase.js.map +1 -1
  45. package/dist/engines/FileStorageEngine.d.ts +1 -1
  46. package/dist/engines/FileStorageEngine.js +2 -6
  47. package/dist/engines/FileStorageEngine.js.map +1 -1
  48. package/dist/engines/MCPEngine.d.ts +1 -1
  49. package/dist/engines/MCPEngine.js +2 -6
  50. package/dist/engines/MCPEngine.js.map +1 -1
  51. package/dist/engines/TypeTablesCache.d.ts +1 -1
  52. package/dist/engines/TypeTablesCache.js +2 -6
  53. package/dist/engines/TypeTablesCache.js.map +1 -1
  54. package/dist/engines/UserInfoEngine.d.ts +1 -1
  55. package/dist/engines/UserInfoEngine.d.ts.map +1 -1
  56. package/dist/engines/UserInfoEngine.js +35 -18
  57. package/dist/engines/UserInfoEngine.js.map +1 -1
  58. package/dist/engines/UserViewEngine.d.ts +1 -1
  59. package/dist/engines/UserViewEngine.js +4 -8
  60. package/dist/engines/UserViewEngine.js.map +1 -1
  61. package/dist/engines/artifacts.d.ts +1 -1
  62. package/dist/engines/artifacts.js +2 -6
  63. package/dist/engines/artifacts.js.map +1 -1
  64. package/dist/engines/component-metadata.d.ts +2 -2
  65. package/dist/engines/component-metadata.js +2 -6
  66. package/dist/engines/component-metadata.js.map +1 -1
  67. package/dist/engines/dashboards.d.ts +2 -2
  68. package/dist/engines/dashboards.js +5 -8
  69. package/dist/engines/dashboards.js.map +1 -1
  70. package/dist/generated/entity_subclasses.d.ts +1633 -56
  71. package/dist/generated/entity_subclasses.d.ts.map +1 -1
  72. package/dist/generated/entity_subclasses.js +9576 -7270
  73. package/dist/generated/entity_subclasses.js.map +1 -1
  74. package/dist/index.d.ts +24 -24
  75. package/dist/index.js +24 -40
  76. package/dist/index.js.map +1 -1
  77. package/package.json +9 -8
  78. package/readme.md +420 -132
package/readme.md CHANGED
@@ -1,16 +1,8 @@
1
1
  # @memberjunction/core-entities
2
2
 
3
- A comprehensive library of strongly-typed entity classes for MemberJunction's core metadata schema. This package provides type-safe access to all MemberJunction system entities with built-in validation, custom business logic, and seamless integration with the MemberJunction framework.
3
+ Strongly-typed entity classes, singleton engine caches, and domain logic for every entity in MemberJunction's core metadata schema. This package is the primary data-access layer that all MJ applications -- server and client -- depend on to interact with the MJ data model in a type-safe, validated way.
4
4
 
5
- ## Overview
6
-
7
- The `@memberjunction/core-entities` package contains:
8
- - **178+ Generated Entity Classes**: Strongly-typed TypeScript classes for all core MemberJunction entities
9
- - **Extended Entity Classes**: Custom subclasses with specialized business logic
10
- - **Artifact Extraction System**: Metadata-driven attribute extraction with hierarchical inheritance
11
- - **Resource Permission Engine**: Comprehensive permission management system
12
- - **Zod Schema Validation**: Built-in runtime validation for all entity types
13
- - **Type Definitions**: Full TypeScript type definitions for enhanced IDE support
5
+ All entity subclasses in this package are **auto-generated by CodeGen**. Manual edits to files under `src/generated/` will be overwritten. Custom business logic is layered on top via extended classes in `src/custom/`.
14
6
 
15
7
  ## Installation
16
8
 
@@ -18,180 +10,476 @@ The `@memberjunction/core-entities` package contains:
18
10
  npm install @memberjunction/core-entities
19
11
  ```
20
12
 
13
+ ## Overview
14
+
15
+ The package is structured into four layers that build on each other:
16
+
17
+ ```mermaid
18
+ flowchart TD
19
+ subgraph Generated["Generated Layer (CodeGen)"]
20
+ ZOD["Zod Schemas<br/>Runtime validation"]
21
+ ENT["272 Entity Subclasses<br/>Typed getters/setters"]
22
+ end
23
+
24
+ subgraph Custom["Custom Layer (Hand-Written)"]
25
+ EXT["Extended Entities<br/>Business logic overrides"]
26
+ RPE["Resource Permissions<br/>Access control"]
27
+ end
28
+
29
+ subgraph Engines["Engine Layer (Singletons)"]
30
+ UIE["UserInfoEngine"]
31
+ UVE["UserViewEngine"]
32
+ DE["DashboardEngine"]
33
+ CME["ComponentMetadataEngine"]
34
+ AME["ArtifactMetadataEngine"]
35
+ FE["FileStorageEngine"]
36
+ EE["EncryptionEngineBase"]
37
+ ME["MCPEngine"]
38
+ TTC["TypeTablesCache"]
39
+ end
40
+
41
+ subgraph Extraction["Artifact Extraction"]
42
+ AER["Extract Rules<br/>Type definitions"]
43
+ AEX["ArtifactExtractor<br/>Rule resolution + execution"]
44
+ end
45
+
46
+ ENT --> EXT
47
+ ZOD --> ENT
48
+ EXT --> Engines
49
+ ENT --> Engines
50
+ AER --> AEX
51
+
52
+ style Generated fill:#2d6a9f,stroke:#1a4971,color:#fff
53
+ style Custom fill:#2d8659,stroke:#1a5c3a,color:#fff
54
+ style Engines fill:#7c5295,stroke:#563a6b,color:#fff
55
+ style Extraction fill:#b8762f,stroke:#8a5722,color:#fff
56
+ ```
57
+
58
+ ### Generated Entity Classes
59
+
60
+ CodeGen scans the MemberJunction database schema and produces:
61
+
62
+ - **Zod schema objects** for every entity, providing runtime validation with field-level descriptions, related-entity annotations, and value-list constraints.
63
+ - **Entity subclasses** extending `BaseEntity<T>` with strongly-typed getter/setter properties for every column, typed `Load()` methods, and JSDoc annotations including SQL types, defaults, and foreign key references.
64
+
65
+ There are currently **272 generated entity classes** covering approximately 78,000 lines of code in a single `entity_subclasses.ts` file.
66
+
67
+ ### Extended Entity Classes
68
+
69
+ Several entities require custom business logic beyond what CodeGen can generate. Extended classes use `@RegisterClass` to override the generated base class in MJ's class factory:
70
+
71
+ | Extended Class | Entity Name | Purpose |
72
+ |---|---|---|
73
+ | `UserViewEntityExtended` | User Views | Filter/column JSON parsing, WHERE clause generation, smart filter AI stub, permission checks |
74
+ | `DashboardEntityExtended` | Dashboards | Default config initialization, permission-based validation on save/delete |
75
+ | `EntityEntityExtended` | Entities | Auto-sets `AutoUpdateDescription` when description is manually changed |
76
+ | `EntityFieldEntityExtended` | Entity Fields | Prevents modification of database-reflected properties, auto-sets `AutoUpdateDescription` |
77
+ | `ComponentEntityExtended` | MJ: Components | Syncs derived fields from Specification JSON, keeps `spec` property in sync |
78
+ | `TemplateEntityExtended` | Templates | Content/param management, template input validation |
79
+ | `ScheduledActionEntityExtended` | Scheduled Actions | Auto-generates CronExpression from schedule type settings |
80
+ | `ListDetailEntityExtended` | List Details | Composite key handling, duplicate detection on save |
81
+ | `EnvironmentEntityExtended` | MJ: Environments | Exposes static `DefaultEnvironmentID` constant |
82
+ | `ResourcePermissionEntityExtended` | Resource Permissions | Notification workflow on permission request/approval |
83
+
84
+ ### Singleton Engines
85
+
86
+ Engine classes extend `BaseEngine<T>` to provide cached, singleton access to groups of related entities. They load data once and keep it in memory, with auto-refresh when underlying data changes.
87
+
88
+ ```mermaid
89
+ flowchart LR
90
+ subgraph App["Application Code"]
91
+ SVC["Services / Components"]
92
+ end
93
+
94
+ subgraph Engines["Singleton Engines"]
95
+ UIE["UserInfoEngine"]
96
+ DE["DashboardEngine"]
97
+ RPE["ResourcePermissionEngine"]
98
+ end
99
+
100
+ subgraph DB["Database"]
101
+ MJD["MJ Schema"]
102
+ end
103
+
104
+ SVC -->|".Instance"| Engines
105
+ Engines -->|"Config() loads once"| DB
106
+ Engines -->|"Cached data"| SVC
107
+
108
+ style App fill:#2d6a9f,stroke:#1a4971,color:#fff
109
+ style Engines fill:#7c5295,stroke:#563a6b,color:#fff
110
+ style DB fill:#64748b,stroke:#475569,color:#fff
111
+ ```
112
+
113
+ ### Artifact Extraction System
114
+
115
+ A metadata-driven system for extracting structured attributes from artifact content using declarative JavaScript-based rules with hierarchical inheritance through parent artifact types.
116
+
21
117
  ## Key Features
22
118
 
23
- ### 1. Strongly-Typed Entity Classes
24
- Every MemberJunction core entity has a corresponding TypeScript class with:
25
- - Full type safety for all properties
26
- - Automatic validation using Zod schemas
27
- - Relationship navigation properties
28
- - Built-in CRUD operations
29
-
30
- ### 2. Extended Entity Classes
31
- Several entities have custom extended classes that provide additional functionality:
32
-
33
- - **UserViewEntityExtended**: Enhanced view management with filter and column parsing
34
- - **DashboardEntityExtended**: Dashboard configuration management
35
- - **AIModelEntityExtended**: AI model utilities and helpers
36
- - **AIPromptEntityExtended**: Prompt management functionality
37
- - **ArtifactVersionExtended**: Automatic content hashing and attribute extraction
38
- - **ListDetailEntityExtended**: List view enhancements
39
- - **ScheduledActionExtended**: Scheduled task management
40
- - **ResourcePermissionEntity**: Resource access control
41
-
42
- ### 3. Artifact Extraction System
43
- A powerful metadata-driven system for extracting structured attributes from artifact content:
44
- - Hierarchical extract rule inheritance
45
- - Declarative JavaScript-based extractors
46
- - Automatic SHA-256 content hashing
47
- - Standard property mappings for UI rendering
48
- - Type-safe attribute storage and retrieval
49
-
50
- ### 4. Resource Permission Engine
51
- A sophisticated permission system for managing access to various resources:
52
- - Role-based permissions
53
- - Resource type definitions
54
- - Permission inheritance
55
- - Cached permission lookups
119
+ - **272 strongly-typed entity classes** covering all MemberJunction core schema entities
120
+ - **Zod runtime validation** with field-level constraints and value list enums
121
+ - **Extended entity classes** with permission checks, workflow logic, and JSON state parsing
122
+ - **9 singleton engine caches** eliminating redundant database queries
123
+ - **Resource permission engine** with role-based access control (View/Edit/Owner levels)
124
+ - **Dashboard permission engine** with owner/direct/category permission hierarchy
125
+ - **User view engine** with filter-to-SQL conversion and smart filter AI support
126
+ - **Artifact extraction** with hierarchical rule inheritance and sandboxed execution
127
+ - **Encryption engine base** for field-level encryption metadata caching
56
128
 
57
129
  ## Usage
58
130
 
59
- ### Basic Entity Usage
131
+ ### Working with Entity Objects
132
+
133
+ Always use `Metadata.GetEntityObject<T>()` to create entity instances -- never instantiate entity classes directly. This ensures the MJ class factory resolves the correct (potentially extended) subclass.
60
134
 
61
135
  ```typescript
62
136
  import { Metadata } from '@memberjunction/core';
63
137
  import { UserEntity, ApplicationEntity } from '@memberjunction/core-entities';
64
138
 
65
- // Always use Metadata to create entity instances
66
139
  const md = new Metadata();
67
140
 
68
- // Load a user by ID
141
+ // Load an existing record
69
142
  const user = await md.GetEntityObject<UserEntity>('Users');
70
- await user.Load('user-id-here');
71
-
72
- // Access strongly-typed properties
143
+ await user.Load('some-user-id');
73
144
  console.log(user.Email);
74
145
  console.log(user.FirstName);
75
146
 
76
- // Create a new application
147
+ // Create a new record
77
148
  const app = await md.GetEntityObject<ApplicationEntity>('Applications');
78
149
  app.NewRecord();
79
- app.Name = 'My New Application';
80
- app.Description = 'A test application';
150
+ app.Name = 'My Application';
151
+ app.Description = 'A custom application';
81
152
  await app.Save();
82
153
  ```
83
154
 
84
- (continuing in next command due to size...)
85
-
86
- ## Artifact Extraction System
87
-
88
- The artifact extraction system enables declarative extraction of structured attributes from artifact content with hierarchical inheritance.
89
-
90
- ### Overview
91
-
92
- Artifacts in MemberJunction can have **extract rules** defined in their `ArtifactType` that specify how to extract attributes from the artifact content. These rules:
93
- - Are stored as JSON in the `ArtifactType.ExtractRules` column
94
- - Support hierarchical inheritance (child types inherit and override parent rules)
95
- - Execute JavaScript code in a controlled environment
96
- - Map extracted values to standard properties (name, description, display formats)
97
- - Are automatically executed when artifact versions are saved
98
-
99
- ### Defining Extract Rules
100
-
101
- Extract rules are defined in the `ArtifactType.ExtractRules` JSON field:
102
-
103
- ```json
104
- [
105
- {
106
- "name": "subject",
107
- "description": "Email subject line",
108
- "type": "string",
109
- "standardProperty": "name",
110
- "extractor": "const parsed = JSON.parse(content); return parsed.subject || 'Untitled';"
111
- },
112
- {
113
- "name": "recipientCount",
114
- "description": "Number of recipients",
115
- "type": "number",
116
- "extractor": "const parsed = JSON.parse(content); return parsed.recipients?.length || 0;"
117
- }
118
- ]
155
+ ### Loading Collections with RunView
156
+
157
+ Use `RunView` with generics for loading collections of entity records:
158
+
159
+ ```typescript
160
+ import { RunView } from '@memberjunction/core';
161
+ import { ActionEntity } from '@memberjunction/core-entities';
162
+
163
+ const rv = new RunView();
164
+ const result = await rv.RunView<ActionEntity>({
165
+ EntityName: 'Actions',
166
+ ExtraFilter: `Status='Active'`,
167
+ OrderBy: 'Name',
168
+ ResultType: 'entity_object'
169
+ });
170
+
171
+ if (result.Success) {
172
+ for (const action of result.Results) {
173
+ console.log(action.Name, action.Status);
174
+ }
175
+ }
119
176
  ```
120
177
 
121
- ### Extract Rule Properties
178
+ ### Using the UserViewEntityExtended
122
179
 
123
- | Property | Type | Description |
124
- |----------|------|-------------|
125
- | `name` | string | Unique identifier for this rule |
126
- | `description` | string | Human-readable description |
127
- | `type` | string | TypeScript type (e.g., `'string'`, `'Array<{x: number}>'`) |
128
- | `standardProperty` | string? | Maps to: `'name'`, `'description'`, `'displayMarkdown'`, `'displayHtml'` |
129
- | `extractor` | string | JavaScript code that receives `content` and returns value |
180
+ The extended User View entity parses JSON state columns into structured objects and generates SQL WHERE clauses:
130
181
 
131
- ### Using the ArtifactExtractor
182
+ ```typescript
183
+ import { Metadata } from '@memberjunction/core';
184
+ import { UserViewEntityExtended, ViewInfo } from '@memberjunction/core-entities';
185
+
186
+ // Load a view by name using the convenience class
187
+ const view = await ViewInfo.GetViewEntityByName('Active Contacts');
188
+
189
+ // Access parsed column and filter info
190
+ const columns = view.Columns; // ViewColumnInfo[]
191
+ const filters = view.Filter; // ViewFilterInfo[]
192
+ const sortInfo = view.ViewSortInfo; // ViewSortInfo[]
193
+
194
+ // Check user permissions
195
+ if (view.UserCanEdit) {
196
+ view.Name = 'Updated View Name';
197
+ await view.Save(); // Auto-regenerates WhereClause from FilterState
198
+ }
199
+ ```
200
+
201
+ ### Using Singleton Engines
202
+
203
+ All engines follow the same pattern: get the singleton instance, call `Config()` to load data, then access cached properties.
204
+
205
+ ```typescript
206
+ import {
207
+ UserInfoEngine,
208
+ DashboardEngine,
209
+ ResourcePermissionEngine
210
+ } from '@memberjunction/core-entities';
211
+
212
+ // UserInfoEngine -- notifications, favorites, settings, applications
213
+ const userEngine = UserInfoEngine.Instance;
214
+ await userEngine.Config(false, contextUser);
215
+ const notifications = userEngine.UnreadNotifications;
216
+ const favorites = userEngine.UserFavorites;
217
+
218
+ // Debounced settings (batches rapid updates)
219
+ userEngine.SetSettingDebounced('ui-preference/theme', 'dark');
220
+
221
+ // DashboardEngine -- dashboards, categories, permissions
222
+ const dashEngine = DashboardEngine.Instance;
223
+ await dashEngine.Config(false, contextUser);
224
+ const accessible = dashEngine.GetAccessibleDashboards(userId);
225
+ const canEdit = dashEngine.CanUserEditDashboard(dashboardId, userId);
226
+
227
+ // ResourcePermissionEngine -- role-based resource access
228
+ const permEngine = ResourcePermissionEngine.Instance;
229
+ await permEngine.Config(false, contextUser);
230
+ const level = permEngine.GetUserResourcePermissionLevel(resourceTypeId, recordId, user);
231
+ // Returns 'View' | 'Edit' | 'Owner' | null
232
+ ```
233
+
234
+ ### Artifact Extraction
235
+
236
+ Extract structured attributes from artifact content using declarative rules:
132
237
 
133
238
  ```typescript
134
239
  import { ArtifactExtractor } from '@memberjunction/core-entities';
135
240
 
136
- // Resolve extract rules with inheritance
137
- const rules = ArtifactExtractor.ResolveExtractRules(artifactTypeChain);
241
+ // Resolve extract rules with inheritance from parent types
242
+ const rules = ArtifactExtractor.ResolveExtractRules([
243
+ childArtifactType, // Most specific (overrides parent rules by name)
244
+ parentArtifactType // Least specific
245
+ ]);
138
246
 
139
247
  // Extract attributes from content
140
248
  const result = await ArtifactExtractor.ExtractAttributes({
141
- content: artifactContent,
249
+ content: '{"subject": "Q4 Campaign", "body": "..."}',
142
250
  extractRules: rules,
143
251
  throwOnError: false,
144
252
  timeout: 5000
145
253
  });
146
254
 
147
- // Get standard properties
255
+ // Access extracted values
148
256
  const name = ArtifactExtractor.GetStandardProperty(result.attributes, 'name');
149
257
  const description = ArtifactExtractor.GetStandardProperty(result.attributes, 'description');
258
+
259
+ // Serialize for database storage
260
+ const serialized = ArtifactExtractor.SerializeForStorage(result.attributes);
150
261
  ```
151
262
 
152
- ### Automatic Extraction with ArtifactVersionExtended
263
+ ### Encryption Metadata
264
+
265
+ The `EncryptionEngineBase` provides cached access to encryption keys, algorithms, and key sources:
153
266
 
154
267
  ```typescript
155
- import { ArtifactVersionExtended } from '@memberjunction/core-entities';
156
- import { Metadata } from '@memberjunction/core';
268
+ import { EncryptionEngineBase } from '@memberjunction/core-entities';
157
269
 
158
- const md = new Metadata();
159
- const version = await md.GetEntityObject<ArtifactVersionExtended>('MJ: Artifact Versions');
160
- version.NewRecord();
161
- version.Content = JSON.stringify({ subject: "Q4 Campaign", body: "..." });
162
-
163
- // Save triggers automatic extraction:
164
- // 1. Calculates SHA-256 hash → ContentHash
165
- // 2. Resolves extract rules from ArtifactType hierarchy
166
- // 3. Extracts attributes → Name and Description
167
- // 4. Creates ArtifactVersionAttribute records
168
- await version.Save();
169
-
170
- console.log(version.Name); // "Q4 Campaign" (extracted)
171
- console.log(version.ContentHash); // "a3f7e2..." (SHA-256)
270
+ const engine = EncryptionEngineBase.Instance;
271
+ await engine.Config(false, contextUser);
272
+
273
+ // Validate a key is usable
274
+ const validation = engine.ValidateKey(keyId);
275
+ if (!validation.isValid) {
276
+ console.error(validation.error);
277
+ }
278
+
279
+ // Get full key configuration (key + algorithm + source)
280
+ const config = engine.GetKeyConfiguration(keyId);
281
+ ```
282
+
283
+ ## API Reference
284
+
285
+ ### Generated Entity Classes
286
+
287
+ Every generated entity class provides:
288
+
289
+ | Member | Description |
290
+ |---|---|
291
+ | `Load(ID, relationships?)` | Load a record by primary key |
292
+ | `Save(options?)` | Persist changes to the database |
293
+ | `Delete(options?)` | Delete the record |
294
+ | `NewRecord()` | Initialize a blank record for creation |
295
+ | `Validate()` | Run Zod schema validation |
296
+ | Typed getters/setters | One per database column, with JSDoc annotations |
297
+
298
+ ### UserViewEntityExtended
299
+
300
+ | Member | Type | Description |
301
+ |---|---|---|
302
+ | `Filter` | `ViewFilterInfo[]` | Parsed filter state from JSON |
303
+ | `Columns` | `ViewColumnInfo[]` | Parsed column configuration from JSON |
304
+ | `ViewSortInfo` | `ViewSortInfo[]` | Parsed sort state |
305
+ | `OrderByClause` | `string` | SQL ORDER BY clause |
306
+ | `ViewEntityInfo` | `EntityInfo` | Metadata for the view's entity |
307
+ | `ParsedDisplayState` | `ViewDisplayState \| null` | View mode and display preferences |
308
+ | `UserCanEdit` | `boolean` | Whether current user can edit this view |
309
+ | `UserCanView` | `boolean` | Whether current user can view this view |
310
+ | `UserCanDelete` | `boolean` | Whether current user can delete this view |
311
+ | `SetDefaultsFromEntity(e)` | method | Initialize columns from entity metadata |
312
+ | `UpdateWhereClause()` | method | Regenerate WHERE clause from filter state |
313
+
314
+ ### ViewInfo (Static Utility)
315
+
316
+ | Method | Description |
317
+ |---|---|
318
+ | `GetViewsForUser(entityId?, contextUser?)` | Load all views for a user |
319
+ | `GetViewID(viewName)` | Look up a view ID by name |
320
+ | `GetViewEntity(viewId, contextUser?)` | Get a cached view by ID |
321
+ | `GetViewEntityByName(viewName, contextUser?)` | Get a cached view by name |
322
+
323
+ ### UserInfoEngine
324
+
325
+ | Member | Description |
326
+ |---|---|
327
+ | `UserNotifications` | Notifications for current user (newest first) |
328
+ | `UnreadNotifications` | Unread notifications only |
329
+ | `Workspaces` | User's workspaces |
330
+ | `UserApplications` | Installed applications (sorted by sequence) |
331
+ | `UserFavorites` | Favorited records (newest first) |
332
+ | `UserRecordLogs` | Recent record access history |
333
+ | `UserSettings` | User settings key-value pairs |
334
+ | `GetSetting(key)` | Get a setting value by key |
335
+ | `SetSetting(key, value)` | Create or update a setting |
336
+ | `SetSettingDebounced(key, value)` | Debounced setting update for rapid UI changes |
337
+ | `FlushPendingSettings()` | Force-save all debounced settings |
338
+ | `InstallApplication(appId)` | Install an application for the user |
339
+ | `DisableApplication(appId)` | Disable (but not delete) an application |
340
+ | `CreateDefaultApplications()` | Create records for default-for-new-user apps |
341
+ | `NotificationPreferences` | User's notification preferences |
342
+
343
+ ### DashboardEngine
344
+
345
+ | Member | Description |
346
+ |---|---|
347
+ | `Dashboards` | All cached dashboards |
348
+ | `DashboardCategories` | All dashboard categories |
349
+ | `DashboardPartTypes` | Dashboard widget/part types |
350
+ | `GetDashboardPermissions(id, userId)` | Get effective permissions (owner/direct/category) |
351
+ | `CanUserReadDashboard(id, userId)` | Check read access |
352
+ | `CanUserEditDashboard(id, userId)` | Check edit access |
353
+ | `CanUserDeleteDashboard(id, userId)` | Check delete access |
354
+ | `GetAccessibleDashboards(userId)` | All dashboards user can read |
355
+ | `GetSharedDashboards(userId)` | Dashboards shared with user (not owned) |
356
+ | `GetAccessibleCategories(userId)` | Categories user can access |
357
+
358
+ ### ResourcePermissionEngine
359
+
360
+ | Member | Description |
361
+ |---|---|
362
+ | `ResourceTypes` | All resource type definitions |
363
+ | `Permissions` | All resource permission records |
364
+ | `GetResourcePermissions(typeId, recordId)` | Get all permissions for a resource |
365
+ | `GetUserResourcePermissionLevel(typeId, recordId, user)` | Get highest permission level (View/Edit/Owner/null) |
366
+ | `GetUserAvailableResources(user, typeId?)` | Get all resources a user can access |
367
+
368
+ ### UserViewEngine
369
+
370
+ | Member | Description |
371
+ |---|---|
372
+ | `AllViews` | All cached views |
373
+ | `GetViewById(id)` | Look up view by ID |
374
+ | `GetViewByName(name)` | Look up view by name |
375
+ | `GetViewsForEntity(entityId)` | Views for a specific entity |
376
+ | `GetViewsForCurrentUser()` | Views owned by current user |
377
+ | `GetAccessibleViewsForEntity(entityId)` | Owned + shared views with permission checks |
378
+ | `GetDefaultViewForEntity(entityId)` | Default view for an entity |
379
+
380
+ ### ArtifactExtractor
381
+
382
+ | Method | Description |
383
+ |---|---|
384
+ | `ResolveExtractRules(typeChain)` | Resolve rules with hierarchical inheritance |
385
+ | `ExtractAttributes(config)` | Execute extraction rules against content |
386
+ | `SerializeForStorage(attributes)` | Convert attributes to database-storable format |
387
+ | `DeserializeFromStorage(stored)` | Convert stored attributes back to runtime objects |
388
+ | `GetStandardProperty(attributes, prop)` | Find a standard property value (name/description/etc.) |
389
+
390
+ ### Other Engines
391
+
392
+ | Engine | Purpose |
393
+ |---|---|
394
+ | `EncryptionEngineBase` | Caches encryption keys, algorithms, and key sources |
395
+ | `FileStorageEngine` | Caches file storage accounts and providers |
396
+ | `MCPEngine` | Caches MCP servers, connections, and tools |
397
+ | `ComponentMetadataEngine` | Caches component definitions, libraries, and registries |
398
+ | `ArtifactMetadataEngine` | Caches artifact type definitions |
399
+ | `TypeTablesCache` | Caches entity relationship display components |
400
+
401
+ ## Permission Model
402
+
403
+ The package implements a layered permission model used across views, dashboards, and resources:
404
+
405
+ ```mermaid
406
+ flowchart TD
407
+ subgraph Check["Permission Resolution Order"]
408
+ direction TB
409
+ OWN["1. Ownership Check<br/>Record owner gets full access"]
410
+ ADM["2. Admin Check<br/>System admins get full access"]
411
+ DIR["3. Direct Permission<br/>User-specific grants"]
412
+ CAT["4. Category Permission<br/>Inherited from categories"]
413
+ ROL["5. Role Permission<br/>Granted through user roles"]
414
+ end
415
+
416
+ OWN -->|"Not owner"| ADM
417
+ ADM -->|"Not admin"| DIR
418
+ DIR -->|"No direct grant"| CAT
419
+ CAT -->|"No category grant"| ROL
420
+ ROL -->|"No role grant"| DENY["Access Denied"]
421
+
422
+ style Check fill:#2d6a9f,stroke:#1a4971,color:#fff
423
+ style DENY fill:#64748b,stroke:#475569,color:#fff
172
424
  ```
173
425
 
174
- For complete documentation, see the [Implementation Summary](../../IMPLEMENTATION_SUMMARY_v2.105.md).
426
+ Permission levels are hierarchical: **Owner** > **Edit** > **View**. The engine returns the highest applicable level across all sources (direct user grants and role-based grants).
427
+
428
+ ## View Filter Architecture
429
+
430
+ The `UserViewEntityExtended` converts structured filter JSON into SQL WHERE clauses:
431
+
432
+ ```mermaid
433
+ flowchart LR
434
+ subgraph Input["Filter State (JSON)"]
435
+ FS["{ logic: 'and',<br/>filters: [...] }"]
436
+ end
437
+
438
+ subgraph Process["UserViewEntityExtended"]
439
+ PARSE["Parse FilterState<br/>JSON column"]
440
+ GEN["GenerateWhereClause()<br/>Recursive group processing"]
441
+ SQL["SQL WHERE clause"]
442
+ end
443
+
444
+ subgraph Modes["Filter Modes"]
445
+ STD["Standard Filter<br/>UI-driven FilterState"]
446
+ SMART["Smart Filter<br/>AI-generated from prompt"]
447
+ CUSTOM["Custom Filter<br/>Admin-set WhereClause"]
448
+ end
449
+
450
+ FS --> PARSE --> GEN --> SQL
451
+ Modes --> GEN
452
+
453
+ style Input fill:#b8762f,stroke:#8a5722,color:#fff
454
+ style Process fill:#2d6a9f,stroke:#1a4971,color:#fff
455
+ style Modes fill:#2d8659,stroke:#1a5c3a,color:#fff
456
+ ```
457
+
458
+ Supported filter operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `startswith`, `endswith`, `contains`, `doesnotcontain`, `isnull`, `isempty`, `isnotnull`, `isnotempty`. Filters support arbitrary nesting with `and`/`or` logic groups.
459
+
460
+ ## Important: CodeGen and This Package
175
461
 
176
- ## Best Practices
462
+ This package's `src/generated/entity_subclasses.ts` file is **entirely auto-generated** by the MemberJunction CodeGen system. Key implications:
177
463
 
178
- 1. **Always use Metadata for entity creation**: Never instantiate entity classes directly
179
- 2. **Use RunView for bulk operations**: More efficient than loading entities individually
180
- 3. **Leverage TypeScript types**: Use exported types for function parameters
181
- 4. **Handle validation errors**: Wrap entity operations in try-catch blocks
182
- 5. **Use extended classes**: When available, use extended versions for additional functionality
183
- 6. **Import artifacts from core-entities**: Artifact extraction utilities are in this package
464
+ - **Never edit generated files** -- changes will be overwritten on the next CodeGen run.
465
+ - **Custom logic goes in `src/custom/`** -- create an extended class with `@RegisterClass` to override the generated base.
466
+ - **Entity names matter** -- some entities use the `MJ: ` prefix (e.g., `MJ: Components`, `MJ: Environments`). Always verify names in the generated file's `@RegisterClass` decorators.
467
+ - **Zod schemas are authoritative** -- they reflect the exact database constraints including value lists, nullable fields, and default values.
184
468
 
185
469
  ## Dependencies
186
470
 
187
- - `@memberjunction/core`: Core MemberJunction functionality
188
- - `@memberjunction/global`: Global utilities and decorators
189
- - `zod`: Runtime type validation
471
+ - [@memberjunction/core](../MJCore/README.md) -- Base entity classes, metadata system, RunView, BaseEngine
472
+ - [@memberjunction/global](../MJGlobal/README.md) -- `@RegisterClass` decorator, global utilities
473
+ - [@memberjunction/ai](../AI/README.md) -- AI integration types (used by some engine classes)
474
+ - [@memberjunction/interactive-component-types](../InteractiveComponentTypes/README.md) -- ComponentSpec type for component entity extensions
475
+ - [zod](https://zod.dev/) -- Runtime schema validation
190
476
 
191
- ## License
477
+ ## Related Packages
192
478
 
193
- ISC - See LICENSE file for details
479
+ - [@memberjunction/core](../MJCore/README.md) -- Framework foundation this package builds on
480
+ - [@memberjunction/core-entities-server](../MJCoreEntitiesServer/README.md) -- Server-side extensions of entities defined here (e.g., smart filter AI implementation)
481
+ - [@memberjunction/server](../MJServer/README.md) -- Server that uses these entities for API operations
194
482
 
195
- ## Support
483
+ ## Contributing
196
484
 
197
- For issues, questions, or contributions, visit the [MemberJunction GitHub repository](https://github.com/MemberJunction/MJ).
485
+ See the [MemberJunction Contributing Guide](../../CONTRIBUTING.md) for development setup and guidelines.