import { UrlOrigin } from "@typez/urls/enums";
import { Schema } from "mongoose";
/**
* URL Counters Schema - Mongoose schema for UrlCounters
* This is a subdocument schema with no _id
* @category Models
*/
const UrlCountersSchema = new Schema({
visitsTotal: {
type: Number,
default: 0,
min: [0, "Visits total cannot be negative"],
},
completionsTotal: {
type: Number,
default: 0,
min: [0, "Completions total cannot be negative"],
},
}, { _id: false });
/**
* URL Schema Definition
* This file contains the main mongoose schema definition for URLs
* @category Models
*/
export const UrlSchema = new Schema({
// Identity & linkage
investigationId: {
type: Schema.Types.ObjectId,
ref: "Investigation",
required: [true, "Investigation ID is required"],
},
key: {
type: String,
required: [true, "Key is required"],
trim: true,
maxlength: [50, "Key cannot exceed 50 characters"],
},
subLink: {
type: String,
required: [true, "SubLink is required"],
trim: true,
lowercase: true,
maxlength: [100, "SubLink cannot exceed 100 characters"],
match: [
/^[a-z0-9._-]+$/,
"SubLink can only contain lowercase letters, numbers, dots, underscores, and hyphens",
],
},
description: {
type: String,
required: [true, "Description is required"],
trim: true,
maxlength: [200, "Description cannot exceed 200 characters"],
},
origin: {
type: String,
enum: Object.values(UrlOrigin),
default: UrlOrigin.HUMAN,
required: true,
},
// Per-link counters (canonical)
counters: {
type: UrlCountersSchema,
default: () => ({
visitsTotal: 0,
completionsTotal: 0,
}),
},
// Admin/trace
createdBy: {
type: Schema.Types.ObjectId,
ref: "User",
default: null,
},
}, {
timestamps: true,
collection: "urls",
});
Source