Skip to content

feat: implement timezone-aware timestamps for projections - #32

Merged
yordis merged 1 commit into
mainfrom
yordis/chore-ecto-migration
Nov 19, 2025
Merged

yordis merged 1 commit into
mainfrom
yordis/chore-ecto-migration

Conversation

@yordis

@yordis yordis commented Nov 19, 2025 •

Copy link
Copy Markdown
Member

Note

Make projection timestamps timezone-aware and add migration helpers, updating schema, migrations, tests, and docs.

  • Ecto Projections:
    • Update ProjectionVersion schema to use timestamps(type: :utc_datetime_usec).
    • Add migration helpers: Commanded.Projections.Ecto.Migrations.V01CreateProjectionVersionsTable and V02UpgradeTimestampsToTimezone (creates projection_versions with :timestamptz; upgrades existing inserted_at/updated_at).
    • Refactor repo migrations to call helper modules (supports :prefix), switch to explicit up/0 and down/0.
    • Bump test migrator version in test/test_helper.exs.
  • Docs:
    • Update guides to use new migration helpers and describe timezone-aware timestamps.
    • Add section in guides/explanations/fork-differences.md detailing the change with usage examples.

Written by Cursor Bugbot for commit 821f65f. This will update automatically on new commits. Configure here.

@coderabbitai

coderabbitai Bot commented Nov 19, 2025 •

Copy link
Copy Markdown

Walkthrough

The changes introduce timezone-aware timestamps for Ecto projections by converting the ProjectionVersion schema from naive datetime microseconds to UTC datetime microseconds. Two new migration helper modules are provided for greenfield and upgrade scenarios, and existing migrations are refactored to delegate to these helpers.

Changes

Cohort / File(s) Summary
Documentation
guides/explanations/fork-differences.md
Adds documentation section describing timezone-aware timestamps feature for projections, including migration scenarios and example code blocks.
Core Schema Update
lib/commanded/projections/ecto.ex
Changes ProjectionVersion schema timestamps type from :naive_datetime_usec to :utc_datetime_usec for timezone-aware time handling.
Migration Helper Modules
lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex, lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex
Introduces two new migration modules: V01 for creating projection_versions table (greenfield), and V02 for upgrading existing installations by converting timestamps from naive to timestamptz. Both support optional prefix parameter.
Migration Refactoring
priv/repo/migrations/20170609113553_create_projection_versions.exs, priv/repo/migrations/20170929080308_create_projection_version_with_prefix.exs
Refactored existing migrations to delegate table creation and teardown to V01CreateProjectionVersionsTable module, replacing inline DDL with module function calls.

Sequence Diagram

sequenceDiagram
    participant Old as Migration (Old)
    participant New as Migration Helper (V01/V02)
    participant DB as Database
    
    rect rgb(240, 248, 255)
    Note over Old,New: Greenfield Setup
    Old->>New: up() delegation
    New->>DB: CREATE projection_versions with timestamptz
    end
    
    rect rgb(255, 250, 240)
    Note over Old,New: Existing Installation Upgrade
    Old->>New: V02.up() delegation
    New->>DB: ALTER TABLE projection_versions<br/>MODIFY timestamps to timestamptz
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify the schema type change from :naive_datetime_usec to :utc_datetime_usec is correctly applied across all projection operations
  • Confirm V01 and V02 migration modules create and alter tables with correct DDL (timestamptz column definitions and composite key handling)
  • Ensure migration delegation in both existing migration files properly forwards prefix parameters and maintains backward compatibility
  • Validate that the documentation accurately reflects the feature and provides correct usage examples for both greenfield and upgrade scenarios

Poem

🐰✨ A hop through time zones, both old and new,
Naive timestamps bid their farewell,
UTC aware, our projections stay true,
Migration helpers weave their spell!
Timezones tamed, the schema's renewed. 🌍⏰

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: implementing timezone-aware timestamps for projections, which is the core objective reflected across all modified files.
Description check ✅ Passed The PR description clearly describes the changeset, covering schema updates, migration helpers, refactoring, and documentation changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch yordis/chore-ecto-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yordis
yordis force-pushed the yordis/chore-ecto-migration branch 3 times, most recently from d35719d to 53cf945 Compare November 19, 2025 06:00
@yordis
yordis marked this pull request as ready for review November 19, 2025 06:01
@yordis
yordis force-pushed the yordis/chore-ecto-migration branch from 53cf945 to 6ecc8ef Compare November 19, 2025 06:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
guides/explanations/fork-differences.md (1)

