codex: database foundation#2
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
More reviews will be available in 30 minutes and 50 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (12)
📝 WalkthroughWalkthroughThis PR introduces a complete database infrastructure layer for the accounting system. It defines a PostgreSQL schema with nine tables (users, audit logs, roles, entities, ledger entries, quarters, raids, treasury accounts), implements Drizzle ORM with Neon serverless connectivity, adds field-level AES-256-GCM encryption utilities, provides local database reset tooling, and establishes GitHub Actions CI/CD for migration verification and production deployment. ChangesDatabase Infrastructure
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR lays down the project’s database foundation by introducing a Drizzle ORM schema + initial migration set, adding local DB reset tooling, and automating migration checks/apply via GitHub Actions. It also introduces server-side encryption/auditing helpers and updates documentation and dependencies to support the new workflow.
Changes:
- Added Drizzle schema definitions, generated migration SQL, and Drizzle CLI config/metadata.
- Added local database reset script and a GitHub Actions workflow to verify/apply migrations.
- Introduced initial server-side encryption + audit logging utilities and integrated Vercel Analytics.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/lib/encryption.ts |
Adds AES-256-GCM helpers for storing encrypted JSON payloads. |
src/lib/audit.ts |
Adds helper to insert audit events into the database. |
src/db/schema.ts |
Defines the initial Postgres schema (tables, enums, indexes) in Drizzle. |
src/db/index.ts |
Creates a Neon + Drizzle DB client accessor. |
src/app/layout.tsx |
Adds Vercel Analytics to the app layout. |
scripts/reset-local-db.mjs |
Implements destructive local-only schema reset + migration runner. |
README.md |
Documents DB scripts, migration workflow, and env/security notes. |
package.json |
Adds Drizzle/Neon/pg dependencies and DB-related scripts. |
pnpm-lock.yaml |
Locks newly added dependencies. |
drizzle/0000_gorgeous_mephisto.sql |
Initial SQL migration creating core DB objects. |
drizzle/meta/_journal.json |
Tracks applied migrations. |
drizzle/meta/0000_snapshot.json |
Snapshot of the schema state for Drizzle. |
drizzle.config.ts |
Drizzle Kit config + dotenv loading for CLI usage. |
.github/workflows/database.yml |
CI workflow for migration generation check and production migration apply. |
.env.example |
Documents ENCRYPTION_KEY format (including rotation-friendly format). |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/database.yml (1)
27-83:⚠️ Potential issue | 🟠 Major | ⚡ Quick winSet explicit permissions following least-privilege principle.
The workflow uses default (broad) permissions. Restrict to only what each job requires.
🔐 Proposed fix to add explicit permissions
Add at workflow level (after
concurrencyblock):concurrency: group: database-${{ github.ref }} cancel-in-progress: false + +permissions: + contents: readFor
migration-check, if the job only reads code and verifies diffs:jobs: migration-check: if: github.event_name == 'pull_request' name: Migration Check runs-on: ubuntu-latest + permissions: + contents: read steps:For
migrate-production, same permissions suffice unless you need to write back to the repo:migrate-production: if: github.event_name == 'push' name: Migrate Production runs-on: ubuntu-latest environment: production + permissions: + contents: read steps:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/database.yml around lines 27 - 83, Add an explicit permissions block to restrict GitHub Actions tokens to least-privilege for the migration-check and migrate-production jobs: set permissions to only what’s needed (e.g., contents: read) instead of the default broad permissions, either as a top-level "permissions" block for the workflow or per-job for "migration-check" and "migrate-production"; ensure no repo write permissions are granted unless a job (e.g., git push) actually requires them.
🧹 Nitpick comments (1)
src/db/schema.ts (1)
69-76: ⚡ Quick win
updatedAtwon't refresh on updates.
defaultNow()only applies on INSERT. Without$onUpdate(or a DB trigger),updated_atwill never change on subsequent UPDATEs, making it indistinguishable fromcreated_at.♻️ Add
$onUpdateto the shared helperconst timestamps = { createdAt: timestamp("created_at", { withTimezone: true }) .defaultNow() .notNull(), updatedAt: timestamp("updated_at", { withTimezone: true }) .defaultNow() + .$onUpdate(() => new Date()) .notNull(), };Please confirm
$onUpdateis supported and behaves as expected in drizzle-orm 0.45.2.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/db/schema.ts` around lines 69 - 76, The shared timestamps helper sets updatedAt with defaultNow(), which only runs on INSERT so updated_at will never change; update the helper (the timestamps const and the updatedAt field) to include an $onUpdate that sets it to the current timestamp (e.g., using the SQL now() expression or drizzle's sql helper) so updatedAt auto-updates on UPDATEs, and confirm that $onUpdate is supported and behaves as expected in drizzle-orm 0.45.2 before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/database.yml:
- Around line 33-34: Update the Checkout steps that use actions/checkout@v4 in
the migration-check and migrate-production jobs to disable credential
persistence by adding persist-credentials: false to each checkout step so
credentials are not exposed to subsequent steps; locate the steps that call
actions/checkout@v4 and insert the persist-credentials: false property under
each of those steps.
- Line 34: Replace floating tags for GitHub Actions with pinned commit SHAs:
locate each "uses: actions/checkout@v4" and any "uses: pnpm/action-setup@..."
occurrences (the uses lines mentioned in the review) and change them to the
corresponding immutable commit SHA form (e.g., actions/checkout@<commit-sha>)
for every job in the workflow; ensure you look up the canonical commit SHAs in
the action repos and apply the same SHA-pinning pattern to all referenced
actions so both jobs use pinned SHAs instead of tags.
In `@src/db/schema.ts`:
- Around line 82-88: The wallet_address uniqueness is case-sensitive and
updated_at never changes on UPDATEs; change the schema to enforce
case-insensitive uniqueness and make updated_at auto-refresh: update the
app_users definition around walletAddress and the
uniqueIndex("app_users_wallet_address_unique") to either (a) store a canonical
form (lowercase) by normalizing inputs in your insert/update paths and keep the
index, or (b) change the index to a functional index on
lower(table.walletAddress) / use citext so mixed-case EIP-55 checksums collide
correctly (pick one approach and apply consistently in code), and for timestamps
replace the current default-only updatedAt (timestamps / updatedAt) with an
on-update mechanism—either use Drizzle's onUpdateNow/updatedAt helper or add a
DB trigger/function that sets updated_at = now() on UPDATE; apply the change to
the same schema symbols: walletAddress,
uniqueIndex("app_users_wallet_address_unique"), timestamps / updatedAt.
In `@src/lib/encryption.ts`:
- Around line 27-41: The key parsing currently uses positional IDs (key-${index
+ 1}) and does not trim entries, which breaks decryption after rotations; update
the parser that currently iterates rawKeyring.split(",") to first split and trim
each entry, split on the first ":" into id and key (trim both), require explicit
ids when more than one entry is present (throw an Error if an entry has no id
while ENCRYPTION_KEY contains >1 item), decode the maybeKey as base64 and
validate 32 bytes as before, and keep references to the same id strings so
encryptField/decryptField can reliably match keys by id.
---
Outside diff comments:
In @.github/workflows/database.yml:
- Around line 27-83: Add an explicit permissions block to restrict GitHub
Actions tokens to least-privilege for the migration-check and migrate-production
jobs: set permissions to only what’s needed (e.g., contents: read) instead of
the default broad permissions, either as a top-level "permissions" block for the
workflow or per-job for "migration-check" and "migrate-production"; ensure no
repo write permissions are granted unless a job (e.g., git push) actually
requires them.
---
Nitpick comments:
In `@src/db/schema.ts`:
- Around line 69-76: The shared timestamps helper sets updatedAt with
defaultNow(), which only runs on INSERT so updated_at will never change; update
the helper (the timestamps const and the updatedAt field) to include an
$onUpdate that sets it to the current timestamp (e.g., using the SQL now()
expression or drizzle's sql helper) so updatedAt auto-updates on UPDATEs, and
confirm that $onUpdate is supported and behaves as expected in drizzle-orm
0.45.2 before merging.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2e9869c4-bc6a-4e86-a890-2d322f957f08
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
.env.example.github/workflows/database.ymlREADME.mddrizzle.config.tsdrizzle/0000_gorgeous_mephisto.sqldrizzle/meta/0000_snapshot.jsondrizzle/meta/_journal.jsonpackage.jsonscripts/reset-local-db.mjssrc/app/layout.tsxsrc/db/index.tssrc/db/schema.tssrc/lib/audit.tssrc/lib/encryption.ts
This pull request introduces a full database migration and local development workflow using Drizzle ORM, adds essential database-related scripts and configuration, and improves documentation and environment setup. The changes establish a robust foundation for database management, including schema migration, local resets, and production deployment automation.
Database schema and migration setup:
drizzle/0000_gorgeous_mephisto.sql) defining all core tables, types, indices, and constraints for the application’s data model.drizzle/meta/_journal.json) to track migration state.drizzle.config.ts) to define migration settings and load environment variables.scripts/reset-local-db.mjs) to safely reset and migrate the local database, with safeguards against destructive actions on production databases.Workflow automation and scripts:
.github/workflows/database.yml) to check for committed migrations on pull requests and automatically apply migrations to production on pushes tomain.Local development and package management:
package.jsonto include Drizzle and Neon dependencies, and added scripts for generating, migrating, resetting, and inspecting the database. [1] [2]src/db/index.ts) using Drizzle ORM and Neon for serverless Postgres connections.Documentation and environment configuration:
README.mdwith detailed instructions for database commands, deployment workflow, environment variable usage, and security notes..env.exampleto document the requiredENCRYPTION_KEYformat for local development and production.Other improvements:
Summary by CodeRabbit
New Features
Documentation
Chores