Skip to content

fix(data): BaseModel.CreatedAt and ModifiedAt as NOT NULL#650

Merged
pitabwire merged 1 commit intomainfrom
fix/basemodel-created-at-not-null
Apr 20, 2026
Merged

fix(data): BaseModel.CreatedAt and ModifiedAt as NOT NULL#650
pitabwire merged 1 commit intomainfrom
fix/basemodel-created-at-not-null

Conversation

@pitabwire
Copy link
Copy Markdown
Owner

Summary

BeforeCreate always populates CreatedAt and ModifiedAt. Without the
`not null` tag, subsequent AutoMigrate runs on existing tables emit
`ALTER COLUMN … DROP NOT NULL`, which Postgres rejects when the column
has been promoted into a composite primary key — the pattern
TimescaleDB hypertables require.

Tagging the columns NOT NULL aligns the model with runtime behaviour and
makes AutoMigrate idempotent on hypertable-bound tables.

Test plan

  • go build ./...
  • go test -race ./data/...
  • go test -race ./datastore/...

BeforeCreate always populates these columns, so the model's GORM schema
should reflect that. Without the tag, AutoMigrate runs on existing tables
would emit `ALTER COLUMN … DROP NOT NULL`, which Postgres rejects when
the column has been promoted into a composite primary key (the
TimescaleDB hypertable pattern).
@pitabwire pitabwire merged commit de58add into main Apr 20, 2026
4 of 5 checks passed
@pitabwire pitabwire deleted the fix/basemodel-created-at-not-null branch April 20, 2026 17:54
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 updates the BaseModel struct in data/model.go to include not null constraints on the CreatedAt and ModifiedAt fields, ensuring consistent schema generation for composite primary keys. Feedback includes a suggestion to use the modern primaryKey GORM tag and restore field alignment for the ID field, as well as a recommendation to update the documentation to include the BeforeUpdate hook's role in the lifecycle of the ModifiedAt field.

Comment thread data/model.go
ID string `gorm:"type:varchar(50);primary_key"`
CreatedAt time.Time
ModifiedAt time.Time
ID string `gorm:"type:varchar(50);primary_key"`
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 alignment of the ID field tag was removed in this change, making it inconsistent with the rest of the struct. Additionally, GORM v2 recommends using the primaryKey tag instead of the legacy primary_key tag.

Suggested change
ID string `gorm:"type:varchar(50);primary_key"`
ID string `gorm:"type:varchar(50);primaryKey"`

Comment thread data/model.go
Comment on lines +23 to +26
// CreatedAt and ModifiedAt are NOT NULL because BeforeCreate always
// populates them. Tagging them here keeps AutoMigrate from trying to
// relax the columns on tables that promote CreatedAt into a composite
// primary key (e.g. TimescaleDB hypertables).
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 documentation for CreatedAt and ModifiedAt is slightly incomplete. While it correctly mentions BeforeCreate, the ModifiedAt field is also updated in the BeforeUpdate hook (line 144). Updating the comment to reflect this would provide a more accurate description of the field's lifecycle.

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