| import { Schema, model, Document, Types } from 'mongoose'; |
|
|
| |
| type FieldType = |
| | 'short_text' |
| | 'long_text' |
| | 'multiple_choice' |
| | 'checkboxes' |
| | 'dropdown' |
| | 'linear_scale' |
| | 'date' |
| | 'time' |
| | 'email' |
| | 'phone' |
| | 'number' |
| | 'file_upload'; |
|
|
| interface IFormField { |
| id: string; |
| type: FieldType; |
| label: string; |
| description?: string; |
| required: boolean; |
| options?: string[]; |
| validation?: { |
| min?: number; |
| max?: number; |
| pattern?: string; |
| maxLength?: number; |
| minLength?: number; |
| fileTypes?: string[]; |
| maxFileSize?: number; |
| }; |
| order: number; |
| } |
|
|
| export interface IForm extends Document { |
| |
| title: string; |
| description?: string; |
|
|
| |
| event?: Types.ObjectId; |
| organization: Types.ObjectId; |
| createdBy: Types.ObjectId; |
|
|
| |
| fields: IFormField[]; |
|
|
| |
| accessType: 'event_attendees' | 'verified_users' | 'public'; |
| restrictToAttendees: boolean; |
| oneResponsePerUser: boolean; |
|
|
| |
| shortCode: string; |
| shareToken: string; |
| qrCode?: string; |
|
|
| |
| acceptingResponses: boolean; |
| showResponseSummary: boolean; |
| allowEditing: boolean; |
|
|
| |
| responseCount: number; |
| status: 'draft' | 'active' | 'closed'; |
|
|
| createdAt: Date; |
| updatedAt: Date; |
| } |
|
|
| const FormSchema = new Schema<IForm>({ |
| title: { |
| type: String, |
| required: true, |
| trim: true, |
| index: 'text' |
| }, |
|
|
| description: { |
| type: String, |
| trim: true |
| }, |
|
|
| event: { |
| type: Schema.Types.ObjectId, |
| ref: 'Event', |
| index: true |
| }, |
|
|
| organization: { |
| type: Schema.Types.ObjectId, |
| ref: 'User', |
| required: false, |
| index: true |
| }, |
|
|
| createdBy: { |
| type: Schema.Types.ObjectId, |
| ref: 'User', |
| required: true, |
| index: true |
| }, |
|
|
| fields: [{ |
| id: { |
| type: String, |
| required: true |
| }, |
| type: { |
| type: String, |
| enum: [ |
| 'short_text', |
| 'long_text', |
| 'multiple_choice', |
| 'checkboxes', |
| 'dropdown', |
| 'linear_scale', |
| 'date', |
| 'time', |
| 'email', |
| 'phone', |
| 'number', |
| 'file_upload' |
| ], |
| required: true |
| }, |
| label: { |
| type: String, |
| required: true |
| }, |
| description: String, |
| required: { |
| type: Boolean, |
| default: false |
| }, |
| options: [String], |
| validation: { |
| min: Number, |
| max: Number, |
| pattern: String, |
| maxLength: Number, |
| minLength: Number, |
| fileTypes: [String], |
| maxFileSize: Number |
| }, |
| order: { |
| type: Number, |
| required: true |
| } |
| }], |
|
|
| accessType: { |
| type: String, |
| enum: ['event_attendees', 'verified_users', 'public'], |
| default: 'verified_users' |
| }, |
|
|
| restrictToAttendees: { |
| type: Boolean, |
| default: false |
| }, |
|
|
| oneResponsePerUser: { |
| type: Boolean, |
| default: true |
| }, |
|
|
| shortCode: { |
| type: String, |
| required: true, |
| unique: true, |
| uppercase: true, |
| trim: true, |
| index: true |
| }, |
|
|
| shareToken: { |
| type: String, |
| required: true, |
| index: true |
| }, |
|
|
| qrCode: String, |
|
|
| acceptingResponses: { |
| type: Boolean, |
| default: true |
| }, |
|
|
| showResponseSummary: { |
| type: Boolean, |
| default: false |
| }, |
|
|
| allowEditing: { |
| type: Boolean, |
| default: false |
| }, |
|
|
| responseCount: { |
| type: Number, |
| default: 0 |
| }, |
|
|
| status: { |
| type: String, |
| enum: ['draft', 'active', 'closed'], |
| default: 'draft', |
| index: true |
| } |
| }, { |
| timestamps: true |
| }); |
|
|
| |
| FormSchema.index({ event: 1, status: 1 }); |
| FormSchema.index({ organization: 1, createdBy: 1 }); |
| FormSchema.index({ shortCode: 1, shareToken: 1 }); |
|
|
| export default model<IForm>('Form', FormSchema); |