Devault
- 11 Devlogs
- 33 Total hours
Devault remembers everything your team builds and decides, so you can just ask it why the code looks the way it does.
Devault remembers everything your team builds and decides, so you can just ask it why the code looks the way it does.
Spent today setting up the ingestion-service module. Decided to go with personal access tokens for GitHub auth instead of building a full GitHub App, way less setup for now and honestly the app registration stuff isn’t worth it yet.
Got the module skeleton wired up too. Hit a dumb Gradle error where IntelliJ kept saying it couldn’t find a Kotlin task in the module, turned out I accidentally put an include() call inside the module’s build.gradle.kts instead of settings.gradle.kts. Classic copy paste mistake. Fixed it and the sync worked fine after that.
Also poked at the JWKS endpoint path stuff on auth-service, decided to keep it out of the api/v1 prefix by using RequestMapping per controller instead of a global context path, since jwks is supposed to live at the root per spec anyway.
Next up is actually building the GitHub client and the data model for ingestion sources.
Fixed most of the bugs from the code review today. Sorted out exception handling in common-lib, fixed a race condition when adding a member to a workspace, got the JWKS key cache working properly, plus a few smaller things along the way. Had some pain with kids in the tokens, but ended up leaving it in a simpler version since it doesn’t really matter without key rotation anyway.
Next up is ingestion-service. Starting with GitHub, using a personal access token for now instead of jumping straight into GitHub App territory. Backfill first, then webhooks, we’ll see how it goes.
Wrapped up MockK unit tests for auth-service-lib - JwtClaimsService, JwtAuthenticationProvider, and JwtAuthenticationFilter are now fully covered. Burned a good chunk of time on one annoying issue with relaxed = true on the HttpServletRequest mock - OncePerRequestFilter internally checks getAttribute/getDispatcherType before even reaching the actual filter logic, and the relaxed mock was returning non-null instead of null, so tests were passing for entirely the wrong reason. Lesson learned: when mocking Servlet API, better to explicitly stub those two calls in @BeforeEach instead of relying on relaxed.
Code review also turned up a real security gap in validate() - a token with no exp claim was passing validation as effectively non-expiring, since JJWT only throws ExpiredJwtException when exp is present and past, not when it’s missing entirely. Fix incoming.
Holding off on MVC/@WebMvcTest for the controllers for now - fixing a handful of code review items first (the missing exp check, plus making exception handling consistent in extractExpiration), then back to controller tests and GlobalExceptionHandler.
I finished auth-service tests now I’m working on auth-lib. One test that failed is spring conected because I didn’t provide on local good configuration that is why it failed but in docker it works perfectly.
I’ve written some tests, but haven’t finished yet. So far I’ve covered services with business logic in workspace-service, and I’m currently working on auth-service. After that, I’m planning to add some MVC tests for controllers and exception handlers, and finally write tests for my shared libraries: auth-service-lib and common-lib.
Just wrapped up workspace-service. As always, had some trouble on the auth side — needed to fix a handful of bugs that came up during code review (a couple of nasty ones: deleteWorkspace was silently broken due to an FK constraint, and transferOwnership wasn’t updating Workspace.ownerId, which could’ve permanently locked workspaces). Also caught a regression in the JWT filter that was blocking even permitAll routes like login/refresh — fixed now.
Along the way I also pulled the ApiResponse wrapper and exception handling into a shared common-lib module, so both auth-service and workspace-service now return a consistent response format.
I might revisit a few design choices here later for my own convenience, but for now the service is functionally complete — workspace CRUD, member management, role changes, and ownership transfer all working with proper error handling.
Starting on tests next, then moving on to ingestion-service.
I have finished basics in workspace-service like some CRUD controllers basic services and repositories with dtos now I’m testing everything in insomnia. I also had some troubles with auth, it was a nightmare to find a bug (i was hardcoding jwt issuer). I added in my screenshot content from testing in insomnia
I fixed up auth-service-lib before jumping into workspace-service. I added AuthenticatedUser
so other services can just use @AuthenticationPrincipal instead of digging through
SecurityContext manually. also fixed some stuff in JwtTokenCandidate that was
technically wrong but worked anyway lol
I made auth-service-lib today, basically a shared lib so i dont have to copy paste the same jwt verification code into every new microservice. workspace-service, query-service etc. I will just import it and get the filter + claims extraction for free. Had a weird issue where JwksClient was trying to fetch the public key from auth-service before it even started, took me a bit to figure out but I fixed it.
I added JWT auth with Ed25519 signing. Now login returns access + refresh token pair, refresh rotates tokens, logout blacklists the refresh token in Redis. JWKS endpoint exposed at /.well-known/jwks.json for other services to verify tokens.
i was working on my auth-service. I changed from basic auth with bearer tokens to access and refresh tokens. Also I added endpoint to refresh tokens when they expire and logout endpoint.