4.7 KiB
4.7 KiB
Spendings → Entries Schema Migration Record
Purpose
This document preserves the original spendings schema and maps it to the new entries schema for future debugging and data migration. It is a historical reference and should be kept alongside the migration that introduces entries.
Source Migrations Reviewed
- packages/db/migrations/001_init.sql
- packages/db/migrations/002_amount_dollars.sql
- packages/db/migrations/002_tags.sql
Baseline Spendings Schema (Pre‑Migration)
From packages/db/migrations/001_init.sql:
Table: spendings
idbigserial PKgroup_idbigint FK →groups(id)ON DELETE CASCADEcreated_bybigint FK →users(id)amount_dollarsnumeric(12,2) NOT NULL CHECK (amount_dollars >= 0)occurred_atdate NOT NULLnecessityenumspending_necessityNOT NULLpurchase_typetext NOT NULLnotestext NULLreceipt_idbigint FK →receipts(id)ON DELETE SET NULLcreated_attimestamptz NOT NULL DEFAULT now()
Indexes
idx_spendings_group_occurredon (group_id,occurred_atDESC)idx_spendings_receipton (receipt_id)
Related Tables
receiptsstores image bytes:bytesbytea NOT NULL andcontent_type.tagsandspending_tagsdefine many‑to‑many tagging.
Amount Conversion (Historical)
From packages/db/migrations/002_amount_dollars.sql:
spendings.amount_centsrenamed toamount_dollars- Type changed to
numeric(12,2)usingamount_dollars / 100.0
Note: This implies older environments may have amount_cents. Fresh installs already use amount_dollars from 001_init.sql.
Tags & Group Settings (Baseline)
From packages/db/migrations/002_tags.sql:
Table: group_settings
group_idPK FK →groups(id)allow_member_tag_manageboolean NOT NULL DEFAULT falseupdated_attimestamptz NOT NULL DEFAULT now()
Table: tags
idbigserial PKgroup_idbigint FK →groups(id)ON DELETE CASCADEnametext NOT NULLcreated_bybigint FK →users(id)created_attimestamptz NOT NULL DEFAULT now()
Constraints & Indexes
- Unique:
tags_group_name_uniqueon (group_id, lower(name)) - Index:
tags_group_id_idxon (group_id)
Join Table: spending_tags
spending_idbigint FK →spendings(id)ON DELETE CASCADEtag_idbigint FK →tags(id)ON DELETE CASCADEcreated_attimestamptz NOT NULL DEFAULT now()- PK (
spending_id,tag_id) - Indexes:
spending_tags_spending_idx,spending_tags_tag_idx
Spendings → Entries Mapping (Planned)
Rename Summary
spending→entryspendings→entries- “spending” labels → “entry” (or “transaction”) in UI and API
Column Mapping
| Spendings Column | Entries Column | Notes |
|---|---|---|
id |
id |
same PK strategy |
group_id |
group_id |
same FK |
created_by |
created_by |
same FK |
amount_dollars |
amount_dollars |
same type/check |
occurred_at |
occurred_at |
same type |
necessity |
necessity |
still applicable for spending entries |
purchase_type |
purchase_type |
same |
notes |
notes |
same |
receipt_id |
receipt_id |
same FK |
created_at |
created_at |
same |
New Entries Fields
entry_typeenum (SPENDING,INCOME) or equivalent flag- Recurring schedule fields (see below)
Recurring Entries (Planned Fields)
Add to entries (or a dedicated recurring_entries) table:
is_recurringboolean NOT NULL DEFAULT falsefrequencyenum (daily, weekly, biweekly, monthly, quarterly, yearly)interval_countinteger NOT NULL DEFAULT 1end_conditionenum (never, after_count, by_date)end_countinteger NULLend_datedate NULLnext_run_atdate NULL (set on creation; if start date is today, set to today)last_executed_atdate NULL DEFAULT NULL
Reminder: Recurrence execution must be implemented via cron/scheduler later.
Non‑Regression Notes
- Spendings list endpoints must not return receipt image bytes (
receipts.bytes). - Tag uniqueness is case‑insensitive per group.
Known Caveats
- Two migrations share the
002_prefix; migration ordering must be deterministic. 002_amount_dollars.sqlassumes legacyamount_centsexists; skip/guard on fresh installs.
Verification Checklist
- Entries schema mirrors spendings constraints and indexes.
- Data migration preserves values and tag associations.
- Tests updated for new names and income/spending support.
Last updated: 2026-02-09