(*--------------------------------------------------------------------------- Copyright (c) 2026 Anil Madhavapeddy . All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (** Aggregated daily changes format. This module provides types and JSON codecs for the aggregated daily changes format stored in [.changes/YYYYMMDD.json] files. These files combine all repository changes for a single day into a structured format suitable for broadcasting. *) (** {1 Change Types} *) (** Classification of changes for grouping in broadcasts. *) type change_type = | Feature (** New features or capabilities *) | Bugfix (** Bug fixes *) | Documentation (** Documentation updates *) | Refactor (** Code refactoring *) | New_library (** Initial import of a new library *) | Unknown (** Unclassified changes *) val change_type_of_string : string -> change_type val string_of_change_type : change_type -> string (** {1 Entry Types} *) type commit_range = { from_hash : string; (** Starting commit hash *) to_hash : string; (** Ending commit hash *) count : int; (** Number of commits in range *) } (** Commit range information. *) type entry = { repository : string; (** Repository name *) hour : int; (** Hour of day 0-23 for filtering *) timestamp : Ptime.t; (** RFC3339 timestamp for precise ordering *) summary : string; (** One-line summary of changes *) changes : string list; (** List of change bullet points *) commit_range : commit_range; (** Commits included *) contributors : string list; (** Contributors to these changes *) repo_url : string option; (** Optional repository URL *) change_type : change_type; (** Classification of the change *) } (** A single repository's changes for the day. *) (** {1 Aggregated File Type} *) type t = { date : string; (** ISO date YYYY-MM-DD *) generated_at : Ptime.t; (** When this file was generated *) git_head : string; (** Monorepo HEAD at generation time *) entries : entry list; (** All repository entries for this day *) authors : string list; (** All unique authors for this day *) } (** The complete aggregated daily changes file. *) (** {1 JSON Codecs} *) val jsont : t Jsont.t val entry_jsont : entry Jsont.t (** {1 File I/O} *) val load : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> date:string -> (t, string) result (** Load aggregated changes for a specific date. [date] should be in YYYY-MM-DD format. *) val load_range : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> from_date:string -> to_date:string -> (t list, string) result (** Load all aggregated changes files in date range. Dates should be in YYYY-MM-DD format. *) val latest : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> (t option, string) result (** Load the most recent aggregated changes file. *) val save : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> t -> (unit, string) result (** Save aggregated changes to the appropriate file. *)