Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP identify suspected cheaters #1249

Merged
merged 34 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a8515d1
add migration files for the feature
george-misan Mar 12, 2024
a693be6
[cheater-feature]: update migration files
george-misan Apr 4, 2024
43998a5
[cheater-feature]: update migration files
george-misan Apr 4, 2024
d40c2f8
[cheater-feature]: update migration files
george-misan Apr 4, 2024
c66b946
[cheater-feature]: update migration files
george-misan Apr 4, 2024
3341d1d
[cheater-feature]: update migration files
george-misan Apr 4, 2024
fce9ec2
[cheater-feature]: update migration files
george-misan Apr 4, 2024
ceb852b
[cheater-feature]: update migration files
george-misan Apr 4, 2024
818e1a7
[cheater-feature]: update migration files
george-misan Apr 4, 2024
7cc7d8a
[cheater-feature]: update migration files
george-misan Apr 4, 2024
5047e7f
[cheater-feature]: update migration files
george-misan Apr 4, 2024
5fedc99
[cheater-feature]: update migration files
george-misan Apr 4, 2024
45d75aa
[migration-task]: merge migration into one file
george-misan Apr 4, 2024
d5d9b03
[cheater-feature]: WIP
george-misan Apr 8, 2024
7d58e6d
[cheater-feature]: add cheater_thresholds TABLE
george-misan Apr 9, 2024
e1f3df0
[cheater-feature]: add cheater_thresholds TABLE
george-misan Apr 9, 2024
1cdb94f
stash commit
george-misan Apr 15, 2024
bd6cac2
[cheater-feature]: add function to get total points of student in a c…
george-misan Apr 18, 2024
ff943d9
[cheater-feature]: add function to get total points of student in a c…
george-misan Apr 18, 2024
c74b4b2
[lint-job]: remove unused import
george-misan Apr 21, 2024
7a553e0
[cheater-feature]: add files
george-misan Apr 21, 2024
c3c3420
[cheater-feature]: generate bindings
george-misan Apr 21, 2024
d1a3240
[cheater-feature]: add suspected-cheaters route
george-misan Apr 21, 2024
9101911
[cheater-feature]: update insert route for suspected-cheaters
george-misan Apr 24, 2024
72ef938
[migration-job]: run migration
george-misan Apr 24, 2024
82d5b25
[cleanup]: update and test suspected -cheaters route
george-misan Apr 25, 2024
ef89e6c
[cheater-feature]: update suspected-cheaters route to use average dur…
george-misan Apr 26, 2024
7774e55
[cheater-feature]: update suspected-cheaters route to use average dur…
george-misan Apr 26, 2024
0faa462
[cheater-feature]: update suspected-cheaters route to use average dur…
george-misan Apr 26, 2024
d1ccf99
[migration-job]: update migaration file
george-misan Apr 27, 2024
fae2fdc
[cleanup]: remove unused code
george-misan Apr 27, 2024
387fbad
[cleanup]: remove unused code
george-misan Apr 27, 2024
6c7b340
[cleanup]: remove redundant commment
george-misan Apr 27, 2024
f7d499b
[code-review]: update migration & insert_suspected_cheaters route
george-misan May 7, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TABLE suspected_cheaters;
DROP TABLE cheater_thresholds;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
CREATE TABLE suspected_cheaters (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES users,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
george-misan marked this conversation as resolved.
Show resolved Hide resolved
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
deleted_at TIMESTAMP WITH TIME ZONE,
total_duration_seconds INTEGER,
total_points INTEGER NOT NULL
);
CREATE TRIGGER set_timestamp BEFORE
UPDATE ON suspected_cheaters FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp();
-- The suspected_cheaters table is a that contains a student that are suspected of cheating because they meet the cheating requirement (i.e. score > threshold && duration > average_duration)
Copy link
Member

Choose a reason for hiding this comment

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

include in the comment on table

