mohd-faraz

_blogs

// blogs / 20260614.md

Dev Log: June 14 Wrap-up

2026-06-14
#java#springboot#security#hibernate#backend

Overview

Today was a heavy 'foundation' day. It wasn't about flashy features, but rather about grinding through the boilerplate and structural work that makes the rest of the app actually function. I spent most of my time mapping out the core data model and getting the security layer to a place where I can actually start building protected routes.

What I Worked On

The Data Model Grind

I spent a significant portion of the day defining the core domain. We're talking over 20 different entities and their corresponding repositories. It's a bit tedious to map out every Address, Category, and Coupon, but getting the JPA mappings right now saves a world of hurt later when Flyway tries to migrate the schema.

One thing I’m being really careful about is multi-tenancy. Almost every repository I wrote today is scoped by a tenant ID. It’s a bit of a mental tax to keep adding findByTenantId logic to every query, but it's non-negotiable for keeping data isolated.

Wiring up Security

I finally got the authentication flow working. I'm using Spring Security 6 with JWT, which is pretty standard, but I added a custom UserPrincipal to bridge the gap between the security context and my actual user entities. This makes it so much easier to grab the current user's ID in a controller without doing a bunch of casting.

I also wired up the basic auth endpoints for registration, login, and token refreshing. Getting that first successful login and seeing a valid JWT come back always feels like a win, even if I've done it a dozen times before.

Better Error Conversations

I hate it when an API just returns a generic 500 error or a messy stack trace. I spent some time today setting up a GlobalExceptionHandler. Now, if a user tries to register with an email that's already taken, or sends a bad request, the API responds with a clean, uniform JSON object.

It looks something like this now:

@RestControllerAdvice
public class APIExceptionHandler {
    
    @ExceptionHandler(AlreadyExistsException.class)
    public ResponseEntity<Object> handleConflict(AlreadyExistsException ex) {
        // Just a clean, standard error shape
        var body = new ErrorInfo(HttpStatus.CONFLICT, ex.getMessage());
        return new ResponseEntity<>(body, HttpStatus.CONFLICT);
    }
}

Making Life Easier for the Team

Finally, I updated the README. I noticed some friction for folks trying to get the dev environment running on Windows, so I added specific guidelines and made sure the Maven wrapper scripts were properly documented. I also mapped out the project structure so anyone jumping in knows exactly where the DTOs end and the Entities begin.

Wrapping Up

It was a long day of 'infrastructure' work, but the backend feels solid now. The plumbing is done—now I can actually start building the features that people see. Tomorrow I'll probably dive into the service layer and start handling the actual business logic for the catalog.

Catch you then.