LazyMagic
LazyMagic.Service.Shared: Core server-side library providing interfaces and classes for repository patterns, caller context management, multi-tenancy configuration, and document handling. Includes IDocumentRepo<T> for CRUD operations, ICallerInfo for request context, and ITenancyConfig for multi-tenant applications.
LazyMagic.Service.Shared provides core interfaces and classes shared across server-side components. It defines the fundamental contracts for repository operations, caller context management, multi-tenancy configuration, and document handling in the LazyMagic framework.
Provides comprehensive context about the caller making a request:
Identity Information
TenantId: Tenant identifierLzUserId: LazyMagic user identifierUserName: Human-readable usernameSessionId: Current session identifierTenancy Hierarchy
System: System-level identifierTenant: Tenant-level identifierSubtenant: Sub-tenant identifierResource Locations
SystemDB, TenantDB, SubtenantDB: Database identifiersSystemAssets, TenantAssets, SubtenantAssets: Asset storage locationsDefaultTenant, DefaultDB, DefaultAssets: Default resource locationsSecurity
Permissions: List of granted permissionsHeaders: Additional context headers (e.g., AWS Region, UserPoolId)Standard repository interface for document operations:
CRUD Operations
CreateAsync: Create new documentReadAsync: Read document by IDUpdateAsync: Update existing document (with optimistic locking support)UpdateCreateAsync: Update or create if not existsDeleteAsync: Delete document by IDQuery Operations
ListAsync: List all or by indexListBeginsWithAsync: Prefix matchingListBetweenAsync: Range queriesListGreaterThanAsync / ListGreaterThanOrEqualAsync: Greater than queriesListLessThanAsync / ListLessThanOrEqualAsync: Less than queriesConfiguration interface for multi-tenant applications:
Tenancy Keys
SystemKey, TenantKey, SubtenantKey: Unique identifiersSs, Ts, Sts: Short identifiersEnv: Environment identifierRegion: Deployment regionResource Collections
Apis: List of API configurationsAssets: Asset storage configurationsWebApps: Web application configurationsCalculated Fields
Marker interface for document envelope implementations. Used to wrap entities with metadata such as:
public class UserRepository : IDocumentRepo<User>
{
public async Task<ActionResult<User>> CreateAsync(
ICallerInfo callerInfo,
User user)
{
// Use caller info for multi-tenant data isolation
var database = GetDatabase(callerInfo.TenantDB);
// Check permissions
if (!callerInfo.Permissions.Contains("user:create"))
return new ForbidResult();
// Create user in tenant-specific storage
return await database.CreateAsync(user);
}
}
var callerInfo = new CallerInfo
{
TenantId = "tenant-123",
LzUserId = "user-456",
UserName = "john.doe@example.com",
Permissions = new List<string> { "read", "write" },
Headers = new Dictionary<string, string>
{
["Region"] = "us-east-1",
["UserPoolId"] = "us-east-1_ABC123"
}
};
await repository.CreateAsync(callerInfo, newItem);
// List all items
var allItems = await repository.ListAsync(callerInfo);
// Query by index
var emailResults = await repository.ListAsync(
callerInfo,
"EmailIndex",
"user@example.com"
);
// Range query
var dateResults = await repository.ListBetweenAsync(
callerInfo,
"DateIndex",
"2023-01-01",
"2023-12-31"
);
// Prefix search
var nameResults = await repository.ListBeginsWithAsync(
callerInfo,
"NameIndex",
"John"
);
public class TenancyConfig : ITenancyConfig
{
// Implementation calculates paths based on tenancy level
public string TenantDB => $"{TenantKey}-db";
public string TenantAssets => $"{TenantKey}-assets";
public void SetCalculatedFields()
{
// Calculate derived fields based on keys
}
}
The framework supports three levels of tenancy:
CallerInfo carries permissions that repositories can check:
if (!callerInfo.Permissions.Contains("admin"))
return new UnauthorizedResult();
Repository interface supports various query patterns:
Resources (databases, assets) are isolated by tenancy level, with calculated paths ensuring proper separation.