Files
homepage/src/models/OpenFoodFact.ts
Alexander Bocken b7397898e3
All checks were successful
CI / update (push) Successful in 5m26s
feat: add barcode scanner with OpenFoodFacts integration
- Camera-based barcode scanning in FoodSearch using barcode-detector (ZXing WASM)
- Import script to load OFF MongoDB dump into lean openfoodfacts collection
  with kJ→kcal fallback and dedup handling
- Barcode lookup API with live OFF API fallback that caches results locally,
  progressively enhancing the local database
- Add 'off' source to food log, custom meal, and favorite ingredient models
- OpenFoodFact mongoose model for the openfoodfacts collection
2026-04-05 11:57:28 +02:00

54 lines
2.0 KiB
TypeScript

import mongoose from 'mongoose';
interface IOpenFoodFact {
barcode: string;
name: string;
nameDe?: string;
brands?: string;
category?: string;
nutriscore?: string;
productQuantityG?: number;
serving?: { description: string; grams: number };
per100g: {
calories: number; protein: number; fat: number; saturatedFat?: number;
carbs: number; fiber?: number; sugars?: number;
calcium?: number; iron?: number; magnesium?: number; phosphorus?: number;
potassium?: number; sodium?: number; zinc?: number;
vitaminA?: number; vitaminC?: number; vitaminD?: number; vitaminE?: number;
vitaminK?: number; thiamin?: number; riboflavin?: number; niacin?: number;
vitaminB6?: number; vitaminB12?: number; folate?: number; cholesterol?: number;
};
}
const ServingSchema = new mongoose.Schema({
description: String,
grams: Number,
}, { _id: false });
const Per100gSchema = new mongoose.Schema({
calories: Number, protein: Number, fat: Number, saturatedFat: Number,
carbs: Number, fiber: Number, sugars: Number,
calcium: Number, iron: Number, magnesium: Number, phosphorus: Number,
potassium: Number, sodium: Number, zinc: Number,
vitaminA: Number, vitaminC: Number, vitaminD: Number, vitaminE: Number,
vitaminK: Number, thiamin: Number, riboflavin: Number, niacin: Number,
vitaminB6: Number, vitaminB12: Number, folate: Number, cholesterol: Number,
}, { _id: false });
const OpenFoodFactSchema = new mongoose.Schema({
barcode: { type: String, required: true, unique: true, index: true },
name: { type: String, required: true },
nameDe: String,
brands: String,
category: String,
nutriscore: String,
productQuantityG: Number,
serving: ServingSchema,
per100g: { type: Per100gSchema, required: true },
}, { collection: 'openfoodfacts' });
let _model: mongoose.Model<IOpenFoodFact>;
try { _model = mongoose.model<IOpenFoodFact>('OpenFoodFact'); } catch { _model = mongoose.model<IOpenFoodFact>('OpenFoodFact', OpenFoodFactSchema); }
export const OpenFoodFact = _model;
export type { IOpenFoodFact };