_blogs
// blogs / 20260624.md
// blogs / 20260624.md
Dev Log: June 24 Wrap-up
Overview
Today was one of those "plumbing" days. I spent most of my time under the hood of our CRM service, specifically focusing on how we handle data isolation for different user roles. The goal was to make the backend smarter about who is asking for what, so the frontend doesn't have to work as hard to stay secure.
What I Worked On
Hardening Data Isolation
The biggest chunk of my day went into refining our query normalization logic. Before, we had a few spots where the system was a bit "forgetful" about whether a user was a Partner or a Distributor. If the session data wasn't structured exactly right, it could lead to empty states or inconsistent views.
I extended our utility methods to automatically inject the correct filters based on the user_type. Now, when a Partner or Distributor is logged in, the backend implicitly enforces their specific IDs on every query. It’s much safer than relying on the frontend to pass the right filters every time, and it cleans up the API contract significantly.
// Centralizing how we inject user-specific filters into database queries
public Expression getSecureExpression(UserContext ctx, Service service) {
Expression baseExpr = service.getFilterExpression(ctx);
if (ctx.getUserType() != null) {
// Fetching the linked ID from the user's account metadata
String scopeId = ctx.getMetadata().get("linked_org_id");
if (isValid(scopeId)) {
// Automatically append the restriction to the query
return Expression.and(baseExpr, new Expression("org_id", OP.EQ, scopeId));
}
}
return baseExpr;
}
Cleaning up User Metadata
I also refactored how we pull Partner and Distributor IDs during the login and session update flows. We were doing some unnecessary hops between services to figure out which "branch" a user belonged to.
I shifted this so that these IDs are retrieved and stored directly in the account's extra data fields. It sounds like a small change, but it simplifies the logic wrappers (the decorators) across the whole CRM. Instead of running extra queries to verify permissions, we just grab the ID once from the user object and we're good to go. I also added a new query case for fetching specific Partner details, which should make the dashboard loading a bit snappier.
Wrapping Up
It feels good to have this layer of the system feeling more solid. It’s less about adding "features" and more about making the existing architecture bulletproof. Tomorrow I’ll probably dive back into the billing side to see how these isolation changes affect the invoice filters I was working on earlier. Hopefully, it just works.