By Gaurav Kumar | Dogfood 2026
A hackathon platform looks simple at first: organizers create events, participants submit projects, and judges assign scores.
But building a reliable platform means thinking beyond the happy path.
I built Dogfood Platform as a self-hostable submission and judging system for Dogfood 2026. The platform brings together team formation, project submissions, judge assignments, weighted rubrics, score normalization, community voting, audit trails, and certificates.
The biggest lesson I learned is that implementing features is only one part of engineering. Making those features predictable, secure, and testable is the harder part.
Project repository: https://github.com/gauravkvbrss6558-spec/dogfood-platform
1. The architecture decision that shaped everything
I chose Next.js for the application, PostgreSQL for relational data, Prisma for database access, and Docker Compose to bring the application and database together.
The goal was to make the platform easier to run and evaluate without requiring a complicated collection of separately deployed services.
A single application reduces infrastructure complexity. A developer can focus on the product instead of spending too much time connecting multiple services before testing the main workflows.
Of course, this approach has trade-offs. A simpler deployment does not automatically guarantee scalability. Database performance, authorization, and concurrent requests still need careful attention.
My takeaway: choose an architecture that solves the project's actual requirements instead of adding complexity just because a technology is popular.
2. The Docker lesson: starting is not the same as reproducing
A container starting successfully does not automatically mean the entire testing environment is reproducible.
One detail worth handling carefully is generated test data. When a fresh database seed creates new identifiers or session tokens, an old test configuration may no longer match the current environment.
That means developers need to distinguish between two questions:
- Does the application start?
- Can the application be tested reliably from a clean environment?
A reproducible setup should explain how the database is initialized, how test sessions are obtained, and how acceptance checks run against the current environment.
For a self-hosted platform, reproducibility is part of the product, not just a developer convenience.
This is also an area where I would keep improving automated setup checks, because a project should be easy for another developer to run without relying on undocumented local state.
3. Making judging more consistent
Judging is one of the most interesting engineering problems in a hackathon platform.
Imagine two judges evaluating the same projects. One regularly gives scores between 8 and 10, while another gives scores between 4 and 7.
A simple average treats these scoring styles as directly comparable, even though the judges may have different scoring habits.
The platform uses weighted criteria and per-judge z-score normalization to address differences in scoring patterns.
The formula is:
z = (x - mean) / standard deviation
Here, x is a score, while the mean and standard deviation are calculated from that judge's scores.
There is an important edge case: what happens if a judge gives every project exactly the same score?
The standard deviation becomes zero, so the usual formula cannot be applied directly. The implementation handles zero variance explicitly by assigning a neutral normalized score rather than dividing by zero.
This matters because an algorithm should remain well-defined even when real-world data does not match the ideal case.
Normalization does not eliminate every form of bias, and it should not be presented as a guarantee of perfect fairness. Its value is that the method is explicit, explainable, and testable.
The broader lesson is simple: when an algorithm influences rankings, edge cases are part of the design, not something to handle later.
4. Permissions are more than hidden buttons
A user might organize one event, judge another, and participate in a third. A single global role cannot accurately describe every event-specific relationship.
The platform distinguishes general user roles from event-specific judging assignments.
Another important principle is that hiding a button in the frontend is not sufficient security. The server must verify whether the requester is authorized to perform an action.
The same applies to submission deadlines. A disabled submit button improves the interface, but the server must enforce the deadline too.
These checks are easy to underestimate when building a prototype. They become essential when multiple people use the platform with different permissions.
A reliable application must consider both the expected user journey and the requests a user should never be allowed to make.
5. Community voting and fair exposure
Community voting introduces another challenge: projects shown first may attract more attention simply because people see them first.
The platform uses a rating-based voting approach and randomized gallery ordering to reduce dependence on a fixed display order.
Duplicate-vote prevention and suspicious voting patterns also need careful handling.
For example, several genuine participants may share the same public IP address at a university or hackathon venue. An IP address alone should not be treated as definitive proof of abuse.
The lesson is to design abuse prevention around realistic user behavior while giving organizers a way to investigate suspicious cases.
Fairness is not just about the final score. It also involves how people discover projects and how the system handles unusual activity.
6. What I would test more aggressively
A successful happy-path test is not proof that the entire platform is correct.
I would prioritize automated tests for these scenarios:
- A judge attempts to access another judge's assignment.
- A participant tries to submit after the deadline.
- A judge assigns identical scores to every submission.
- A fresh Docker startup generates new database identifiers.
- Two requests attempt to create conflicting team memberships.
- A voting pattern looks suspicious but may involve legitimate users sharing a network.
Each scenario tests a different assumption.
Together, they provide a more useful picture of reliability than simply checking whether the home page loads.
I would also continue improving observability so that organizers can understand why an action was rejected, why a score was calculated a certain way, and which cases require human review.
7. What I learned
Three lessons stand out from building Dogfood Platform.
First, simple deployment is an architectural advantage.
A project becomes easier to evaluate when its setup is reproducible and its infrastructure requirements are understandable.
Second, edge cases are part of the feature.
Permissions, deadlines, duplicate requests, and zero-variance scores deserve the same attention as the main user interface.
Third, explainability matters when software influences decisions.
A judging formula should be understandable, testable, and open to scrutiny. Organizers should be able to reason about the result instead of blindly trusting a number.
The question I want to keep asking is not only:
"Does this feature work?"
It is:
"Under what conditions could this feature stop being trustworthy, and how can I test those conditions?"
That is the engineering challenge I found most valuable while building Dogfood Platform.
I built this project to explore what it takes to make hackathon submissions and judging more structured, transparent, and reproducible. There is always more to test and improve, but documenting the assumptions and edge cases is an important part of that process.
Explore the project: https://github.com/gauravkvbrss6558-spec/dogfood-platform
Top comments (0)