package org import ( "context" "fmt" "regexp" "strings" "go.b0esche.cloud/backend/internal/database" "github.com/google/uuid" "github.com/jackc/pgconn" ) // ResolveUserOrgs returns the organizations a user belongs to func ResolveUserOrgs(ctx context.Context, db *database.DB, userID uuid.UUID) ([]database.Organization, error) { return db.GetUserOrganizations(ctx, userID) } // CheckMembership checks if user is member of org and returns role func CheckMembership(ctx context.Context, db *database.DB, userID, orgID uuid.UUID) (string, error) { membership, err := db.GetUserMembership(ctx, userID, orgID) if err != nil { return "", err } return membership.Role, nil } // CreateOrg creates a new organization and adds the user as owner func CreateOrg(ctx context.Context, db *database.DB, userID uuid.UUID, name, slug string) (*database.Organization, error) { trimmedName := strings.TrimSpace(name) if trimmedName == "" { return nil, fmt.Errorf("organization name cannot be empty") } baseSlug := slugify(slug) if baseSlug == "" { baseSlug = slugify(trimmedName) } if baseSlug == "" { baseSlug = fmt.Sprintf("org-%s", uuid.NewString()[:8]) } var org *database.Organization var err error // Try a handful of suffixes on unique constraint violation for i := 0; i < 5; i++ { candidate := baseSlug if i > 0 { candidate = fmt.Sprintf("%s-%d", baseSlug, i+1) } org, err = db.CreateOrg(ctx, userID, trimmedName, candidate) if err != nil { if pgErr, ok := err.(*pgconn.PgError); ok && pgErr.Code == "23505" { // Unique violation; try next suffix continue } return nil, err } break } if err != nil { return nil, err } if err = db.AddMembership(ctx, userID, org.ID, "owner"); err != nil { return nil, err } return org, nil } // slugify converts a string to a URL-safe slug with hyphens. func slugify(s string) string { lower := strings.ToLower(strings.TrimSpace(s)) if lower == "" { return "" } // Replace non-alphanumeric with hyphen re := regexp.MustCompile(`[^a-z0-9]+`) slug := re.ReplaceAllString(lower, "-") slug = strings.Trim(slug, "-") // Collapse multiple hyphens slug = strings.ReplaceAll(slug, "--", "-") return slug }