Files
butcem/src/models/attachment.ts
T

52 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { model, models, Schema, type InferSchemaType, type Model } from "mongoose";
import { ATTACHMENT_KINDS } from "@/shared/attachments";
/** Ek dosyanın bağlanabileceği kayıt türleri (ileride: alışveriş fişi, cari hareket…). */
export const ATTACHMENT_OWNER_TYPES = ["transaction", "product"] as const;
export type AttachmentOwnerType = (typeof ATTACHMENT_OWNER_TYPES)[number];
/**
* Ek dosya meta verisi (Bölüm 7.4). Dosyanın kendisi depolama sürücüsünde, rastgele anahtarla.
* - Yüklenince `ownerId: null` (bekleyen); kayıt kaydedilince sahibine bağlanır.
* - Bekleyen ek yalnızca yükleyene görünür ve 24 saat içinde bağlanmazsa temizlenir.
* - Kayıttan çıkarılan ek `deletedAt` alır; dosya saklama süresi sonunda silinir.
*/
const attachmentSchema = new Schema(
{
householdId: { type: Schema.Types.ObjectId, required: true },
ownerType: { type: String, enum: ATTACHMENT_OWNER_TYPES, default: null },
ownerId: { type: Schema.Types.ObjectId, default: null },
kind: { type: String, enum: ATTACHMENT_KINDS, required: true },
/** Saklanan içeriğin türü (görseller her zaman WebP'ye çevrilir). */
mimeType: { type: String, enum: ["image/webp", "application/pdf"], required: true },
/** Kaynak tür (jpeg, png, webp, heic, pdf) — bilgi amaçlı. */
sourceType: { type: String, required: true },
originalName: { type: String, default: "", maxlength: 120 },
size: { type: Number, required: true },
originalSize: { type: Number, required: true },
width: { type: Number, default: null },
height: { type: Number, default: null },
storageKey: { type: String, required: true },
thumbKey: { type: String, default: null },
uploadedBy: { type: Schema.Types.ObjectId, required: true },
/** Kayıt içindeki sıra (carousel sırası). */
order: { type: Number, default: 0 },
deletedAt: { type: Date, default: null },
},
{ timestamps: true, collection: "attachments" },
);
attachmentSchema.index({ householdId: 1, ownerType: 1, ownerId: 1, deletedAt: 1, order: 1 });
attachmentSchema.index({ ownerId: 1, createdAt: 1 });
attachmentSchema.index(
{ deletedAt: 1 },
{ partialFilterExpression: { deletedAt: { $type: "date" } } },
);
attachmentSchema.index({ storageKey: 1 }, { unique: true });
export type Attachment = InferSchemaType<typeof attachmentSchema>;
export const AttachmentModel: Model<Attachment> =
(models.Attachment as Model<Attachment> | undefined) ??
model<Attachment>("Attachment", attachmentSchema);