writekit/internal/db/tenants.go
2026-01-09 00:16:46 +02:00

147 lines
4 KiB
Go

package db
import (
"context"
"github.com/jackc/pgx/v5"
)
func (db *DB) GetTenantBySubdomain(ctx context.Context, subdomain string) (*Tenant, error) {
var t Tenant
var ownerID, customDomain *string
err := db.pool.QueryRow(ctx,
`SELECT id, owner_id, subdomain, custom_domain, premium, members_enabled, donations_enabled, created_at
FROM tenants WHERE subdomain = $1`,
subdomain).Scan(&t.ID, &ownerID, &t.Subdomain, &customDomain, &t.Premium,
&t.MembersEnabled, &t.DonationsEnabled, &t.CreatedAt)
if err == pgx.ErrNoRows {
return nil, nil
}
if ownerID != nil {
t.OwnerID = *ownerID
}
if customDomain != nil {
t.CustomDomain = *customDomain
}
return &t, err
}
func (db *DB) GetTenantByOwner(ctx context.Context, ownerID string) (*Tenant, error) {
var t Tenant
var owner, customDomain *string
err := db.pool.QueryRow(ctx,
`SELECT id, owner_id, subdomain, custom_domain, premium, members_enabled, donations_enabled, created_at
FROM tenants WHERE owner_id = $1`,
ownerID).Scan(&t.ID, &owner, &t.Subdomain, &customDomain, &t.Premium,
&t.MembersEnabled, &t.DonationsEnabled, &t.CreatedAt)
if err == pgx.ErrNoRows {
return nil, nil
}
if owner != nil {
t.OwnerID = *owner
}
if customDomain != nil {
t.CustomDomain = *customDomain
}
return &t, err
}
func (db *DB) CreateTenant(ctx context.Context, ownerID, subdomain string) (*Tenant, error) {
var t Tenant
err := db.pool.QueryRow(ctx,
`INSERT INTO tenants (owner_id, subdomain)
VALUES ($1, $2)
RETURNING id, owner_id, subdomain, custom_domain, premium, members_enabled, donations_enabled, created_at`,
ownerID, subdomain).Scan(&t.ID, &t.OwnerID, &t.Subdomain, &t.CustomDomain, &t.Premium,
&t.MembersEnabled, &t.DonationsEnabled, &t.CreatedAt)
return &t, err
}
func (db *DB) GetTenantByID(ctx context.Context, id string) (*Tenant, error) {
var t Tenant
var ownerID, customDomain *string
err := db.pool.QueryRow(ctx,
`SELECT id, owner_id, subdomain, custom_domain, premium, members_enabled, donations_enabled, created_at
FROM tenants WHERE id = $1`,
id).Scan(&t.ID, &ownerID, &t.Subdomain, &customDomain, &t.Premium,
&t.MembersEnabled, &t.DonationsEnabled, &t.CreatedAt)
if err == pgx.ErrNoRows {
return nil, nil
}
if ownerID != nil {
t.OwnerID = *ownerID
}
if customDomain != nil {
t.CustomDomain = *customDomain
}
return &t, err
}
func (db *DB) IsUserTenantOwner(ctx context.Context, userID, tenantID string) (bool, error) {
var exists bool
err := db.pool.QueryRow(ctx,
`SELECT EXISTS(SELECT 1 FROM tenants WHERE id = $1 AND owner_id = $2)`,
tenantID, userID).Scan(&exists)
return exists, err
}
func (db *DB) IsSubdomainAvailable(ctx context.Context, subdomain string) (bool, error) {
var exists bool
err := db.pool.QueryRow(ctx,
`SELECT EXISTS(SELECT 1 FROM reserved_subdomains WHERE subdomain = $1)`,
subdomain).Scan(&exists)
if err != nil {
return false, err
}
if exists {
return false, nil
}
err = db.pool.QueryRow(ctx,
`SELECT EXISTS(SELECT 1 FROM demos WHERE subdomain = $1 AND expires_at > NOW())`,
subdomain).Scan(&exists)
if err != nil {
return false, err
}
if exists {
return false, nil
}
err = db.pool.QueryRow(ctx,
`SELECT EXISTS(SELECT 1 FROM tenants WHERE subdomain = $1)`,
subdomain).Scan(&exists)
if err != nil {
return false, err
}
return !exists, nil
}
func (db *DB) ListTenants(ctx context.Context) ([]Tenant, error) {
rows, err := db.pool.Query(ctx,
`SELECT id, owner_id, subdomain, custom_domain, premium, members_enabled, donations_enabled, created_at
FROM tenants`)
if err != nil {
return nil, err
}
defer rows.Close()
var tenants []Tenant
for rows.Next() {
var t Tenant
var ownerID, customDomain *string
if err := rows.Scan(&t.ID, &ownerID, &t.Subdomain, &customDomain, &t.Premium,
&t.MembersEnabled, &t.DonationsEnabled, &t.CreatedAt); err != nil {
return nil, err
}
if ownerID != nil {
t.OwnerID = *ownerID
}
if customDomain != nil {
t.CustomDomain = *customDomain
}
tenants = append(tenants, t)
}
return tenants, rows.Err()
}