business-as-code
Version:
Primitives for expressing business logic and processes as code
145 lines • 3.92 kB
JavaScript
/**
* Product definition and management
*/
/**
* Define a product with pricing, features, and roadmap
*
* @example
* ```ts
* const product = Product({
* name: 'Widget Pro',
* description: 'Enterprise-grade widget management platform',
* category: 'SaaS',
* targetSegment: 'Enterprise',
* valueProposition: 'Reduce widget management costs by 50%',
* pricingModel: 'subscription',
* price: 99,
* currency: 'USD',
* cogs: 20,
* features: [
* 'Unlimited widgets',
* 'Advanced analytics',
* 'API access',
* '24/7 support',
* ],
* roadmap: [
* {
* name: 'Mobile app',
* description: 'Native iOS and Android apps',
* targetDate: new Date('2024-09-01'),
* priority: 'high',
* status: 'in-progress',
* },
* {
* name: 'AI-powered insights',
* description: 'Automated widget optimization suggestions',
* targetDate: new Date('2024-12-01'),
* priority: 'high',
* status: 'planned',
* },
* ],
* })
* ```
*/
export function Product(definition) {
if (!definition.name) {
throw new Error('Product name is required');
}
return {
...definition,
pricingModel: definition.pricingModel || 'one-time',
currency: definition.currency || 'USD',
features: definition.features || [],
roadmap: definition.roadmap || [],
metadata: definition.metadata || {},
};
}
/**
* Calculate gross margin for a product
*/
export function calculateGrossMargin(product) {
if (!product.price || !product.cogs)
return 0;
return ((product.price - product.cogs) / product.price) * 100;
}
/**
* Calculate gross profit for a product
*/
export function calculateGrossProfit(product, unitsSold) {
if (!product.price || !product.cogs)
return 0;
return (product.price - product.cogs) * unitsSold;
}
/**
* Get roadmap items by status
*/
export function getRoadmapByStatus(product, status) {
return product.roadmap?.filter((item) => item.status === status) || [];
}
/**
* Get roadmap items by priority
*/
export function getRoadmapByPriority(product, priority) {
return product.roadmap?.filter((item) => item.priority === priority) || [];
}
/**
* Get overdue roadmap items
*/
export function getOverdueRoadmapItems(product) {
const now = new Date();
return (product.roadmap?.filter((item) => item.targetDate &&
item.targetDate < now &&
item.status !== 'completed' &&
item.status !== 'cancelled') || []);
}
/**
* Update roadmap item status
*/
export function updateRoadmapItem(product, itemName, updates) {
const roadmap = product.roadmap?.map((item) => item.name === itemName ? { ...item, ...updates } : item);
const result = { ...product };
if (roadmap !== undefined)
result.roadmap = roadmap;
return result;
}
/**
* Add feature to product
*/
export function addFeature(product, feature) {
return {
...product,
features: [...(product.features || []), feature],
};
}
/**
* Remove feature from product
*/
export function removeFeature(product, feature) {
return {
...product,
features: product.features?.filter((f) => f !== feature) || [],
};
}
/**
* Validate product definition
*/
export function validateProduct(product) {
const errors = [];
if (!product.name) {
errors.push('Product name is required');
}
if (product.price && product.price < 0) {
errors.push('Product price cannot be negative');
}
if (product.cogs && product.cogs < 0) {
errors.push('Product COGS cannot be negative');
}
if (product.price && product.cogs && product.cogs > product.price) {
errors.push('Product COGS cannot exceed price');
}
return {
valid: errors.length === 0,
errors,
};
}
//# sourceMappingURL=product.js.map