This update adds S3 management APIs for viewing storage usage, listing cached answer sheets and score sheets, and deleting stored files.
Exam results now have an all-scores API with pagination, filtering, search, and sorting. Score sheet export uses the VIEW_EXAM_DATA permission, with SCHOOL users limited to their own school.
Administrators can now publish exams locally for individual schools before ZhiXue officially releases them. Students can access their own results when their scores are already stored. Score retrieval also handles missing totals and rankings while marking is still in progress.
Answer sheets now show subquestion scores, step scores, and teacher scoring records more clearly, with improved indentation and positioning.
The backend now requires Python 3.11 and uses psycopg 3. Dependencies were upgraded, and a database migration was added for per-school exam publication status.
Recently, on the backend, I added support for customizing the “from-address” for the SMTP service, rather than using the SMTP username directly as the sender’s email address as before.
Additionally, to make the project more robust, I added support for S3 storage on the backend to store the generated answer sheets and score sheets, replacing the original local file system cache. Administrators can freely choose between the two options via environment variables.
On the frontend, I first synchronized the changes related to the backend’s S3 storage support, then updated the loading animation to feature a logo that gradually changes in size as the central element, accompanied by a circular animation, replacing the previous simple Lucide React icon.
Next, I will implement management features for S3 storage and synchronize the changes across both the front end and backend.
This update fixes how the backend handles school_id in multi-school exam scenarios. Previously, some score and answersheet APIs accepted school_id from the client and used it during score lookup or teacher account selection. In multi-school exams, that could allow a SCHOOL-level user to query data outside their own school if the request parameters were crafted manually.
The score and answer sheet APIs now resolve the effective student and school context on the server first. SELF users are always limited to their own bound student account, and any client-provided student_id, student_name, or school_id is ignored. SCHOOL users are always limited to their own school, even if another school_id is provided. GLOBAL users can still use school_id as an optional filter.
Student name based lookup no longer requires school_id. The backend searches within the current user’s accessible scope. If multiple students match the same name, the error message now includes both school and class information for disambiguation.
Score sheet export was also tightened. SCHOOL users always export their own school’s data, and any provided school_id is ignored. GLOBAL users can still export all schools or a specific school.
Since this is just a backend fix related to permissions, I can only provide screenshots of the code I modified.
In this update, I added a feature to the front end that remembers the user’s selection in this dropdown menu.
In addition, I added a button to the exam details page so that users with the appropriate permissions can view more data about the exam directly in the “Data View” tab without having to copy and paste the exam_id.
I fixed two race conditions caused by data desynchronization on the back end and manually cleaned up two rows of corrupted data from the prod database.