// Command seed creates demo users, a family group and a few messages. // It is idempotent: existing usernames are left untouched. package main import ( "context" "fmt" "os" "messenger/internal/auth" "messenger/internal/platform/config" "messenger/internal/platform/logger" "messenger/internal/store" "github.com/jackc/pgx/v5/pgxpool" ) type seedUser struct { username string displayName string password string } var demoUsers = []seedUser{ {"papa", "Папа", "password123"}, {"mama", "Мама", "password123"}, {"syn", "Сын", "password123"}, {"doch", "Дочь", "password123"}, } func main() { log := logger.New() cfg, err := config.Load() if err != nil { log.Error("invalid configuration", "error", err) os.Exit(1) } ctx := context.Background() pool, err := pgxpool.New(ctx, cfg.DatabaseURL) if err != nil { log.Error("failed to connect", "error", err) os.Exit(1) } defer pool.Close() st := store.New(pool) if err := st.Migrate(ctx); err != nil { log.Error("migration failed", "error", err) os.Exit(1) } created, err := ensureUsers(ctx, st) if err != nil { log.Error("seed users failed", "error", err) os.Exit(1) } fmt.Printf("users created: %d\n", created) group, err := ensureGroup(ctx, st) if err != nil { log.Error("seed group failed", "error", err) os.Exit(1) } fmt.Printf("group ready: %s (id=%d)\n", group.Name, group.ID) } func ensureUsers(ctx context.Context, st *store.Store) (int, error) { created := 0 for _, u := range demoUsers { if _, err := st.GetUserByUsername(ctx, u.username); err == nil { continue } hash, err := auth.HashPassword(u.password) if err != nil { return created, err } if _, err := st.CreateUser(ctx, u.username, u.displayName, hash); err != nil { return created, err } created++ } return created, nil } func ensureGroup(ctx context.Context, st *store.Store) (*store.Conversation, error) { users := make([]int64, 0, len(demoUsers)) var ownerID int64 for _, u := range demoUsers { user, err := st.GetUserByUsername(ctx, u.username) if err != nil { return nil, fmt.Errorf("user %s missing: %w", u.username, err) } if ownerID == 0 { ownerID = user.ID } users = append(users, user.ID) } // Reuse an existing group with the same name if present. conversations, err := st.ListConversationsForUser(ctx, ownerID) if err != nil { return nil, err } for i := range conversations { if conversations[i].Type == "group" && conversations[i].Name == "Семья" { return &conversations[i].Conversation, nil } } group, err := st.CreateGroup(ctx, ownerID, "Семья", users[1:]) if err != nil { return nil, err } if _, err := st.InsertMessage(ctx, group.ID, ownerID, "Всем привет! Это наша семейная группа.", nil); err != nil { return nil, err } return group, nil }