import { model, models, Schema, type InferSchemaType, type Model } from "mongoose"; /** * Ürün (marka/varyant, Bölüm 6.11): "Ariel Matik 5 kg / 50 yıkama". Bir ürün tipine bağlıdır; * fiyatlar (Faz 12b) bu seviyede tutulur. Paket miktarı binde bir. `typeQuantity`: paket birimi * ürün tipinin birimine kendiliğinden çevrilemiyorsa bir paketin ürün tipi birimindeki karşılığı * (zorunlu); çevrilebiliyorsa null. Görseller `attachments` (ownerType "product"). */ const productSchema = new Schema( { householdId: { type: Schema.Types.ObjectId, required: true }, productTypeId: { type: Schema.Types.ObjectId, required: true }, brand: { type: String, required: true, trim: true, maxlength: 60 }, /** Tanım (ör. "Matik Dağ Esintisi"). */ name: { type: String, default: "", trim: true, maxlength: 120 }, /** Arama anahtarı: marka + tanım (Türkçe katlanmış). */ searchKey: { type: String, required: true }, barcode: { type: String, default: null }, packageQuantity: { type: Number, required: true, min: 1 }, packageUnit: { type: String, required: true, trim: true, maxlength: 20 }, typeQuantity: { type: Number, default: null, min: 1 }, note: { type: String, default: "", maxlength: 300 }, imageCount: { type: Number, default: 0 }, archivedAt: { type: Date, default: null }, seedRef: { type: String, default: null }, createdBy: { type: Schema.Types.ObjectId, required: true }, updatedBy: { type: Schema.Types.ObjectId, required: true }, }, { timestamps: true, collection: "products" }, ); productSchema.index({ householdId: 1, productTypeId: 1, archivedAt: 1 }); productSchema.index( { householdId: 1, barcode: 1 }, { partialFilterExpression: { barcode: { $type: "string" } } }, ); productSchema.index( { householdId: 1, seedRef: 1 }, { unique: true, partialFilterExpression: { seedRef: { $type: "string" } } }, ); export type Product = InferSchemaType; export const ProductModel: Model = (models.Product as Model | undefined) ?? model("Product", productSchema);