COMMENT ON TABLE suspected_cheaters IS 'This table stores data regarding student that are suspected of cheating in a course instance.';
COMMENT ON COLUMN suspected_cheaters.id IS 'A unique, stable identifier for the record.';
COMMENT ON COLUMN suspected_cheaters.user_id IS 'The user_id of the student being suspected.';
COMMENT ON COLUMN suspected_cheaters.created_at IS 'Timestamp when the record was created.';
COMMENT ON COLUMN suspected_cheaters.updated_at IS 'Timestamp when the record was updated.';
COMMENT ON COLUMN suspected_cheaters.deleted_at IS 'Timestamp when the record was deleted. If null, the record is not deleted.';
COMMENT ON COLUMN suspected_cheaters.total_duration_seconds IS 'The total duration the student spent completing the course.';
COMMENT ON COLUMN suspected_cheaters.total_points IS 'The total points earned by the student in the course.';
-- The cheater_thresholds table contains thresholds set by the instructor, representing the maximum score or duration a student can surpass before being suspected of cheating.
CREATE TABLE cheater_thresholds (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
course_instance_id UUID NOT NULL REFERENCES course_instances,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
deleted_at TIMESTAMP WITH TIME ZONE,
points INTEGER NOT NULL,
duration_seconds INTEGER
);
CREATE TRIGGER set_timestamp BEFORE
UPDATE ON cheater_thresholds FOR EACH ROW EXECUTE PROCEDURE trigger_set_timestamp();
COMMENT ON TABLE cheater_thresholds IS 'This table stores thresholds set by the instructor, representing the maximum score or duration a student can surpass before being suspected of cheating cheaters.';
COMMENT ON COLUMN cheater_thresholds.id IS 'A unique, stable identifier for the record.';
COMMENT ON COLUMN cheater_thresholds.course_instance_id IS 'The course_instance_id of the course.';
COMMENT ON COLUMN cheater_thresholds.created_at IS 'Timestamp when the record was created.';
COMMENT ON COLUMN cheater_thresholds.updated_at IS 'Timestamp when the record was updated.';
COMMENT ON COLUMN cheater_thresholds.deleted_at IS 'Timestamp when the record was deleted. If null, the record is not deleted.';
COMMENT ON COLUMN cheater_thresholds.points IS 'The score threshold of the course.';
COMMENT ON COLUMN cheater_thresholds.duration_seconds IS 'The duration threshold of the course.';

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions services/headless-lms/models/src/course_instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,54 @@ WHERE user_id = $1
Ok(())
}

pub async fn get_course_average_duration(
conn: &mut PgConnection,
course_instance_id: Uuid,
) -> ModelResult<Option<i64>> {
let res = sqlx::query!(
"
SELECT
AVG(EXTRACT(EPOCH FROM cmc.completion_date - ce.created_at))::int8 AS average_duration_seconds
FROM course_instance_enrollments ce
JOIN course_module_completions cmc ON cmc.course_instance_id = ce.course_instance_id
WHERE ce.course_instance_id = $1
AND ce.deleted_at IS NULL
AND cmc.deleted_at IS NULL;
",
course_instance_id
)
.fetch_one(conn)
.await?;

Ok(res.average_duration_seconds)
}

pub async fn get_student_duration(
conn: &mut PgConnection,
user_id: Uuid,
course_instance_id: Uuid,
) -> ModelResult<Option<i64>> {
let res = sqlx::query!(
"
SELECT
COALESCE(EXTRACT(EPOCH FROM cmc.completion_date - ce.created_at)::int8, 0) AS student_duration_seconds
FROM course_instance_enrollments ce
JOIN course_module_completions cmc ON cmc.course_instance_id = ce.course_instance_id
AND cmc.user_id = ce.user_id
WHERE ce.course_instance_id = $1
AND ce.user_id = $2
AND ce.deleted_at IS NULL
AND cmc.deleted_at IS NULL;
",
course_instance_id,
user_id
)
.fetch_one(conn)
.await?;

Ok(res.student_duration_seconds)
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
Loading
Loading