sap-entity-manager.ts•6.42 kB
import { SAPClient } from '../services/sap-client.js';
import { Logger } from '../utils/logger.js';
import { EntityType, ODataService } from '../types/sap-types.js';
/**
* SAP Entity Manager - Handles entity metadata and operations
*/
export class SAPEntityManager {
constructor(
private sapClient: SAPClient,
private logger: Logger
) {}
/**
* Get entity metadata for a specific entity type
*/
async getEntityMetadata(entityType: string): Promise<EntityType | null> {
try {
this.logger.debug(`Getting metadata for entity type: ${entityType}`);
// This is a simplified implementation that would normally query the SAP system
// For now, return a mock entity metadata structure
const mockMetadata: EntityType = {
name: entityType,
namespace: 'SAP',
entitySet: `${entityType}Set`,
keys: ['ID'],
properties: [
{
name: 'ID',
type: 'Edm.String',
nullable: false,
maxLength: '10',
},
{
name: 'Name',
type: 'Edm.String',
nullable: true,
maxLength: '255',
},
{
name: 'Description',
type: 'Edm.String',
nullable: true,
maxLength: '1000',
},
{
name: 'CreatedAt',
type: 'Edm.DateTimeOffset',
nullable: true,
},
{
name: 'UpdatedAt',
type: 'Edm.DateTimeOffset',
nullable: true,
},
],
navigationProperties: [],
creatable: true,
updatable: true,
deletable: true,
addressable: true,
};
return mockMetadata;
} catch (error) {
this.logger.error(`Error getting entity metadata for ${entityType}:`, error);
return null;
}
}
/**
* Get all available services
*/
async getAvailableServices(): Promise<ODataService[]> {
try {
this.logger.debug('Getting available SAP services');
// This would normally query the SAP system for available services
// For now, return mock services
const mockServices: ODataService[] = [
{
id: 'CUSTOMER_SERVICE',
title: 'Customer Service',
description: 'Manage customer data and relationships',
url: '/sap/opu/odata/customer/',
version: '1.0',
odataVersion: 'v2',
metadataUrl: '/sap/opu/odata/customer/$metadata',
entitySets: ['CustomerSet'],
metadata: {
entityTypes: [
{
name: 'Customer',
namespace: 'SAP.Customer',
entitySet: 'CustomerSet',
keys: ['CustomerID'],
properties: [
{ name: 'CustomerID', type: 'Edm.String', nullable: false, maxLength: '10' },
{ name: 'CompanyName', type: 'Edm.String', nullable: false, maxLength: '255' },
{ name: 'ContactPerson', type: 'Edm.String', nullable: true, maxLength: '100' },
],
navigationProperties: [],
creatable: true,
updatable: true,
deletable: true,
addressable: true,
},
],
entitySets: [{ CustomerSet: 'Customer' }],
version: '1.0',
namespace: 'SAP.Customer',
},
},
{
id: 'SALES_ORDER_SERVICE',
title: 'Sales Order Service',
description: 'Handle sales orders and related operations',
url: '/sap/opu/odata/sales/',
version: '1.0',
odataVersion: 'v2',
metadataUrl: '/sap/opu/odata/sales/$metadata',
entitySets: ['SalesOrderSet'],
metadata: {
entityTypes: [
{
name: 'SalesOrder',
namespace: 'SAP.Sales',
entitySet: 'SalesOrderSet',
keys: ['OrderID'],
properties: [
{ name: 'OrderID', type: 'Edm.String', nullable: false, maxLength: '10' },
{ name: 'CustomerID', type: 'Edm.String', nullable: false, maxLength: '10' },
{ name: 'OrderDate', type: 'Edm.DateTimeOffset', nullable: false },
{ name: 'TotalAmount', type: 'Edm.Decimal', nullable: false },
],
navigationProperties: [],
creatable: true,
updatable: true,
deletable: false,
addressable: true,
},
],
entitySets: [{ SalesOrderSet: 'SalesOrder' }],
version: '1.0',
namespace: 'SAP.Sales',
},
},
];
return mockServices;
} catch (error) {
this.logger.error('Error getting available services:', error);
return [];
}
}
/**
* Validate entity fields against schema
*/
validateEntityFields(
entityType: string,
fields: Record<string, any>
): { valid: boolean; errors: string[] } {
try {
const errors: string[] = [];
// This would normally validate against the actual entity schema
// For now, perform basic validation
if (!fields || Object.keys(fields).length === 0) {
errors.push('No fields provided');
}
// Check for required ID field (simplified validation)
if (!fields.ID && !fields.id) {
errors.push('ID field is required');
}
return {
valid: errors.length === 0,
errors,
};
} catch (error) {
this.logger.error(`Error validating fields for ${entityType}:`, error);
return {
valid: false,
errors: ['Validation error occurred'],
};
}
}
/**
* Get field types for an entity
*/
async getEntityFieldTypes(entityType: string): Promise<Record<string, string>> {
try {
const metadata = await this.getEntityMetadata(entityType);
if (!metadata) {
return {};
}
const fieldTypes: Record<string, string> = {};
metadata.properties.forEach(prop => {
fieldTypes[prop.name] = prop.type;
});
return fieldTypes;
} catch (error) {
this.logger.error(`Error getting field types for ${entityType}:`, error);
return {};
}
}
}