140 lines
4.2 KiB
Go
140 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/szabadpalya/api/internal/store"
|
|
"github.com/szabadpalya/api/test/seeddata"
|
|
)
|
|
|
|
// reset clears the campaign side of the database. Relations cascade, so
|
|
// campaigns and owners are enough; users go too because the seed's
|
|
// pledges are anonymous and any account left behind would be an orphan.
|
|
func (s *seeder) reset(ctx context.Context) error {
|
|
for _, table := range []string{"Pledge", "Campaign", "Owner", "User"} {
|
|
if _, err := s.pool.Exec(ctx, fmt.Sprintf(`DELETE FROM %q`, table)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// campaign writes one fixture campaign and returns how many pledges it created
|
|
// and what they add up to.
|
|
func (s *seeder) campaign(ctx context.Context, c seeddata.Campaign) (int, int, error) {
|
|
endsAt, err := s.store.EndOfDay(c.EndsAt)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
tx, err := s.pool.Begin(ctx)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
defer tx.Rollback(ctx)
|
|
|
|
var ownerID string
|
|
if err := tx.QueryRow(ctx, `
|
|
INSERT INTO "Owner" ("id","slug","name","initials","location","blurb","avatarUrl","approved")
|
|
VALUES ($1,$2,$3,$4,$5,$6,NULLIF($7,''),true)
|
|
ON CONFLICT ("slug") DO UPDATE SET "name" = EXCLUDED."name"
|
|
RETURNING "id"`,
|
|
store.NewID(), c.Owner.Slug, c.Owner.Name, c.Owner.Initials, c.Owner.Location, c.Owner.Blurb,
|
|
c.Owner.AvatarURL,
|
|
).Scan(&ownerID); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
campaignID := store.NewID()
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "Campaign" ("id","slug","title","category","summary","art","goalAmount",
|
|
"endsAt","status","ownerId")
|
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9::"CampaignStatus",$10)`,
|
|
campaignID, c.Slug, c.Title, c.Category, c.Summary, c.Art, c.GoalAmount,
|
|
endsAt, c.Status, ownerID); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
for i, sec := range c.Story {
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "StorySection" ("id","campaignId","heading","body","position")
|
|
VALUES ($1,$2,$3,$4,$5)`,
|
|
store.NewID(), campaignID, sec.Heading, sec.Body, i); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
|
|
// Was the goal reached? That decides whether physical tiers were charged.
|
|
raised := 0
|
|
for _, t := range c.Tiers {
|
|
raised += t.Price * t.Backers
|
|
}
|
|
goalReached := raised >= c.GoalAmount
|
|
|
|
pledgeCount := 0
|
|
now := time.Now()
|
|
for i, t := range c.Tiers {
|
|
var delivery *time.Time
|
|
if t.EstimatedDelivery != "" {
|
|
d, err := s.store.EndOfDay(t.EstimatedDelivery)
|
|
if err != nil {
|
|
return 0, 0, err
|
|
}
|
|
delivery = &d
|
|
}
|
|
tierID := store.NewID()
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "RewardTier" ("id","campaignId","type","price","listPrice","title",
|
|
"includes","inventoryLimit","estimatedDelivery",
|
|
"featured","position")
|
|
VALUES ($1,$2,$3::"TierType",$4,$5,$6,$7,$8,$9,$10,$11)`,
|
|
tierID, campaignID, t.Type, t.Price, t.ListPrice, t.Title, t.Includes,
|
|
t.InventoryLimit, delivery, t.Featured, i); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
|
|
// A physical tier on a campaign that missed its goal is still only
|
|
// authorized — that is the fulfillment guard, visible in the fixture.
|
|
held := t.Type == "PHYSICAL" && !goalReached
|
|
status := "CAPTURED"
|
|
var capturedAt *time.Time
|
|
if held {
|
|
status = "AUTHORIZED"
|
|
} else {
|
|
capturedAt = &now
|
|
}
|
|
|
|
for n := 0; n < t.Backers; n++ {
|
|
pledgeCount++
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "Pledge" ("id","campaignId","tierId","backerEmail","quantity",
|
|
"amount","status","capturedAt")
|
|
VALUES ($1,$2,$3,$4,1,$5,$6::"PledgeStatus",$7)`,
|
|
store.NewID(), campaignID, tierID,
|
|
fmt.Sprintf("tamogato-%s@example.invalid", store.NewID()),
|
|
t.Price, status, capturedAt); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
}
|
|
|
|
for _, u := range c.Updates {
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "CampaignUpdate" ("id","campaignId","title","body")
|
|
VALUES ($1,$2,$3,$4)`, store.NewID(), campaignID, u.Title, u.Body); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
for _, m := range c.Comments {
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO "Comment" ("id","campaignId","authorName","body")
|
|
VALUES ($1,$2,$3,$4)`, store.NewID(), campaignID, m.AuthorName, m.Body); err != nil {
|
|
return 0, 0, err
|
|
}
|
|
}
|
|
|
|
return pledgeCount, raised, tx.Commit(ctx)
|
|
}
|