package storage import ( "context" "errors" "time" "github.com/jackc/pgx/v5" ) // ShareLink — состояние ссылки «только просмотр» на дашборд клиники (без самого токена). type ShareLink struct { Exists bool `json:"exists"` CreatedAt *time.Time `json:"created_at"` LastUsedAt *time.Time `json:"last_used_at"` } // SetShareLink выпускает ссылку клиники: прежняя перестаёт работать. func (s *Storage) SetShareLink(ctx context.Context, clinic, tokenHash string, adminID int64) error { _, err := s.pool.Exec(ctx, ` INSERT INTO share_links (clinic, token_hash, admin_id) VALUES ($1,$2,$3) ON CONFLICT (clinic) DO UPDATE SET token_hash=EXCLUDED.token_hash, admin_id=EXCLUDED.admin_id, created_at=now(), last_used_at=NULL`, clinic, tokenHash, adminID) return err } func (s *Storage) DeleteShareLink(ctx context.Context, clinic string) error { _, err := s.pool.Exec(ctx, `DELETE FROM share_links WHERE clinic=$1`, clinic) return err } func (s *Storage) ShareLinkInfo(ctx context.Context, clinic string) (ShareLink, error) { var l ShareLink err := s.pool.QueryRow(ctx, `SELECT created_at, last_used_at FROM share_links WHERE clinic=$1`, clinic). Scan(&l.CreatedAt, &l.LastUsedAt) if errors.Is(err, pgx.ErrNoRows) { return ShareLink{}, nil } l.Exists = err == nil return l, err } // ShareLinkClinic — клиника по хешу токена (заодно отмечает время открытия); // ErrNotFound, если ссылки нет или её перевыпустили. func (s *Storage) ShareLinkClinic(ctx context.Context, tokenHash string) (string, error) { var clinic string err := s.pool.QueryRow(ctx, ` UPDATE share_links SET last_used_at = now() WHERE token_hash = $1 RETURNING clinic`, tokenHash).Scan(&clinic) if errors.Is(err, pgx.ErrNoRows) { return "", ErrNotFound } return clinic, err }