teacher-tools/api/source/api_modules/classroom_compliance/api_class.d

153 lines
5.0 KiB
D
Raw Permalink Normal View History

2025-01-23 17:10:32 +00:00
module api_modules.classroom_compliance.api_class;
import handy_httpd;
import ddbc;
import api_modules.classroom_compliance.model;
import api_modules.classroom_compliance.util;
import api_modules.auth : User, getUserOrThrow;
import db;
import data_utils;
void createClass(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
struct ClassPayload {
ushort number;
string schoolYear;
}
auto payload = readJsonPayload!(ClassPayload)(ctx);
const bool classNumberExists = recordExists(
conn,
"SELECT id FROM classroom_compliance_class WHERE number = ? AND school_year = ? AND user_id = ?",
payload.number, payload.schoolYear, user.id
);
if (classNumberExists) {
ctx.response.status = HttpStatus.BAD_REQUEST;
ctx.response.writeBodyString("There is already a class with this number, for the same school year.");
return;
}
ulong classId = insertOne(
conn,
"INSERT INTO classroom_compliance_class (number, school_year, user_id) VALUES (?, ?, ?) RETURNING id",
payload.number, payload.schoolYear, user.id
);
auto newClass = findOne(
conn,
"SELECT * FROM classroom_compliance_class WHERE id = ? AND user_id = ?",
&ClassroomComplianceClass.parse,
classId, user.id
).orElseThrow();
writeJsonBody(ctx, newClass);
}
void getClasses(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
const query = "
SELECT
c.id, c.number, c.school_year,
COUNT(DISTINCT s.id) AS student_count,
COUNT(DISTINCT e.id) AS entry_count,
MAX(e.date) AS last_entry_date
FROM classroom_compliance_class c
LEFT JOIN classroom_compliance_student s ON c.id = s.class_id
LEFT JOIN classroom_compliance_entry e ON c.id = e.class_id
WHERE c.user_id = ?
GROUP BY c.id
ORDER BY school_year DESC, number ASC
";
struct ClassResponse {
ulong id;
ushort number;
string schoolYear;
uint studentCount;
uint entryCount;
string lastEntryDate;
}
ClassResponse[] classes = findAll(
2025-01-23 17:10:32 +00:00
conn,
query,
r => ClassResponse(
r.getUlong(1),
r.getUshort(2),
r.getString(3),
r.getUint(4),
r.getUint(5),
r.getDate(6).toISOExtString()
),
2025-01-23 17:10:32 +00:00
user.id
);
writeJsonBody(ctx, classes);
}
void getClass(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
writeJsonBody(ctx, cls);
}
void deleteClass(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
const query = "DELETE FROM classroom_compliance_class WHERE id = ? AND user_id = ?";
PreparedStatement ps = conn.prepareStatement(query);
scope(exit) ps.close();
ps.setUlong(1, cls.id);
ps.setUlong(2, user.id);
ps.executeUpdate();
}
2025-01-30 15:23:25 +00:00
void getClassNotes(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
const query = "SELECT * FROM classroom_compliance_class_note WHERE class_id = ? ORDER BY created_at DESC";
const notes = findAll(conn, query, &ClassroomComplianceClassNote.parse, cls.id);
writeJsonBody(ctx, notes);
}
void createClassNote(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
struct Payload {string content;}
Payload payload = readJsonPayload!(Payload)(ctx);
const query = "INSERT INTO classroom_compliance_class_note (class_id, content) VALUES (?, ?) RETURNING id";
ulong id = insertOne(conn, query, cls.id, payload.content);
const note = findOne(
conn,
"SELECT * FROM classroom_compliance_class_note WHERE id = ?",
&ClassroomComplianceClassNote.parse,
id
);
writeJsonBody(ctx, note);
}
void deleteClassNote(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
ulong noteId = ctx.request.getPathParamAs!ulong("noteId");
const query = "DELETE FROM classroom_compliance_class_note WHERE class_id = ? AND id = ?";
update(conn, query, cls.id, noteId);
}
void resetStudentDesks(ref HttpRequestContext ctx) {
Connection conn = getDb();
scope(exit) conn.close();
User user = getUserOrThrow(ctx, conn);
auto cls = getClassOrThrow(ctx, conn, user);
const query = "UPDATE classroom_compliance_student SET desk_number = 0 WHERE class_id = ?";
update(conn, query, cls.id);
}