feat: implement structured grading system with predefined assessment types
- Add structured grading policy with predefined types (Continuous Assessment, Midterm, Final Test, Exam) - Replace free-text category input with combobox selection in Grading Policy page - Update Lesson Editor to use dropdown selector for grading category assignment - Fix create_grading_category handler to capture organization context - Fix update_course handler to set audit context in database transaction - Implement getImageUrl helper for proper asset path resolution - Add unoptimized prop to organization logo images to bypass Next.js optimization - Add database migrations for organization_id in content tables - Seed default tutorial courses for Admin, Instructor, and Student roles - Fix audit log constraints and content schema issues
This commit is contained in:
@@ -262,6 +262,22 @@ pub async fn update_course(
|
||||
.and_then(|s| s.parse::<DateTime<Utc>>().ok())
|
||||
.or(existing.end_date);
|
||||
|
||||
// BEGIN TRANSACTION
|
||||
let mut tx = pool
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
// Set auditing context
|
||||
sqlx::query(
|
||||
"SELECT set_config('app.current_user_id', $1, true), set_config('app.org_id', $2, true)",
|
||||
)
|
||||
.bind(claims.sub.to_string())
|
||||
.bind(org_ctx.id.to_string())
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
let course = sqlx::query_as::<_, Course>(
|
||||
"SELECT * FROM fn_update_course($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
)
|
||||
@@ -274,7 +290,7 @@ pub async fn update_course(
|
||||
.bind(start_date)
|
||||
.bind(end_date)
|
||||
.bind(certificate_template)
|
||||
.fetch_one(&pool)
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
(
|
||||
@@ -283,6 +299,10 @@ pub async fn update_course(
|
||||
)
|
||||
})?;
|
||||
|
||||
tx.commit()
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
Ok(Json(course))
|
||||
}
|
||||
|
||||
@@ -944,13 +964,15 @@ pub async fn get_grading_categories(
|
||||
|
||||
pub async fn create_grading_category(
|
||||
State(pool): State<PgPool>,
|
||||
Org(org_ctx): Org,
|
||||
Json(payload): Json<GradingPayload>,
|
||||
) -> Result<Json<common::models::GradingCategory>, (StatusCode, String)> {
|
||||
let category = sqlx::query_as::<_, common::models::GradingCategory>(
|
||||
"INSERT INTO grading_categories (course_id, name, weight, drop_count)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
"INSERT INTO grading_categories (organization_id, course_id, name, weight, drop_count)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING *",
|
||||
)
|
||||
.bind(org_ctx.id)
|
||||
.bind(payload.course_id)
|
||||
.bind(payload.name)
|
||||
.bind(payload.weight)
|
||||
|
||||
Reference in New Issue
Block a user