import { model, models, Schema, type InferSchemaType, type Model } from "mongoose"; import { SHOPPING_ITEM_KINDS, SHOPPING_ITEM_SOURCES, SHOPPING_LIST_STATUSES, } from "@/shared/shopping"; /** * Alışveriş kalemi (Bölüm 6.12): ürün tipi (genel), belirli ürün (marka/paket) ya da serbest metin. * Miktar binde bir: ürün tipinde tipin biriminde, üründe paket adedi, serbest metinde `unit` ile. * `checked`: alışveriş modunda sepete alındı. */ const shoppingItemSchema = new Schema( { kind: { type: String, enum: SHOPPING_ITEM_KINDS, required: true }, productTypeId: { type: Schema.Types.ObjectId, default: null }, productId: { type: Schema.Types.ObjectId, default: null }, text: { type: String, default: "", trim: true, maxlength: 120 }, /** Boşsa "1 paket" kabul edilir. */ quantity: { type: Number, default: null, min: 0 }, /** Serbest metin kaleminin birimi. */ unit: { type: String, default: "", trim: true, maxlength: 20 }, note: { type: String, default: "", trim: true, maxlength: 200 }, source: { type: String, enum: SHOPPING_ITEM_SOURCES, default: "manual" }, checked: { type: Boolean, default: false }, checkedBy: { type: Schema.Types.ObjectId, default: null }, checkedAt: { type: Date, default: null }, addedBy: { type: Schema.Types.ObjectId, required: true }, addedAt: { type: Date, default: () => new Date() }, }, { _id: true }, ); /** Alışveriş listesi; hane içinde ortak. Birden çok aktif liste olabilir. Silme: soft delete. */ const shoppingListSchema = new Schema( { householdId: { type: Schema.Types.ObjectId, required: true }, name: { type: String, required: true, trim: true, maxlength: 80 }, status: { type: String, enum: SHOPPING_LIST_STATUSES, default: "active" }, note: { type: String, default: "", trim: true, maxlength: 300 }, items: { type: [shoppingItemSchema], default: [] }, completedAt: { type: Date, default: null }, deletedAt: { 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: "shoppingLists" }, ); shoppingListSchema.index({ householdId: 1, deletedAt: 1, status: 1, updatedAt: -1 }); shoppingListSchema.index( { householdId: 1, seedRef: 1 }, { unique: true, partialFilterExpression: { seedRef: { $type: "string" } } }, ); export type ShoppingList = InferSchemaType; export const ShoppingListModel: Model = (models.ShoppingList as Model | undefined) ?? model("ShoppingList", shoppingListSchema);