From 3fdb0f36b3f49c59fa388dafcc05358e54557c95 Mon Sep 17 00:00:00 2001 From: Sergei Poljanski Date: Tue, 26 May 2026 17:43:18 +0300 Subject: [PATCH] db: connection helper and invoices migration DB.connect! opens a single Sequel connection from DATABASE_URL; DB.migrate! runs Sequel migrations from db/migrations/. The first migration creates the invoices table: uuid PK, unique invoice number, client + currency fields, JSONB for line items, GEL conversion rate captured at issue time, paid_at for the status toggle, pdf_key for the MinIO object. --- db/migrations/001_invoices.rb | 23 +++++++++++++++++++++++ lib/db.rb | 22 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 db/migrations/001_invoices.rb create mode 100644 lib/db.rb diff --git a/db/migrations/001_invoices.rb b/db/migrations/001_invoices.rb new file mode 100644 index 0000000..81b58ce --- /dev/null +++ b/db/migrations/001_invoices.rb @@ -0,0 +1,23 @@ +Sequel.migration do + change do + create_table(:invoices) do + column :uuid, :uuid, primary_key: true + String :number, null: false, unique: true + String :client_name, null: false + String :client_email, null: false + String :client_address, text: true + String :currency, null: false, size: 3 + BigDecimal :gel_rate, size: [12, 4], null: false + BigDecimal :subtotal, size: [14, 2], null: false + column :items, :jsonb, null: false + Date :issued_on, null: false + Date :due_on, null: false + DateTime :paid_at + String :pdf_key, null: false + String :notes, text: true + DateTime :created_at, null: false + end + + run "CREATE INDEX invoices_created_at_idx ON invoices (created_at DESC)" + end +end diff --git a/lib/db.rb b/lib/db.rb new file mode 100644 index 0000000..7f87eeb --- /dev/null +++ b/lib/db.rb @@ -0,0 +1,22 @@ +require 'sequel' + +module DB + module_function + + def connect! + @connection ||= Sequel.connect( + ENV.fetch('DATABASE_URL'), + max_connections: 5, + logger: ($env == 'development' ? $logger : nil) + ) + end + + def connection + @connection or raise 'DB not connected — call DB.connect! first' + end + + def migrate! + Sequel.extension :migration + Sequel::Migrator.run(connection, File.join($root, 'db', 'migrations')) + end +end