@@ -5,13 +5,61 @@ import type { Insertable, Selectable, Updateable } from 'kysely'
55
66import type { DB , Usuario , CourseUsuario } from '@/db/db.d'
77
8+ const USD_TO_SLE_RATE = 22 ;
9+ const SLE_TO_SCORE_RATIO = 10 ;
10+
811interface CourseData {
912 [ key : number ] : number
1013}
1114
15+ /**
16+ * Adds a calculated learning score to a user's profile based on a donation amount.
17+ *
18+ * @param db The Kysely database instance.
19+ * @param userId The ID of the user to whom the score will be added.
20+ * @param donationAmountUSD The amount of the donation in USD.
21+ * @returns The new total learning score.
22+ */
23+ export async function addDonationToLearningScore (
24+ db : Kysely < DB > ,
25+ userId : string ,
26+ donationAmountUSD : number
27+ ) : Promise < number > {
28+ const scoreToAdd = ( donationAmountUSD * USD_TO_SLE_RATE ) / SLE_TO_SCORE_RATIO ;
29+
30+ // Round to 2 decimal places to avoid floating point inaccuracies
31+ const roundedScoreToAdd = Math . round ( scoreToAdd * 100 ) / 100 ;
32+
33+ const user = await db
34+ . selectFrom ( 'usuario' )
35+ . where ( 'id' , '=' , userId )
36+ . select ( 'learningscore' )
37+ . executeTakeFirst ( ) ;
38+
39+ if ( ! user ) {
40+ throw new Error ( `User with ID ${ userId } not found.` ) ;
41+ }
42+
43+ const currentScore = user . learningscore || 0 ;
44+ const newLearningScore = currentScore + roundedScoreToAdd ;
45+
46+ await db
47+ . updateTable ( 'usuario' )
48+ . set ( {
49+ learningscore : newLearningScore ,
50+ updated_at : new Date ( ) ,
51+ } )
52+ . where ( 'id' , '=' , userId )
53+ . execute ( ) ;
54+
55+ return newLearningScore ;
56+ }
57+
58+
1259/**
1360 * Calculates and updates all scores for a user, including global scores
1461 * and course-specific metrics, within a single database transaction.
62+ * This function now preserves the fractional part of the learning score (from donations).
1563 *
1664 * @param db - The Kysely database instance.
1765 * @param user - The user object, as selected from the database.
@@ -22,7 +70,9 @@ export async function updateUserAndCoursePoints(
2270 user : Selectable < Usuario > ,
2371 courseId : number | null ,
2472) : Promise < number > {
25- console . log ( "OJO updateUserAndCoursePoints. user=" , user )
73+ // Preserve the fractional part of the learning score, which comes from donations.
74+ const donationScore = ( user . learningscore || 0 ) % 1 ;
75+
2676 // Process each guide the user has answered
2777 const guidesUsuario = await sql < any > `
2878 SELECT *
@@ -32,13 +82,11 @@ export async function updateUserAndCoursePoints(
3282 WHERE guide_usuario.usuario_id = ${ user . id }
3383 ` . execute ( db )
3484
35- console . log ( "OJO guidesUsuario=" , guidesUsuario )
3685 const pointsGuidesCourse : CourseData = { }
3786 const earnedCourse : CourseData = { }
3887 const amountGuidesCourse : CourseData = { }
3988
4089 for ( const guideUsuario of guidesUsuario . rows ) {
41- console . log ( " OJO guideUsuario=" , guideUsuario )
4290 const courseId = guideUsuario . proyectofinanciero_id ;
4391 if ( pointsGuidesCourse [ courseId ] ==
4492 undefined ) {
@@ -65,14 +113,12 @@ export async function updateUserAndCoursePoints(
65113 }
66114 for ( const cId of courseIds ) {
67115 const currentCourseId = Number ( cId ) ;
68- console . log ( " OJO courseId=" , currentCourseId )
69116 const userCourse = ( await db
70117 . selectFrom ( 'course_usuario' )
71118 . where ( 'usuario_id' , '=' , user . id )
72119 . where ( 'proyectofinanciero_id' , '=' , currentCourseId )
73120 . selectAll ( )
74121 . execute ( ) ) || [ ]
75- console . log ( " OJO userCourse=" , userCourse )
76122 if ( userCourse . length == 0 ) {
77123 const cp : Insertable < CourseUsuario > = {
78124 usuario_id : user . id ,
@@ -82,23 +128,20 @@ export async function updateUserAndCoursePoints(
82128 amountscholarship : 0 ,
83129 percentagecompleted : 0 ,
84130 }
85- const icp = await db
131+ await db
86132 . insertInto ( 'course_usuario' )
87133 . values ( cp )
88134 . returningAll ( )
89135 . executeTakeFirstOrThrow ( )
90- console . log ( 'After insert icp=' , icp )
91136 }
92137 const courseGuidesCountResult = await db
93138 . selectFrom ( 'cor1440_gen_actividadpf' )
94139 . where ( 'proyectofinanciero_id' , '=' , currentCourseId )
95140 . select ( db . fn . countAll ( ) . as ( 'count' ) )
96141 . executeTakeFirst ( )
97142 const totalGuidesInCourse = Number ( courseGuidesCountResult ?. count ) || 0
98- console . log ( " OJO totalGuidesInCourse=" , totalGuidesInCourse )
99143 const percentd = totalGuidesInCourse > 0 ?
100144 ( ( amountGuidesCourse [ currentCourseId ] || 0 ) / totalGuidesInCourse ) * 100 : 0
101- console . log ( " OJO percentd=" , percentd )
102145
103146 const updateCourseUsuario = {
104147 guidespoints : pointsGuidesCourse [ currentCourseId ] || 0 ,
@@ -114,29 +157,30 @@ export async function updateUserAndCoursePoints(
114157 }
115158
116159
117- // 3. Calculate global Learning Score
160+ // 3. Calculate global Learning Score from courses and guides (the integer part)
118161 const totalGuidePointsResult = await db
119162 . selectFrom ( 'guide_usuario' )
120163 . where ( 'usuario_id' , '=' , user . id )
121164 . select ( db . fn . sum ( 'points' ) . as ( 'total_points' ) )
122165 . executeTakeFirst ( )
123166 const totalGuidePoints = Number ( totalGuidePointsResult ?. total_points ) || 0
124- console . log ( "OJO totalGuidePoints=" , totalGuidePoints )
125167
126168 const totalCoursePointsResult = await db
127169 . selectFrom ( 'course_usuario' )
128170 . where ( 'usuario_id' , '=' , user . id )
129171 . select ( db . fn . sum ( 'points' ) . as ( 'total_points' ) )
130172 . executeTakeFirst ( )
131173 const totalCoursePoints = Number ( totalCoursePointsResult ?. total_points ) || 0
132- console . log ( "OJO totalCoursePoints=" , totalCoursePoints )
133174
134- const learningscore = totalGuidePoints + totalCoursePoints
135- console . log ( "OJO learningscore=" , learningscore )
175+ // This is the score from educational activities
176+ const baseLearningscore = totalGuidePoints + totalCoursePoints
177+
178+ // Combine the base score with the preserved donation score
179+ const finalLearningscore = baseLearningscore + donationScore ;
136180
137181 // 4. Update the main usuario table
138182 const uUsuario : Updateable < Usuario > = {
139- learningscore : learningscore ,
183+ learningscore : finalLearningscore ,
140184 updated_at : new Date ( ) ,
141185 }
142186
@@ -145,5 +189,5 @@ export async function updateUserAndCoursePoints(
145189 . set ( uUsuario )
146190 . where ( 'id' , '=' , user . id ) . execute ( )
147191
148- return learningscore
192+ return finalLearningscore
149193}
0 commit comments