syntax = "proto3";

package nominal.iceberg.v1;

import "buf/validate/validate.proto";
import "google/protobuf/timestamp.proto";
import "nominal/protos/iceberg/v1/table.proto";

option java_multiple_files = true;
option java_package = "io.nominal.iceberg.v1";

// One Parquet file just uploaded to object storage by the streaming Iceberg
// writer. The downstream committer reads these from a Kafka "WAL" topic,
// groups them per Iceberg TableIdentifier, and registers them with Iceberg in
// a single AppendFiles per (table, batch) snapshot.
//
// The writer encodes the full table target (namespace + table name) AND the
// resolved partition value the file belongs in.
//
// File-level statistics (row count, column min/max, split offsets, file size)
// are derived commit ParquetUtil.fileMetrics(...) so the WAL schema stays independent of Iceberg internals.
//
// The Kafka record key is DatasetRid so all files for one dataset land on the same partition.
// The producer is the authority on table location — the consumer never re-derives namespaces.
message IcebergFileWrittenEvent {
  // Full Iceberg table location (namespace + table name).
  TableTarget table = 1 [(buf.validate.field).required = true];

  // Pre-computed Iceberg partition value. For series tables (identity partition
  // on int month) this is raw yyyymm; for data tables (month(timestamp)
  // transform) this is months-since-epoch. The committer passes this through
  // unchanged to PartitionData.set(0, ...).
  int32 partition_value = 2;

  // Storage-agnostic object key, e.g. s3://… URIs for S3/MinIO or gs://… URIs for GCS.
  // The Iceberg catalog's FileIO resolves the appropriate cheme at commit time.
  // Also used as the dedupe key for the snapshot-summary ledger (nominal.appended-paths), so producers must
  // emit deterministic keys across writer retries.
  string object_key = 3 [(buf.validate.field).string.min_len = 1];

  // Wall-clock ingest timestamp captured by the writer, primarily for
  // observability (lag, end-to-end latency monitoring).
  google.protobuf.Timestamp ingested_at = 4;
}
