Documentation
¶
Overview ¶
Package export builds results-populated XLSX workbooks from live mobile-app tournament state. It is a SEPARATE path from the blank-template export in internal/engine/export.go; the existing ExportCompetitionXlsx and GET /api/competitions/:id/export endpoint are not modified.
The single public entry point is BuildResultsWorkbook. Follow-up agents (CLI command + HTTP handler) call it to get the xlsx bytes.
Index ¶
- Variables
- func BuildResultsWorkbook(store *state.Store, eng *engine.Engine, compID string) ([]byte, error)
- func DecisionSuffix(decision string, encho *state.EnchoMetadata, decidedByHantei bool) string
- func FlagsScorePair(a, b int) (string, string)
- func IpponsScore(ippons []string) string
- func MiddleCellText(decision, suffix string) string
Constants ¶
This section is empty.
Variables ¶
var ErrCompetitionNotFound = errors.New("competition not found")
ErrCompetitionNotFound is returned by BuildResultsWorkbook when the competition ID does not exist, so the handler can map it to HTTP 404 (matching every other competition endpoint) rather than an opaque 500.
var ErrSwissExportUnsupported = errors.New("results export is not supported for Swiss competitions; use the live standings view")
ErrSwissExportUnsupported is returned by BuildResultsWorkbook for Swiss-format competitions, which have no static bracket to render. Callers should surface a clear message and point operators at the live Swiss standings instead.
Functions ¶
func BuildResultsWorkbook ¶
BuildResultsWorkbook reads live tournament state and produces a results- populated XLSX workbook for the given competition. Both pool results (scores + standings) and elimination bracket results are included as literal values, so the workbook is suitable for archiving after a live event.
This is a SEPARATE path from Engine.ExportCompetitionXlsx (the blank-template export). That function and the existing GET /api/competitions/:id/export endpoint are not modified.
Download filename served by the handler: "results-<compID>.xlsx".
func DecisionSuffix ¶
func DecisionSuffix(decision string, encho *state.EnchoMetadata, decidedByHantei bool) string
DecisionSuffix returns the display suffix for a match decision, encho, and hantei flag. It follows the canonical JS decisionSuffix() in web-mobile/js/bracket.jsx, including the "Ht" suffix mandated by the "Excel + viewer parity" comment there (FIK 7-5 / 29-6).
Composition order:
- Base decision label: kiken variants -> "Kiken"; fusenpai/fusensho -> "Fus."; daihyosen -> "DH".
- If enchoOn -> append " (E)".
- If hanteiOn -> append " Ht".
DELIBERATE DIVERGENCE from the JS: the JS omits fusensho (the per-bout default WIN) here because the viewer surfaces it via a separate bout badge. A flat spreadsheet cell has no such badge, so this export folds fusensho into the suffix ("Fus.") too, preserving the defaulted-bout signal in the archive rather than dropping it.
A zero/nil Encho (or PeriodCount == 0) is treated as no encho. Returns "" when no suffix applies.
func FlagsScorePair ¶
FlagsScorePair returns the display strings for both sides of an engi bout.
Pairwise rule: when EITHER side has a positive flag count, write BOTH counts numerically (clamping any negative to 0). When both counts are <=0, return ("", "") to leave both cells blank.
Why pairwise? A flag-decided bout (e.g. 5-0) means the losing side genuinely scored zero flags - that "0" is a real score and must appear so the operator can tell "bout was fought and decided 5-0" from "bout was kiken/fusenpai with no flags recorded at all (0-0 but decided without scoring)". By contrast, a kiken/fusenpai decision with no flags on either side has nothing to display, so both cells stay blank.
func IpponsScore ¶
IpponsScore formats an ippon slice as a readable score string: ["M","K"] -> "MK", nil/empty -> "". Mirrors the character-join behaviour in formatIpponsScore (bracket.jsx) without the full display logic (bye/hikiwake special cases live in the caller).
func MiddleCellText ¶
MiddleCellText composes the value for a match's centre "vs" cell from the hikiwake draw marker and the decision suffix. When a match is a draw AND also carries a suffix (a scoreless encho draw -> "X (E)", a hantei-decided draw -> "X Ht", a team encounter drawn into a daihyosen -> "X DH"), BOTH are kept so the exported workbook never loses the draw indicator. This mirrors formatIpponsScore in web-mobile/js/bracket.jsx, which renders "X" + suffix for a scoreless draw. Returns "" when neither applies, so the caller can leave the cell untouched rather than blanking a formula.
Types ¶
This section is empty.