Files
Brancheneinstufung2/competitor-analysis-app/services/geminiService.ts
Floke 249b06463b feat(competitor-analysis): Fix 404, SDK compatibility, and update docs
Resolved multiple issues preventing the 'competitor-analysis' app from running and serving its frontend:

1.  **Fixed Python SyntaxError in Prompts:** Corrected unterminated string literals and ensure proper multi-line string formatting (using .format() instead of f-strings for complex prompts) in .
2.  **Addressed Python SDK Compatibility (google-generativeai==0.3.0):**
    *   Removed  for  and  by adapting the orchestrator to pass JSON schemas as direct Python dictionaries, as required by the older SDK version.
    *   Updated  with detailed guidance on handling / imports and dictionary-based schema definitions for older SDKs.
3.  **Corrected Frontend Build Dependencies:** Moved critical build dependencies (like , , ) from  to  in .
    *   Updated  to include this  pitfall, ensuring frontend build tools are installed in Docker.
4.  **Updated Documentation:**
    *   : Added comprehensive lessons learned regarding  dependencies, Python SDK versioning (specifically  and  imports for ), and robust multi-line prompt handling.
    *   : Integrated specific details of the encountered errors and their solutions, making the migration report a more complete historical record and guide.

These changes collectively fix the 404 error by ensuring the Python backend starts correctly and serves the frontend assets after a successful build.
2026-01-10 09:10:00 +00:00

130 lines
5.2 KiB
TypeScript

import type { Product, TargetIndustry, Keyword, CompetitorCandidate, Analysis, AppState, Conclusion, SilverBullet, Battlecard, ShortlistedCompetitor, ReferenceAnalysis } from '../types';
const API_BASE_URL = './'; // Relative to the application sub-path (/ca/)
export const fetchProductDetails = async (name: string, url: string, language: 'de' | 'en'): Promise<Product> => {
const response = await fetch(`${API_BASE_URL}api/fetchProductDetails`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, url, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep1Data = async (startUrl: string, language: 'de' | 'en'): Promise<{ products: Product[], target_industries: TargetIndustry[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep1Data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ start_url: startUrl, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep2Data = async (products: Product[], industries: TargetIndustry[], language: 'de' | 'en'): Promise<{ keywords: Keyword[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep2Data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ products, industries, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep3Data = async (keywords: Keyword[], marketScope: string, language: 'de' | 'en'): Promise<{ competitor_candidates: CompetitorCandidate[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep3Data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ keywords, market_scope: marketScope, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep4Data = async (company: AppState['company'], competitors: CompetitorCandidate[], language: 'de' | 'en'): Promise<{ analyses: Analysis[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep4Data`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ company, competitors, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep5Data_SilverBullets = async (company: AppState['company'], analyses: Analysis[], language: 'de' | 'en'): Promise<{ silver_bullets: SilverBullet[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep5Data_SilverBullets`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ company, analyses, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep6Data_Conclusion = async (company: AppState['company'], products: Product[], industries: TargetIndustry[], analyses: Analysis[], silver_bullets: SilverBullet[], language: 'de' | 'en'): Promise<{ conclusion: Conclusion }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep6Data_Conclusion`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ company, products, industries, analyses, silver_bullets, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep7Data_Battlecards = async (company: AppState['company'], analyses: Analysis[], silver_bullets: SilverBullet[], language: 'de' | 'en'): Promise<{ battlecards: Battlecard[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep7Data_Battlecards`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ company, analyses, silver_bullets, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};
export const fetchStep8Data_ReferenceAnalysis = async (competitors: ShortlistedCompetitor[], language: 'de' | 'en'): Promise<{ reference_analysis: ReferenceAnalysis[], groundingMetadata: any[] }> => {
const response = await fetch(`${API_BASE_URL}api/fetchStep8Data_ReferenceAnalysis`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ competitors, language }),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
};