very avg comp science student… also likes grapes. Ex-ASE @accenture

will be treating this as a version control for my brain
8
I reworked thread navigation around three separate layers of state: Repository state → Thread state → Message state Messages are cached by thread ID. So switching: → Thread B → Thread A doesn't require rebuilding everything from scratch.
1
2
I also added request cancellation / stale-response protection so an old request can never overwrite the currently active thread. The result: thread switching feels much more direct.
2
The biggest issue was asynchronous requests racing each other. Click Thread A → request A starts Click Thread B → request B starts Request B finishes → UI shows B Request A finishes later → UI overwrites the state
1
2
Suddenly you're looking at Thread B with Thread A's messages. The fix wasn't "add another loading spinner." I had to make the active thread the source of truth and prevent stale requests from mutating current state.
Once persistent threads were implemented, the UI started exposing a bunch of race conditions. Switching: Thread A → Thread B could briefly show Thread A's messages inside Thread B before correcting itself. Sometimes the wrong thread remained selected.
1
New threads felt slow. Deleting threads felt slow. Renaming a thread had another weird issue: while typing a new name, the input could get overwritten by another state update. The database was working. The problem was the frontend state architecture.
THREADS. Instead of: Repository → Chat the model is now: → Repository → Multiple Threads → Messages So the same repo can have separate conversations: • Architecture • Authentication • Database • Performance • Debugging
1
Previously, analyzing a repo was basically a one off interaction. Now it remembers the repositories a user has worked with. A user can log back in and see: → previous analysis → previous conversations → continue where they left off
1
I also kept repository analysis/cache separate from user history so the same repo doesn't need to be unnecessarily analyzed and stored again for every user.
added Google OAuth so RExplain now has actual user accounts instead of treating every session as isolated. → verify identity → create/find RExplain user → secure session → load their workspace User-specific data is now tied to the account rather than the browser.
1
The important part was keeping OAuth credentials server side and making the backend session the source of truth.
RExplain went from being a tool where you analyze a GitHub repo and chat with it → to a persistent AI workspace. added: • Google OAuth • Persistent user accounts • Repo history • Persistent chat threads • Threads • Conversation persistence • Automatic thread creation
Spent today debugging a weird issue with REXPLAIN. Public GitHub repos were showing: “Repository is private or access is restricted.” Turns out it wasn't a repository problem at all. Here’s what actually happened
1
3
GitHub API rate limits frontend was checking GitHub before sending the repo to the backend. GitHub returns 403 when the unauthenticated API rate limit is hit. My code assumed: 403 = Private repo But actually: 403 ≠ always private That was the first bug.
2
thanks to @unlayer and @RicoDC95 here is my take on #BuiltWithImageEditor instead of a basic 2d template; KLUSTOR is a web based 3D arcade racing game and livery design studio. where a better design results to a faster car github.com/swaekaa/klustor klustor.vercel.app/
4
3
765
Camera design turned into an engineering problem too. The camera follows the car transform while smoothing position/rotation instead of directly copying the vehicle every frame. Small change, but it made the racing feel much less rigid. #BuiltWithImageEditor
2
Another architecture problem: Unlayer exports the livery as a dataUrl. It would be very easy to accidentally do: editor → Base64 → Socket.IO → every player repeatedly. #BuiltWithImageEditor
1
2
That's a terrible idea for bandwidth. Instead: SAVE DRAFT locally SUBMIT LIVERY once Broadcast metadata/state, not the full image on every room update. #BuiltWithImageEditor
2
One thing I didn't want was every browser running its own independent challenge timer. So the server owns: { status: "editing", startedAt, deadline } #BuiltWithImageEditor
1
3
The client calculates display time from the server deadline.That means a player can't simply change their local clock and get extra editing time. #BuiltWithImageEditor
2