import type { Types } from "mongoose"; import { createContact, createContactEntry } from "@/features/contacts/service"; import { AccountModel } from "@/models/account"; import { ContactModel } from "@/models/contact"; import type { ContactEntryKind, ContactRelation } from "@/shared/contacts"; import { todayIstanbul } from "@/shared/dates"; import { formatMoneyInput } from "@/shared/money"; import { addDays } from "@/shared/recurrence"; import { contactEntrySchema, contactFormSchema } from "@/shared/schemas/contact"; /** * Örnek cariler (Faz 8a): vadesi yaklaşan alacak, kısmen ödenen borç, vadesi geçmiş küçük alacak * ve "yalnızca ben" cari. İdempotent: cari `seedRef` ile; hareketler yalnızca cari ilk * oluşturulduğunda eklenir. */ type SeedContact = { ref: string; household: string; by: string; name: string; relation: ContactRelation; phone?: string; isPrivate?: boolean; dueInDays?: number; reminderDays?: number; entries: { kind: ContactEntryKind; account: string; amountMinor: number; daysAgo: number; description?: string; }[]; }; const CONTACTS: SeedContact[] = [ { ref: "ahmet", household: "Çakır Ailesi", by: "admin", name: "Ahmet Yılmaz", relation: "friend", phone: "0532 000 00 01", dueInDays: 5, reminderDays: 7, entries: [ { kind: "lend", account: "Ziraat Maaş", amountMinor: 5_000_00, daysAgo: 70, description: "Araba tamiri için", }, { kind: "collect", account: "Cüzdan", amountMinor: 2_000_00, daysAgo: 30 }, ], }, { ref: "hasan", household: "Çakır Ailesi", by: "admin", name: "Hasan Çakır", relation: "family", dueInDays: 60, entries: [ { kind: "borrow", account: "Ziraat Maaş", amountMinor: 20_000_00, daysAgo: 120, description: "Ev eşyası için", }, { kind: "repay", account: "Ziraat Maaş", amountMinor: 5_000_00, daysAgo: 60 }, { kind: "repay", account: "Ziraat Maaş", amountMinor: 5_000_00, daysAgo: 10 }, ], }, { ref: "elif", household: "Çakır Ailesi", by: "ayse", name: "Elif (komşu)", relation: "neighbor", dueInDays: -2, entries: [ { kind: "lend", account: "Cüzdan", amountMinor: 300_00, daysAgo: 12, description: "Pazar alışverişi", }, ], }, { ref: "selin", household: "Çakır Ailesi", by: "ayse", name: "Selin (iş arkadaşı)", relation: "work", isPrivate: true, entries: [{ kind: "lend", account: "Cüzdan", amountMinor: 1_000_00, daysAgo: 8 }], }, { ref: "ali", household: "Annemler", by: "fatma", name: "Ali Demir", relation: "family", dueInDays: 45, entries: [{ kind: "borrow", account: "Vakıfbank Emekli", amountMinor: 3_000_00, daysAgo: 25 }], }, ]; export async function seedContacts( householdIds: Map, userIds: Map, ): Promise { const today = todayIstanbul(); let created = 0; for (const c of CONTACTS) { const householdId = householdIds.get(c.household)!; const seedRef = `contact:${c.ref}`; if (await ContactModel.exists({ householdId, seedRef })) continue; const by = userIds.get(c.by)!; const oldest = Math.max(...c.entries.map((e) => e.daysAgo)); const r = await createContact( by, String(householdId), contactFormSchema.parse({ name: c.name, relation: c.relation, phone: c.phone ?? "", openingDate: addDays(today, -oldest - 1), isPrivate: c.isPrivate ?? false, dueDate: c.dueInDays !== undefined ? addDays(today, c.dueInDays) : null, reminderDays: c.reminderDays ?? 3, }), ); if (!r.ok) throw new Error(`Seed carisi oluşturulamadı (${c.name}): ${r.error}`); await ContactModel.updateOne({ _id: r.data.id }, { $set: { seedRef } }); for (const e of c.entries) { const account = await AccountModel.findOne({ householdId, name: e.account }).lean(); const x = await createContactEntry( by, String(householdId), r.data.id, contactEntrySchema.parse({ kind: e.kind, accountId: String(account!._id), amount: formatMoneyInput(e.amountMinor), date: addDays(today, -e.daysAgo), description: e.description ?? "", }), ); if (!x.ok) throw new Error(`Seed cari hareketi oluşturulamadı (${c.name}): ${x.error}`); } created++; } return created; }