package user import ( "context" "fmt" "github.com/jackc/pgx/v5/pgxpool" ) // SuperadminStore verwaltet mandantenuebergreifende Superadmin-Konten in der // Control-Plane-Registry (siehe internal/tenant.Registry). Superadmin-ohne- // Tenant ist dadurch ein eigener Typ statt eines Sonderfalls von User/ // TenantUserStore — es gibt keinen Tenant-Parameter, den man weglassen // koennte (IAM-01, "ohne Sonderbehandlung im Code"). type SuperadminStore struct { pool *pgxpool.Pool } func NewSuperadminStore(pool *pgxpool.Pool) *SuperadminStore { return &SuperadminStore{pool: pool} } func (s *SuperadminStore) Create(ctx context.Context, email, name string) (User, error) { if err := ValidateEmail(email); err != nil { return User{}, err } var u User u.Email, u.Name, u.Status = email, name, StatusActive row := s.pool.QueryRow(ctx, ` INSERT INTO superadmins (email, name, status) VALUES ($1, $2, $3) RETURNING id, created_at, updated_at `, u.Email, u.Name, u.Status) if err := row.Scan(&u.ID, &u.CreatedAt, &u.UpdatedAt); err != nil { return User{}, mapWriteErr(err) } return u, nil } func (s *SuperadminStore) Get(ctx context.Context, id string) (User, error) { return scanUser(s.pool.QueryRow(ctx, ` SELECT id, email, name, status, created_at, updated_at FROM superadmins WHERE id = $1 `, id)) } func (s *SuperadminStore) List(ctx context.Context) ([]User, error) { rows, err := s.pool.Query(ctx, ` SELECT id, email, name, status, created_at, updated_at FROM superadmins ORDER BY created_at `) if err != nil { return nil, fmt.Errorf("superadmins auflisten: %w", err) } defer rows.Close() var out []User for rows.Next() { var u User if err := rows.Scan(&u.ID, &u.Email, &u.Name, &u.Status, &u.CreatedAt, &u.UpdatedAt); err != nil { return nil, fmt.Errorf("superadmin lesen: %w", err) } out = append(out, u) } return out, rows.Err() } func (s *SuperadminStore) Deactivate(ctx context.Context, id string) (User, error) { return scanUser(s.pool.QueryRow(ctx, ` UPDATE superadmins SET status = $2, updated_at = now() WHERE id = $1 RETURNING id, email, name, status, created_at, updated_at `, id, StatusInactive)) }