Product Management Service Reference Service Overview The Product Management Service governs product lifecycles inside Subscrio: creation, updates, archival, deletion, and feature associations. Products sit at the top of the hierarchy—plans, billing cycles, and subscriptions all reference them.
Product keys are global, immutable identifiers. Deletion is guarded by domain rules: products must be archived and free of plans before removal. Features must be associated with a product before plans under it can set feature values. Accessing the Service Method Catalog Method Reference createProduct Description Creates a new product after validating key format, display name, and optional metadata. Rejects duplicate keys.
TypeScript .NET
Signature createProduct ( dto : CreateProductDto ) : Promise < ProductDto >
Name Type Required Description dto CreateProductDto Yes Contains the product key, display name, optional description, and metadata.
Field Type Required Description key string Yes 1–255 chars, lowercase alphanumeric plus -. displayName string Yes 1–255 char label. description string No ≤1000 chars. metadata Record<string, unknown> No JSON-safe metadata blob.
Returns Promise<ProductDto> – persisted product with timestamps and status (active).
Return Properties Field Type Description key string Immutable product key. displayName string Display name. description string \| null Optional description. status string active, inactive, or archived. metadata Record<string, unknown> \| null Metadata blob. createdAt string ISO timestamp. updatedAt string ISO timestamp.
Example const product = await products . createProduct ({
key : 'pro-suite' ,
displayName : 'Pro Suite' ,
description : 'Advanced tier' ,
metadata : { tier : 'pro' }
});
Signature Task < ProductDto > CreateProductAsync ( CreateProductDto dto )
Name Type Required Description dto CreateProductDto Yes Contains the product key, display name, optional description, and metadata.
Property Type Required Description Key string Yes 1–255 chars, lowercase alphanumeric plus -. DisplayName string Yes 1–255 char label. Description string No ≤1000 chars. Metadata Dictionary<string, object?> No JSON-safe metadata blob.
Returns Task<ProductDto> – persisted product with timestamps and status (active).
Return Properties Property Type Description Key string Immutable product key. DisplayName string Display name. Description string? Optional description. Status string active, inactive, or archived. Metadata Dictionary<string, object?>? Metadata blob. CreatedAt string ISO timestamp. UpdatedAt string ISO timestamp.
Example var product = await subscrio . Products . CreateProductAsync ( new CreateProductDto (
Key : "pro-suite" ,
DisplayName : "Pro Suite" ,
Description : "Advanced tier" ,
Metadata : new Dictionary < string , object? > { [ "tier" ] = "pro" }
));
Expected Results Validates input via Zod schema (TS) / validation (C#). Ensures no product already exists with the provided key. Creates a domain entity with status active and persists it. Potential Errors Error When ValidationError DTO fails schema checks (bad key format, display name length, etc.). ConflictError A product with the same key already exists.
updateProduct Description Applies partial updates to display name, description, or metadata of an existing product.
TypeScript .NET
Signature updateProduct ( key : string , dto : UpdateProductDto ) : Promise < ProductDto >
Name Type Required Description key string Yes Immutable product key to update. dto UpdateProductDto Yes Partial data containing new display name, description, or metadata.
Field Type Description displayName string Updated label (1–255 chars). description string Replacement description (≤1000 chars). metadata Record<string, unknown> Full metadata blob (overwrites stored value).
Returns Promise<ProductDto> – updated product snapshot.
Example const updated = await products . updateProduct ( 'pro-suite' , {
displayName : 'Pro Suite (2025)' ,
metadata : { tier : 'pro' , version : '2025.1' }
});
Signature Task < ProductDto > UpdateProductAsync ( string key , UpdateProductDto dto )
Name Type Required Description key string Yes Immutable product key to update. dto UpdateProductDto Yes Partial data containing new display name, description, or metadata.
Property Type Required Description DisplayName string? No Updated label (1–255 chars). Description string? No Replacement description (≤1000 chars). Metadata Dictionary<string, object?>? No Full metadata blob (overwrites stored value).
Returns Task<ProductDto> – updated product snapshot.
Example var updated = await subscrio . Products . UpdateProductAsync ( "pro-suite" , new UpdateProductDto (
DisplayName : "Pro Suite (2025)" ,
Metadata : new Dictionary < string , object? > { [ "tier" ] = "pro" , [ "version" ] = "2025.1" }
));
Expected Results Validates the DTO. Loads the product by key and mutates allowed fields. Updates updatedAt and persists the entity. Potential Errors Error When ValidationError DTO fields fail schema (e.g., display name too short). NotFoundError Product key does not exist.
getProduct Description Fetches a product snapshot by key, returning null when it does not exist.
Expected Results Loads product by key and maps domain entity to DTO. Potential Errors None – method returns null for missing products. listProducts Description Lists products with status, search, and pagination controls.
TypeScript .NET
Signature listProducts ( filters? : ProductFilterDto ) : Promise < ProductDto [] >
Name Type Required Description filters ProductFilterDto No Optional filter object; defaults applied (limit 50, offset 0, sort asc).
Field Type Required Description status 'active' \| 'archived' No Filter by lifecycle state. search string No Performs key/displayName search. limit number No 1–100, default 50. offset number No ≥0, default 0. sortBy 'displayName' \| 'createdAt' No Sort column. sortOrder 'asc' \| 'desc' No Sort direction; default 'asc'.
Returns Promise<ProductDto[]> – all products matching the filters.
Example const activeProducts = await products . listProducts ({
status : 'active' ,
search : 'suite' ,
limit : 25
});
Signature Task < List < ProductDto >> ListProductsAsync ( ProductFilterDto ? filters = null )
Name Type Required Description filters ProductFilterDto? No Optional filter object; defaults applied.
Property Type Required Description Status string? No active or archived. Search string? No Performs key/displayName search. Limit int No 1–100, default 50. Offset int No ≥0, default 0. SortBy string? No displayName or createdAt. SortOrder string No asc or desc; default asc.
Returns Task<List<ProductDto>> – all products matching the filters.
Example var activeProducts = await subscrio . Products . ListProductsAsync ( new ProductFilterDto (
Status : "active" ,
Search : "suite" ,
Limit : 25
));
Expected Results Validates filters. Delegates to repository for query and maps each entity to DTO. Potential Errors Error When ValidationError Filters contain invalid values (e.g., limit > 100).
deleteProduct Description Permanently deletes an archived product that has no associated plans.
Expected Results Fetches product and verifies it exists. Calls product.canDelete() (must be archived). Ensures the product has zero plans before deletion. Removes the product record. Potential Errors Error When NotFoundError Product does not exist. DomainError Product is not archived or still has plans.
archiveProduct Description Transitions a product to the archived state.
Expected Results Loads product, calls the entity's archive() method, persists, and returns DTO. Potential Errors Error When NotFoundError Product key not found.
unarchiveProduct Description Reverses archiveProduct by calling the entity's unarchive() method and restoring the product to active.
Expected Results Loads product, ensures it exists, calls unarchive(), and persists. Potential Errors Error When NotFoundError Product key missing.
associateFeature Description Links an existing feature to a product so plans under the product can set values for it.
Expected Results Validates both product and feature exist. Inserts association in repository layer. Potential Errors Error When NotFoundError Product or feature is missing.
dissociateFeature Description Removes an existing feature association from a product.
Expected Results Validates both entities exist. Deletes the join row if present. Potential Errors Error When NotFoundError Product or feature missing.
Products must exist before you create plans (PlanManagementService references productKey). Deleting a product requires archival and removal of all plans to avoid DomainError. Feature associations determine which features plans under the product can set values for—coordinate with FeatureManagementService.