104-148: Docs for timezone-aware timestamps are accurate; consider mentioning :prefix

The new section correctly describes the switch to timestamptz, the :utc_datetime_usec schema change, and the V01/V02 helper usage. To make multi-schema setups more discoverable, consider adding a short note that both helpers accept a :prefix option (e.g. V01CreateProjectionVersionsTable.up(prefix: "projections")), mirroring the code in Commanded.Projections.Ecto.Migrations.V01CreateProjectionVersionsTable.

lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (1)

38-45: Verify database timezone configuration before running this migration.

When PostgreSQL converts timestamp to timestamptz, it interprets existing timestamp values in the database's timezone setting. Ensure your database timezone is set to UTC (or matches the timezone used when storing the original timestamps) to avoid unexpected timestamp shifts.

You can verify your database timezone with:

#!/bin/bash
# Check PostgreSQL timezone configuration
# Replace with your actual database connection details

psql -U postgres -d your_database -c "SHOW timezone;"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c552e8 and 53cf945.

📒 Files selected for processing (6)
  • guides/explanations/fork-differences.md (1 hunks)
  • lib/commanded/projections/ecto.ex (1 hunks)
  • lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (1 hunks)
  • lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (1 hunks)
  • priv/repo/migrations/20170609113553_create_projection_versions.exs (1 hunks)
  • priv/repo/migrations/20170929080308_create_projection_version_with_prefix.exs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
priv/repo/migrations/20170929080308_create_projection_version_with_prefix.exs (2)
lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (2)
  • up (38-47)
  • down (49-52)
lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (2)
  • up (38-45)
  • down (47-54)
lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (1)
lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (2)
  • up (38-45)
  • down (47-54)
lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (1)
lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (2)
  • up (38-47)
  • down (49-52)
priv/repo/migrations/20170609113553_create_projection_versions.exs (1)
lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (2)
  • up (38-47)
  • down (49-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Quality Assurance (1.18.x, 27)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (5)
lib/commanded/projections/ecto.ex (1)

574-578: ProjectionVersion timestamps now correctly use UTC-aware type

Changing ProjectionVersion to timestamps(type: :utc_datetime_usec) matches the new timestamptz columns from V01/V02 and is the right choice for timezone-aware projections. Just make sure consumers run the upgrade migration before deploying this schema change to avoid type mismatches on existing databases.

priv/repo/migrations/20170929080308_create_projection_version_with_prefix.exs (1)

2-13: Delegating prefixed migration to V01 keeps behavior and centralizes DDL

Switching this migration to call V01CreateProjectionVersionsTable.up/down(prefix: "test") preserves the existing prefix behavior while reusing the shared projection_versions DDL. This keeps the schema definition in one place and reduces drift risk between migrations.

lib/commanded/projections/ecto/migrations/v01_create_projection_versions_table.ex (1)

1-54: Well-factored, prefix-aware V01 migration module

The guarded V01 migration cleanly encapsulates projection_versions DDL with optional :prefix and timezone-aware timestamptz timestamps. Centralizing this logic for reuse (and documenting usage in the moduledoc) should make future projection schema evolution and multi-schema setups much easier to manage.

priv/repo/migrations/20170609113553_create_projection_versions.exs (1)

2-12: Migration now correctly delegates to versioned V01 up/down

Having this migration call V01CreateProjectionVersionsTable.up/0 and .down/0 centralizes the table definition and ensures it stays consistent with the versioned migration module. The switch from an inline change/0 to explicit up/down is appropriate given the versioned helpers.

lib/commanded/projections/ecto/migrations/v02_upgrade_timestamps_to_timezone.ex (1)

1-56: LGTM! Well-structured migration with comprehensive documentation.

The migration correctly upgrades timestamp columns to timezone-aware types using Ecto's alter/modify pattern. The implementation is consistent with V01's structure, properly reversible, and includes clear usage examples with prefix support.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis force-pushed the yordis/chore-ecto-migration branch from 6ecc8ef to 821f65f Compare November 19, 2025 06:09
@yordis
yordis merged commit af1bb2c into main Nov 19, 2025
6 of 7 checks passed
@yordis
yordis deleted the yordis/chore-ecto-migration branch November 19, 2025 06:12
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