Files
descrybe/apps/api/cmd/sync-plans/main.go
T

66 lines
1.8 KiB
Go
Raw Normal View History

// Command sync-plans upserts public Free→Enterprise ladder meters into Postgres.
// Usage (from apps/api):
//
// go run ./cmd/sync-plans -postgres "$DATABASE_URL"
package main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"time"
"github.com/descrybe/descrybe-v2/apps/api/internal/billing"
"github.com/jackc/pgx/v5/pgxpool"
)
func main() {
pg := flag.String("postgres", os.Getenv("DATABASE_URL"), "Postgres DATABASE_URL")
flag.Parse()
if strings.TrimSpace(*pg) == "" {
fmt.Fprintln(os.Stderr, "DATABASE_URL or -postgres required")
os.Exit(1)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
pool, err := pgxpool.New(ctx, *pg)
if err != nil {
fmt.Fprintf(os.Stderr, "connect: %v\n", err)
os.Exit(1)
}
defer pool.Close()
svc := &billing.Service{Pool: pool}
if err := svc.EnsureDefaultPlans(ctx); err != nil {
fmt.Fprintf(os.Stderr, "EnsureDefaultPlans: %v\n", err)
os.Exit(1)
}
rows, err := pool.Query(ctx, `
SELECT name, monthly_credits, COALESCE(max_products::text, 'unlimited')
FROM plans
WHERE lower(name) IN ('free','starter','plus','growth','business','scale','enterprise')
ORDER BY CASE lower(name)
WHEN 'free' THEN 0 WHEN 'starter' THEN 1 WHEN 'plus' THEN 2 WHEN 'growth' THEN 3
WHEN 'business' THEN 4 WHEN 'scale' THEN 5 WHEN 'enterprise' THEN 6 ELSE 9 END`)
if err != nil {
fmt.Fprintf(os.Stderr, "list: %v\n", err)
os.Exit(1)
}
defer rows.Close()
fmt.Println("Public plans synced:")
for rows.Next() {
var name, maxP string
var credits int
if err := rows.Scan(&name, &credits, &maxP); err != nil {
fmt.Fprintf(os.Stderr, "scan: %v\n", err)
os.Exit(1)
}
fmt.Printf(" %-12s credits=%-8d max_products=%s\n", name, credits, maxP)
}
if err := rows.Err(); err != nil {
fmt.Fprintf(os.Stderr, "rows: %v\n", err)
os.Exit(1)
}
}