From 38e2a7a26d8498475cf5107d57f3eae95e3f231a Mon Sep 17 00:00:00 2001 From: suphicakir Date: Thu, 5 Nov 2026 02:14:10 +0300 Subject: [PATCH] feat(models): households ve householdMembers Mongoose modelleri Co-Authored-By: Claude Opus 5.5 --- src/models/.gitkeep | 0 src/models/household-member.ts | 26 +++++++++++++++++ src/models/household.ts | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) delete mode 100644 src/models/.gitkeep create mode 100644 src/models/household-member.ts create mode 100644 src/models/household.ts diff --git a/src/models/.gitkeep b/src/models/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/models/household-member.ts b/src/models/household-member.ts new file mode 100644 index 0000000..9aea0cc --- /dev/null +++ b/src/models/household-member.ts @@ -0,0 +1,26 @@ +import { model, models, Schema, type InferSchemaType, type Model } from "mongoose"; +import { HOUSEHOLD_ROLES } from "@/features/households/types"; + +/** Kullanıcının bir hanedeki üyeliği ve hane içi rolü (owner | member | viewer). */ +const householdMemberSchema = new Schema( + { + householdId: { type: Schema.Types.ObjectId, ref: "Household", required: true }, + /** Better Auth `user` koleksiyonundaki _id. */ + userId: { type: Schema.Types.ObjectId, required: true }, + role: { type: String, enum: HOUSEHOLD_ROLES, required: true }, + createdBy: { type: Schema.Types.ObjectId, required: true }, + updatedBy: { type: Schema.Types.ObjectId, required: true }, + }, + { timestamps: true, collection: "householdMembers" }, +); + +// Bir kullanıcı bir hanede yalnızca bir kez üye olabilir. +householdMemberSchema.index({ householdId: 1, userId: 1 }, { unique: true }); +// Kullanıcının hanelerini hızlı listelemek için. +householdMemberSchema.index({ userId: 1, householdId: 1 }); + +export type HouseholdMember = InferSchemaType; + +export const HouseholdMemberModel: Model = + (models.HouseholdMember as Model | undefined) ?? + model("HouseholdMember", householdMemberSchema); diff --git a/src/models/household.ts b/src/models/household.ts new file mode 100644 index 0000000..68d0878 --- /dev/null +++ b/src/models/household.ts @@ -0,0 +1,52 @@ +import { + model, + models, + Schema, + type HydratedDocument, + type InferSchemaType, + type Model, +} from "mongoose"; + +/** Hane ayarları (Faz 0 kararları: bütçe ayı başlangıcı, taksit ve günlük plan tercihleri). */ +const householdSettingsSchema = new Schema( + { + /** Bütçe ayının başlangıç günü (1 = takvim ayı). */ + budgetMonthStartDay: { type: Number, min: 1, max: 28, default: 1 }, + /** Taksitlerin bütçe etkisi: her taksit kendi ayına | tamamı harcama ayına. */ + installmentBudgetMode: { + type: String, + enum: ["per_installment", "purchase_month"], + default: "per_installment", + }, + /** Günlük plan: değişken bütçe eşit dağıtılır | önceki ayın örüntüsüne göre. */ + dailyPlanMode: { type: String, enum: ["even", "previous_month_pattern"], default: "even" }, + /** "Yalnızca ben" hesapları hane toplamlarına dahil edilsin mi? */ + includePrivateAccountsInTotals: { type: Boolean, default: true }, + /** Akıllı mağaza önerisi: ek mağaza ancak tasarruf bu tutarı aşarsa (kuruş). */ + extraStoreSavingThresholdMinor: { type: Number, min: 0, default: 10_000 }, + }, + { _id: false }, +); + +const householdSchema = new Schema( + { + name: { type: String, required: true, trim: true, minlength: 2, maxlength: 80 }, + currency: { type: String, enum: ["TRY"], default: "TRY" }, + timezone: { type: String, default: "Europe/Istanbul" }, + settings: { type: householdSettingsSchema, default: () => ({}) }, + archivedAt: { type: Date, default: null }, + createdBy: { type: Schema.Types.ObjectId, required: true }, + updatedBy: { type: Schema.Types.ObjectId, required: true }, + }, + { timestamps: true, collection: "households" }, +); + +householdSchema.index({ name: 1 }); + +export type Household = InferSchemaType; +export type HouseholdDoc = HydratedDocument; + +/** HMR'de modelin yeniden derlenmesini önler. */ +export const HouseholdModel: Model = + (models.Household as Model | undefined) ?? + model("Household", householdSchema);