Education / Independent product
Keep students focused and answers recoverable.
An exam platform in development with locally retained answers, retry after reconnection, server-side attempt checks, and configurable exam-session monitoring.
- Project
- Ujianku
- My role
- Product and full-stack developer
- Scope
- Web and mobile exam experience, answer recovery, timed submission, grading, and session controls
- Built with
- Go, React, TypeScript, PostgreSQL, Flutter, Docker
- Period
- 2025–2026 · repository activity
- Project status
- In development
Engineering focus
Recover pending answers
The web runner retains pending answers locally and retries saving after reconnection, giving interrupted sessions a recovery path.
Check attempts on the server
Answer saves check the student, school-scoped attempt, active state, and deadline before updating the stored answer.
Handle expiry and session events
A server worker submits expired attempts; monitoring policies can warn or submit when configured violation limits are reached.
Independent product in development by Jufianto Henri. The diagram shows the implemented answer-save path; it is an explanatory overview, not a product screenshot or proof of production scale.
The inspected history runs from November 2025 to August 2026. These are repository dates, not a launch or client-delivery period. No production users, as confirmed by the owner in September 2026. This case study describes the current implementation.
Keep an interruption from becoming a lost answer
A timed exam asks students to concentrate while the application handles saving, reconnection, and the clock. Ujianku is my exam product in development, bringing a React web runner, Flutter mobile client, and Go backend together around those responsibilities.
In the web runner, pending answers are retained in browser storage. Saving is debounced, and the application attempts to flush pending changes when connectivity returns. The mobile client has its own local answer queue and retry path. This is the concrete work behind a smoother exam experience: treating a failed request as a recoverable state the application needs to handle.
Put exam rules behind the interface
The backend checks that an attempt belongs to the requesting student, is scoped to the school, is still in progress, and is within its allowed deadline. Stored answers use an upsert for the attempt and question, so a repeated save updates the current answer rather than creating another row.
The running exam also records session events such as tab switching. Configurable policies can warn the student or trigger submission. These are implemented integrity controls; browser event monitoring cannot establish that an exam is cheat-proof.
Close attempts even when the browser cannot
A background worker periodically finds expired attempts, submits them with a system-generated reason, and invokes automatic grading. It provides a server-side backstop when a student leaves a session open or the client cannot finish normally.
Answer saves go directly through the Go API to PostgreSQL. The browser keeps a recovery buffer for pending changes, while the worker handles expired attempts independently.
What a client can assess today
This work demonstrates how I approach stateful workflows: retain unfinished work, make deadlines enforceable on the server, and provide explicit recovery and review paths. It is relevant to exam products and other applications where an interrupted session should be recoverable.
Ujianku has no production users yet. The implementation and its test workflows are available for development review, but this case study makes no production concurrency or reliability claim. Separate load-test experiments are not customer outcomes.