EV-Connect: The Booking Engine That Treats a Charger Like a Shared Physical Resource

A Spring Boot and vanilla JavaScript platform that blends map search, slot reservation, async OTP verification, and defensive fallback design into a surprisingly complete EV charging workflow.

7 min read • View on GitHub • More from P-narkhede-2034

A shared charging post stands at the center of a crowded mechanical scene, with one hand reserving a slot and another holding a phone showing an OTP code. The image explains that EV-Connect is built around coordinating access to a scarce physical resource, not just managing a web form.
EV-Connect turns charger access into a trust loop: reserve, verify, then complete the session.
Key Takeaways

The hidden problem EV-Connect is really solving

A charger is not a calendar event. It is a location, a time window, and a piece of hardware that can only serve one driver at a time. That makes EV charging a coordination problem first and a software problem second.

EV-Connect, as described in the supplied research, is built around that reality. It does not stop at letting someone reserve a slot on a map. It tries to close the loop between booking, verification, and completion so the digital record matches the physical world.

A narrow gate admits one reservation ticket while a duplicate ticket is blocked, and an email envelope travels off on a side track. Beneath the gate, a map layer remains visible, showing that the interface can still function even when the backend is under stress.
The system is designed to handle contention, background email, and fallback rendering at the same time.

From map to slot to OTP to success

The product flow is straightforward, which is why it works. A user finds a station on the map, selects a slot, and submits a booking request. The backend creates the reservation, generates a 6-digit OTP, and sends it by email while the UI keeps moving.

A booking request only becomes a success after it passes through slot contention, OTP delivery, and human verification.

The interesting part is the final handoff. The attendant verifies the OTP, and the payment or booking status moves into success only after the physical world confirms the user is actually there. That is the difference between a generic reservation system and a system built for shared infrastructure.

Why synchronized booking is the right kind of boring

The research points to a `synchronized` booking method in `BookingService.java`. That is not glamorous, and it is exactly why it matters. When two users race for the same slot, the safest answer is often the simplest one: let one request enter the critical section at a time.

public synchronized Booking bookSlot(BookingRequest request) {
    validateUser(request.getUserId());
    if (bookingRepository.existsByStationAndDateAndTime(
            request.getStationId(), request.getDate(), request.getTime())) {
        throw new IllegalStateException("Slot already booked");
    }

    Booking booking = new Booking();
    booking.setOtp(generateSixDigitOtp());
    booking.setStatus("PENDING");
    return bookingRepository.save(booking);
}

That choice narrows the failure surface. It avoids a class of race conditions that can appear when multiple users hit the same time window, and it keeps the logic legible for a small team or a future maintainer.

Async email makes the UI feel alive

The OTP email is dispatched with `@Async`, which matters more than it sounds like it should. If SMTP is slow, the user should not have to wait for Gmail before the interface responds. The background work can lag without freezing the booking experience.

@Async
public void sendOtpEmail(String to, String otp) {
    // build message
    // send via JavaMailSender
}

This is a small implementation detail with product-level consequences. The app feels responsive because the main interaction is not blocked by an external service. The user gets confirmation quickly, while email delivery happens behind the scenes.

Vanilla JS, but not minimalist

The frontend avoids React and Vue, but that does not make it primitive. The research describes modular ES6 JavaScript, Leaflet for maps, routing via OSRM, and a central `api.js` layer for backend calls. That is a lean stack, not a thin one.

EV-ConnectTypical modern web app
Vanilla JS modulesFramework-heavy component tree
Spring Boot servicesAPI plus layered client state
Synchronized bookingHeavier contention abstractions
Async OTP emailSynchronous send or opaque queue
Static fallback station listHard dependency on live backend
Leaflet map experienceMap logic buried inside app state

The more interesting detail is the fallback station list. When the backend is down, the map still renders from static data. That is not a polish feature. It is defensive design, and it tells you the developer expects the system to fail in the real world.

The fallback that keeps the map usable

A lot of apps are only happy-path demos dressed up as products. EV-Connect does the opposite. It keeps a usable map experience even when the server is unreachable, which means the interface preserves some value instead of collapsing completely.

Backend onlineBackend unavailable
Live stations, reservations, and verification flowStatic station list still renders on the map
Full booking lifecycleDiscovery remains available
OTP and status updates proceed normallyUser still sees a functional interface
Shared trust loop completesDegraded but usable experience

That is the sort of detail that usually only shows up after a team has been burned by outages. It is also the detail that makes the system feel like infrastructure rather than a demo.

What this stack gets right, and what it deliberately avoids

EV-Connect appears to choose clarity over fashion. The backend is a familiar Spring Boot monolith with JPA and MySQL. The frontend is modular but framework-free. The system keeps the number of moving parts low, which makes the trust loop easier to reason about.

That does not mean this is the only way to build an EV platform. It does mean the repo, as described, has a coherent architecture for a problem that is fundamentally about state transitions, not visual novelty. It is a calm stack for a messy domain.