refactor: replace uuid with int64 for user and todo IDs#155
Open
Gautam7352 wants to merge 8 commits into
Open
Conversation
- models: User.ID and Todo.ID/UserID changed from uuid.UUID to int64 - services: use RETURNING id on INSERT instead of generating uuid client-side - handlers: use int64 type assertions, extract request structs, use http.Status* constants - middleware/auth: parse user_id claim as float64 then cast to int64 - routes: update wiring for new handler signatures - frontend: Todo.id type widened to number|string, api normalise uses Number(), guest id uses counter instead of crypto.randomUUID()
- types: id is number (not number|string) - API always returns integers - hooks: genId() returns negative number instead of string - hooks: toggleTodo/deleteTodo/updateTodo params changed from string to number - api: toggle/update/delete id params changed from string to number - fixes optimistic update comparisons (t.id === id was always false for authed todos)
TanishqSingla
requested changes
Apr 18, 2026
| } | ||
|
|
||
| func (h *AuthHandler) Signup(c *gin.Context) { | ||
| var req signupRequest |
Contributor
There was a problem hiding this comment.
You can name it as reqBody
| -- as the schema reference snapshot. | ||
| -- Source of truth for schema changes: backend/migration/db/migrations/*.sql | ||
|
|
||
| CREATE TABLE IF NOT EXISTS users ( |
Contributor
There was a problem hiding this comment.
You mentioned, SERIAL in the design doc but in the code it's mentioned BIGSERIAL.
Why this deviation
|
|
||
| const normalise = (raw: Record<string, unknown>): Todo => ({ | ||
| id: String(raw.id ?? raw.ID), | ||
| id: Number(raw.id ?? raw.ID), |
Contributor
There was a problem hiding this comment.
You can't use Number for postgres's Bigserial, they are incompatible
Comment on lines
+6
to
+10
| let _guestIdCounter = 0 | ||
| const genId = (): number => { | ||
| _guestIdCounter -= 1 | ||
| return _guestIdCounter | ||
| } |
Contributor
There was a problem hiding this comment.
Why are we changing this here?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & Why
The codebase previously used
uuid.UUID(viagithub.com/google/uuid) for primary keys onusersandtodostables, and passed UUIDs through every layer — models, services, handlers, middleware, and the frontend.The database schema was changed to use
SERIAL/ auto-incrementintprimary keys (handled in the migration PR). This PR updates all application code to match that schema change.Using database-generated integer IDs also simplifies inserts — no need to generate a UUID client-side before writing to the DB.
How to check failure
On
dev(before this PR), with the new int-based schema applied:POST /signup→ creates a user, DB returns an integeridPOST /login→ JWT is minted withuser_idas a UUID string (now stale/wrong)GET /todos→ middleware tries to parseuser_idclaim asuuid.UUID, fails →401 invalid token claimsPOST /todos→ same failurecrypto.randomUUID()for local IDs — these are strings, but the API now returns numeric IDs, causing type mismatches in the todo listChanges
Backend — models
User.ID,Todo.ID,Todo.UserID:uuid.UUID→int64github.com/google/uuidimport from modelsBackend — services
auth_service:SignupusesINSERT ... RETURNING idinstead of generating a UUID; JWTuser_idclaim is now anint64todo_service: all method signatures updated fromuuid.UUIDtoint64;AddTodousesINSERT ... RETURNING idTodoServiceinterface updated accordinglyBackend — handlers
auth.go: extractedsignupRequest/loginRequeststructs; all status codes usehttp.Status*constantstodo.go:uuid.Parsereplaced withstrconv.ParseInt; request structs extracted;http.Status*constants used throughoutBackend — middleware
auth.go: JWTuser_idclaim parsed asfloat64(JSON number default) then cast toint64; setsuserIDasint64in context; removeduuiddependencyBackend — routes
Frontend
types/index.ts:Todo.idwidened tonumber | stringto handle both API (numeric) and guest (string) todoslib/api.ts:normalise()usesNumber()instead ofString()foridhooks/useTodos.ts: guest todo ID generation replaced with a decrementing integer counter (negative to avoid collisions with server IDs)How to verify correction
Backend