mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-05 17:05:53 +08:00
Wochenreport
This commit is contained in:
41
server/models/FeedbackSubmission.ts
Normal file
41
server/models/FeedbackSubmission.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export type FeedbackProduct = 'classroom' | 'liveatc'
|
||||
|
||||
export interface FeedbackSubmissionDocument extends mongoose.Document {
|
||||
product: FeedbackProduct
|
||||
name?: string
|
||||
email?: string
|
||||
discordHandle?: string
|
||||
excitement: number
|
||||
highlightSelections: string[]
|
||||
highlightNotes?: string
|
||||
frictionSelections: string[]
|
||||
frictionNotes?: string
|
||||
classroomNotes?: string
|
||||
hostingInterest?: string
|
||||
otherIdeas?: string
|
||||
contactConsent: boolean
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
const feedbackSubmissionSchema = new mongoose.Schema<FeedbackSubmissionDocument>({
|
||||
product: { type: String, enum: ['classroom', 'liveatc'], default: 'classroom', index: true },
|
||||
name: { type: String, trim: true },
|
||||
email: { type: String, lowercase: true, trim: true },
|
||||
discordHandle: { type: String, trim: true },
|
||||
excitement: { type: Number, required: true, min: 1, max: 5 },
|
||||
highlightSelections: { type: [String], default: () => [] },
|
||||
highlightNotes: { type: String, trim: true },
|
||||
frictionSelections: { type: [String], default: () => [] },
|
||||
frictionNotes: { type: String, trim: true },
|
||||
classroomNotes: { type: String, trim: true },
|
||||
hostingInterest: { type: String, trim: true },
|
||||
otherIdeas: { type: String, trim: true },
|
||||
contactConsent: { type: Boolean, default: false },
|
||||
createdAt: { type: Date, default: () => new Date(), index: true },
|
||||
})
|
||||
|
||||
export const FeedbackSubmission =
|
||||
(mongoose.models.FeedbackSubmission as mongoose.Model<FeedbackSubmissionDocument> | undefined) ||
|
||||
mongoose.model<FeedbackSubmissionDocument>('FeedbackSubmission', feedbackSubmissionSchema)
|
||||
23
server/models/KpiReportDelivery.ts
Normal file
23
server/models/KpiReportDelivery.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export interface KpiReportDeliveryDocument extends mongoose.Document {
|
||||
weekKey: string
|
||||
periodStart: Date
|
||||
periodEnd: Date
|
||||
recipient: string
|
||||
sentAt: Date
|
||||
mailAccepted: boolean
|
||||
}
|
||||
|
||||
const kpiReportDeliverySchema = new mongoose.Schema<KpiReportDeliveryDocument>({
|
||||
weekKey: { type: String, required: true, unique: true, trim: true, index: true },
|
||||
periodStart: { type: Date, required: true },
|
||||
periodEnd: { type: Date, required: true },
|
||||
recipient: { type: String, required: true, trim: true },
|
||||
sentAt: { type: Date, default: () => new Date() },
|
||||
mailAccepted: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
export const KpiReportDelivery =
|
||||
(mongoose.models.KpiReportDelivery as mongoose.Model<KpiReportDeliveryDocument> | undefined) ||
|
||||
mongoose.model<KpiReportDeliveryDocument>('KpiReportDelivery', kpiReportDeliverySchema)
|
||||
28
server/models/LandingAnalyticsEvent.ts
Normal file
28
server/models/LandingAnalyticsEvent.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export type LandingAnalyticsEventType = 'view' | 'scrolled' | 'waitlist_submit'
|
||||
export type AnalyticsProduct = 'classroom' | 'liveatc'
|
||||
|
||||
export interface LandingAnalyticsEventDocument extends mongoose.Document {
|
||||
type: LandingAnalyticsEventType
|
||||
product: AnalyticsProduct
|
||||
sessionId?: string
|
||||
path?: string
|
||||
source?: string
|
||||
scrollDepth?: number
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
const landingAnalyticsEventSchema = new mongoose.Schema<LandingAnalyticsEventDocument>({
|
||||
type: { type: String, enum: ['view', 'scrolled', 'waitlist_submit'], required: true, index: true },
|
||||
product: { type: String, enum: ['classroom', 'liveatc'], default: 'classroom', index: true },
|
||||
sessionId: { type: String, trim: true, index: true },
|
||||
path: { type: String, trim: true },
|
||||
source: { type: String, trim: true },
|
||||
scrollDepth: { type: Number, min: 0, max: 100 },
|
||||
createdAt: { type: Date, default: () => new Date(), index: true },
|
||||
})
|
||||
|
||||
export const LandingAnalyticsEvent =
|
||||
(mongoose.models.LandingAnalyticsEvent as mongoose.Model<LandingAnalyticsEventDocument> | undefined) ||
|
||||
mongoose.model<LandingAnalyticsEventDocument>('LandingAnalyticsEvent', landingAnalyticsEventSchema)
|
||||
27
server/models/ProductUsageSession.ts
Normal file
27
server/models/ProductUsageSession.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import mongoose from 'mongoose'
|
||||
|
||||
export type ProductUsageKey = 'classroom' | 'liveatc'
|
||||
|
||||
export interface ProductUsageSessionDocument extends mongoose.Document {
|
||||
user?: mongoose.Types.ObjectId
|
||||
product: ProductUsageKey
|
||||
path?: string
|
||||
durationSeconds: number
|
||||
startedAt: Date
|
||||
endedAt: Date
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
const productUsageSessionSchema = new mongoose.Schema<ProductUsageSessionDocument>({
|
||||
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', index: true },
|
||||
product: { type: String, enum: ['classroom', 'liveatc'], required: true, index: true },
|
||||
path: { type: String, trim: true },
|
||||
durationSeconds: { type: Number, required: true, min: 0 },
|
||||
startedAt: { type: Date, required: true },
|
||||
endedAt: { type: Date, required: true, index: true },
|
||||
createdAt: { type: Date, default: () => new Date() },
|
||||
})
|
||||
|
||||
export const ProductUsageSession =
|
||||
(mongoose.models.ProductUsageSession as mongoose.Model<ProductUsageSessionDocument> | undefined) ||
|
||||
mongoose.model<ProductUsageSessionDocument>('ProductUsageSession', productUsageSessionSchema)
|
||||
@@ -7,6 +7,7 @@ export interface WaitlistEntryDocument extends mongoose.Document {
|
||||
name?: string
|
||||
notes?: string
|
||||
source?: string
|
||||
product: 'classroom' | 'liveatc'
|
||||
consentPrivacy: boolean
|
||||
consentTerms: boolean
|
||||
joinedAt: Date
|
||||
@@ -28,6 +29,7 @@ const waitlistSchema = new mongoose.Schema<WaitlistEntryDocument>({
|
||||
name: { type: String, trim: true },
|
||||
notes: { type: String, trim: true },
|
||||
source: { type: String, default: 'landing' },
|
||||
product: { type: String, enum: ['classroom', 'liveatc'], default: 'classroom', index: true },
|
||||
consentPrivacy: { type: Boolean, default: false },
|
||||
consentTerms: { type: Boolean, default: false },
|
||||
joinedAt: { type: Date, default: () => new Date() },
|
||||
|
||||
Reference in New Issue
Block a user