mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-02 06:46:18 +08:00
feat(onboarding): add PilotProfile model
This commit is contained in:
32
server/models/PilotProfile.test.ts
Normal file
32
server/models/PilotProfile.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, it } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { PilotProfile } from '~~/server/models/PilotProfile'
|
||||
|
||||
describe('PilotProfile model', () => {
|
||||
it('is importable without a DB connection', () => {
|
||||
assert.ok(PilotProfile, 'PilotProfile model must be importable')
|
||||
})
|
||||
|
||||
it('schema defines the expected fields', () => {
|
||||
const paths = PilotProfile.schema.paths
|
||||
for (const field of [
|
||||
'user', 'simulator', 'os', 'hardware', 'radioConfidence', 'radioPainPoint',
|
||||
'networkExperience', 'toolkit', 'toolkitDuration', 'topFeatures',
|
||||
'pricingPreference', 'resultCallsign', 'completedAt', 'skippedAt',
|
||||
]) {
|
||||
assert.ok(field in paths, `schema must have ${field}`)
|
||||
}
|
||||
})
|
||||
|
||||
it('user reference is required and unique', () => {
|
||||
const userPath = PilotProfile.schema.path('user') as any
|
||||
assert.equal(userPath?.options?.required, true)
|
||||
assert.equal(userPath?.options?.unique, true)
|
||||
})
|
||||
|
||||
it('radioConfidence is bounded 1-5', () => {
|
||||
const path = PilotProfile.schema.path('radioConfidence') as any
|
||||
assert.equal(path?.options?.min, 1)
|
||||
assert.equal(path?.options?.max, 5)
|
||||
})
|
||||
})
|
||||
48
server/models/PilotProfile.ts
Normal file
48
server/models/PilotProfile.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import mongoose from 'mongoose'
|
||||
import type {
|
||||
FeatureWish, HardwareItem, NetworkExperience, OperatingSystem, PricingPreference,
|
||||
RadioPainPoint, Simulator, ToolkitDuration, ToolkitItem,
|
||||
} from '~~/shared/onboarding/config'
|
||||
|
||||
export interface PilotProfileDocument extends mongoose.Document {
|
||||
user: mongoose.Types.ObjectId
|
||||
simulator?: Simulator
|
||||
os?: OperatingSystem
|
||||
hardware: HardwareItem[]
|
||||
radioConfidence?: number
|
||||
radioPainPoint?: RadioPainPoint
|
||||
networkExperience: NetworkExperience[]
|
||||
toolkit: ToolkitItem[]
|
||||
toolkitDuration: Partial<Record<ToolkitItem, ToolkitDuration>>
|
||||
topFeatures: FeatureWish[]
|
||||
pricingPreference?: PricingPreference
|
||||
resultCallsign?: string
|
||||
completedAt?: Date
|
||||
skippedAt?: Date
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
const pilotProfileSchema = new mongoose.Schema<PilotProfileDocument>(
|
||||
{
|
||||
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true, unique: true },
|
||||
simulator: { type: String },
|
||||
os: { type: String },
|
||||
hardware: { type: [String], default: () => [] },
|
||||
radioConfidence: { type: Number, min: 1, max: 5 },
|
||||
radioPainPoint: { type: String },
|
||||
networkExperience: { type: [String], default: () => [] },
|
||||
toolkit: { type: [String], default: () => [] },
|
||||
toolkitDuration: { type: mongoose.Schema.Types.Mixed, default: () => ({}) },
|
||||
topFeatures: { type: [String], default: () => [] },
|
||||
pricingPreference: { type: String },
|
||||
resultCallsign: { type: String, trim: true },
|
||||
completedAt: { type: Date },
|
||||
skippedAt: { type: Date },
|
||||
},
|
||||
{ timestamps: true },
|
||||
)
|
||||
|
||||
export const PilotProfile =
|
||||
(mongoose.models.PilotProfile as mongoose.Model<PilotProfileDocument> | undefined) ||
|
||||
mongoose.model<PilotProfileDocument>('PilotProfile', pilotProfileSchema)
|
||||
Reference in New Issue
Block a user