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
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
import "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 {
|
||||
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