# Metadata Exporter

This directory holds the downstream-first metadata export tool.

Goal:

1. read live metadata state from the current database
2. export a raw `metadata/` directory outside the database (raw mode)
3. export pack-shaped `objects/` directory matching L2 pack format (pack mode)
4. compare two exports to identify drift between environments

## Two export modes

### Raw mode (default)

Exports raw metadata tables:

```bash
python3 packs/metadata-exporter/exporter.py \
  --dsn "$MYSQL_DSN" \
  --output-dir /tmp/live-metadata-export \
  --mode raw
```

Output:

```
tmp/live-metadata-export/
  metadata/
    _System_Object.json
    _System_Field.json
    ...
```

### Pack mode

Exports component-shaped metadata focused on L1/L2 drift review:

```bash
python3 packs/metadata-exporter/exporter.py \
  --dsn "$MYSQL_DSN" \
  --output-dir /tmp/live-metadata-export \
  --mode pack
```

Output:

```
tmp/live-metadata-export/
  objects/
    Account.json
    Contact.json
    Opportunity.json
    CustomObject__c.json
  record_types/
    record_types.json
  validation/
    standard_validation_rules.json
  permissions/
    crm_standard_permissions.json
  report_types/
    standard_report_types.json
  layouts/
    account_account_layout_curated.json
    ...
  flow_definitions/
    flow_definitions.json
  .component-index.json
```

`pack` mode is intentionally diff-first, not round-trip-authoritative.
It is designed to answer:

1. what changed between two environments
2. which changes look like pack-owned / L1
3. which changes look like admin-authored / L2

## Compare two exports

After exporting two environments, compare the **exporter output directories**:

```bash
python3 packs/metadata-exporter/compare.py \
  --left /tmp/export-staging \
  --right /tmp/export-prod \
  --output /tmp/diff-report.md
```

Text format (default):

```bash
python3 packs/metadata-exporter/compare.py \
  --left /tmp/export-staging \
  --right /tmp/export-prod
```

JSON format:

```bash
python3 packs/metadata-exporter/compare.py \
  --left /tmp/export-staging \
  --right /tmp/export-prod \
  --format json
```

Include live Salesforce-vs-TiDB data drift from a reconcile summary:

```bash
python3 packs/metadata-exporter/compare.py \
  --left /tmp/export-staging \
  --right /tmp/export-prod \
  --reconcile-summary docs/migration/2026-05-25-212801-prod-reconcile-gap-backfill/reconcile-mismatch-summary.json
```

When `--reconcile-summary` is provided, the report adds:

1. missing-only objects
2. extra-only objects
3. mixed-drift objects
4. non-zero exit status when live data drift exists even if metadata files match

## Typical workflow

1. Export staging metadata:
   ```bash
   python3 exporter.py --dsn "mysql://user:pass@staging-host:4000/db?tls=true" \
     --output-dir /tmp/staging-export --mode pack
   ```

2. Export prod metadata:
   ```bash
   python3 exporter.py --dsn "mysql://user:pass@prod-host:4000/db?tls=true" \
     --output-dir /tmp/prod-export --mode pack
   ```

3. Compare:
   ```bash
   python3 compare.py --left /tmp/staging-export --right /tmp/prod-export
   ```

## Output contract

The exporter should write:

1. a pack root directory
2. stable JSON formatting
3. deterministic file ordering
4. for raw mode: a `metadata/` directory whose filenames match table names
5. for pack mode: an `objects/` directory matching L2 pack structure

The intent is:

```text
live DB metadata -> exported pack directory -> diff / diagnosis
```

## Layout

```text
packs/metadata-exporter/
  README.md
  spec.md
  exporter.py    # export tool (raw + pack modes)
  compare.py     # diff two exports
```
