Sfoglia il codice sorgente

refs 117514: save questionnaire answers when failed to send

Futa Arai 3 anni fa
parent
commit
cf379a48ad

+ 13 - 0
packages/app/src/interfaces/questionnaire/proactive-questionnaire-answer.ts

@@ -0,0 +1,13 @@
+import { IGrowiInfo } from './growi-info';
+import { IUserInfo } from './user-info';
+
+export interface IProactiveQuestionnaireAnswer {
+  satisfaction: number,
+  commentText: string,
+  growiInfo: IGrowiInfo,
+  userInfo: IUserInfo,
+  answeredAt: Date,
+  lengthOfExperience?: string,
+  position?: string,
+  occupation?: string,
+}

+ 26 - 0
packages/app/src/server/models/questionnaire/proactive-questionnaire-answer.ts

@@ -0,0 +1,26 @@
+import { Model, Schema } from 'mongoose';
+
+import { IProactiveQuestionnaireAnswer } from '~/interfaces/questionnaire/proactive-questionnaire-answer';
+import { getOrCreateModel } from '~/server/util/mongoose-utils';
+
+import { growiInfoSchema } from './schema/growi-info';
+import { userInfoSchema } from './schema/user-info';
+
+interface ProactiveQuestionnaireAnswerDocument extends IProactiveQuestionnaireAnswer, Document {}
+
+type ProactiveQuestionnaireAnswerModel = Model<ProactiveQuestionnaireAnswerDocument>
+
+export const proactiveQuestionnaireAnswerSchema = new Schema<ProactiveQuestionnaireAnswerDocument>({
+  satisfaction: { type: Number, required: true },
+  lengthOfExperience: { type: String },
+  position: { type: String },
+  occupation: { type: String },
+  commentText: { type: String, required: true },
+  growiInfo: { type: growiInfoSchema, required: true },
+  userInfo: { type: userInfoSchema, required: true },
+  answeredAt: { type: Date },
+}, { timestamps: true });
+
+export default getOrCreateModel<ProactiveQuestionnaireAnswerDocument, ProactiveQuestionnaireAnswerModel>(
+  'ProactiveQuestionnaireAnswer', proactiveQuestionnaireAnswerSchema,
+);

+ 21 - 0
packages/app/src/server/models/questionnaire/questionnaire-answer.ts

@@ -0,0 +1,21 @@
+import { Document, Model, Schema } from 'mongoose';
+
+import { IQuestionnaireAnswer } from '~/interfaces/questionnaire/questionnaire-answer';
+import { getOrCreateModel } from '~/server/util/mongoose-utils';
+
+import { answerSchema } from './schema/answer';
+import { growiInfoSchema } from './schema/growi-info';
+import { userInfoSchema } from './schema/user-info';
+
+interface QuestionnaireAnswerDocument extends IQuestionnaireAnswer, Document {}
+
+type QuestionnaireAnswerModel = Model<QuestionnaireAnswerDocument>
+
+const questionnaireAnswerSchema = new Schema<QuestionnaireAnswerDocument>({
+  answers: [answerSchema],
+  answeredAt: { type: Date, required: true },
+  growiInfo: { type: growiInfoSchema, required: true },
+  userInfo: { type: userInfoSchema, required: true },
+}, { timestamps: true });
+
+export default getOrCreateModel<QuestionnaireAnswerDocument, QuestionnaireAnswerModel>('QuestionnaireAnswer', questionnaireAnswerSchema);

+ 9 - 0
packages/app/src/server/models/questionnaire/schema/answer.ts

