Files
chapter-organizer/tools/GoogleSheetsScheduleImport/MappingConfig.cs
poprhythm f400813667 Update EventOccurrence parsing to use EventOccurrenceParseGroup for improved data structure
This commit refactors the EventOccurrence parsing logic to utilize the EventOccurrenceParseGroup class, enhancing the organization of parsed occurrences by grouping them based on event definitions and optional section levels. The changes include updates to the EventOccurrenceParseResult, EventOccurrenceParser, and EventOccurrenceParserService to accommodate the new grouping structure. Additionally, tests are modified to reflect these changes, ensuring that the parsing functionality remains intact and accurate. This refactor improves data handling and aligns with the overall architecture of the application.
2026-04-04 21:55:44 -04:00

62 lines
2.4 KiB
C#

using System.Text.Json.Serialization;
namespace GoogleSheetsScheduleImport;
/// <summary>
/// JSON config: sheet tab titles mapped to calendar days plus optional defaults.
/// </summary>
public sealed class MappingConfig
{
/// <summary>Calendar year for occurrence dates (overridden by CLI --year).</summary>
public int? Year { get; set; }
/// <summary>
/// Emitted before occurrence lines for each sheet (unless overridden per sheet).
/// Use "General Schedule" when grid cells are generic schedule items.
/// </summary>
public string? DefaultSectionHeader { get; set; }
/// <summary>Per-sheet overrides and day mapping.</summary>
public List<SheetDayMapping>? Sheets { get; set; }
/// <summary>
/// Event titles (cell text) to treat as site-wide: one output line per date+time, no location.
/// If omitted, built-in rules still include CURFEW.
/// </summary>
public List<string>? SiteWideEventNames { get; set; }
/// <summary>
/// Path to event definitions CSV (column <c>Event</c>), relative to this mapping file or absolute.
/// When set (or when <c>--events-csv</c> is passed), output is grouped into <c>Event - MS/HS</c> sections when possible.
/// </summary>
public string? EventDefinitionsCsv { get; set; }
}
public sealed class SheetDayMapping
{
/// <summary>Exact tab title as it appears in Google Sheets.</summary>
public string Title { get; set; } = "";
/// <summary>Month name matching EventOccurrenceGrammar (e.g. "April").</summary>
public string Month { get; set; } = "";
/// <summary>Day of month (1-31).</summary>
public int Day { get; set; }
/// <summary>Optional section header line for this tab only (e.g. "General Schedule" or "Biotechnology - MS").</summary>
public string? SectionHeader { get; set; }
[JsonIgnore]
public string? NormalizedMonth => string.IsNullOrWhiteSpace(Month) ? null : Month.Trim();
public void Validate()
{
if (string.IsNullOrWhiteSpace(Title))
throw new InvalidOperationException("Mapping entry must include a non-empty Title (sheet tab name).");
if (string.IsNullOrWhiteSpace(Month))
throw new InvalidOperationException($"Sheet '{Title}': Month is required.");
if (Day is < 1 or > 31)
throw new InvalidOperationException($"Sheet '{Title}': Day must be between 1 and 31.");
}
}