@@ -11,6 +11,8 @@ import type Engine from 'publicodes'
11
11
import { prisma } from '../../adapters/prisma/client'
12
12
import type { Session } from '../../adapters/prisma/transaction'
13
13
import { transaction } from '../../adapters/prisma/transaction'
14
+ import { redis } from '../../adapters/redis/client'
15
+ import { KEYS } from '../../adapters/redis/constant'
14
16
import { EntityNotFoundException } from '../../core/errors/EntityNotFoundException'
15
17
import { ForbiddenException } from '../../core/errors/ForbiddenException'
16
18
import { EventBus } from '../../core/event-bus/event-bus'
@@ -26,7 +28,7 @@ import {
26
28
createPollUserSimulation ,
27
29
createUserSimulation ,
28
30
fetchPollSimulations ,
29
- fetchUserSimulation ,
31
+ fetchSimulationById ,
30
32
fetchUserSimulations ,
31
33
} from './simulations.repository'
32
34
import type {
@@ -48,7 +50,7 @@ const simulationToDto = (
48
50
polls,
49
51
user,
50
52
...rest
51
- } : Partial < Awaited < ReturnType < typeof fetchUserSimulation > > > ,
53
+ } : Partial < Awaited < ReturnType < typeof fetchSimulationById > > > ,
52
54
connectedUser : string
53
55
) => ( {
54
56
...rest ,
@@ -105,7 +107,7 @@ export const fetchSimulations = async (params: UserParams) => {
105
107
export const fetchSimulation = async ( params : UserSimulationParams ) => {
106
108
try {
107
109
const simulation = await transaction (
108
- ( session ) => fetchUserSimulation ( params , { session } ) ,
110
+ ( session ) => fetchSimulationById ( params , { session } ) ,
109
111
prisma
110
112
)
111
113
@@ -237,7 +239,7 @@ const isValidSimulation = <T>(
237
239
] . every ( ( v ) => v <= MAX_VALUE )
238
240
}
239
241
240
- const getFunFactValues = async (
242
+ const computeAllFunFactValues = async (
241
243
{ id, engine } : { id : string ; engine ?: Engine } ,
242
244
{ session } : { session : Session }
243
245
) => {
@@ -271,14 +273,70 @@ const getFunFactValues = async (
271
273
} , funFactValues )
272
274
}
273
275
274
- return {
275
- simulationCount,
276
- funFactValues,
276
+ return { simulationCount, funFactValues }
277
+ }
278
+
279
+ const getFunFactValues = async (
280
+ {
281
+ id,
282
+ simulationId,
283
+ engine,
284
+ } : { id : string ; simulationId ?: string ; engine ?: Engine } ,
285
+ { session } : { session : Session }
286
+ ) => {
287
+ const redisKey = `${ KEYS . pollsFunFactsResults } :${ id } `
288
+
289
+ let result :
290
+ | {
291
+ simulationCount : number
292
+ funFactValues : { [ key in DottedName ] ?: number }
293
+ }
294
+ | undefined
295
+ if ( simulationId ) {
296
+ const rawPreviousFunFactValues = await redis . get ( redisKey )
297
+ if ( rawPreviousFunFactValues ) {
298
+ const result = JSON . parse ( rawPreviousFunFactValues )
299
+ const simulation = await fetchSimulationById (
300
+ { simulationId } ,
301
+ { session }
302
+ )
303
+
304
+ if ( isValidSimulation ( simulation ) ) {
305
+ const { situation } = simulation
306
+ Object . values ( funFactsRules ) . reduce ( ( acc , dottedName ) => {
307
+ if ( dottedName in frRules ) {
308
+ acc [ dottedName ] =
309
+ ( acc [ dottedName ] || 0 ) +
310
+ ( engine
311
+ ? getSituationDottedNameValueWithEngine ( {
312
+ dottedName,
313
+ situation,
314
+ engine,
315
+ } )
316
+ : getSituationDottedNameValue ( {
317
+ dottedName,
318
+ situation,
319
+ rules : frRules ,
320
+ } ) )
321
+ }
322
+ return acc
323
+ } , result . funFactValues )
324
+ }
325
+ }
326
+ }
327
+
328
+ if ( ! result ) {
329
+ result = await computeAllFunFactValues ( { id, engine } , { session } )
277
330
}
331
+
332
+ await redis . set ( redisKey , JSON . stringify ( result ) )
333
+ await redis . expire ( redisKey , 60 * 60 )
334
+
335
+ return result
278
336
}
279
337
280
338
export const getPollFunFacts = async (
281
- params : { id : string ; engine ?: Engine } ,
339
+ params : { id : string ; simulationId ?: string ; engine ?: Engine } ,
282
340
session : { session : Session }
283
341
) => {
284
342
const { funFactValues, simulationCount } = await getFunFactValues (
0 commit comments