feat(05-01): migration SQL and Go model types for template system
- Create 002_templates.sql: item_tier enum, ALTER budget_items, templates and template_items tables with CHECK constraint - Add ItemTier type with fixed/variable/one_off constants to models.go - Add ItemTier field to BudgetItem struct - Add Template, TemplateItem, TemplateDetail structs
This commit is contained in:
@@ -18,6 +18,14 @@ const (
|
|||||||
CategoryIncome CategoryType = "income"
|
CategoryIncome CategoryType = "income"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ItemTier string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ItemTierFixed ItemTier = "fixed"
|
||||||
|
ItemTierVariable ItemTier = "variable"
|
||||||
|
ItemTierOneOff ItemTier = "one_off"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
@@ -58,6 +66,7 @@ type BudgetItem struct {
|
|||||||
CategoryID uuid.UUID `json:"category_id"`
|
CategoryID uuid.UUID `json:"category_id"`
|
||||||
CategoryName string `json:"category_name,omitempty"`
|
CategoryName string `json:"category_name,omitempty"`
|
||||||
CategoryType CategoryType `json:"category_type,omitempty"`
|
CategoryType CategoryType `json:"category_type,omitempty"`
|
||||||
|
ItemTier ItemTier `json:"item_tier"`
|
||||||
BudgetedAmount decimal.Decimal `json:"budgeted_amount"`
|
BudgetedAmount decimal.Decimal `json:"budgeted_amount"`
|
||||||
ActualAmount decimal.Decimal `json:"actual_amount"`
|
ActualAmount decimal.Decimal `json:"actual_amount"`
|
||||||
Notes string `json:"notes"`
|
Notes string `json:"notes"`
|
||||||
@@ -86,3 +95,30 @@ type BudgetDetail struct {
|
|||||||
Items []BudgetItem `json:"items"`
|
Items []BudgetItem `json:"items"`
|
||||||
Totals BudgetTotals `json:"totals"`
|
Totals BudgetTotals `json:"totals"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Template struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateItem struct {
|
||||||
|
ID uuid.UUID `json:"id"`
|
||||||
|
TemplateID uuid.UUID `json:"template_id"`
|
||||||
|
CategoryID uuid.UUID `json:"category_id"`
|
||||||
|
CategoryName string `json:"category_name,omitempty"`
|
||||||
|
CategoryType CategoryType `json:"category_type,omitempty"`
|
||||||
|
CategoryIcon string `json:"category_icon,omitempty"`
|
||||||
|
ItemTier ItemTier `json:"item_tier"`
|
||||||
|
BudgetedAmount *decimal.Decimal `json:"budgeted_amount"`
|
||||||
|
SortOrder int `json:"sort_order"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateDetail struct {
|
||||||
|
Template
|
||||||
|
Items []TemplateItem `json:"items"`
|
||||||
|
}
|
||||||
|
|||||||
27
backend/migrations/002_templates.sql
Normal file
27
backend/migrations/002_templates.sql
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
CREATE TYPE item_tier AS ENUM ('fixed', 'variable', 'one_off');
|
||||||
|
|
||||||
|
ALTER TABLE budget_items ADD COLUMN item_tier item_tier NOT NULL DEFAULT 'fixed';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS templates (
|
||||||
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
name TEXT NOT NULL DEFAULT 'My Template',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX idx_templates_user_id ON templates (user_id);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS template_items (
|
||||||
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
template_id UUID NOT NULL REFERENCES templates(id) ON DELETE CASCADE,
|
||||||
|
category_id UUID NOT NULL REFERENCES categories(id) ON DELETE RESTRICT,
|
||||||
|
item_tier item_tier NOT NULL,
|
||||||
|
budgeted_amount NUMERIC(12, 2),
|
||||||
|
sort_order INT NOT NULL DEFAULT 0,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
CONSTRAINT chk_template_items_no_one_off CHECK (item_tier IN ('fixed', 'variable'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_template_items_template_id ON template_items (template_id);
|
||||||
Reference in New Issue
Block a user