@@ -5,18 +5,22 @@ import {
55 achievement_type_enum as AchievementType ,
66 achievement_template ,
77 pupil_screening_status_enum ,
8+ Prisma ,
89} from '@prisma/client' ;
9- import { User , getPupil , getStudent } from '../user' ;
10- // TODO: Fix import when other PR is in
10+ import { User , getPupil } from '../user' ;
1111import { prisma } from '../prisma' ;
1212import { achievement_with_template } from './types' ;
1313import { getAchievementTemplates , TemplateSelectEnum } from './template' ;
14+ import { createRelation , EventRelationType } from './relation' ;
15+
16+ const PupilNewMatchGroup = 'pupil_new_match' ;
17+ const PupilNewMatchGroupOrder = 3 ;
1418
1519const GhostAchievements : { [ key : string ] : achievement_template } = {
1620 pupil_new_match_1 : {
1721 id : - 1 ,
1822 templateFor : AchievementTemplateFor . Match ,
19- group : 'pupil_new_match' ,
23+ group : PupilNewMatchGroup ,
2024 groupOrder : 1 ,
2125 type : AchievementType . SEQUENTIAL ,
2226 image : 'gamification/achievements/release/finish_onboarding/two_pieces/step_1.png' ,
@@ -40,7 +44,7 @@ const GhostAchievements: { [key: string]: achievement_template } = {
4044 pupil_new_match_2 : {
4145 id : - 1 ,
4246 templateFor : AchievementTemplateFor . Match ,
43- group : 'pupil_new_match' ,
47+ group : PupilNewMatchGroup ,
4448 groupOrder : 2 ,
4549 type : AchievementType . SEQUENTIAL ,
4650 image : 'gamification/achievements/release/finish_onboarding/two_pieces/step_2.png' ,
@@ -82,8 +86,7 @@ export async function deriveAchievements(user: User, realAchievements: achieveme
8286 }
8387
8488 if ( user . studentId ) {
85- const student = await getStudent ( user ) ;
86-
89+ // const student = await getStudent(user);
8790 // await deriveStudentOnboarding(student, result);
8891 // await deriveStudentMatching(student, result);
8992 // ...
@@ -96,23 +99,19 @@ export function deriveAchievementTemplates(group: string): achievement_template[
9699 return Object . values ( GhostAchievements ) . filter ( ( row ) => row . group === group ) ;
97100}
98101
99- async function derivePupilMatching ( user : User , pupil : Pupil , result : achievement_with_template [ ] , userAchievements : achievement_with_template [ ] ) {
100- const hasRequest = pupil . openMatchRequestCount > 0 ;
101- // const hasOpenScreening = (await prisma.pupil_screening.count({ where: { pupilId: pupil.id, status: 'pending', invalidated: false } })) > 0;
102- const hasSuccessfulScreening = await prisma . pupil_screening . count ( {
103- where : { pupilId : pupil . id , status : pupil_screening_status_enum . success , invalidated : false } ,
104- } ) ;
105-
106- const userAchievement = userAchievements . find ( ( row ) => row . template . group === 'pupil_new_match' ) ;
107- const matches = await prisma . match . findMany ( { where : { pupilId : pupil . id } } ) ;
108-
109- // if (!userAchievement && matches.length > 0) {
110- // return [];
111- // }
112-
113- if ( ! userAchievement ) {
102+ async function generatePupilMatching (
103+ achievement : achievement_with_template | null ,
104+ user : User ,
105+ hasRequest : boolean ,
106+ hasSuccessfulScreening : boolean ,
107+ ctx : PupilNewMatchGhostContext
108+ ) : Promise < achievement_with_template [ ] > {
109+ const result : achievement_with_template [ ] = [ ] ;
110+ // Generating a ramdom relation to be able to show multiple sequences of this kind in parallel
111+ const randomRelation = createRelation ( EventRelationType . Match , Math . random ( ) ) + '-tmp' ;
112+ if ( ! achievement ) {
114113 const groups = await getAchievementTemplates ( TemplateSelectEnum . BY_GROUP ) ;
115- if ( ! groups . has ( 'pupil_new_match' ) || groups . get ( 'pupil_new_match' ) . length === 0 ) {
114+ if ( ! groups . has ( PupilNewMatchGroup ) || groups . get ( PupilNewMatchGroup ) . length === 0 ) {
116115 throw new Error ( 'group template not found!' ) ;
117116 }
118117 // If there is no real achievement yet, we have to fake the first one in the row as well
@@ -121,11 +120,11 @@ async function derivePupilMatching(user: User, pupil: Pupil, result: achievement
121120 templateId : - 1 ,
122121 userId : user . userID ,
123122 isSeen : true ,
124- template : groups . get ( 'pupil_new_match' ) [ 0 ] ,
125- context : { } ,
123+ template : groups . get ( PupilNewMatchGroup ) [ 0 ] ,
124+ context : ctx ,
126125 recordValue : null ,
127126 achievedAt : null ,
128- relation : null ,
127+ relation : randomRelation ,
129128 } ) ;
130129 }
131130
@@ -135,11 +134,10 @@ async function derivePupilMatching(user: User, pupil: Pupil, result: achievement
135134 userId : user . userID ,
136135 isSeen : true ,
137136 template : GhostAchievements . pupil_new_match_1 ,
138- context : { } ,
137+ context : ctx ,
139138 recordValue : null ,
140- achievedAt : hasRequest || userAchievement ? new Date ( ) : null ,
141- // achievedAt: new Date(),
142- relation : userAchievement ?. relation ?? null ,
139+ achievedAt : hasRequest || achievement ? new Date ( ) : null ,
140+ relation : achievement ?. relation ?? randomRelation ,
143141 } ) ;
144142
145143 result . push ( {
@@ -148,9 +146,42 @@ async function derivePupilMatching(user: User, pupil: Pupil, result: achievement
148146 userId : user . userID ,
149147 isSeen : true ,
150148 template : GhostAchievements . pupil_new_match_2 ,
151- context : { } ,
149+ context : ctx ,
152150 recordValue : null ,
153- achievedAt : hasSuccessfulScreening || userAchievement ? new Date ( ) : null ,
154- relation : userAchievement ?. relation ?? null ,
151+ achievedAt : hasSuccessfulScreening || achievement ? new Date ( ) : null ,
152+ relation : achievement ?. relation ?? randomRelation ,
155153 } ) ;
154+ return result ;
155+ }
156+
157+ interface PupilNewMatchGhostContext extends Prisma . JsonObject {
158+ lastScreeningDate : string | null ;
159+ }
160+
161+ async function derivePupilMatching ( user : User , pupil : Pupil , result : achievement_with_template [ ] , userAchievements : achievement_with_template [ ] ) {
162+ const hasRequest = pupil . openMatchRequestCount > 0 ;
163+ const successfulScreenings = await prisma . pupil_screening . findMany ( {
164+ where : { pupilId : pupil . id , status : pupil_screening_status_enum . success , invalidated : false } ,
165+ orderBy : { createdAt : 'desc' } ,
166+ } ) ;
167+
168+ const newMatchAchievements = userAchievements . filter (
169+ ( row ) => row . template . group === PupilNewMatchGroup && row . template . groupOrder === PupilNewMatchGroupOrder
170+ ) ;
171+
172+ const ctx : PupilNewMatchGhostContext = {
173+ lastScreeningDate : null ,
174+ } ;
175+ if ( successfulScreenings . length > 0 ) {
176+ ctx . lastScreeningDate = successfulScreenings [ 0 ] . updatedAt . toISOString ( ) ;
177+ }
178+ for ( let i = 0 ; i < pupil . openMatchRequestCount ; i ++ ) {
179+ const ghosts = await generatePupilMatching ( null , user , hasRequest , successfulScreenings . length > 0 , ctx ) ;
180+ result . push ( ...ghosts ) ;
181+ }
182+
183+ for ( const userAchievement of newMatchAchievements ) {
184+ const ghosts = await generatePupilMatching ( userAchievement , user , hasRequest , successfulScreenings . length > 0 , ctx ) ;
185+ result . push ( ...ghosts ) ;
186+ }
156187}
0 commit comments