Skip to content

CRITICAL: participant submission flow is disconnected from the real judging engine (stub writes to legacy exercise_team, never judged) #22

Description

@matbrgz

Summary

The application ships two entirely disconnected data models and code paths for contests/problems/submissions. The legacy one is wired to every screen a user actually clicks; the real, BOCA-compatible one (with a working auto-judge service) is only reachable through the JSON API and has no UI at all. As a result, a contestant cannot get a real judged submission through the web app today — the visible "Submit" flow is a non-functional stub.

This is the most important finding of the BOCA-parity audit: schema-level parity is high (see prior audit / issues #18-#21), but the wired, user-facing system does not actually execute a judged run end-to-end.

Evidence — legacy path (wired to every screen)

  • Contest creation: /wizard and the "Nova Maratona" button under Configurações are handled by Backend\ContestWizardController and inline closures in routes/web.php (around line 249, 274, 283, 310) that all read/write the hackathons table (DB::table('hackathons')...), a leftover from the original 2017 migration (2017_06_17_011431_create_hackathons_table). This table has no relationship to sites, languages, answers, or problems at all.
  • Problem management: "Gerenciar Problemas" (/backend/exercises) and the participant-facing "Problemas" list (/exercises, App\Http\Controllers\ExerciseController) both read/write the exercises table (exerciseName, category, difficulty, score, expectedOutcome — see routes/web.php lines 153-171 and app/Http/Controllers/ExerciseController.php). This table has no time/memory limits, no test cases, no language bindings — nothing an auto-judge could use.
  • Submission: GET/POST /submit/{id} (routes/web.php lines 39-63) is a stub — the POST handler's own comment says "This would integrate with the auto-judge system" and then just does:
    DB::table('exercise_team')->insert([... 'result' => 'pending', ...]);
    It never creates a runs row, never calls AutoJudgeService, and nothing ever updates that 'pending' result — the submission is judged never.

Evidence — real BOCA-compatible engine (API-only, no UI reaches it)

  • contests, sites, languages, answers, problems, test_cases, runs, clarifications, tasks, backups, logs, scores — the full 2025-11-25 migration set — model BOCA closely and are used consistently by App\Http\Controllers\SubmissionController (joins runs → problems/answers/languages), App\Services\AutoJudgeService (406 lines, compiles/runs/compares using safeexec, real implementation), and App\Http\Controllers\Api\RunController (store, judge, rejudge, downloadSource).
  • These are exposed only via routes/api.php (Route::apiResource('runs', RunController::class), /runs/{run}/rejudge, /runs/{run}/judge).
  • grep -rl "api/runs" resources/js/ returns nothing — the Vue frontend never calls this API. There is no admin screen to create a Contest, Site, Language, or Problem row either — the only way data gets into these tables today is the import-boca route (zip import) and the demo seeder added in this PR.

Impact

Following the README end-to-end (register a team, browse problems, submit a solution, get judged, see the scoreboard update) does not work: the submission a contestant makes is written to a table (exercise_team) that nothing reads back, so it sits as 'pending' forever, and none of the sandboxed compile/run/compare logic in AutoJudgeService ever executes for it. The judging engine itself appears complete and reasonably faithful to BOCA's approach (uses safeexec, per-answer configurable verdicts, etc.) — it's just not connected to anything a contestant can click.

Suggested scope

This needs a product decision, not just a patch:

  1. Decide whether hackathons/exercises/exercise_team should be deleted (they predate the BOCA-compatible rewrite and appear to be dead weight now that contests/problems/runs exist), or whether the intent is to keep a simpler "hackathon mode" alongside full BOCA-style contests.
  2. Wire the participant Problems/Submit UI to problems/languages and POST /api/runs (or an equivalent web route that creates a real Run and triggers AutoJudgeService), instead of the exercises/exercise_team stub.
  3. Add an admin UI (or fix the existing wizard) to create/edit Contest, Site, Language, and Problem (with test cases) — right now the only way to populate the real schema is the BOCA-zip import or direct API/DB access.

Found via a functional, hands-on audit (actually logging in, seeding data, and tracing the submission flow through the code) as part of verifying microHelium can execute everything BOCA does — not just a schema comparison.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions