Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 54x 238x 238x 238x 54x 54x 54x 163x 156x 163x 156x 163x 156x 54x | import mongoose from "mongoose";
import { z } from "zod";
import dayjs from "dayjs";
import { config } from "shared/config";
import { SignupQuestionSchema } from "shared/types/models/settings";
import {
EventSignupStrategy,
LoginProvider,
} from "shared/config/eventConfigTypes";
import { EmailNotificationTrigger } from "shared/types/emailNotification";
export const SettingsSchemaDb = z
.object({
hiddenProgramItemIds: z.array(z.string()),
appOpen: z.boolean(),
adminMessageFi: z.string(),
adminMessageEn: z.string(),
signupQuestions: z.array(SignupQuestionSchema),
signupStrategy: z.enum(EventSignupStrategy),
programUpdateLastRun: z
.date()
.transform((date) => dayjs(date).toISOString()),
assignmentLastRun: z.date().transform((date) => dayjs(date).toISOString()),
latestServerStartTime: z
.date()
.transform((date) => dayjs(date).toISOString()),
loginProvider: z.enum(LoginProvider),
emailNotificationTrigger: z.array(z.enum(EmailNotificationTrigger)),
})
.strip();
const selectOptionSchema = new mongoose.Schema({
optionFi: { type: String, required: true },
optionEn: { type: String, required: true },
});
const signupQuestionSchema = new mongoose.Schema({
programItemId: { type: String, required: true },
questionFi: { type: String, required: true },
questionEn: { type: String, required: true },
private: { type: Boolean, required: true },
type: { type: String, required: true },
selectOptions: { type: [selectOptionSchema], default: [] },
});
const settingsSchema = new mongoose.Schema(
{
hiddenProgramItemIds: { type: [String], default: [] },
appOpen: { type: Boolean, default: true },
adminMessageFi: { type: String, default: "" },
adminMessageEn: { type: String, default: "" },
signupQuestions: { type: [signupQuestionSchema], default: [] },
signupStrategy: {
type: String,
default: config.event().defaultSignupStrategy,
},
programUpdateLastRun: {
type: Date,
get: (value: Date) => new Date(value),
default: () => new Date(),
},
assignmentLastRun: {
type: Date,
get: (value: Date) => new Date(value),
// Epoch (not "now") so a fresh settings row means "no assignment has run yet" — set to
// the run time on each successful assignment
default: () => new Date(0),
},
assignmentInProgressStartTime: {
type: Date,
// The assignment-in-progress lock: null means free, otherwise the time the running
// assignment acquired it. Held for the whole run and reset to null on completion; a held
// lock older than the stale timeout is treated as abandoned (a crashed run) so a crash
// can't deadlock assignments. Fresh row starts free (null)
default: null,
},
latestServerStartTime: {
type: Date,
get: (value: Date) => new Date(value),
// Epoch (not "now") so a settings row recreated mid-run reads as older than any live
// instance and the cron guard surfaces it as an error — a "now" default would masquerade
// as a newer server instance and silently stop cronjobs. Server start overwrites this
default: () => new Date(0),
},
loginProvider: {
type: String,
default: config.event().defaultLoginProvider,
},
emailNotificationTrigger: {
type: [String],
default: config.server().emailNotificationTrigger,
},
},
{ timestamps: true },
);
export const SettingsModel = mongoose.model("settings", settingsSchema);
|