Import Melee matches exports, add tests and local podman stack
- Parse Melee matches exports (one round per file, byes, null GameWins); one import form detects matches vs standings exports. Re-importing a round replaces just that round and keeps entered decks. - Per-player deck entry for sessions scored from matches. - node:test suite with anonymised fixtures; lockfile. - scripts/local.sh runs the compose stack under podman with its own .env.local, project name and volume. - README and CLAUDE.md docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a7f440c658
commit
985c85bcef
15 files changed
+2450
-27
No files matched your search
+11
-5
@@ -1,4 +1,5 @@
|
||||
<%- include('head') %>
|
||||
<% if (admin) { %><datalist id="decks"><% known.forEach(k => { %><option value="<%= k %>"><% }) %></datalist><% } %>
|
||||
<h1><%= lg.name %> – Session <%= gs.number %> (<%= gs.date %>)</h1>
|
||||
<p><a href="<%= base %>/league/<%= lg.id %>">← Standings</a></p>
|
||||
<% rounds.forEach(r => { %><h2>Round <%= r.round %></h2><table>
|
||||
@@ -8,20 +9,25 @@
|
||||
<td><b><%= m.p1_wins %>–<%= m.p2_wins %><%= m.draws ? '–' + m.draws : '' %></b></td></tr>
|
||||
<% }) %></table><% }) %>
|
||||
<% if (!rounds.length && !results.length) { %><p>No results yet.</p><% } %>
|
||||
<% if (admin && matchPlayers.length) { %><h2>Decks played</h2>
|
||||
<form method="post" action="<%= base %>/admin/session/<%= gs.id %>/match-decks"><table><tr><th>Player</th><th>Deck</th></tr>
|
||||
<% matchPlayers.forEach(p => { %><tr><td><%= p.name %></td><td><input name="mdeck_<%= p.id %>" value="<%= p.deck || '' %>" list="decks"></td></tr><% }) %></table>
|
||||
<button>Save decks</button></form><% } %>
|
||||
<% if (results.length) { %><h2>Standings <small>(imported)</small></h2>
|
||||
<form method="post" action="<%= base %>/admin/session/<%= gs.id %>/decks">
|
||||
<table><tr><th>Player</th><th>Points</th><th>W-D-L</th><th>Deck</th></tr>
|
||||
<% results.forEach(r => { %><tr><td><%= r.name %></td><td><b><%= r.points %></b></td><td><%= r.rec %></td>
|
||||
<td><% if (admin) { %><input name="deck_<%= r.id %>" value="<%= r.deck || '' %>" list="decks"><% } else { %><%= r.deck || '' %><% } %></td></tr><% }) %></table>
|
||||
<% if (admin) { %><datalist id="decks"><% known.forEach(k => { %><option value="<%= k %>"><% }) %></datalist><button>Save decks</button><% } %>
|
||||
<% if (admin) { %><button>Save decks</button><% } %>
|
||||
</form>
|
||||
<p><small>If this session also has match rows, those are used for scoring instead.</small></p><% } %>
|
||||
<% if (admin) { %>
|
||||
<h2>Import Melee standings export</h2>
|
||||
<p>Upload the CSV/JSON from Melee's Standings tab (or paste it). Saving replaces this session's imported standings but keeps decks already entered.</p>
|
||||
<form method="post" enctype="multipart/form-data" action="<%= base %>/admin/session/<%= gs.id %>/import-standings">
|
||||
<h2>Import Melee export</h2>
|
||||
<p>Upload a <b>matches</b> or <b>standings</b> export from Melee (JSON or CSV), or paste it. A matches export holds one round, so import each round in turn;
|
||||
re-importing a round replaces just that round. Decks you've entered are kept. If a session has matches, they are used for scoring.</p>
|
||||
<form method="post" enctype="multipart/form-data" action="<%= base %>/admin/session/<%= gs.id %>/import-melee">
|
||||
<input type="file" name="file" accept=".csv,.json,.txt"><br>
|
||||
<textarea name="data" rows="5" style="width:100%;font-family:monospace" placeholder="...or paste here"></textarea><br><button>Import standings</button></form>
|
||||
<textarea name="data" rows="5" style="width:100%;font-family:monospace" placeholder="...or paste here"></textarea><br><button>Import</button></form>
|
||||
<h2>Import matches by hand</h2>
|
||||
<p>One match per line: <code>round, player1, deck1, player2, deck2, p1 wins, p2 wins, draws</code>. Leave player 2 blank for a bye.
|
||||
Comma- or tab-separated. Saving <b>replaces</b> this session's matches.</p>
|
||||
|
||||
Reference in new issue
Block a user