Entity subclasses for the metadata layer of MemberJunction that are only used on server side applications like MJAPI, distributed as part of each release of MemberJunction
npm install @memberjunction/core-entities-serverServer-side entity subclasses for MemberJunction that provide extended functionality and business logic for core entities when running in a Node.js environment.
This package contains server-side implementations of MemberJunction entity subclasses that require server-specific functionality such as:
- Direct database access
- File system operations
- Server-side API integrations
- Complex business logic that should only run on the server
- Automatic creation/management of related entities
While the base @memberjunction/core-entities package provides entity classes that work in any JavaScript environment (browser or server), some entity operations require server-specific capabilities. This package provides those extended implementations.
- Core Entities: Work everywhere, basic CRUD operations, suitable for client-side usage
- Core Entities Server: Server-only, extended functionality, can directly interact with system resources
``bash`
npm install @memberjunction/core-entities-server
`typescript
import { LoadCoreEntitiesServerSubClasses } from '@memberjunction/core-entities-server';
// Load all server-side entity subclasses at application startup
LoadCoreEntitiesServerSubClasses();
`
Important: Call LoadCoreEntitiesServerSubClasses() early in your application initialization to ensure the server-side subclasses are registered with the MemberJunction metadata system before any entities are instantiated.
The package includes an extended AI Prompt entity that automatically manages Template and Template Contents records:
`typescript
import { Metadata } from '@memberjunction/core';
// The metadata system will automatically use the server-side subclass
const md = new Metadata();
const aiPrompt = await md.GetEntityObject
// Setting TemplateText will automatically create/update Template records
aiPrompt.TemplateText = You are a helpful assistant...;
// Save will handle all the Template management automatically
await aiPrompt.Save();
`
Extends the base AI Prompt entity with automatic Template management:
- Virtual Property: TemplateText - A convenient way to get/set the prompt template content
- Automatic Template Creation: Creates Template and Template Contents records when saving
- Automatic Template Updates: Updates existing templates when content changes
- Proper Relationship Management: Maintains proper foreign key relationships
Extends the Component entity with automatic vector embedding generation:
- Automatic Embeddings: Generates vector embeddings for FunctionalRequirements and TechnicalDesign fields
- Model Tracking: Stores the AI model ID used for each embedding
- Smart Updates: Only regenerates embeddings when source text changes
- Parallel Processing: Generates multiple embeddings concurrently for performance
Extends the Query entity with automatic Template management similar to AIPromptEntity:
- Virtual Property: TemplateText - Manages the SQL query template content
- Automatic Template Management: Creates and updates Template records when saving
- Dynamic SQL Support: Supports parameterized queries with Nunjucks templates
The package uses MemberJunction's entity subclassing system:
1. At startup, LoadCoreEntitiesServerSubClasses() is called
2. This registers all server-side entity subclasses with the metadata system
3. When code requests an entity (e.g., "AI Prompts"), the metadata system returns the server-side subclass
4. The server-side subclass extends the base entity with additional functionality
Server-side entities can expose virtual properties that don't exist in the database but provide convenient access to complex data:
`typescript
export class AIPromptEntityExtendedServer extends AIPromptEntity {
private _TemplateText?: string;
get TemplateText(): string | undefined {
return this._TemplateText;
}
set TemplateText(value: string | undefined) {
this._TemplateText = value;
}
}
`
1. Create a new file in src/custom/
2. Import and extend the base entity class
3. Add server-specific functionality
4. Register the subclass in the loader
Example:
`typescript
import { BaseEntity, RegisterClass } from '@memberjunction/core';
import { UserEntity } from '@memberjunction/core-entities';
@RegisterClass(BaseEntity, 'Users')
export class UserEntityExtendedServer extends UserEntity {
async BeforeSave(): Promise
// Server-side validation or processing
if (this.Email) {
// Verify email domain against company whitelist
const validDomain = await this.checkEmailDomain(this.Email);
if (!validDomain) {
throw new Error('Invalid email domain');
}
}
return super.BeforeSave();
}
private async checkEmailDomain(email: string): Promise
// Server-side logic to validate email domain
return true;
}
}
`
1. Keep It Server-Side: Only include code that must run on the server
2. Extend, Don't Replace: Always extend the base entity class, don't replace core functionality
3. Handle Errors Gracefully: Server-side operations can fail - handle errors appropriately
4. Document Virtual Properties: Clearly document any virtual properties and their behavior
5. Test Thoroughly: Server-side logic can be complex - ensure comprehensive testing
This package works seamlessly with:
- @memberjunction/core: Provides the base entity system@memberjunction/core-entities
- : Provides the base entity classes@memberjunction/server
- : Can be used in MJ server applications@memberjunction/cli
- : Used by CLI tools like MetadataSync
This package provides a utility helper for server-side entities to easily implement vector embedding generation using the MemberJunction AI Engine.
A shared utility function that simplifies embedding generation for any server-side entity:
`typescript
import { EmbedTextLocalHelper } from '@memberjunction/core-entities-server';
import { BaseEntity, SimpleEmbeddingResult } from '@memberjunction/core';
@RegisterClass(BaseEntity, 'MyEntity')
export class MyEntityServer extends MyEntity {
protected async EmbedTextLocal(textToEmbed: string): Promise
return EmbedTextLocalHelper(this, textToEmbed);
}
}
`
The helper:
- Configures the AI Engine with the current user context
- Calls the embedding generation
- Validates the response
- Returns a properly typed SimpleEmbeddingResult
1. Add database fields for storing vectors and model IDs
2. Override EmbedTextLocal using the helper function
3. Call GenerateEmbeddings in your Save method:
`typescript`
public async Save(): Promise
await this.GenerateEmbeddingsByFieldName([
{
fieldName: "Content",
vectorFieldName: "ContentVector",
modelFieldName: "ContentVectorModelID"
}
]);
return await super.Save();
}
typescript
// AI Prompts automatically manage their Template records
const prompt = await md.GetEntityObject('AI Prompts');
prompt.TemplateText = "New prompt content";
await prompt.Save(); // Template and Template Contents created/updated automatically
`$3
`typescript
// Components automatically generate embeddings for text fields
const component = await md.GetEntityObject('MJ: Components');
component.FunctionalRequirements = "The system shall...";
component.TechnicalDesign = "Architecture overview...";
await component.Save(); // Embeddings generated automatically
`$3
`typescript
@RegisterClass(BaseEntity, 'Documents')
export class DocumentEntityServer extends DocumentEntity {
async BeforeSave(): Promise {
// Scan document for viruses using server-side scanner
if (this.Content) {
const isSafe = await virusScanner.scan(this.Content);
if (!isSafe) {
throw new Error('Document failed security scan');
}
}
return super.BeforeSave();
}
}
`$3
`typescript
@RegisterClass(BaseEntity, 'Orders')
export class OrderEntityServer extends OrderEntity {
async AfterSave(): Promise {
// Send order to fulfillment system
await fulfillmentAPI.submitOrder(this);
// Update inventory
await inventorySystem.decrementStock(this.OrderItems);
return super.AfterSave();
}
}
`Troubleshooting
$3
Ensure LoadCoreEntitiesServerSubClasses()` is called before any entity instantiation.- Additional server-side entity implementations
- Integration with file storage providers
- Advanced caching mechanisms
- Batch processing utilities
- Background job integration
When contributing new server-side entities:
1. Follow the existing patterns
2. Document all virtual properties
3. Include comprehensive tests
4. Ensure no client-side dependencies
5. Update this README with new entities
This package is part of the MemberJunction open-source project.