feat: implement plant identification result card component and initialize backend server infrastructure
This commit is contained in:
@@ -100,8 +100,8 @@ export const ResultCard: React.FC<ResultCardProps> = ({
|
|||||||
<View style={styles.careGrid}>
|
<View style={styles.careGrid}>
|
||||||
{[
|
{[
|
||||||
{ icon: 'water' as const, label: t.water, value: t.waterEveryXDays.replace('{0}', result.careInfo.waterIntervalDays.toString()), color: colors.info, bg: colors.infoSoft },
|
{ icon: 'water' as const, label: t.water, value: t.waterEveryXDays.replace('{0}', result.careInfo.waterIntervalDays.toString()), color: colors.info, bg: colors.infoSoft },
|
||||||
{ icon: 'sunny' as const, label: t.light, value: result.careInfo.light || t.unknown, color: colors.warning, bg: colors.warningSoft },
|
{ icon: 'sunny' as const, label: t.light, value: (result.careInfo.light && result.careInfo.light !== 'Unknown') ? result.careInfo.light : t.unknown, color: colors.warning, bg: colors.warningSoft },
|
||||||
{ icon: 'thermometer' as const, label: t.temp, value: result.careInfo.temp || t.unknown, color: colors.danger, bg: colors.dangerSoft },
|
{ icon: 'thermometer' as const, label: t.temp, value: (result.careInfo.temp && result.careInfo.temp !== 'Unknown') ? result.careInfo.temp : t.unknown, color: colors.danger, bg: colors.dangerSoft },
|
||||||
].map((item) => (
|
].map((item) => (
|
||||||
<View key={item.label} style={[styles.careCard, { backgroundColor: colors.surface, borderColor: colors.border }]}>
|
<View key={item.label} style={[styles.careCard, { backgroundColor: colors.surface, borderColor: colors.border }]}>
|
||||||
<View style={[styles.careIcon, { backgroundColor: item.bg }]}>
|
<View style={[styles.careIcon, { backgroundColor: item.bg }]}>
|
||||||
@@ -118,8 +118,8 @@ export const ResultCard: React.FC<ResultCardProps> = ({
|
|||||||
<Text style={[styles.detailsTitle, { color: colors.textSecondary }]}>{t.detailedCare}</Text>
|
<Text style={[styles.detailsTitle, { color: colors.textSecondary }]}>{t.detailedCare}</Text>
|
||||||
{[
|
{[
|
||||||
{ text: t.careTextWater.replace('{0}', result.careInfo.waterIntervalDays.toString()), color: colors.success },
|
{ text: t.careTextWater.replace('{0}', result.careInfo.waterIntervalDays.toString()), color: colors.success },
|
||||||
{ text: t.careTextLight.replace('{0}', result.careInfo.light || t.unknown), color: colors.warning },
|
{ text: t.careTextLight.replace('{0}', (result.careInfo.light && result.careInfo.light !== 'Unknown') ? result.careInfo.light : t.unknown), color: colors.warning },
|
||||||
{ text: t.careTextTemp.replace('{0}', result.careInfo.temp || t.unknown), color: colors.danger },
|
{ text: t.careTextTemp.replace('{0}', (result.careInfo.temp && result.careInfo.temp !== 'Unknown') ? result.careInfo.temp : t.unknown), color: colors.danger },
|
||||||
].map((item, i) => (
|
].map((item, i) => (
|
||||||
<View key={i} style={styles.detailRow}>
|
<View key={i} style={styles.detailRow}>
|
||||||
<View style={[styles.detailDot, { backgroundColor: item.color }]} />
|
<View style={[styles.detailDot, { backgroundColor: item.color }]} />
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ const SEMANTIC_SEARCH_COST = 2;
|
|||||||
const HEALTH_CHECK_COST = 2;
|
const HEALTH_CHECK_COST = 2;
|
||||||
const LOW_CONFIDENCE_REVIEW_THRESHOLD = 0.8;
|
const LOW_CONFIDENCE_REVIEW_THRESHOLD = 0.8;
|
||||||
|
|
||||||
|
let catalogCache = null;
|
||||||
|
|
||||||
|
const getCachedCatalogEntries = async (db) => {
|
||||||
|
if (catalogCache) return catalogCache;
|
||||||
|
catalogCache = await getPlants(db, { limit: 500 });
|
||||||
|
return catalogCache;
|
||||||
|
};
|
||||||
|
|
||||||
const DEFAULT_BOOTSTRAP_PLANTS = [
|
const DEFAULT_BOOTSTRAP_PLANTS = [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -627,18 +635,16 @@ app.post('/v1/scan', async (request, response) => {
|
|||||||
let modelUsed = null;
|
let modelUsed = null;
|
||||||
let modelFallbackCount = 0;
|
let modelFallbackCount = 0;
|
||||||
|
|
||||||
if (!isGuest(userId)) {
|
const [creditResult, accountSnapshot, catalogEntries] = await Promise.all([
|
||||||
creditsCharged += await consumeCreditsWithIdempotency(
|
isGuest(userId)
|
||||||
db,
|
? Promise.resolve(0)
|
||||||
userId,
|
: consumeCreditsWithIdempotency(db, userId, chargeKey('scan-primary', userId, idempotencyKey), SCAN_PRIMARY_COST),
|
||||||
chargeKey('scan-primary', userId, idempotencyKey),
|
getAccountSnapshot(db, userId),
|
||||||
SCAN_PRIMARY_COST,
|
getCachedCatalogEntries(db),
|
||||||
);
|
]);
|
||||||
}
|
creditsCharged += creditResult;
|
||||||
|
|
||||||
const accountSnapshot = await getAccountSnapshot(db, userId);
|
|
||||||
const scanPlan = accountSnapshot.plan === 'pro' ? 'pro' : 'free';
|
const scanPlan = accountSnapshot.plan === 'pro' ? 'pro' : 'free';
|
||||||
const catalogEntries = await getPlants(db, { limit: 500 });
|
|
||||||
let result = pickCatalogFallback(catalogEntries, imageUri, false, { silent: true });
|
let result = pickCatalogFallback(catalogEntries, imageUri, false, { silent: true });
|
||||||
let usedOpenAi = false;
|
let usedOpenAi = false;
|
||||||
|
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ const applyCatalogGrounding = (aiResult, catalogEntries, language = 'en') => {
|
|||||||
description: aiResult.description || matchedEntry.description || '',
|
description: aiResult.description || matchedEntry.description || '',
|
||||||
careInfo: {
|
careInfo: {
|
||||||
waterIntervalDays: Math.max(1, Number(matchedEntry.careInfo?.waterIntervalDays) || Number(aiResult.careInfo?.waterIntervalDays) || 7),
|
waterIntervalDays: Math.max(1, Number(matchedEntry.careInfo?.waterIntervalDays) || Number(aiResult.careInfo?.waterIntervalDays) || 7),
|
||||||
light: matchedEntry.careInfo?.light || aiResult.careInfo?.light || 'Unknown',
|
light: (matchedEntry.careInfo?.light && matchedEntry.careInfo.light !== 'Unknown') ? matchedEntry.careInfo.light : (aiResult.careInfo?.light || 'Unknown'),
|
||||||
temp: matchedEntry.careInfo?.temp || aiResult.careInfo?.temp || 'Unknown',
|
temp: (matchedEntry.careInfo?.temp && matchedEntry.careInfo.temp !== 'Unknown') ? matchedEntry.careInfo.temp : (aiResult.careInfo?.temp || 'Unknown'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user