Skip to content

Commit

Permalink
Fix models types (#3929)
Browse files Browse the repository at this point in the history
* chore: redefine IFollowupModel to be only the model (collection) interface

* chore: redefine FolloupInterface to be instance (document) interface

* fix: make req.followup a folloupInterface

* fix: mongoose Followup definition

Note: inspired by : https://medium.com/@agentwhs/complete-guide-for-typescript-for-mongoose-for-node-js-8cc0a7e470c1

* fix: use FollowupInterface when needed

* feat: arange interfaces

* chore: fix simulation interfaces

* chore: remove useless function

* feat: rename simulations that were followups
  • Loading branch information
baptou12 authored Aug 30, 2023
1 parent 7555fa7 commit 37268ea
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 101 deletions.
41 changes: 11 additions & 30 deletions backend/controllers/followups.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Followup from "../models/followup.js"
import { IFollowup } from "../types/models.d.js"
import { FollowupInterface } from "../../lib/types/followup.d.js"
import Benefits from "../../data/all.js"
import pollResult from "../lib/mattermost-bot/poll-result.js"
Expand All @@ -10,11 +9,6 @@ import { FollowupFactory } from "../lib/followup-factory.js"
import { FetchSurveyLayout } from "../../lib/types/survey.d.js"
import Request from "../types/express.d.js"

// TODO next line is to be updated once tokens are used globally
const excludeFields = ["accessToken", "surveys.accessToken"]
.join(" -")
.replace(/^/, "-")

export function followup(
req: Request,
res: Response,
Expand All @@ -23,7 +17,7 @@ export function followup(
) {
Followup.findById(id)
.populate("simulation")
.exec(function (err: any, followup: any) {
.exec(function (err: any, followup: FollowupInterface | null) {
if (err) {
return next(err)
}
Expand Down Expand Up @@ -56,7 +50,7 @@ export async function persist(req: Request, res: Response) {
simulation,
req.body.email,
req.body.surveyOptin
)) as IFollowup
)) as FollowupInterface

await followup.sendSimulationResultsEmail()

Expand All @@ -76,11 +70,11 @@ export function getFollowup(req: Request, res: Response) {
} as FetchSurveyLayout)
}

export function showSurveyResult(req: Request, res: Response) {
Followup.findById(req.params.surveyId)
.then((simulation: any) => {
if (!simulation) return res.sendStatus(404)
res.send([simulation])
export function showFollowup(req: Request, res: Response) {
Followup.findById(req.params.followupId)
.then((followup: FollowupInterface | null) => {
if (!followup) return res.sendStatus(404)
res.send([followup])
})
.catch((error: Error) => {
console.error("error", error)
Expand Down Expand Up @@ -108,22 +102,9 @@ export function showSurveyResults(req: Request, res: Response) {

export function showSurveyResultByEmail(req: Request, res: Response) {
Followup.findByEmail(req.params.email)
.then((simulations: any) => {
if (!simulations || !simulations.length) return res.sendStatus(404)
res.send(simulations)
})
.catch((error: Error) => {
console.error("error", error)
return res.sendStatus(400)
})
}

export function showSimulation(req: Request, res: Response) {
Followup.findById(req.params.surveyId)
.select(excludeFields)
.then((simulation: any) => {
if (!simulation) return res.sendStatus(404)
res.send([simulation])
.then((followups: FollowupInterface[]) => {
if (!followups || !followups.length) return res.sendStatus(404)
res.send(followups)
})
.catch((error: Error) => {
console.error("error", error)
Expand All @@ -137,7 +118,7 @@ export async function followupByAccessToken(
next: NextFunction,
accessToken: any
) {
const followup: IFollowup | null = await Followup.findOne({
const followup: FollowupInterface | null = await Followup.findOne({
accessToken,
})
if (!followup) return res.sendStatus(404)
Expand Down
13 changes: 8 additions & 5 deletions backend/controllers/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import openfiscaTestLib from "../lib/openfisca/test.js"
import { apply } from "../lib/migrations/index.js"

import Simulation from "../models/simulation.js"
import { SimulationModel } from "../types/models.d.js"
import Followup from "../models/followup.js"
import { FollowupInterface } from "../../lib/types/followup.d.js"
import { SimulationInterface } from "../../lib/types/simulation.d.js"
import allBenefits from "../../data/all.js"
import Request from "../types/express.d.js"

function setSimulationOnRequest(req: Request, simulation: SimulationModel) {
function setSimulationOnRequest(req: Request, simulation: SimulationInterface) {
req.simulation = apply(simulation)
req.situation = generateSituation(req.simulation)
}
Expand All @@ -22,18 +22,21 @@ function simulation(
req: Request,
res,
next,
simulationOrSimulationId: SimulationModel | SimulationModel["_id"] | string
simulationOrSimulationId:
| SimulationInterface
| SimulationInterface["_id"]
| string
) {
if (
typeof simulationOrSimulationId === "object" &&
simulationOrSimulationId._id
) {
const simulation = simulationOrSimulationId as unknown as SimulationModel
const simulation = simulationOrSimulationId as SimulationInterface
setSimulationOnRequest(req, simulation)
return next()
}

const simulationId = simulationOrSimulationId as SimulationModel["_id"]
const simulationId = simulationOrSimulationId as SimulationInterface["_id"]
Simulation.findById(simulationId, (err, simulation) => {
if (!simulation) return res.sendStatus(404)
if (err) return next(err)
Expand Down
8 changes: 4 additions & 4 deletions backend/lib/emails/sending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dayjs from "dayjs"
import { EmailType } from "../../enums/email.js"
import { SurveyType } from "../../../lib/enums/survey.js"
import Followup from "../../models/followup.js"
import { IFollowupModel } from "../../types/models.d.js"
import { FollowupInterface } from "../../../lib/types/followup.js"

const DaysBeforeInitialEmail = 6
const DaysBeforeTousABordNotificationEmail = 2
Expand Down Expand Up @@ -45,7 +45,7 @@ async function sendMultipleInitialEmails(limit: number) {
.limit(limit)

const results: { ok?: any; ko?: any }[] = await Promise.all(
followups.map(async (followup: IFollowupModel) => {
followups.map(async (followup: FollowupInterface) => {
const surveyType =
Math.random() > 0.5
? SurveyType.trackClickOnBenefitActionEmail
Expand Down Expand Up @@ -89,7 +89,7 @@ async function sendMultipleTousABordNotificationEmails(limit: number) {
.limit(limit)

const results = await Promise.all(
followups.map(async (followup: any) => {
followups.map(async (followup: FollowupInterface) => {
try {
const result = await followup.sendSurvey(
SurveyType.tousABordNotification
Expand All @@ -104,7 +104,7 @@ async function sendMultipleTousABordNotificationEmails(limit: number) {
}

async function processSingleEmail(emailType: EmailType, followupId: string) {
const followup: IFollowupModel | null = await Followup.findById(followupId)
const followup: FollowupInterface | null = await Followup.findById(followupId)
if (!followup) {
throw new Error("Followup not found")
}
Expand Down
4 changes: 2 additions & 2 deletions backend/lib/followup-factory.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import Followup from "../models/followup.js"
import { SimulationModel } from "../types/models.js"
import { FollowupInterface } from "@lib/types/followup.js"
import { SimulationInterface } from "@lib/types/simulation.js"
import utils from "../lib/utils.js"

const DefaultVersion = 3
const TokenLength = 17

export const FollowupFactory = {
create: async (
simulation: SimulationModel,
simulation: SimulationInterface,
email: string,
surveyOptin: boolean
): Promise<FollowupInterface> => {
Expand Down
6 changes: 4 additions & 2 deletions backend/models/followup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,7 @@ FollowupSchema.virtual("wasNotUsefulPath").get(function (this) {
return `/api/followups/surveys/${this.accessToken}/${SurveyType.trackClickOnSimulationUsefulnessEmail}`
})

//export default mongoose.model<FollowupInterface, IFollowupModel>(
export default mongoose.model<any, IFollowupModel>("Followup", FollowupSchema)
export default mongoose.model<FollowupInterface, IFollowupModel>(
"Followup",
FollowupSchema
)
6 changes: 3 additions & 3 deletions backend/routes/followups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import express, { Express } from "express"
import {
followupByAccessToken,
postSurvey,
showSurveyResult,
showFollowup,
showSurveyResults,
showSurveyResultByEmail,
getFollowup,
Expand All @@ -22,9 +22,9 @@ const followupsRoutes = function (api: Express) {
.get(cookieParser(), githubController.access)
.get(showSurveyResults)
api
.route("/followups/id/:surveyId")
.route("/followups/id/:followupId")
.get(cookieParser(), githubController.access)
.get(showSurveyResult)
.get(showFollowup)
api
.route("/followups/email/:email")
.get(cookieParser(), githubController.access)
Expand Down
7 changes: 4 additions & 3 deletions backend/types/express.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Request } from "express"
import { IFollowupModel, SimulationModel } from "./models.d.js"
import { FollowupInterface } from "../../lib/types/followup.js"
import { SimulationInterface } from "../../lib/types/simulation.js"

declare global {
export namespace Express {
interface Request {
simulation: SimulationModel
followup: IFollowupModel
simulation: SimulationInterface
followup: FollowupInterface
situation: any
simulationId: string
}
Expand Down
58 changes: 10 additions & 48 deletions backend/types/models.d.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,23 @@
import mongoose, { Model, HydratedDocument } from "mongoose"
import { Model, HydratedDocument } from "mongoose"
import { FollowupInterface } from "@lib/types/followup.d.js"
import { SimulationInterface } from "@lib/types/simulation.d.js"
import { SurveyType } from "@lib/enums/survey.js"

export interface MongooseLayout {
[id: string]: any
}

export interface IFollowupMethods {
postSimulationResultsEmail(messageId: string): void
renderSimulationResultsEmail(): any
sendSimulationResultsEmail(): Promise<void>
renderSurveyEmail(surveyType: SurveyType): any
addSurveyIfMissing(surveyType: SurveyType): Promise<any>
sendSurvey(surveyType: SurveyType): Promise<any>

updateSurvey(action: SurveyType, data?: any)

save()
interface FollowupStaticMethods {
findByEmail(email: string): Promise<HydratedDocument<FollowupInterface[]>>
}

export interface IFollowupModel
extends Model<FollowupInterface>,
FollowupInterface,
IFollowupMethods {
findByEmail(
email: string
): Promise<HydratedDocument<FollowupInterface, IFollowupMethods>>
emailRenderPath: string
returnPath: string
surveyPath: string
tousABordNotificationCta: string
surveyPathTracker: string
wasUsefulPath: string
wasNotUsefulPath: string
}
export interface IFollowup
extends FollowupInterface,
IFollowupMethods,
IFollowupModel {}
FollowupStaticMethods {}

export interface SimulationModel extends Model<SimulationInterface> {
_id: mongoose.Types.ObjectId
cookieName: string
token: string
returnPath: string
isAccessible(keychain: Record<string, string>): boolean
getSituation(): any
compute(): Promise<any>
findById(
simulationId: mongoose.Types.ObjectId | string,
callback: (error: Error, simulation: SimulationModel) => void
)
interface SimulationStaticMethods {
cookiePrefix(): string
create(
data: any,
callback: (error: Error, simulation: SimulationModel) => void
)
hasFollowup: boolean
save()
}

export interface SimulationModel
extends Model<SimulationInterface>,
SimulationStaticMethods {}
31 changes: 30 additions & 1 deletion lib/types/followup.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Document } from "mongoose"

import { SurveyLayout } from "./survey.js"
export interface FollowupInterface {

interface FollowupAttributes {
_id: string
simulation: any
email?: string
Expand All @@ -16,3 +19,29 @@ export interface FollowupInterface {
tousABordNotificationEmail: any
__v: number
}

interface FollowupMethods {
postSimulationResultsEmail(messageId: string): void
renderSimulationResultsEmail(): any
sendSimulationResultsEmail(): Promise<void>
renderSurveyEmail(surveyType: SurveyType): any
addSurveyIfMissing(surveyType: SurveyType): Promise<any>
sendSurvey(surveyType: SurveyType): Promise<any>
updateSurvey(action: SurveyType, data?: any)
}

interface FollowupVirtuals {
emailRenderPath: string
returnPath: string
surveyPath: string
tousABordNotificationCta: string
surveyPathTracker: string
wasUsefulPath: string
wasNotUsefulPath: string
}

export interface FollowupInterface
extends Document,
FollowupAttributes,
FollowupMethods,
FollowupVirtuals {}
21 changes: 20 additions & 1 deletion lib/types/simulation.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Document } from "mongoose"

import { SimulationStatusEnum } from "../enums/simulation.js"

export interface Answer {
Expand All @@ -8,7 +10,7 @@ export interface Answer {
path: string
}

export interface SimulationInterface {
interface SimulationAttributes {
_id: string
answers: {
all: Answer[]
Expand All @@ -28,3 +30,20 @@ export interface SimulationInterface {
teleservice?: string
token: string
}

interface SimulationMethods {
isAccessible(keychain: Record<string, string>): boolean
getSituation(): any
compute(): Promise<any>
}

interface SimulationVirtuals {
cookieName: string
returnPath: string
}

export interface SimulationInterface
extends Document,
SimulationAttributes,
SimulationMethods,
SimulationVirtuals {}
Loading

0 comments on commit 37268ea

Please sign in to comment.