Fix CIM template data linkage issues - update field mapping to use proper nested paths
This commit is contained in:
@@ -461,9 +461,13 @@ export class OptimizedAgenticRAGProcessor {
|
||||
// Use the existing LLM service to generate CIM review
|
||||
const result = await llmService.processCIMDocument(text, 'BPCP CIM Review Template');
|
||||
|
||||
// Generate a comprehensive summary from the analysis data
|
||||
const analysisData = result.jsonOutput || {} as CIMReview;
|
||||
const summary = this.generateSummaryFromAnalysis(analysisData);
|
||||
|
||||
return {
|
||||
summary: 'Document processed with optimized agentic RAG',
|
||||
analysisData: result.jsonOutput || {} as CIMReview
|
||||
summary,
|
||||
analysisData
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Failed to generate LLM analysis for document: ${documentId}`, error);
|
||||
@@ -474,6 +478,114 @@ export class OptimizedAgenticRAGProcessor {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a comprehensive summary from analysis data
|
||||
*/
|
||||
private generateSummaryFromAnalysis(analysisData: CIMReview): string {
|
||||
let summary = '# CIM Review Summary\n\n';
|
||||
|
||||
// Add deal overview
|
||||
if (analysisData.dealOverview?.targetCompanyName) {
|
||||
summary += `## Deal Overview\n\n`;
|
||||
summary += `**Target Company:** ${analysisData.dealOverview.targetCompanyName}\n\n`;
|
||||
|
||||
if (analysisData.dealOverview.industrySector) {
|
||||
summary += `**Industry:** ${analysisData.dealOverview.industrySector}\n\n`;
|
||||
}
|
||||
if (analysisData.dealOverview.transactionType) {
|
||||
summary += `**Transaction Type:** ${analysisData.dealOverview.transactionType}\n\n`;
|
||||
}
|
||||
if (analysisData.dealOverview.geography) {
|
||||
summary += `**Geography:** ${analysisData.dealOverview.geography}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add financial summary
|
||||
if (analysisData.financialSummary?.financials) {
|
||||
summary += `## Financial Summary\n\n`;
|
||||
const financials = analysisData.financialSummary.financials;
|
||||
|
||||
if (financials.fy3) {
|
||||
summary += `### FY3 (Latest)\n\n`;
|
||||
if (financials.fy3.revenue) summary += `- **Revenue:** ${financials.fy3.revenue}\n`;
|
||||
if (financials.fy3.ebitda) summary += `- **EBITDA:** ${financials.fy3.ebitda}\n`;
|
||||
if (financials.fy3.ebitdaMargin) summary += `- **EBITDA Margin:** ${financials.fy3.ebitdaMargin}\n`;
|
||||
if (financials.fy3.revenueGrowth) summary += `- **Revenue Growth:** ${financials.fy3.revenueGrowth}\n\n`;
|
||||
}
|
||||
|
||||
if (financials.fy2) {
|
||||
summary += `### FY2\n\n`;
|
||||
if (financials.fy2.revenue) summary += `- **Revenue:** ${financials.fy2.revenue}\n`;
|
||||
if (financials.fy2.ebitda) summary += `- **EBITDA:** ${financials.fy2.ebitda}\n`;
|
||||
if (financials.fy2.ebitdaMargin) summary += `- **EBITDA Margin:** ${financials.fy2.ebitdaMargin}\n`;
|
||||
if (financials.fy2.revenueGrowth) summary += `- **Revenue Growth:** ${financials.fy2.revenueGrowth}\n\n`;
|
||||
}
|
||||
|
||||
if (financials.fy1) {
|
||||
summary += `### FY1\n\n`;
|
||||
if (financials.fy1.revenue) summary += `- **Revenue:** ${financials.fy1.revenue}\n`;
|
||||
if (financials.fy1.ebitda) summary += `- **EBITDA:** ${financials.fy1.ebitda}\n`;
|
||||
if (financials.fy1.ebitdaMargin) summary += `- **EBITDA Margin:** ${financials.fy1.ebitdaMargin}\n`;
|
||||
if (financials.fy1.revenueGrowth) summary += `- **Revenue Growth:** ${financials.fy1.revenueGrowth}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add business description
|
||||
if (analysisData.businessDescription?.coreOperationsSummary) {
|
||||
summary += `## Business Description\n\n`;
|
||||
summary += `**Core Operations:** ${analysisData.businessDescription.coreOperationsSummary}\n\n`;
|
||||
|
||||
if (analysisData.businessDescription.keyProductsServices) {
|
||||
summary += `**Key Products/Services:** ${analysisData.businessDescription.keyProductsServices}\n\n`;
|
||||
}
|
||||
if (analysisData.businessDescription.uniqueValueProposition) {
|
||||
summary += `**Unique Value Proposition:** ${analysisData.businessDescription.uniqueValueProposition}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add key questions and next steps
|
||||
if (analysisData.keyQuestionsNextSteps?.criticalQuestions) {
|
||||
summary += `## Key Questions & Next Steps\n\n`;
|
||||
summary += `**Critical Questions:** ${analysisData.keyQuestionsNextSteps.criticalQuestions}\n\n`;
|
||||
|
||||
if (analysisData.keyQuestionsNextSteps.preliminaryRecommendation) {
|
||||
summary += `**Preliminary Recommendation:** ${analysisData.keyQuestionsNextSteps.preliminaryRecommendation}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add management team
|
||||
if (analysisData.managementTeamOverview?.keyLeaders) {
|
||||
summary += `## Management Team\n\n`;
|
||||
summary += `**Key Leaders:** ${analysisData.managementTeamOverview.keyLeaders}\n\n`;
|
||||
|
||||
if (analysisData.managementTeamOverview.managementQualityAssessment) {
|
||||
summary += `**Quality Assessment:** ${analysisData.managementTeamOverview.managementQualityAssessment}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add market analysis
|
||||
if (analysisData.marketIndustryAnalysis?.estimatedMarketSize) {
|
||||
summary += `## Market & Industry Analysis\n\n`;
|
||||
summary += `**Market Size:** ${analysisData.marketIndustryAnalysis.estimatedMarketSize}\n\n`;
|
||||
|
||||
if (analysisData.marketIndustryAnalysis.keyIndustryTrends) {
|
||||
summary += `**Industry Trends:** ${analysisData.marketIndustryAnalysis.keyIndustryTrends}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add investment thesis
|
||||
if (analysisData.preliminaryInvestmentThesis?.keyAttractions) {
|
||||
summary += `## Investment Thesis\n\n`;
|
||||
summary += `**Key Attractions:** ${analysisData.preliminaryInvestmentThesis.keyAttractions}\n\n`;
|
||||
|
||||
if (analysisData.preliminaryInvestmentThesis.potentialRisks) {
|
||||
summary += `**Potential Risks:** ${analysisData.preliminaryInvestmentThesis.potentialRisks}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
}
|
||||
|
||||
export const optimizedAgenticRAGProcessor = new OptimizedAgenticRAGProcessor();
|
||||
@@ -239,62 +239,93 @@ const CIMReviewTemplate: React.FC<CIMReviewTemplateProps> = ({
|
||||
|
||||
const renderField = (
|
||||
label: string,
|
||||
field: keyof CIMReviewData,
|
||||
fieldPath: string,
|
||||
type: 'text' | 'textarea' | 'date' = 'text',
|
||||
placeholder?: string,
|
||||
rows?: number
|
||||
) => (
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
{label}
|
||||
</label>
|
||||
{type === 'textarea' ? (
|
||||
<textarea
|
||||
value={getFieldValue(data, field) || ''}
|
||||
onChange={(e) => updateData(field, e.target.value)}
|
||||
placeholder={placeholder}
|
||||
rows={rows || 3}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
) : type === 'date' ? (
|
||||
<input
|
||||
type="date"
|
||||
value={getFieldValue(data, field) || ''}
|
||||
onChange={(e) => updateData(field, e.target.value)}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type="text"
|
||||
value={getFieldValue(data, field) || ''}
|
||||
onChange={(e) => updateData(field, e.target.value)}
|
||||
placeholder={placeholder}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
) => {
|
||||
const path = fieldPath.split('.');
|
||||
const value = getNestedFieldValue(data, path);
|
||||
|
||||
// Helper function to safely get field values
|
||||
const updateNestedField = (newValue: string) => {
|
||||
setData(prev => {
|
||||
const newData = { ...prev };
|
||||
let current = newData;
|
||||
for (let i = 0; i < path.length - 1; i++) {
|
||||
if (!current[path[i]]) {
|
||||
current[path[i]] = {};
|
||||
}
|
||||
current = current[path[i]];
|
||||
}
|
||||
current[path[path.length - 1]] = newValue;
|
||||
return newData;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
{label}
|
||||
</label>
|
||||
{type === 'textarea' ? (
|
||||
<textarea
|
||||
value={value || ''}
|
||||
onChange={(e) => updateNestedField(e.target.value)}
|
||||
placeholder={placeholder}
|
||||
rows={rows || 3}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
) : type === 'date' ? (
|
||||
<input
|
||||
type="date"
|
||||
value={value || ''}
|
||||
onChange={(e) => updateNestedField(e.target.value)}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type="text"
|
||||
value={value || ''}
|
||||
onChange={(e) => updateNestedField(e.target.value)}
|
||||
placeholder={placeholder}
|
||||
disabled={readOnly}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm disabled:bg-gray-50 disabled:text-gray-500"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Helper function to safely get field values with proper nested structure handling
|
||||
const getFieldValue = (obj: any, field: keyof CIMReviewData): string => {
|
||||
const value = obj[field];
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'object' && value !== null) {
|
||||
// For nested objects, try to find a string value
|
||||
for (const key in value) {
|
||||
if (typeof value[key] === 'string') {
|
||||
return value[key];
|
||||
}
|
||||
}
|
||||
// For nested objects, we need to handle them specifically
|
||||
// This function should only be called for top-level fields that are strings
|
||||
// For nested objects, we should use specific accessors
|
||||
return '';
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
// Helper function to get nested field values
|
||||
const getNestedFieldValue = (obj: any, path: string[]): string => {
|
||||
let current = obj;
|
||||
for (const key of path) {
|
||||
if (current && typeof current === 'object' && key in current) {
|
||||
current = current[key];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return typeof current === 'string' ? current : '';
|
||||
};
|
||||
|
||||
const renderFinancialTable = () => (
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-medium text-gray-900">Key Historical Financials</h4>
|
||||
@@ -400,39 +431,39 @@ const CIMReviewTemplate: React.FC<CIMReviewTemplateProps> = ({
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{renderField('Target Company Name', 'dealOverview')}
|
||||
{renderField('Industry/Sector', 'dealOverview')}
|
||||
{renderField('Geography (HQ & Key Operations)', 'dealOverview')}
|
||||
{renderField('Deal Source', 'dealOverview')}
|
||||
{renderField('Transaction Type', 'dealOverview')}
|
||||
{renderField('Date CIM Received', 'dealOverview', 'date')}
|
||||
{renderField('Date Reviewed', 'dealOverview', 'date')}
|
||||
{renderField('Reviewer(s)', 'dealOverview')}
|
||||
{renderField('CIM Page Count', 'dealOverview')}
|
||||
{renderField('Target Company Name', 'dealOverview.targetCompanyName')}
|
||||
{renderField('Industry/Sector', 'dealOverview.industrySector')}
|
||||
{renderField('Geography (HQ & Key Operations)', 'dealOverview.geography')}
|
||||
{renderField('Deal Source', 'dealOverview.dealSource')}
|
||||
{renderField('Transaction Type', 'dealOverview.transactionType')}
|
||||
{renderField('Date CIM Received', 'dealOverview.dateCIMReceived', 'date')}
|
||||
{renderField('Date Reviewed', 'dealOverview.dateReviewed', 'date')}
|
||||
{renderField('Reviewer(s)', 'dealOverview.reviewers')}
|
||||
{renderField('CIM Page Count', 'dealOverview.cimPageCount')}
|
||||
</div>
|
||||
{renderField('Stated Reason for Sale (if provided)', 'dealOverview', 'textarea', 'Enter the stated reason for sale...', 4)}
|
||||
{renderField('Stated Reason for Sale (if provided)', 'dealOverview.statedReasonForSale', 'textarea', 'Enter the stated reason for sale...', 4)}
|
||||
</div>
|
||||
);
|
||||
|
||||
case 'business-description':
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{renderField('Core Operations Summary (3-5 sentences)', 'businessDescription', 'textarea', 'Describe the core operations...', 4)}
|
||||
{renderField('Key Products/Services & Revenue Mix (Est. % if available)', 'businessDescription', 'textarea', 'List key products/services and revenue mix...', 4)}
|
||||
{renderField('Unique Value Proposition (UVP) / Why Customers Buy', 'businessDescription', 'textarea', 'Describe the unique value proposition...', 4)}
|
||||
{renderField('Core Operations Summary (3-5 sentences)', 'businessDescription.coreOperationsSummary', 'textarea', 'Describe the core operations...', 4)}
|
||||
{renderField('Key Products/Services & Revenue Mix (Est. % if available)', 'businessDescription.keyProductsServices', 'textarea', 'List key products/services and revenue mix...', 4)}
|
||||
{renderField('Unique Value Proposition (UVP) / Why Customers Buy', 'businessDescription.uniqueValueProposition', 'textarea', 'Describe the unique value proposition...', 4)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-medium text-gray-900">Customer Base Overview</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{renderField('Key Customer Segments/Types', 'businessDescription')}
|
||||
{renderField('Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue)', 'businessDescription')}
|
||||
{renderField('Typical Contract Length / Recurring Revenue %', 'businessDescription')}
|
||||
{renderField('Key Customer Segments/Types', 'businessDescription.customerBaseOverview.keyCustomerSegments')}
|
||||
{renderField('Customer Concentration Risk (Top 5 and/or Top 10 Customers as % Revenue)', 'businessDescription.customerBaseOverview.customerConcentrationRisk')}
|
||||
{renderField('Typical Contract Length / Recurring Revenue %', 'businessDescription.customerBaseOverview.typicalContractLength')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-medium text-gray-900">Key Supplier Overview (if critical & mentioned)</h4>
|
||||
{renderField('Dependence/Concentration Risk', 'businessDescription', 'textarea', 'Describe supplier dependencies...', 3)}
|
||||
{renderField('Dependence/Concentration Risk', 'businessDescription.keySupplierOverview.dependenceConcentrationRisk', 'textarea', 'Describe supplier dependencies...', 3)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -441,21 +472,21 @@ const CIMReviewTemplate: React.FC<CIMReviewTemplateProps> = ({
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{renderField('Estimated Market Size (TAM/SAM - if provided)', 'marketIndustryAnalysis')}
|
||||
{renderField('Estimated Market Growth Rate (% CAGR - Historical & Projected)', 'marketIndustryAnalysis')}
|
||||
{renderField('Estimated Market Size (TAM/SAM - if provided)', 'marketIndustryAnalysis.estimatedMarketSize')}
|
||||
{renderField('Estimated Market Growth Rate (% CAGR - Historical & Projected)', 'marketIndustryAnalysis.estimatedMarketGrowthRate')}
|
||||
</div>
|
||||
{renderField('Key Industry Trends & Drivers (Tailwinds/Headwinds)', 'marketIndustryAnalysis', 'textarea', 'Describe key industry trends...', 4)}
|
||||
{renderField('Key Industry Trends & Drivers (Tailwinds/Headwinds)', 'marketIndustryAnalysis.keyIndustryTrends', 'textarea', 'Describe key industry trends...', 4)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-medium text-gray-900">Competitive Landscape</h4>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{renderField('Key Competitors Identified', 'marketIndustryAnalysis')}
|
||||
{renderField('Target\'s Stated Market Position/Rank', 'marketIndustryAnalysis')}
|
||||
{renderField('Basis of Competition', 'marketIndustryAnalysis')}
|
||||
{renderField('Key Competitors Identified', 'marketIndustryAnalysis.competitiveLandscape.keyCompetitors')}
|
||||
{renderField('Target\'s Stated Market Position/Rank', 'marketIndustryAnalysis.competitiveLandscape.targetMarketPosition')}
|
||||
{renderField('Basis of Competition', 'marketIndustryAnalysis.competitiveLandscape.basisOfCompetition')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{renderField('Barriers to Entry / Competitive Moat (Stated/Inferred)', 'marketIndustryAnalysis', 'textarea', 'Describe barriers to entry...', 4)}
|
||||
{renderField('Barriers to Entry / Competitive Moat (Stated/Inferred)', 'marketIndustryAnalysis.barriersToEntry', 'textarea', 'Describe barriers to entry...', 4)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -467,12 +498,12 @@ const CIMReviewTemplate: React.FC<CIMReviewTemplateProps> = ({
|
||||
<div className="space-y-4">
|
||||
<h4 className="text-lg font-medium text-gray-900">Key Financial Notes & Observations</h4>
|
||||
<div className="grid grid-cols-1 gap-6">
|
||||
{renderField('Quality of Earnings/Adjustments (Initial Impression)', 'financialSummary', 'textarea', 'Assess quality of earnings...', 3)}
|
||||
{renderField('Revenue Growth Drivers (Stated)', 'financialSummary', 'textarea', 'Identify revenue growth drivers...', 3)}
|
||||
{renderField('Margin Stability/Trend Analysis', 'financialSummary', 'textarea', 'Analyze margin trends...', 3)}
|
||||
{renderField('Capital Expenditures (Approx. LTM % of Revenue)', 'financialSummary')}
|
||||
{renderField('Working Capital Intensity (Impression)', 'financialSummary', 'textarea', 'Assess working capital intensity...', 3)}
|
||||
{renderField('Free Cash Flow (FCF) Proxy Quality (Impression)', 'financialSummary', 'textarea', 'Assess FCF quality...', 3)}
|
||||
{renderField('Quality of Earnings/Adjustments (Initial Impression)', 'financialSummary.qualityOfEarnings', 'textarea', 'Assess quality of earnings...', 3)}
|
||||
{renderField('Revenue Growth Drivers (Stated)', 'financialSummary.revenueGrowthDrivers', 'textarea', 'Identify revenue growth drivers...', 3)}
|
||||
{renderField('Margin Stability/Trend Analysis', 'financialSummary.marginStabilityAnalysis', 'textarea', 'Analyze margin trends...', 3)}
|
||||
{renderField('Capital Expenditures (Approx. LTM % of Revenue)', 'financialSummary.capitalExpenditures')}
|
||||
{renderField('Working Capital Intensity (Impression)', 'financialSummary.workingCapitalIntensity', 'textarea', 'Assess working capital intensity...', 3)}
|
||||
{renderField('Free Cash Flow (FCF) Proxy Quality (Impression)', 'financialSummary.freeCashFlowQuality', 'textarea', 'Assess FCF quality...', 3)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -481,31 +512,31 @@ const CIMReviewTemplate: React.FC<CIMReviewTemplateProps> = ({
|
||||
case 'management-team':
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{renderField('Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)', 'managementTeamOverview', 'textarea', 'List key leaders...', 4)}
|
||||
{renderField('Initial Assessment of Quality/Experience (Based on Bios)', 'managementTeamOverview', 'textarea', 'Assess management quality...', 4)}
|
||||
{renderField('Management\'s Stated Post-Transaction Role/Intentions (if mentioned)', 'managementTeamOverview', 'textarea', 'Describe post-transaction intentions...', 4)}
|
||||
{renderField('Organizational Structure Overview (Impression)', 'managementTeamOverview', 'textarea', 'Describe organizational structure...', 4)}
|
||||
{renderField('Key Leaders Identified (CEO, CFO, COO, Head of Sales, etc.)', 'managementTeamOverview.keyLeaders', 'textarea', 'List key leaders...', 4)}
|
||||
{renderField('Initial Assessment of Quality/Experience (Based on Bios)', 'managementTeamOverview.managementQualityAssessment', 'textarea', 'Assess management quality...', 4)}
|
||||
{renderField('Management\'s Stated Post-Transaction Role/Intentions (if mentioned)', 'managementTeamOverview.postTransactionIntentions', 'textarea', 'Describe post-transaction intentions...', 4)}
|
||||
{renderField('Organizational Structure Overview (Impression)', 'managementTeamOverview.organizationalStructure', 'textarea', 'Describe organizational structure...', 4)}
|
||||
</div>
|
||||
);
|
||||
|
||||
case 'investment-thesis':
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{renderField('Key Attractions / Strengths (Why Invest?)', 'preliminaryInvestmentThesis', 'textarea', 'List key attractions...', 4)}
|
||||
{renderField('Potential Risks / Concerns (Why Not Invest?)', 'preliminaryInvestmentThesis', 'textarea', 'List potential risks...', 4)}
|
||||
{renderField('Initial Value Creation Levers (How PE Adds Value)', 'preliminaryInvestmentThesis', 'textarea', 'Identify value creation levers...', 4)}
|
||||
{renderField('Alignment with Fund Strategy', 'preliminaryInvestmentThesis', 'textarea', 'Assess alignment with BPCP strategy...', 4)}
|
||||
{renderField('Key Attractions / Strengths (Why Invest?)', 'preliminaryInvestmentThesis.keyAttractions', 'textarea', 'List key attractions...', 4)}
|
||||
{renderField('Potential Risks / Concerns (Why Not Invest?)', 'preliminaryInvestmentThesis.potentialRisks', 'textarea', 'List potential risks...', 4)}
|
||||
{renderField('Initial Value Creation Levers (How PE Adds Value)', 'preliminaryInvestmentThesis.valueCreationLevers', 'textarea', 'Identify value creation levers...', 4)}
|
||||
{renderField('Alignment with Fund Strategy', 'preliminaryInvestmentThesis.alignmentWithFundStrategy', 'textarea', 'Assess alignment with BPCP strategy...', 4)}
|
||||
</div>
|
||||
);
|
||||
|
||||
case 'next-steps':
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{renderField('Critical Questions Arising from CIM Review', 'keyQuestionsNextSteps', 'textarea', 'List critical questions...', 4)}
|
||||
{renderField('Key Missing Information / Areas for Diligence Focus', 'keyQuestionsNextSteps', 'textarea', 'Identify missing information...', 4)}
|
||||
{renderField('Preliminary Recommendation', 'keyQuestionsNextSteps')}
|
||||
{renderField('Rationale for Recommendation (Brief)', 'keyQuestionsNextSteps', 'textarea', 'Provide rationale...', 4)}
|
||||
{renderField('Proposed Next Steps', 'keyQuestionsNextSteps', 'textarea', 'Outline next steps...', 4)}
|
||||
{renderField('Critical Questions Arising from CIM Review', 'keyQuestionsNextSteps.criticalQuestions', 'textarea', 'List critical questions...', 4)}
|
||||
{renderField('Key Missing Information / Areas for Diligence Focus', 'keyQuestionsNextSteps.missingInformation', 'textarea', 'Identify missing information...', 4)}
|
||||
{renderField('Preliminary Recommendation', 'keyQuestionsNextSteps.preliminaryRecommendation')}
|
||||
{renderField('Rationale for Recommendation (Brief)', 'keyQuestionsNextSteps.rationaleForRecommendation', 'textarea', 'Provide rationale...', 4)}
|
||||
{renderField('Proposed Next Steps', 'keyQuestionsNextSteps.proposedNextSteps', 'textarea', 'Outline next steps...', 4)}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user