Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom-dependency-tree.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/ai/elimu/entity/analytics/AssessmentEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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.
* E.g. <code>ai.elimu.soundcards</code>.
*/
@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:
* <pre>
* {'word_ids_presented': [1,2,3], 'word_id_selected': 2}
* </pre>
*/
@Column(length = 1024)
private String additionalData;
}
Original file line number Diff line number Diff line change
@@ -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. <code>["s", "h"]</code>.
*/
private String[] letterSoundLetters;

/**
* The sequence of sounds (IPA values). E.g. <code>["ʃ"]</code>.
*/
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;
Comment on lines +29 to +32
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation constraint for mastery score range.

The JavaDoc specifies a range [0.0, 1.0] but there's no validation to enforce this constraint.

+import jakarta.validation.constraints.DecimalMax;
+import jakarta.validation.constraints.DecimalMin;

 /**
  * A value in the range [0.0, 1.0].
  */
+@DecimalMin(value = "0.0", message = "Mastery score must be between 0.0 and 1.0")
+@DecimalMax(value = "1.0", message = "Mastery score must be between 0.0 and 1.0")
 private Float masteryScore;
🤖 Prompt for AI Agents
In src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java
around lines 29 to 32, the masteryScore field has a JavaDoc specifying it should
be in the range [0.0, 1.0], but no validation enforces this. Add a validation
annotation such as @DecimalMin("0.0") and @DecimalMax("1.0") to the masteryScore
field to ensure the value stays within the specified range.


/**
* The number of milliseconds passed between the student opening the assessment task
* and submitting a response. E.g. <code>15000</code>.
*/
private Long timeSpentMs;
Comment on lines +34 to +38
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for time measurement.

Consider adding validation to ensure timeSpentMs is non-negative, as negative time values wouldn't make sense for assessment duration.

+import jakarta.validation.constraints.Min;

 /**
  * The number of milliseconds passed between the student opening the assessment task 
  * and submitting a response. E.g. <code>15000</code>.
  */
+@Min(value = 0, message = "Time spent must be non-negative")
 private Long timeSpentMs;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/java/ai/elimu/entity/analytics/LetterSoundAssessmentEvent.java
around lines 34 to 38, add validation to ensure the timeSpentMs field is never
set to a negative value. Implement a check in the setter method or wherever
timeSpentMs is assigned to throw an exception or reject values less than zero,
enforcing that the assessment duration is always non-negative.

}
22 changes: 22 additions & 0 deletions src/main/resources/META-INF/jpa-schema-export.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Comment thread
coderabbitai[bot] marked this conversation as resolved.

create table LetterSoundContributionEvent (
id bigint not null auto_increment,
comment text,
Expand Down Expand Up @@ -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)
Expand Down