Skip to content

Conversation

@cejiogu
Copy link

@cejiogu cejiogu commented Dec 28, 2025

Overview

In this pull request, I introduce in-house event form submission and moderation functionality to Navi, creating the backend logic needed to enable users to submit requests to host events directly through the app. These event requests are persisted in the backend on the SQLite database, and moderated by an approval workflow. The goal is to replace the need for external tools (e.g. Google Forms) with a fully integrated backend solution, and to facilitate real-time updates to both submitters and administrators.

Changes Made

Change 1: Introduce event form persistence via database migrations
I added a new migration to introduce an event_forms table, which stores event submission metadata including:

  • submitting user (netid)
  • event name and type (temporary tabling vs permanent hotspot)
  • conditional fields for temporary events (dates and hosting organization)
  • event description, location, and approval status

Change 2: Implement REST endpoints for event submission and retrieval
I added REST endpoints and a corresponding controller to support the full event submission lifecycle:

  • POST /events/create-event to submit a new event request
  • GET /events to retrieve all submissions (admin-facing, includes public and private information)
  • GET /events/approved to retrieve all approved events (public-facing, sanitized output)
  • PUT /events/:id to approve or reject a submission (admin-only)
    Swagger documentation was updated to reflect all new endpoints and request/response schemas.

Change 3: Add real-time updates using WebSockets (Socket.IO)
To facilitate real-time, bi-directional communication between server and client(s), I integrated WebSockets using the JavaScript Socket.io library to push updates to clients in real time:

  • Admin clients are notified when a new event request is submitted
  • All clients (admin + users) are notified when an event is approved
  • Only the submitting user client are notified when an event is rejected

Room-based routing is used to scope messages appropriately:

  • public room for approved events
  • admin room for relevant moderation events
  • per-user rooms (netid:<netid>) for personalized notifications, particularly when submitted events are rejected

I introduced a toPublicEvent helper to ensure that only public-safe fields are sent to non-admin clients. Internal identifiers and metadata (e.g. database IDs and timestamps) are excluded from public payloads, reducing frontend coupling to database schema.

Change 4: Migration adjustments
I added a migration to remove a UNIQUE constraint from the printers.location column via a safe table-recreation migration, done to reflect real-world usage where multiple printers may exist at the same location. Additionally, I implemented a trigger on the event_forms table to automatically update the updated_at attribute of a given record upon data change.

Test Coverage

I manually tested the feature end-to-end using a combination of REST requests and WebSocket clients via multiple terminals.

  • Verified that submitting an event via POST /events/create-event correctly inserts a record into the database
  • Used curl to approve and reject events via PUT /events/:id, confirming that:
    • the approval_status field updates correctly
    • appropriate WebSocket messages are emitted to admin, public, and submitter clients
  • Used a lightweight Socket.io test client to confirm correct room membership and message routing
  • Confirmed Swagger documentation matches runtime behavior

Next Steps

  • Add support for photo uploads using DigitalOcean Spaces, including signed upload URLs and an event_attachments table
  • Introduce stronger authentication guarantees for Socket.IO connections

@cejiogu cejiogu requested a review from Daniel-jw December 28, 2025 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants