From 93f04d2c3632066dea7e2e6c0bf4d7f02b6d4c38 Mon Sep 17 00:00:00 2001 From: "Jo G." <1451036+jo-elimu@users.noreply.github.com> Date: Sat, 24 May 2025 19:12:06 +0700 Subject: [PATCH 1/7] feat: assessment event #2191 --- pom-dependency-tree.txt | 2 +- .../entity/analytics/AssessmentEvent.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java diff --git a/pom-dependency-tree.txt b/pom-dependency-tree.txt index a72ca2ca8..ca2c41403 100644 --- a/pom-dependency-tree.txt +++ b/pom-dependency-tree.txt @@ -1,4 +1,4 @@ -ai.elimu:webapp:war:2.6.15-SNAPSHOT +ai.elimu:webapp:war:2.6.16-SNAPSHOT +- ai.elimu:model:jar:model-2.0.97:compile | \- com.google.code.gson:gson:jar:2.13.0:compile | \- com.google.errorprone:error_prone_annotations:jar:2.37.0:compile diff --git a/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java b/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java new file mode 100644 index 000000000..e4807474d --- /dev/null +++ b/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java @@ -0,0 +1,52 @@ +package ai.elimu.entity.analytics; + +import ai.elimu.entity.BaseEntity; +import ai.elimu.entity.application.Application; +import jakarta.persistence.Column; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; +import jakarta.validation.constraints.NotNull; +import java.util.Calendar; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@MappedSuperclass +public abstract class AssessmentEvent extends BaseEntity { + + @NotNull + @Temporal(TemporalType.TIMESTAMP) + private Calendar timestamp; + + /** + * See https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID + */ + @NotNull + private String androidId; + + /** + * The package name of the {@link #application} where the assessment event occurred. + */ + @NotNull + private String packageName; + + /** + * This field will only be populated if a corresponding {@link Application} can be found in the database for the {@link #packageName}. + */ + @ManyToOne + private Application application; + + /** + * Any additional data should be stored in the format of a JSON object. + * + * Example: + *
+ * {'word_ids_presented': [1,2,3], 'word_id_selected': 2}
+ *
+ */
+ @Column(length = 1024)
+ private String additionalData;
+}
From 6a53986a345a7338233eeab560ee2ddb48d058ec Mon Sep 17 00:00:00 2001
From: "Jo G." <1451036+jo-elimu@users.noreply.github.com>
Date: Sat, 24 May 2025 19:38:58 +0700
Subject: [PATCH 2/7] feat: letter-sound assessment event
#2191
---
.../entity/analytics/AssessmentEvent.java | 4 +-
.../analytics/LetterSoundAssessmentEvent.java | 39 +++++++++++++++++++
.../resources/META-INF/jpa-schema-export.sql | 22 +++++++++++
3 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java
diff --git a/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java b/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java
index e4807474d..d9fbc1fca 100644
--- a/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java
+++ b/src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java
@@ -29,12 +29,14 @@ public abstract class AssessmentEvent extends BaseEntity {
/**
* The package name of the {@link #application} where the assessment event occurred.
+ * E.g. ai.elimu.soundcards.
*/
@NotNull
private String packageName;
/**
- * This field will only be populated if a corresponding {@link Application} can be found in the database for the {@link #packageName}.
+ * This field will only be populated if a corresponding {@link Application} can be
+ * found in the database for the {@link #packageName}.
*/
@ManyToOne
private Application application;
diff --git a/src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java b/src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java
new file mode 100644
index 000000000..d7690fb91
--- /dev/null
+++ b/src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java
@@ -0,0 +1,39 @@
+package ai.elimu.entity.analytics;
+
+import jakarta.persistence.Entity;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Entity
+public class LetterSoundAssessmentEvent extends AssessmentEvent {
+
+ /**
+ * The sequence of letters. E.g. ["s", "h"].
+ */
+ private String[] letterSoundLetters;
+
+ /**
+ * The sequence of sounds (IPA values). E.g. ["ʃ"].
+ */
+ private String [] letterSoundSounds;
+
+ /**
+ * This field might not be included, e.g. if the assessment task was done in a
+ * 3rd-party app that did not load the content from the elimu.ai Content Provider.
+ * In this case, the {@link #letterSoundId} will be {@code null}.
+ */
+ private Long letterSoundId;
+
+ /**
+ * A value in the range [0.0, 1.0].
+ */
+ private Float masteryScore;
+
+ /**
+ * The number of milliseconds passed between the student opening the assessment task
+ * and submitting a response. E.g. 15000.
+ */
+ private Long timeSpentMs;
+}
diff --git a/src/main/resources/META-INF/jpa-schema-export.sql b/src/main/resources/META-INF/jpa-schema-export.sql
index 96cf69fae..7439d5a00 100644
--- a/src/main/resources/META-INF/jpa-schema-export.sql
+++ b/src/main/resources/META-INF/jpa-schema-export.sql
@@ -43,6 +43,8 @@
drop table if exists LetterSound_Sound;
+ drop table if exists LetterSoundAssessmentEvent;
+
drop table if exists LetterSoundContributionEvent;
drop table if exists LetterSoundLearningEvent;
@@ -304,6 +306,21 @@
primary key (LetterSound_id, sounds_ORDER)
) type=MyISAM;
+ create table LetterSoundAssessmentEvent (
+ id bigint not null auto_increment,
+ additionalData text,
+ androidId varchar(255),
+ packageName varchar(255),
+ timestamp datetime,
+ letterSoundId bigint,
+ letterSoundLetters varbinary(255),
+ letterSoundSounds varbinary(255),
+ masteryScore float(23),
+ timeSpentMs bigint,
+ application_id bigint,
+ primary key (id)
+ ) type=MyISAM;
+
create table LetterSoundContributionEvent (
id bigint not null auto_increment,
comment text,
@@ -755,6 +772,11 @@
foreign key (LetterSound_id)
references LetterSound (id);
+ alter table LetterSoundAssessmentEvent
+ add constraint FKehf1rjbixnmdjol91didaj4b5
+ foreign key (application_id)
+ references Application (id);
+
alter table LetterSoundContributionEvent
add constraint FK5uk320agfa13pvh52v6n6ncbs
foreign key (contributor_id)
From 27de0847b31ebd4246b47491cb1414b976afd9ba Mon Sep 17 00:00:00 2001
From: "Jo G." <1451036+jo-elimu@users.noreply.github.com>
Date: Mon, 26 May 2025 19:24:10 +0700
Subject: [PATCH 3/7] feat: letter-sound assessment events - dao
#2191
---
.../java/ai/elimu/dao/LetterSoundAssessmentEventDao.java | 8 ++++++++
.../elimu/dao/jpa/LetterSoundAssessmentEventDaoJpa.java | 9 +++++++++
.../elimu/web/analytics/students/StudentController.java | 8 ++++++++
.../webapp/WEB-INF/spring/applicationContext-jpa.xml | 1 +
4 files changed, 26 insertions(+)
create mode 100644 src/main/java/ai/elimu/dao/LetterSoundAssessmentEventDao.java
create mode 100644 src/main/java/ai/elimu/dao/jpa/LetterSoundAssessmentEventDaoJpa.java
diff --git a/src/main/java/ai/elimu/dao/LetterSoundAssessmentEventDao.java b/src/main/java/ai/elimu/dao/LetterSoundAssessmentEventDao.java
new file mode 100644
index 000000000..daa2b0173
--- /dev/null
+++ b/src/main/java/ai/elimu/dao/LetterSoundAssessmentEventDao.java
@@ -0,0 +1,8 @@
+package ai.elimu.dao;
+
+import ai.elimu.entity.analytics.LetterSoundAssessmentEvent;
+
+public interface LetterSoundAssessmentEventDao extends GenericDao${student.androidId}Student ID
+ #${student.id}Android ID
+${student.androidId}
+ | Skill | ++ | Mastery | + + +
|---|---|---|
| + ${literacySkill} + | ++ 0% + | +
+
+
+
+ |
+
| Skill | ++ | Mastery | + + +
|---|---|---|
| + ${numeracySkill} + | ++ 0% + | +
+
+
+
+ |
+