feat: add billing and usage domain cores
This commit is contained in:
1 parent
48dd5d07c8
commit
5e60bb40e7
14 files changed
+931
No files matched your search
@@ -0,0 +1,68 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/billing"
|
||||
)
|
||||
|
||||
const ListBillingPriceRulesSQL = `SELECT id, provider, capability, req_key, unit, standard_unit_price_fen, markup_multiplier, enabled, conditions, quantity_source, priority, parameter_dimensions
|
||||
FROM public.billing_price_rules
|
||||
WHERE ($1::boolean OR enabled = true)
|
||||
ORDER BY provider, capability, id`
|
||||
|
||||
type BillingWalletPoster struct{ database *Database }
|
||||
|
||||
func NewBillingWalletPoster(database *Database) BillingWalletPoster {
|
||||
return BillingWalletPoster{database: database}
|
||||
}
|
||||
func (poster BillingWalletPoster) PostWalletEntry(ctx context.Context, p billing.WalletPostParams) (billing.WalletPosting, error) {
|
||||
metadata, err := json.Marshal(p.Metadata)
|
||||
if err != nil {
|
||||
return billing.WalletPosting{}, fmt.Errorf("encode wallet metadata: %w", err)
|
||||
}
|
||||
row, err := poster.database.PostWalletEntry(ctx, WalletEntryParams{LedgerID: p.LedgerID, OrganizationID: p.OrganizationID, AccountID: p.AccountID, JobID: p.JobID, Kind: p.Kind, DeltaFen: p.DeltaFen, Currency: p.Currency, IdempotencyKey: p.IdempotencyKey, Description: p.Description, Metadata: metadata})
|
||||
if err != nil {
|
||||
return billing.WalletPosting{}, err
|
||||
}
|
||||
return billing.WalletPosting{LedgerID: row.LedgerID, BalanceAfterFen: row.BalanceAfterFen, BalanceFen: row.BalanceFen, TotalRechargedFen: row.TotalRechargedFen, TotalChargedFen: row.TotalChargedFen, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, DeltaFen: row.DeltaFen}, nil
|
||||
}
|
||||
|
||||
func (db *Database) ListBillingPriceRules(ctx context.Context, includeDisabled bool) ([]billing.PriceRule, error) {
|
||||
if db.config.Backend != BackendPostgres || db.querier == nil {
|
||||
return nil, fmt.Errorf("PostgreSQL is unavailable when ZHINIAN_DATA_BACKEND=%s", db.config.Backend)
|
||||
}
|
||||
rows, err := db.querier.Query(ctx, ListBillingPriceRulesSQL, includeDisabled)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list billing price rules: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var out []billing.PriceRule
|
||||
for rows.Next() {
|
||||
var rule billing.PriceRule
|
||||
var req, quantity sql.NullString
|
||||
var conditions, dimensions json.RawMessage
|
||||
if err := rows.Scan(&rule.ID, &rule.Provider, &rule.Capability, &req, &rule.Unit, &rule.StandardUnitPriceFen, &rule.MarkupMultiplier, &rule.Enabled, &conditions, &quantity, &rule.Priority, &dimensions); err != nil {
|
||||
return nil, fmt.Errorf("scan billing price rule: %w", err)
|
||||
}
|
||||
rule.ReqKey = req.String
|
||||
rule.QuantitySource = billing.QuantitySource(quantity.String)
|
||||
if len(conditions) > 0 {
|
||||
if err := json.Unmarshal(conditions, &rule.Conditions); err != nil {
|
||||
return nil, fmt.Errorf("decode billing conditions: %w", err)
|
||||
}
|
||||
}
|
||||
if len(dimensions) > 0 {
|
||||
if err := json.Unmarshal(dimensions, &rule.Dimensions); err != nil {
|
||||
return nil, fmt.Errorf("decode billing dimensions: %w", err)
|
||||
}
|
||||
}
|
||||
out = append(out, rule)
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
var _ billing.WalletPoster = BillingWalletPoster{}
|
||||
Reference in new issue
Block a user