Skip to content

fix(data): fall back to time.Now() for non-xid BaseModel IDs#648

Merged
pitabwire merged 1 commit intomainfrom
fix/created-at-fallback-on-non-xid
Apr 20, 2026
Merged

fix(data): fall back to time.Now() for non-xid BaseModel IDs#648
pitabwire merged 1 commit intomainfrom
fix/created-at-fallback-on-non-xid

Conversation

@pitabwire
Copy link
Copy Markdown
Owner

Summary

Follow-up to v1.94.2. The strict xid check in BeforeCreate broke existing
tests and hand-crafted migration seeds that use readable non-xid IDs like
`"client-1"` or `"test-event-123"`. Those are ergonomic fixtures — not
a production pattern — and blocking inserts on them makes frame upgrades
painful for downstream repos.

Now: `createdAtFromID` still returns an error for non-xid IDs, but
`BeforeCreate` catches it, logs a WARN, and falls back to time.Now().
Production IDs always take the xid path (because util.IDString produces
xids) so the sort-by-id ≡ sort-by-created_at guarantee still holds in
practice.

Test plan

  • go build ./...
  • go test -race -count=1 ./data/...
  • go test -race -count=1 ./datastore/...

…d IDs

Non-xid BaseModel IDs (typically test fixtures or legacy hand-crafted
migration seeds) can no longer derive a deterministic CreatedAt from the
id's embedded timestamp. Rather than blocking the insert, log a WARN and
fall back to time.Now().

createdAtFromID still returns an error so callers that want strict
behaviour — or want to surface the violation — can do so. Production IDs
always come from util.IDString() and take the hot path.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the BeforeCreate hook in data/model.go to allow the use of non-xid IDs, which now trigger a fallback to time.Now() for the CreatedAt timestamp instead of returning an error. This change is aimed at supporting test fixtures and legacy migrations. Tests in datastore/repository_test.go have been updated accordingly. Review feedback suggests simplifying the warning log message to avoid redundancy, as the ID and error details are already included as log fields.

Comment thread data/model.go
Comment on lines +113 to +116
util.Log(db.Statement.Context).
WithError(err).
WithField("id", model.ID).
Warn("BaseModel.ID is not a valid xid; falling back to time.Now() for CreatedAt")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The log message is redundant because the id and the validation error are already included in the log fields via WithField("id", model.ID) and WithError(err). Simplifying the message improves log clarity and reduces verbosity.

Suggested change
util.Log(db.Statement.Context).
WithError(err).
WithField("id", model.ID).
Warn("BaseModel.ID is not a valid xid; falling back to time.Now() for CreatedAt")
util.Log(db.Statement.Context).
WithError(err).
WithField("id", model.ID).
Warn("falling back to time.Now() for CreatedAt")

@pitabwire pitabwire merged commit 6cc43a9 into main Apr 20, 2026
8 of 9 checks passed
@pitabwire pitabwire deleted the fix/created-at-fallback-on-non-xid branch April 20, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant