version: 1

# Managed load of a ONE-OFF, AD-HOC, provided source (ADR 0018): the frozen Salesforce Revenue__c
# snapshot. There is no managed extract stage — the Parquet was produced once by the audit helper
# `adhoc_extract.py` into a long-retention ad-hoc S3 bucket (#16). This load is the managed half: it
# lists the bucket, infers + solidifies the `source` contract under contracts/upstream/, and COPYs
# into the raw layer, owning only the raw-snapshot product contract (ADR 0016).
#
# Because the bucket holds a single fixed `run-<ts>` snapshot, the filename strategy only ever loads
# on first run (or an explicit backfill/reload) — it never sees new files. Revenue is no longer
# recorded in Salesforce/NexusCRM; the go-forward process is tracked in #19.

load:
  name: salesforce
  engine: databend
  secrets_file: secrets.env

cloud_lake:
  dsn_env: DATABEND_DSN
  databases:
    # Load provisions only the raw layer (ADR 0016).
    raw: salesforce_raw

external:
  uri: s3://pingcap-datalake-adhoc-247906201378-us-west-2/adhoc/salesforce_revenue/revenue_c/
  incremental:
    # Epoch-ms stamp in each object name (run-1748476800000-part-0.parquet). A single fixed stamp
    # means one snapshot, loaded once; later runs find nothing new (idempotent, no new files ever).
    strategy: filename
    pattern: 'run-(?P<ts>\d+)-'
  delta: true
  table: revenue_c
  domain: finance
  owner: data-platform
  system: salesforce
  # one-off ad-hoc lifecycle: the extract is unmanaged (adhoc_extract.py); flagged in the committed
  # source contract under contracts/upstream/ (extensions.lifecycle = one_off_ad_hoc).
  cadence: one_off
  # The external producer enforces no primary key; declare it for raw dedup detection.
  primary_key: [id]
  source_contract:
    purpose: >-
      Source-faithful one-off provided Parquet export of revenue_c landed at
      s3://pingcap-datalake-adhoc-247906201378-us-west-2/adhoc/salesforce_revenue/revenue_c/,
      consumed by the lakehouse load stage. Schema is inferred from a sample object; drift routes
      to a contract update process.
    source:
      description: >-
        One-off provided object-store snapshot export at
        s3://pingcap-datalake-adhoc-247906201378-us-west-2/adhoc/salesforce_revenue/revenue_c/
    assets:
      - produced_by:
          kind: other
          ref: one-off audit helper ingestion/load/s3_bulk_load/sources/salesforce/adhoc_extract.py
    freshness:
      max_age: P3650D
      degrade_after: P3650D
    tests:
      - id: revenue_c_source_contract_declares_one_off_lifecycle
        type: sql
        severity: informational
        description: >-
          Informational check placeholder for the provided one-off source contract; raw/staging/curated
          contracts carry executable parity gates.
        sql: select 1
    governance:
      retention:
        period: P3650D
    extensions:
      lifecycle: one_off_ad_hoc
      managed_extract: false
      row_estimate: 9384
      known_blind_spots:
        - Intra-snapshot changes are collapsed.
        - >-
          Schema is inferred from a sample object; a change routes to a contract update process,
          not a silent overwrite.
        - Primary key is declared in load source config (the external producer does not enforce one).
  raw_contract:
    freshness:
      max_age: P3650D
      degrade_after: P3650D
    tests:
      - id: revenue_c_raw_expected_rows
        type: sql
        severity: blocking
        description: Frozen Revenue__c raw snapshot must keep the expected one-off row count.
        sql: >-
          select row_count from (select count(*) as row_count from
          salesforce_raw.salesforce_revenue_c_snapshots) where row_count <> 9384
      - id: revenue_c_raw_active_rows
        type: sql
        severity: blocking
        description: Frozen Revenue__c raw snapshot must keep the expected active record count and ids.
        sql: >-
          select active_rows, active_ids from (select sum(case when is_deleted = false then 1 else 0 end)
          as active_rows, count(distinct case when is_deleted = false then id end) as active_ids from
          salesforce_raw.salesforce_revenue_c_snapshots) where active_rows <> 7766 or active_ids <> 7766
    governance:
      retention:
        period: P3650D

s3:
  region: us-west-2
  # Read credentials for Databend's s3:// external stage. SSO/STS temporary credentials are fine —
  # the stage carries the SESSION_TOKEN when present. Values live in the ignored secrets.env.
  credentials:
    access_key_id_env: SALESFORCE_S3_ACCESS_KEY_ID
    secret_access_key_env: SALESFORCE_S3_SECRET_ACCESS_KEY
    session_token_env: SALESFORCE_S3_SESSION_TOKEN

governance:
  classifications:
    - restricted
    - financial
    - customer_data
  classification_patterns:
    financial: "amount|revenue|credit|rate|fee"
    customer_data: "account|name"

setup:
  databend:
    files:
      - ingestion/load/s3_bulk_load/setup/databend/salesforce/001_databases.sql

# Provided one-off source: its `source` contract is bootstrapped by inference (`infer-source`) and
# committed under contracts/upstream/. This load owns only the raw-snapshot product contract it
# generates from that upstream (ADR 0015/0016/0018).
source_contracts:
  - ref: ingestion/load/s3_bulk_load/sources/salesforce/contracts/upstream/*.external.source.contract.yaml
