UNPKG

@mazaventures/valentine

Version:

Toolkit for Venture Capital firms to run their back office efficiently and openly

152 lines 5.37 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PortfolioService = void 0; const types_1 = require("../models/types"); const decimal_js_1 = __importDefault(require("decimal.js")); /** * Service for managing portfolio companies and investments. * Handles company information, investment tracking, and ownership calculations. * * @example * ```typescript * const portfolio = new PortfolioService(); * * // Add a company * const company = await portfolio.addCompany({ * name: "TechCo", * sector: "SaaS", * stage: "SERIES_A", * founded: new Date("2024-01-01") * }); * ``` */ class PortfolioService { /** * Initializes a new instance of the PortfolioService class. * * @description Creates a new PortfolioService instance with empty company and investment maps. */ constructor() { this.companies = new Map(); this.investments = new Map(); } /** * Adds a new company to the portfolio. * * @param company - Company information without ID * @returns Newly created company with generated ID * @throws {Error} If company data validation fails */ async addCompany(company) { const id = crypto.randomUUID(); const newCompany = types_1.CompanySchema.parse({ ...company, id }); this.companies.set(id, newCompany); return newCompany; } /** * Retrieves a company by its ID. * * @param id - Company ID * @returns Company information or undefined if not found */ async getCompany(id) { return this.companies.get(id); } /** * Updates an existing company's information. * * @param id - Company ID * @param updates - Partial company information to update * @returns Updated company information * @throws {Error} If company not found or validation fails */ async updateCompany(id, updates) { const existing = this.companies.get(id); if (!existing) { throw new Error(`Company with id ${id} not found`); } const updated = types_1.CompanySchema.parse({ ...existing, ...updates }); this.companies.set(id, updated); return updated; } /** * Lists all companies in the portfolio. * * @returns Array of all companies */ async listCompanies() { return Array.from(this.companies.values()); } /** * Records a new investment in a portfolio company. * * @param investment - Investment information without ID * @returns Newly created investment with generated ID * @throws {Error} If company not found or validation fails */ async addInvestment(investment) { const id = crypto.randomUUID(); const newInvestment = types_1.InvestmentSchema.parse({ ...investment, id }); if (!this.companies.has(newInvestment.companyId)) { throw new Error(`Company with id ${newInvestment.companyId} not found`); } this.investments.set(id, newInvestment); return newInvestment; } /** * Retrieves an investment by its ID. * * @param id - Investment ID * @returns Investment information or undefined if not found */ async getInvestment(id) { return this.investments.get(id); } /** * Lists investments, optionally filtered by company. * * @param companyId - Optional company ID to filter investments * @returns Array of investments */ async listInvestments(companyId) { const investments = Array.from(this.investments.values()); return companyId ? investments.filter(i => i.companyId === companyId) : investments; } /** * Calculates total invested amount, optionally for a specific company. * * @param companyId - Optional company ID to calculate total for * @returns Object containing total amount and currency */ async getTotalInvested(companyId) { const investments = await this.listInvestments(companyId); const byCurrency = new Map(); for (const inv of investments) { const current = byCurrency.get(inv.currency) || new decimal_js_1.default(0); byCurrency.set(inv.currency, current.plus(inv.amount)); } // For now, return the first currency group. In practice, you'd want to handle // multiple currencies and possibly convert them to a base currency const [firstCurrency] = byCurrency.entries(); return firstCurrency ? { amount: firstCurrency[1], currency: firstCurrency[0] } : { amount: new decimal_js_1.default(0), currency: 'USD' }; } /** * Calculates total ownership percentage in a company. * * @param companyId - Company ID to calculate ownership for * @returns Total ownership percentage as a decimal */ async getOwnership(companyId) { const investments = await this.listInvestments(companyId); return investments.reduce((total, inv) => total.plus(inv.ownership), new decimal_js_1.default(0)); } } exports.PortfolioService = PortfolioService; //# sourceMappingURL=portfolio.js.map