feat: update models
This commit is contained in:
parent
7be5510753
commit
735d9e810c
20 changed files with 91 additions and 586 deletions
|
|
@ -1,54 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BudgetPeriod string
|
|
||||||
|
|
||||||
const (
|
|
||||||
BudgetPeriodWeekly BudgetPeriod = "weekly"
|
|
||||||
BudgetPeriodMonthly BudgetPeriod = "monthly"
|
|
||||||
BudgetPeriodYearly BudgetPeriod = "yearly"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BudgetStatus string
|
|
||||||
|
|
||||||
const (
|
|
||||||
BudgetStatusOnTrack BudgetStatus = "on_track"
|
|
||||||
BudgetStatusWarning BudgetStatus = "warning"
|
|
||||||
BudgetStatusOver BudgetStatus = "over"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Budget struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Period BudgetPeriod `db:"period"`
|
|
||||||
StartDate time.Time `db:"start_date"`
|
|
||||||
EndDate *time.Time `db:"end_date"`
|
|
||||||
IsActive bool `db:"is_active"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type BudgetWithSpent struct {
|
|
||||||
Budget
|
|
||||||
Tags []*Tag
|
|
||||||
Spent decimal.Decimal
|
|
||||||
Percentage float64
|
|
||||||
Status BudgetStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BudgetWithSpent) TagNames() string {
|
|
||||||
names := make([]string, len(b.Tags))
|
|
||||||
for i, t := range b.Tags {
|
|
||||||
names[i] = t.Name
|
|
||||||
}
|
|
||||||
return strings.Join(names, ", ")
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ExpenseType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExpenseTypeExpense ExpenseType = "expense"
|
|
||||||
ExpenseTypeTopup ExpenseType = "topup"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Expense struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Type ExpenseType `db:"type"`
|
|
||||||
Date time.Time `db:"date"`
|
|
||||||
PaymentMethodID *string `db:"payment_method_id"`
|
|
||||||
RecurringExpenseID *string `db:"recurring_expense_id"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExpenseWithTags struct {
|
|
||||||
Expense
|
|
||||||
Tags []*Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExpenseWithTagsAndMethod struct {
|
|
||||||
Expense
|
|
||||||
Tags []*Tag
|
|
||||||
PaymentMethod *PaymentMethod
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExpenseTag struct {
|
|
||||||
ExpenseID string `db:"expense_id"`
|
|
||||||
TagID string `db:"tag_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ExpenseItem struct {
|
|
||||||
ExpenseID string `db:"expense_id"`
|
|
||||||
ItemID string `db:"item_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type TagExpenseSummary struct {
|
|
||||||
TagID string `db:"tag_id"`
|
|
||||||
TagName string `db:"tag_name"`
|
|
||||||
TagColor *string `db:"tag_color"`
|
|
||||||
TotalAmount decimal.Decimal `db:"total_amount"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
FileTypeAvatar = "avatar"
|
|
||||||
)
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
UserID string `db:"user_id"` // Who owns/created this file
|
|
||||||
OwnerType string `db:"owner_type"` // "user", "profile", etc. - the entity that owns the file
|
|
||||||
OwnerID string `db:"owner_id"` // Polymorphic FK
|
|
||||||
Type string `db:"type"`
|
|
||||||
Filename string `db:"filename"`
|
|
||||||
OriginalName string `db:"original_name"`
|
|
||||||
MimeType string `db:"mime_type"`
|
|
||||||
Size int64 `db:"size"`
|
|
||||||
StoragePath string `db:"storage_path"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
}
|
|
||||||
41
internal/model/financial_management.go
Normal file
41
internal/model/financial_management.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
ID string `db:"id"`
|
||||||
|
Name string `db:"name"`
|
||||||
|
SpaceID string `db:"space_id"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TransactionTypeDeposit TransactionType = "deposit"
|
||||||
|
TransactionTypeWithdrawal TransactionType = "withdrawal"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Transaction struct {
|
||||||
|
ID string `db:"id"`
|
||||||
|
Value decimal.Decimal `db:"value"`
|
||||||
|
Type TransactionType `db:"type"`
|
||||||
|
AccountID string `db:"account_id"`
|
||||||
|
Description *string `db:"description"`
|
||||||
|
RelatedTransactionID *string `db:"related_transaction_id"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tag struct {
|
||||||
|
ID string `db:"id"`
|
||||||
|
Name string `db:"name"`
|
||||||
|
SpaceID string `db:"space_id"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,22 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import "time"
|
||||||
"time"
|
|
||||||
)
|
type User struct {
|
||||||
|
ID string `db:"id"`
|
||||||
|
Email string `db:"email"`
|
||||||
|
Name *string `db:"name"`
|
||||||
|
// Allow null for passwordless users
|
||||||
|
PasswordHash *string `db:"password_hash"`
|
||||||
|
PendingEmail *string `db:"pending_email"`
|
||||||
|
EmailVerifiedAt *time.Time `db:"email_verified_at"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) HasPassword() bool {
|
||||||
|
return u.PasswordHash != nil && *u.PasswordHash != ""
|
||||||
|
}
|
||||||
|
|
||||||
type Token struct {
|
type Token struct {
|
||||||
ID string `db:"id"`
|
ID string `db:"id"`
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type InvitationStatus string
|
|
||||||
|
|
||||||
const (
|
|
||||||
InvitationStatusPending InvitationStatus = "pending"
|
|
||||||
InvitationStatusAccepted InvitationStatus = "accepted"
|
|
||||||
InvitationStatusExpired InvitationStatus = "expired"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SpaceInvitation struct {
|
|
||||||
Token string `db:"token"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
InviterID string `db:"inviter_id"`
|
|
||||||
Email string `db:"email"`
|
|
||||||
Status InvitationStatus `db:"status"`
|
|
||||||
ExpiresAt time.Time `db:"expires_at"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Loan struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
OriginalAmount decimal.Decimal `db:"original_amount"`
|
|
||||||
OriginalAmountCents int `db:"original_amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
InterestRateBps int `db:"interest_rate_bps"`
|
|
||||||
StartDate time.Time `db:"start_date"`
|
|
||||||
EndDate *time.Time `db:"end_date"`
|
|
||||||
IsPaidOff bool `db:"is_paid_off"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type LoanWithPaymentSummary struct {
|
|
||||||
Loan
|
|
||||||
TotalPaid decimal.Decimal
|
|
||||||
Remaining decimal.Decimal
|
|
||||||
ReceiptCount int
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FormatMoney formats a decimal as a dollar string like "$12.50"
|
|
||||||
func FormatMoney(d decimal.Decimal) string {
|
|
||||||
return fmt.Sprintf("$%s", d.StringFixed(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormatDecimal formats a decimal for form input values like "12.50"
|
|
||||||
func FormatDecimal(d decimal.Decimal) string {
|
|
||||||
return d.StringFixed(2)
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TransferDirection string
|
|
||||||
|
|
||||||
const (
|
|
||||||
TransferDirectionDeposit TransferDirection = "deposit"
|
|
||||||
TransferDirectionWithdrawal TransferDirection = "withdrawal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MoneyAccount struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccountTransfer struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
AccountID string `db:"account_id"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Direction TransferDirection `db:"direction"`
|
|
||||||
Note string `db:"note"`
|
|
||||||
RecurringDepositID *string `db:"recurring_deposit_id"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MoneyAccountWithBalance struct {
|
|
||||||
MoneyAccount
|
|
||||||
Balance decimal.Decimal
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccountTransferWithAccount struct {
|
|
||||||
AccountTransfer
|
|
||||||
AccountName string `db:"account_name"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type PaymentMethodType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
PaymentMethodTypeCredit PaymentMethodType = "credit"
|
|
||||||
PaymentMethodTypeDebit PaymentMethodType = "debit"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PaymentMethod struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Type PaymentMethodType `db:"type"`
|
|
||||||
LastFour *string `db:"last_four"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type Profile struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
UserID string `db:"user_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Timezone *string `db:"timezone"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location returns the *time.Location for this profile's timezone.
|
|
||||||
// Returns UTC if timezone is nil or invalid.
|
|
||||||
func (p *Profile) Location() *time.Location {
|
|
||||||
if p.Timezone == nil || *p.Timezone == "" {
|
|
||||||
return time.UTC
|
|
||||||
}
|
|
||||||
loc, err := time.LoadLocation(*p.Timezone)
|
|
||||||
if err != nil {
|
|
||||||
return time.UTC
|
|
||||||
}
|
|
||||||
return loc
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FundingSourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
FundingSourceBalance FundingSourceType = "balance"
|
|
||||||
FundingSourceAccount FundingSourceType = "account"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Receipt struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
LoanID string `db:"loan_id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
TotalAmount decimal.Decimal `db:"total_amount"`
|
|
||||||
TotalAmountCents int `db:"total_amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Date time.Time `db:"date"`
|
|
||||||
RecurringReceiptID *string `db:"recurring_receipt_id"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReceiptFundingSource struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
ReceiptID string `db:"receipt_id"`
|
|
||||||
SourceType FundingSourceType `db:"source_type"`
|
|
||||||
AccountID *string `db:"account_id"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
LinkedExpenseID *string `db:"linked_expense_id"`
|
|
||||||
LinkedTransferID *string `db:"linked_transfer_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReceiptWithSources struct {
|
|
||||||
Receipt
|
|
||||||
Sources []ReceiptFundingSource
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReceiptFundingSourceWithAccount struct {
|
|
||||||
ReceiptFundingSource
|
|
||||||
AccountName string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReceiptWithSourcesAndAccounts struct {
|
|
||||||
Receipt
|
|
||||||
Sources []ReceiptFundingSourceWithAccount
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Frequency string
|
|
||||||
|
|
||||||
const (
|
|
||||||
FrequencyDaily Frequency = "daily"
|
|
||||||
FrequencyWeekly Frequency = "weekly"
|
|
||||||
FrequencyBiweekly Frequency = "biweekly"
|
|
||||||
FrequencyMonthly Frequency = "monthly"
|
|
||||||
FrequencyYearly Frequency = "yearly"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RecurringExpense struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Type ExpenseType `db:"type"`
|
|
||||||
PaymentMethodID *string `db:"payment_method_id"`
|
|
||||||
Frequency Frequency `db:"frequency"`
|
|
||||||
StartDate time.Time `db:"start_date"`
|
|
||||||
EndDate *time.Time `db:"end_date"`
|
|
||||||
NextOccurrence time.Time `db:"next_occurrence"`
|
|
||||||
IsActive bool `db:"is_active"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecurringExpenseWithTags struct {
|
|
||||||
RecurringExpense
|
|
||||||
Tags []*Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecurringExpenseWithTagsAndMethod struct {
|
|
||||||
RecurringExpense
|
|
||||||
Tags []*Tag
|
|
||||||
PaymentMethod *PaymentMethod
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RecurringReceipt struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
LoanID string `db:"loan_id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Description string `db:"description"`
|
|
||||||
TotalAmount decimal.Decimal `db:"total_amount"`
|
|
||||||
TotalAmountCents int `db:"total_amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
Frequency Frequency `db:"frequency"`
|
|
||||||
StartDate time.Time `db:"start_date"`
|
|
||||||
EndDate *time.Time `db:"end_date"`
|
|
||||||
NextOccurrence time.Time `db:"next_occurrence"`
|
|
||||||
IsActive bool `db:"is_active"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecurringReceiptSource struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
RecurringReceiptID string `db:"recurring_receipt_id"`
|
|
||||||
SourceType FundingSourceType `db:"source_type"`
|
|
||||||
AccountID *string `db:"account_id"`
|
|
||||||
Amount decimal.Decimal `db:"amount"`
|
|
||||||
AmountCents int `db:"amount_cents"` // deprecated: kept for SELECT * compatibility
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecurringReceiptWithSources struct {
|
|
||||||
RecurringReceipt
|
|
||||||
Sources []RecurringReceiptSource
|
|
||||||
}
|
|
||||||
|
|
||||||
type RecurringReceiptWithLoan struct {
|
|
||||||
RecurringReceipt
|
|
||||||
LoanName string
|
|
||||||
Sources []RecurringReceiptSource
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DailySpending struct {
|
|
||||||
Date time.Time `db:"date"`
|
|
||||||
Total decimal.Decimal `db:"total"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MonthlySpending struct {
|
|
||||||
Month string `db:"month"`
|
|
||||||
Total decimal.Decimal `db:"total"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PaymentMethodExpenseSummary struct {
|
|
||||||
PaymentMethodID string `db:"payment_method_id"`
|
|
||||||
PaymentMethodName string `db:"payment_method_name"`
|
|
||||||
PaymentMethodType string `db:"payment_method_type"`
|
|
||||||
TotalAmount decimal.Decimal `db:"total_amount"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SpendingReport struct {
|
|
||||||
ByTag []*TagExpenseSummary
|
|
||||||
ByPaymentMethod []*PaymentMethodExpenseSummary
|
|
||||||
DailySpending []*DailySpending
|
|
||||||
MonthlySpending []*MonthlySpending
|
|
||||||
TopExpenses []*ExpenseWithTagsAndMethod
|
|
||||||
TotalIncome decimal.Decimal
|
|
||||||
TotalExpenses decimal.Decimal
|
|
||||||
NetBalance decimal.Decimal
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type ShoppingList struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListItem struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
ListID string `db:"list_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
IsChecked bool `db:"is_checked"`
|
|
||||||
CreatedBy string `db:"created_by"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListWithUncheckedItems struct {
|
|
||||||
List *ShoppingList
|
|
||||||
Items []*ListItem
|
|
||||||
}
|
|
||||||
|
|
||||||
type ListCardData struct {
|
|
||||||
List *ShoppingList
|
|
||||||
Items []*ListItem
|
|
||||||
CurrentPage int
|
|
||||||
TotalPages int
|
|
||||||
}
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type Role string
|
|
||||||
|
|
||||||
const (
|
|
||||||
RoleOwner Role = "owner"
|
|
||||||
RoleMember Role = "member"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Space struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
OwnerID string `db:"owner_id"`
|
|
||||||
Timezone *string `db:"timezone"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location returns the *time.Location for this space's timezone.
|
|
||||||
// Returns nil if timezone is not set, so callers can distinguish "not set" from "UTC".
|
|
||||||
func (s *Space) Location() *time.Location {
|
|
||||||
if s.Timezone == nil || *s.Timezone == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
loc, err := time.LoadLocation(*s.Timezone)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return loc
|
|
||||||
}
|
|
||||||
|
|
||||||
type SpaceMember struct {
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
UserID string `db:"user_id"`
|
|
||||||
Role Role `db:"role"`
|
|
||||||
JoinedAt time.Time `db:"joined_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SpaceMemberWithProfile struct {
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
UserID string `db:"user_id"`
|
|
||||||
Role Role `db:"role"`
|
|
||||||
JoinedAt time.Time `db:"joined_at"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Email string `db:"email"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type Tag struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
SpaceID string `db:"space_id"`
|
|
||||||
Name string `db:"name"`
|
|
||||||
Color *string `db:"color"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package model
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type User struct {
|
|
||||||
ID string `db:"id"`
|
|
||||||
Email string `db:"email"`
|
|
||||||
// Allow null for passwordless users
|
|
||||||
PasswordHash *string `db:"password_hash"`
|
|
||||||
PendingEmail *string `db:"pending_email"`
|
|
||||||
EmailVerifiedAt *time.Time `db:"email_verified_at"`
|
|
||||||
CreatedAt time.Time `db:"created_at"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *User) HasPassword() bool {
|
|
||||||
return u.PasswordHash != nil && *u.PasswordHash != ""
|
|
||||||
}
|
|
||||||
33
internal/model/workspace_collaboration.go
Normal file
33
internal/model/workspace_collaboration.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Role string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoleOwner Role = "owner"
|
||||||
|
RoleMember Role = "member"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Space struct {
|
||||||
|
ID string `db:"id"`
|
||||||
|
Name string `db:"name"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpaceMember struct {
|
||||||
|
SpaceID string `db:"space_id"`
|
||||||
|
UserID string `db:"user_id"`
|
||||||
|
Role Role `db:"role"`
|
||||||
|
JoinedAt time.Time `db:"joined_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SpaceInvitation struct {
|
||||||
|
Token string `db:"token"`
|
||||||
|
SpaceID string `db:"space_id"`
|
||||||
|
InviterID string `db:"inviter_id"`
|
||||||
|
InviteeEmail string `db:"invitee_email"`
|
||||||
|
ExpiresAt time.Time `db:"expires_at"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue