Files
LaDOSE/LaDOSE.Src/LaDOSE.Entity/Sheets/SheetExport.cs
T
darkstack 937b8554dd
Build App / Build (push) Failing after 3s
Docker Compose bot + Google Api
2026-08-06 16:23:50 +02:00

125 lines
4.7 KiB
C#

using System.Collections.Generic;
namespace LaDOSE.Entity
{
/// <summary>
/// One spreadsheet write: the tables to put in it, and which spreadsheet.
/// Not an entity — never mapped by EF. It arrives as SheetExportRequestDTO and is
/// mapped by AutoMapper, same pattern as <see cref="MatchStats"/>, so property names
/// must stay identical to the DTO's.
///
/// The tables are built client-side by $lib/tournaments/cumulative.ts, which reuses the
/// very same buildRanking() that produces the CSV export. That is deliberate: the sheet
/// and the CSV cannot drift because one function produces both.
/// </summary>
public class SheetExportRequest
{
/// <summary>
/// Resolved by SheetsExportService from configuration — never supplied by the caller,
/// so a client cannot aim the export at someone else's spreadsheet.
/// </summary>
public string SpreadsheetId { get; set; }
/// <summary>
/// One tab per selected event, oldest first. Tab N holds events 1..N merged, so the
/// last tab is the full cumulative ranking for the scope.
/// </summary>
public List<SheetTable> Tabs { get; set; } = new List<SheetTable>();
}
/// <summary>One tab: a players x games grid with a Total column.</summary>
public class SheetTable
{
/// <summary>Desired tab title, e.g. "Ranking #1301". Sanitised before use.</summary>
public string Name { get; set; }
/// <summary>
/// Provenance and logging only. Tabs are addressed by title, never by this — see the
/// note on tab identity in SheetsExportService.
/// </summary>
public int EventId { get; set; }
/// <summary>["Players", &lt;game names...&gt;, "Total"].</summary>
public List<string> Header { get; set; } = new List<string>();
public List<SheetRow> Rows { get; set; } = new List<SheetRow>();
/// <summary>
/// Written below the grid, one line per entry, blank row in between. Carries which
/// events went into this tab so a stale or incomplete tab identifies itself.
/// </summary>
public List<string> Footer { get; set; } = new List<string>();
}
public class SheetRow
{
public string Player { get; set; }
/// <summary>Index-aligned with Header[1..^1] — one entry per game column.</summary>
public List<int> Points { get; set; } = new List<int>();
public int Total { get; set; }
}
public class SheetExportResult
{
public string SpreadsheetId { get; set; }
public string SpreadsheetUrl { get; set; }
/// <summary>Which ISheetsWriter did the work — "ServiceAccount", "Logging", ...</summary>
public string Writer { get; set; }
public List<SheetTabResult> Tabs { get; set; } = new List<SheetTabResult>();
/// <summary>Anything the user should know but that did not stop the write, e.g. renames.</summary>
public List<string> Warnings { get; set; } = new List<string>();
}
public class SheetTabResult
{
/// <summary>The title as asked for, before sanitisation.</summary>
public string RequestedName { get; set; }
/// <summary>The title actually written to.</summary>
public string Name { get; set; }
public int Rows { get; set; }
public int Columns { get; set; }
/// <summary>False when an existing tab of that name was rewritten in place.</summary>
public bool Created { get; set; }
}
/// <summary>What the UI needs to render the export panel. Never carries a secret.</summary>
public class SheetsConfig
{
public string Writer { get; set; }
/// <summary>The writer has its credentials and a target spreadsheet is configured.</summary>
public bool Configured { get; set; }
public string SpreadsheetId { get; set; }
public int MaxTabs { get; set; }
public int MaxRowsPerTab { get; set; }
}
/// <summary>
/// Server-side limits and the target spreadsheet, read from the GoogleSheets configuration
/// section. Constructor-injected rather than IOptions, matching how the Challonge and Smash
/// providers take their keys.
/// </summary>
public class SheetsSettings
{
/// <summary>
/// The spreadsheet everything is written to. Reset each year — see .env.example.
/// </summary>
public string SpreadsheetId { get; set; }
public int MaxTabs { get; set; } = 60;
public int MaxRowsPerTab { get; set; } = 5000;
/// <summary>Google caps a tab at 100 chars; this caps the grid width.</summary>
public int MaxColumns { get; set; } = 200;
}
}