HackMolFinalRepo: The Railway Complaint System That Turns Text Into Triage

A MERN-plus-Python stack uses a fine-tuned small model to sort passenger grievances by urgency, surface the worst problems first, and make public-service queues feel less blind.

7 to 8 min read • View on GitHub • More from pbcool05

A long conveyor belt carries handwritten railway complaint slips into a sorting room where a central triage desk separates urgent cases from routine ones. The scene explains the project’s core idea: complaints are not just collected, they are ranked so the most serious issues move first.
The project treats grievance handling less like a inbox and more like a sorting system for urgency.
Key Takeaways

When every complaint is not equal

Most complaint portals make one quiet assumption: first in, first out. That works for a support inbox. It fails for public services, where a broken seat, a missing ticket, and a safety issue do not deserve the same place in line.

HackMolFinalRepo starts from a better question: what needs help first? That shift turns the project from a standard grievance app into a triage machine, where the system helps decide which complaints deserve attention before a human ever opens the queue.

What HackMolFinalRepo actually does

The flow is straightforward. A passenger submits a complaint through the web app. The backend stores it in MongoDB, the AI layer scores its urgency, and the admin view pulls the updated record back into a color-coded queue.

That gives the project two jobs at once. It is both a complaint intake system and a railway-specific assistant, with a chatbot layer for general queries and a prioritization layer for operational action.

The loop is the product: complaint in, priority out, dashboard updated, human action next.

Passenger complaint -> Express validation -> MongoDB insert
                        -> Python inference -> priority score
                        -> MongoDB update -> admin dashboard refresh

The triage engine inside the repo

The most interesting part of the repo is the scoring path. Complaints are fetched from MongoDB, passed into an inference function, and written back with a numeric priority from 0 to 5. That is the moment the system stops being a form and starts behaving like an operations tool.

The model stack is pragmatic rather than luxurious. The repo uses Unsloth to fine-tune Phi-3.5-mini-instruct, with LoRA targeting attention modules like q_proj and v_proj. The point is not maximal model size. It is getting useful classification behavior out of constrained compute.

That matters because the project is not trying to be a general chatbot platform. It is trying to classify messy grievance text with enough reliability that the queue order becomes more meaningful than a plain timestamp.

Two linked workbenches show the project’s split architecture. On the left, a Node.js desk manages forms, authentication stamps, and MongoDB drawers. On the right, a Python bench runs a compact model that writes a priority score onto a clipboard. A narrow bridge carries complaint text between them.
The architecture is split on purpose: web plumbing on one side, inference on the other.

Why the stack is split across Node and Python

This repo uses a sidecar pattern in the most practical sense. Node and Express handle authentication, CRUD, and the app shell. Python handles the AI work, including the chatbot and the priority inference. The split keeps each layer in the ecosystem that fits it best.

That is a real engineering choice, not just a stylistic one. JavaScript owns the user-facing product path. Python owns the model path. MongoDB sits in the middle as the shared state that both sides can read and update.

DimensionTraditional complaint portalHackMolFinalRepo
Handling modelStore and display submissionsScore urgency and reorder work
Ordering logicChronological queuePriority-ranked queue
Human effortOperators scan everythingOperators scan the worst items first
AI involvementNoneClassification and chatbot support
Operational riskImportant issues can hide in the pileModel mistakes can mis-rank cases
Scale trade-offSimple but blindSmarter, but more moving parts

The admin dashboard turns scores into action

The dashboard is where the model becomes visible. The repo polls for updates every 10 seconds, then maps the numeric score to color with a function like getPriorityColor. Suddenly the system is no longer just storing complaints. It is turning them into a heat map of urgency.

That small design choice matters. A triage score is only useful if the person on the other end can read it in seconds. The dashboard gives the project its operational face.

The trade-off: speed now, heavy baggage later

HackMolFinalRepo also shows its seams. Images are converted to Base64 before submission, which keeps the stack simple but makes payloads heavier. The backend sets a 10 MB document limit, which is a reminder that convenience and scale pull in opposite directions.

The repo also feels like a hackathon build in the best and worst ways. It is ambitious, functional, and coherent. It is also not the same thing as production hardened.

Trade-offWhat the repo gainsWhat it pays
Base64 uploadsNo separate file pipelineLarger payloads and bulkier documents
Polling dashboardSimple refresh logicExtra load and delayed updates
Small fine-tuned modelLower compute needsPossible ceiling on accuracy
Split Node plus Python stackRight tool for each layerMore integration and deployment complexity

What this project says about modern civic software

The larger idea here is easy to miss: public-service software does not have to be a passive inbox. It can rank, route, and surface urgency before a human triages the queue.

That is the promise of this repo. Not that AI replaces operators, but that it gives them a better first pass. The open question is whether the model is trustworthy enough for real civic use. The code points to the possibility. The deployment story would need to prove it.