@@ -0,0 +1,9 @@
+import { Schema } from 'mongoose';
+
+import { IAnswer } from '~/interfaces/questionnaire/answer';
+import { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
+
+export const answerSchema = new Schema<IAnswer<ObjectIdLike>>({
+  question: { type: Schema.Types.ObjectId, ref: 'Question', required: true },
+  value: { type: String, required: true },
+});

+ 24 - 0
packages/app/src/server/models/questionnaire/schema/growi-info.ts

@@ -0,0 +1,24 @@
+import { Schema } from 'mongoose';
+
+import {
+  GrowiAttachmentType, GrowiDeploymentType, GrowiExternalAuthProviderType, GrowiServiceType, GrowiWikiType, IGrowiInfo,
+} from '~/interfaces/questionnaire/growi-info';
+
+export const growiInfoSchema = new Schema<IGrowiInfo>({
+  version: { type: String, required: true },
+  appSiteUrl: { type: String },
+  appSiteUrlHashed: { type: String, required: true },
+  type: { type: String, required: true, enum: Object.values(GrowiServiceType) },
+  currentUsersCount: { type: Number, required: true },
+  currentActiveUsersCount: { type: Number, required: true },
+  wikiType: { type: String, required: true, enum: Object.values(GrowiWikiType) },
+  attachmentType: { type: String, required: true, enum: Object.values(GrowiAttachmentType) },
+  activeExternalAccountTypes: [{ type: String, enum: Object.values(GrowiExternalAuthProviderType) }],
+  osInfo: {
+    type: { type: String },
+    platform: String,
+    arch: String,
+    totalmem: Number,
+  },
+  deploymentType: { type: String, enum: (<(string | null)[]>Object.values(GrowiDeploymentType)).concat([null]) },
+});

+ 9 - 0
packages/app/src/server/models/questionnaire/schema/user-info.ts

@@ -0,0 +1,9 @@
+import { Schema } from 'mongoose';
+
+import { IUserInfo, UserType } from '~/interfaces/questionnaire/user-info';
+
+export const userInfoSchema = new Schema<IUserInfo>({
+  userIdHash: { type: String },
+  type: { type: String, required: true, enum: Object.values(UserType) },
+  userCreatedAt: { type: Date },
+});

+ 16 - 4
packages/app/src/server/routes/apiv3/questionnaire.ts

@@ -1,8 +1,11 @@
 import { Router, Request } from 'express';
 import { body, validationResult } from 'express-validator';
 
+import { IProactiveQuestionnaireAnswer } from '~/interfaces/questionnaire/proactive-questionnaire-answer';
 import { StatusType } from '~/interfaces/questionnaire/questionnaire-answer-status';
 import Crowi from '~/server/crowi';
+import ProactiveQuestionnaireAnswer from '~/server/models/questionnaire/proactive-questionnaire-answer';
+import QuestionnaireAnswer from '~/server/models/questionnaire/questionnaire-answer';
 import QuestionnaireAnswerStatus from '~/server/models/questionnaire/questionnaire-answer-status';
 import axios from '~/utils/axios';
 import loggerFactory from '~/utils/logger';
@@ -55,7 +58,6 @@ module.exports = (crowi: Crowi): Router => {
     const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
     const userInfo = crowi.questionnaireService!.getUserInfo(req.user ?? null, growiInfo.appSiteUrlHashed);
 
-    // TODO: add condition
     try {
       const questionnaireOrders = await crowi.questionnaireService!.getQuestionnaireOrdersToShow(userInfo, growiInfo, req.user?._id ?? null);
 
@@ -78,7 +80,7 @@ module.exports = (crowi: Crowi): Router => {
       const growiInfo = await crowi.questionnaireService!.getGrowiInfo();
       const userInfo = crowi.questionnaireService!.getUserInfo(req.user ?? null, growiInfo.appSiteUrlHashed);
 
-      const body = {
+      const proactiveQuestionnaireAnswer: IProactiveQuestionnaireAnswer = {
         satisfaction: req.body.satisfaction,
         lengthOfExperience: req.body.lengthOfExperience,
         position: req.body.position,
@@ -89,7 +91,12 @@ module.exports = (crowi: Crowi): Router => {
         answeredAt: new Date(),
       };
 
-      await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive`, body);
+      await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer/proactive`, proactiveQuestionnaireAnswer)
+        .catch(async(err) => {
+          if (err.request != null) {
+            await ProactiveQuestionnaireAnswer.create(proactiveQuestionnaireAnswer);
+          }
+        });
     };
 
     const errors = validationResult(req);
@@ -120,7 +127,12 @@ module.exports = (crowi: Crowi): Router => {
         answeredAt: new Date(),
       };
 
-      await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer);
+      await axios.post(`${growiQuestionnaireServerOrigin}/questionnaire-answer`, questionnaireAnswer)
+        .catch(async(err) => {
+          if (err.request != null) {
+            await QuestionnaireAnswer.create(questionnaireAnswer);
+          }
+        });
     };
 
     const errors = validationResult(req);