_blogs
// blogs / 20260608.md
// blogs / 20260608.md
Dev Log: June 08 Wrap-up
Overview
Today was a mix of architectural groundwork and some deep-sea diving into query logic. I moved from the 'high-level drawing' phase of the new e-commerce backend into actually laying down the database schema and getting the automation pipeline ready.
What I Worked On
Turning Diagrams into Reality
I spent a good chunk of time translating my ER diagrams into actual SQL migrations. I started with the coupons system. Since this is a multi-tenant setup, everything has to be scoped by a tenant_id. It’s a simple table on the surface—handling percentage and flat discounts—but getting the unique constraints right for tenant-specific codes is key.
I also spent some time on product_variants. I decided to use JSONB for variant attributes (like size or color). Schema flexibility is a lifesaver here because I really didn't want to deal with a separate table for every possible product property. It keeps the queries cleaner and the code a lot more maintainable.
Automating the Boring Stuff (Flyway)
I'm a big believer in 'day zero' migrations. I integrated Flyway into the Maven build today. There’s always that annoying 5-second window where your Spring Boot app tries to connect to a Dockerized Postgres instance before the DB is actually ready to talk. I added some retry logic in the dev profile to handle that:
spring:
flyway:
connect-retries: 5
# No more crashing because Docker was sleepy
It's a small change, but it stops the 'app-crash-on-startup' loop that usually kills my flow.
Untangling Query Conflicts
Later in the day, I had to jump into a different project to fix some issues in a lead management decorator. We were seeing some conflicts where specific queries were clashing, especially when negating certain values. I ended up refactoring the way filter expressions are normalized before they hit the service layer.
I added a new query type for custom pagination and cleaned up the logic so that the filter normalization happens once, consistently, across all query types (sums, counts, and lists).
public BaseResource[] processQuery(Context ctx, String queryType, Map<String, Object> params) {
// Normalize the expression early to prevent logic conflicts downstream
Expression filter = normalize_logic(service.getExpression(ctx));
return switch (queryType) {
case "GET_TOTAL" -> handle_sum(filter, params);
case "GET_PAGINATED" -> handle_page(filter, params);
default -> throw new RuntimeException("Unknown query type");
};
}
Wrapping Up
The backend foundation is feeling solid. It’s always satisfying to see the V10__ migration files start to pile up. Tomorrow, I’ll probably start looking at the security layer—specifically how I want to handle those tenant-scoped JWTs.
Catch you tomorrow.