- PlayerService with CRUD, FTS5 typeahead search, duplicate merge, CSV import - CSV import safety limits: 10K rows, 20 columns, 1K chars/field - QR code generation per player using skip2/go-qrcode library - Tournament player operations: register, bust, undo bust - TournamentPlayerDetail with computed investment, net result, action history - RankingEngine derives positions from ordered bust-out list (never stored) - RecalculateAllRankings for undo consistency - All mutations record audit entries and broadcast via WebSocket Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31 lines
811 B
Go
31 lines
811 B
Go
package player
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
qrcode "github.com/skip2/go-qrcode"
|
|
)
|
|
|
|
// QRCodeSize is the default QR code image size in pixels.
|
|
const QRCodeSize = 256
|
|
|
|
// GenerateQRCode generates a QR code PNG image encoding the player UUID.
|
|
// The QR code encodes a URL in the format: felt://player/{uuid}
|
|
// This is intended for future PWA self-check-in via camera scan.
|
|
func (s *Service) GenerateQRCode(ctx context.Context, playerID string) ([]byte, error) {
|
|
// Verify player exists
|
|
_, err := s.GetPlayer(ctx, playerID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Generate QR code with player URL
|
|
url := fmt.Sprintf("felt://player/%s", playerID)
|
|
png, err := qrcode.Encode(url, qrcode.Medium, QRCodeSize)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("player: generate QR code: %w", err)
|
|
}
|
|
|
|
return png, nil
|
|
}
|