Games coordinator - #16
Conversation
…rd and coordinator views
…efining token management and redirect logic
…improve registration fee calculation logic
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 27232410 | Triggered | Company Email Password | 0320108 | backend/scripts/createGameCoordinator.js | View secret |
| 27313297 | Triggered | Username Password | 6b78719 | backend/scripts/updateGameCoordinator.js | View secret |
| 27313298 | Triggered | Company Email Password | 6b78719 | backend/scripts/updateGameCoordinator.js | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds a game coordinator login/dashboard flow and extends admin/coordinator views to better navigate and report on sports registrations, including fee-related statistics and endpoint/auth handling.
Changes:
- Redirect coordinator away from login when already authenticated; persist selected sport in the coordinator dashboard via URL query params for better back navigation.
- Update coordinator registration fetching to use
/game-coordinator/registrationsendpoints and adjust frontend API token selection/redirect behavior by endpoint type. - Add fee calculation logic for sports registrations on the backend and display fee collection stats in admin/coordinator-related pages; include maintenance scripts for coordinator and fee fixes.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/pages/coordinator/CoordinatorLogin.jsx | Adds auto-redirect to dashboard when coordinator token/data already exist. |
| frontend/src/pages/coordinator/CoordinatorDashboard.jsx | Uses URL search params for selected sport; updates endpoints to /game-coordinator/registrations. |
| frontend/src/pages/admin/AdminSportsRegistrations.jsx | Computes fee totals for confirmed registrations and adds a fee collection UI section. |
| frontend/src/pages/admin/AdminDashboard.jsx | Displays registration counts and fee stats on the admin dashboard. |
| frontend/src/config/api.js | Chooses auth token based on request path and improves 401/403 handling with role-aware redirects. |
| backend/scripts/updateGameCoordinator.js | Adds script to create/update coordinator credentials. |
| backend/scripts/fixRegistrationFees.js | Adds script to backfill/correct registration fees in existing data. |
| backend/scripts/createGameCoordinator.js | Updates default coordinator credentials output/creation behavior. |
| backend/package.json | Adds fix-fees script entry. |
| backend/controllers/registration.controller.js | Introduces sport/category-based fee calculation for sports registrations. |
| backend/controllers/gameCoordinator.controller.js | Changes coordinator registration filtering to use eventName directly. |
| backend/controllers/admin.controller.js | Adds aggregation for registration counts and fee totals in admin dashboard stats. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const fixRegistrationFees = async () => { | ||
| try { | ||
| console.log("🔌 Connecting to MongoDB..."); | ||
| await mongoose.connect(process.env.MONGODB_URI); |
There was a problem hiding this comment.
mongoose.connect(process.env.MONGODB_URI) will throw an opaque error if MONGODB_URI is unset. Add an explicit check with a clear message (or a safe localhost fallback like the other scripts) so running npm run fix-fees fails fast with actionable guidance.
| await mongoose.connect(process.env.MONGODB_URI); | |
| const mongoUri = process.env.MONGODB_URI; | |
| if (!mongoUri) { | |
| console.error( | |
| "❌ MONGODB_URI is not set. Please define it in your environment or .env file before running `npm run fix-fees`." | |
| ); | |
| process.exit(1); | |
| } | |
| await mongoose.connect(mongoUri); |
| console.log("✅ MongoDB Connected"); | ||
|
|
||
| // Find existing coordinator | ||
| const existingCoordinator = await GameCoordinator.findOne({}); |
There was a problem hiding this comment.
GameCoordinator.findOne({}) will update whichever coordinator happens to be returned first, which is risky if multiple coordinators exist. Prefer querying by a stable identifier (e.g., username/email) or using findOneAndUpdate with an explicit filter.
| const existingCoordinator = await GameCoordinator.findOne({}); | |
| const existingCoordinator = await GameCoordinator.findOne({ | |
| email: "coordinator@sggsie.ac.in", | |
| }); |
| <span className="text-gray-400 text-sm">Total Collected</span> | ||
| </div> | ||
| <p className="text-3xl font-bold text-orange-400"> | ||
| ₹{(stats.totalRegistrationFee || 0).toLocaleString("en-IN")} |
There was a problem hiding this comment.
The "Total Collected" card is rendering stats.totalRegistrationFee, which duplicates the "Registration Fees" value and ignores accommodation fees. Use the aggregated total (e.g., stats.totalFeeCollected) and/or include stats.totalAccommodationFee to match the label.
| ₹{(stats.totalRegistrationFee || 0).toLocaleString("en-IN")} | |
| ₹{( | |
| stats.totalFeeCollected ?? | |
| ((stats.totalRegistrationFee || 0) + (stats.totalAccommodationFee || 0)) | |
| ).toLocaleString("en-IN")} |
| label: "Total Fee Collected", | ||
| value: `₹${(stats?.totalRegistrationFee || 0).toLocaleString( | ||
| "en-IN" | ||
| )}`, | ||
| icon: "💰", |
There was a problem hiding this comment.
This "Total Fee Collected" stat uses stats.totalRegistrationFee (registration-only). The backend response includes totalFeeCollected (registration + accommodation) and totalAccommodationFee; either display stats.totalFeeCollected or rename the label to avoid misleading totals.
| // Apply filters | ||
| if (status) query.status = status; | ||
| if (eventName) query.eventName = eventName; | ||
| if (eventName) query.eventName = eventName; // Override with specific eventName if provided |
There was a problem hiding this comment.
if (eventName) query.eventName = eventName overrides the assigned-sports $in filter, allowing a coordinator to request registrations for sports they are not assigned by passing an arbitrary eventName. Validate that eventName is within coordinator.assignedSports (or intersect the filters) instead of overwriting.
| if (eventName) query.eventName = eventName; // Override with specific eventName if provided | |
| if (eventName) { | |
| if (coordinator.assignedSports.length > 0) { | |
| // Only allow narrowing to a specific event if it is within the assigned sports | |
| if (coordinator.assignedSports.includes(eventName)) { | |
| query.eventName = eventName; | |
| } | |
| // If the requested eventName is not assigned, keep the original $in restriction | |
| } else { | |
| // No assignedSports restriction; allow filtering by any eventName | |
| query.eventName = eventName; | |
| } | |
| } |
| // Create a default game coordinator | ||
| const coordinator = new GameCoordinator({ | ||
| username: "coordinator", | ||
| email: "coordinator@zenith2026.com", | ||
| password: "coordinator123", // Password will be hashed by the pre-save hook | ||
| username: "SggsCoordinator", | ||
| email: "coordinator@sggsie.ac.in", | ||
| password: "SggsGame@2026", // Password will be hashed by the pre-save hook | ||
| assignedSports: allSports, // Assign all sports by default | ||
| }); |
There was a problem hiding this comment.
This script hard-codes default coordinator credentials in source control. Use environment variables / interactive prompts and avoid committing real passwords (even for "default" accounts).
| // Sport fees configuration - must match frontend | ||
| const SPORTS_FEES = { | ||
| Cricket: {amount: 6500, note: "per team"}, |
There was a problem hiding this comment.
The PR description focuses on a coordinator panel, but this change set also adds/changes registration fee calculation and admin fee dashboards. Either update the PR description/scope or split the fee-related changes into a separate PR to keep review and rollback risk manageable.
| console.log( | ||
| `Calculating fee for ${sportName} (${genderCategory}): ₹${registrationFee}` | ||
| ); |
There was a problem hiding this comment.
Avoid logging per-request fee calculation details from the controller (console.log(...)), as it can leak user-provided data into logs and create unnecessary noise in production. Prefer structured debug logging gated by environment (or remove entirely).
| console.log( | |
| `Calculating fee for ${sportName} (${genderCategory}): ₹${registrationFee}` | |
| ); | |
| if (process.env.NODE_ENV === "development") { | |
| console.debug("Registration fee calculated", { | |
| sportName, | |
| genderCategory, | |
| registrationFee, | |
| }); | |
| } |
|
|
||
| console.log("\n📋 Updated Coordinator Details:"); | ||
| console.log(" Username: SggsCoordinator"); | ||
| console.log(" Password: SggsGame@2026"); |
There was a problem hiding this comment.
The script prints the coordinator password to stdout. This can leak credentials via CI logs, shell history, or shared terminals. Avoid printing passwords; print only the username/login URL (or a one-time setup instruction).
| console.log(" Password: SggsGame@2026"); | |
| console.log(" Password has been set. Please store it securely and do not share it in logs."); |
| console.log("\n✅ Game Coordinator Created Successfully!"); | ||
| console.log("\n📋 Coordinator Details:"); | ||
| console.log(" Username: coordinator"); | ||
| console.log(" Email: coordinator@zenith2026.com"); | ||
| console.log(" Password: coordinator123"); | ||
| console.log(" Username: SggsCoordinator"); | ||
| console.log(" Email: coordinator@sggsie.ac.in"); | ||
| console.log(" Password: SggsGame@2026"); | ||
| console.log(" Assigned Sports: All Sports"); |
There was a problem hiding this comment.
This script logs the coordinator password to stdout, which can leak credentials in CI logs or shared terminals. Avoid outputting passwords; provide a reset/change-password instruction instead.
…dd scripts for checking duplicates and fees
… and export options
- Changed visuals and messaging in RegistrationClosed component to reflect event closure. - Updated MarathonRegistration page to display cancellation notice and remove registration form. - Adjusted UniversalRegistration to always show registration closed state for ZENITH 2026. - Added a cancellation banner in AdminMarathon for clarity on registration status. - Modified AdminSportsRegistrations to improve table data presentation and removed status column.
- Implemented a new script to segregate marathon refunds based on payment screenshots using OCR. - Added functionality to classify accounts and extract transaction details. - Created CSV and JSON outputs for analyzed refund data. - Developed an admin dashboard for managing marathon refunds, including viewing screenshots and updating refund statuses. - Integrated summary statistics for refunds by participant and status.
…or gallery and registration status when backend is offline
Games coordinator panel created