feat(transactions): ek bağlama, hesap ekstresi ve mutabakat servisi, 004 migration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ export const AUDIT_ACTIONS = [
|
||||
"account.update",
|
||||
"account.archive",
|
||||
"account.unarchive",
|
||||
"account.reconcile",
|
||||
"category.archive",
|
||||
"category.unarchive",
|
||||
"category.move",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { model, models, Schema, type InferSchemaType, type Model } from "mongoose";
|
||||
|
||||
/**
|
||||
* Mutabakat kaydı (Bölüm 6.1): kullanıcı ekstre bakiyesini girdi, uygulama bakiyesiyle
|
||||
* karşılaştırıldı, fark varsa düzeltme işlemi oluşturuldu ve o tarihe kadarki işlemler işaretlendi.
|
||||
*/
|
||||
const reconciliationSchema = new Schema(
|
||||
{
|
||||
householdId: { type: Schema.Types.ObjectId, required: true },
|
||||
accountId: { type: Schema.Types.ObjectId, required: true },
|
||||
/** İstanbul gününün başlangıç anı (UTC); o günün sonuna kadarki işlemler dahil. */
|
||||
statementDate: { type: Date, required: true },
|
||||
/** Uygulamadaki işaretle (kredi kartında eksi = borç). */
|
||||
statementBalanceMinor: { type: Number, required: true },
|
||||
appBalanceMinor: { type: Number, required: true },
|
||||
differenceMinor: { type: Number, required: true },
|
||||
adjustmentTransactionId: { type: Schema.Types.ObjectId, default: null },
|
||||
markedCount: { type: Number, default: 0 },
|
||||
createdBy: { type: Schema.Types.ObjectId, required: true },
|
||||
},
|
||||
{ timestamps: { createdAt: true, updatedAt: false }, collection: "reconciliations" },
|
||||
);
|
||||
|
||||
reconciliationSchema.index({ householdId: 1, accountId: 1, statementDate: -1, createdAt: -1 });
|
||||
|
||||
export type Reconciliation = InferSchemaType<typeof reconciliationSchema>;
|
||||
|
||||
export const ReconciliationModel: Model<Reconciliation> =
|
||||
(models.Reconciliation as Model<Reconciliation> | undefined) ??
|
||||
model<Reconciliation>("Reconciliation", reconciliationSchema);
|
||||
@@ -35,6 +35,7 @@ const transactionSchema = new Schema(
|
||||
/** Arama için normalize metin (açıklama + satıcı + kalem notları). */
|
||||
searchText: { type: String, default: "" },
|
||||
tags: { type: [String], default: [] },
|
||||
/** Bağlı (silinmemiş) ek dosya sayısı; liste ikonu için (asıl kayıt attachments'ta). */
|
||||
attachmentCount: { type: Number, default: 0 },
|
||||
// İleri fazlar: planlı işlem kuralı (7), taksit (7), kart dönemi (7), cari (8).
|
||||
recurringRuleId: { type: Schema.Types.ObjectId, default: null },
|
||||
@@ -47,7 +48,13 @@ const transactionSchema = new Schema(
|
||||
},
|
||||
statementId: { type: Schema.Types.ObjectId, default: null },
|
||||
contactId: { type: Schema.Types.ObjectId, default: null },
|
||||
reconciledAt: { type: Date, default: null },
|
||||
/**
|
||||
* Mutabakatı yapılmış hesaplar (Bölüm 6.1). Transfer iki hesaba dokunduğu için hesap bazında
|
||||
* tutulur. Tutar, tarih, tür veya hesap değişirse işaret kalkar.
|
||||
*/
|
||||
reconciledAccountIds: { type: [Schema.Types.ObjectId], default: [] },
|
||||
/** Mutabakat düzeltme işlemi: kategorisiz; düzenlenemez, yalnızca silinebilir. */
|
||||
isAdjustment: { type: Boolean, default: false },
|
||||
deletedAt: { type: Date, default: null },
|
||||
/** Seed verisinin idempotent yüklenmesi için sabit anahtar. */
|
||||
seedRef: { type: String, default: null },
|
||||
|
||||
Reference in New Issue
Block a user