完善生图5.0的功能

This commit is contained in:
andy committed 2026-08-25 14:06:04 +08:00
1 parent 88a4268d40
commit 678d213f40
31 files changed
+3281 -107

No files matched your search

@@ -51,7 +51,11 @@ func (db *Database) ChargeAndActivateCreation(ctx context.Context, request billi
}
var posting WalletEntry
if !rows.Next() {
rowsErr := rows.Err()
rows.Close()
if rowsErr != nil {
return nil, fmt.Errorf("charge and activate generation creation: read wallet: %w", rowsErr)
}
return nil, fmt.Errorf("charge and activate generation creation: wallet returned no row")
}
if err := rows.Scan(&posting.LedgerID, &posting.BalanceAfterFen, &posting.BalanceFen, &posting.TotalRechargedFen, &posting.TotalChargedFen, &posting.CreatedAt, &posting.UpdatedAt, &posting.DeltaFen); err != nil {
@@ -79,7 +83,11 @@ func (db *Database) ChargeAndActivateCreation(ctx context.Context, request billi
return nil, fmt.Errorf("charge and activate generation creation: activate job: %w", err)
}
if !activation.Next() {
rowsErr := activation.Err()
activation.Close()
if rowsErr != nil {
return nil, fmt.Errorf("charge and activate generation creation: read activation: %w", rowsErr)
}
return nil, fmt.Errorf("charge and activate generation creation: job is not pending")
}
var id string
@@ -48,6 +48,34 @@ func TestChargeAndActivateCreationRollsBackWhenActivationFails(t *testing.T) {
}
}
func TestChargeAndActivateCreationPreservesDeferredWalletError(t *testing.T) {
deferred := &pgconn.PgError{Code: "P0001", Message: "BILLING_INSUFFICIENT_BALANCE"}
tx := &generationStateTransaction{results: []*jobRows{{err: deferred}}}
db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx})
_, err := db.ChargeAndActivateCreation(context.Background(), billing.ChargeRequest{OrganizationID: "org", JobID: "job", AmountFen: 39}, json.RawMessage(`{"status":"pending"}`))
var postgresErr *pgconn.PgError
if !errors.As(err, &postgresErr) || postgresErr.Code != "P0001" || tx.rollbacks != 1 {
t.Fatalf("err=%v postgres=%#v rollbacks=%d", err, postgresErr, tx.rollbacks)
}
}
func TestChargeAndActivateCreationPreservesDeferredActivationError(t *testing.T) {
now := time.Now()
deferred := &pgconn.PgError{Code: "40001", Message: "could not serialize access"}
tx := &generationStateTransaction{results: []*jobRows{
{rows: [][]any{{"ledger-1", int64(1), int64(1), int64(1), int64(1), now, now, int64(-1)}}},
{err: deferred},
}}
db := NewDatabase(Config{Backend: BackendPostgres}, &generationStatePool{tx: tx})
_, err := db.ChargeAndActivateCreation(context.Background(), billing.ChargeRequest{OrganizationID: "org", JobID: "job", AmountFen: 1}, json.RawMessage(`{"status":"pending"}`))
var postgresErr *pgconn.PgError
if !errors.As(err, &postgresErr) || postgresErr.Code != "40001" || tx.rollbacks != 1 {
t.Fatalf("err=%v postgres=%#v rollbacks=%d", err, postgresErr, tx.rollbacks)
}
}
func TestChargeAndActivateCreationTreatsCommittedButLostResponseAsSuccess(t *testing.T) {
now := time.Date(2026, 8, 13, 8, 0, 0, 0, time.UTC)
charged := json.RawMessage(`{"status":"charged","amountFen":35,"ledgerEntryId":"ledger-1"}`)