acumatica-cli 0.34.0__tar.gz → 0.36.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/PKG-INFO +89 -66
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/README.md +88 -65
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/pyproject.toml +1 -1
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/pyproject.toml.orig +1 -1
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap.py +17 -18
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/cli.py +417 -277
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/client.py +206 -20
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/config.py +130 -75
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/extract.py +22 -19
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/output.py +21 -1
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/reconcile.py +0 -2
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/run.py +101 -20
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/seed.py +380 -87
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/seed_catalog.yaml +49 -49
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/state.py +29 -3
- acumatica_cli-0.36.0/src/acumatica_cli/templates/README.md +60 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/overlays/README.md +13 -21
- acumatica_cli-0.36.0/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +17 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/tenant.py +99 -13
- acumatica_cli-0.34.0/src/acumatica_cli/templates/README.md +0 -62
- acumatica_cli-0.34.0/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +0 -12
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/__init__.py +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap_plugin.cs +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/bootstrap_project.xml +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/firstlogin.py +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/inventory.py +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/models.py +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/10-subaccounts.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/20-accounts.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/40-ledger.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/50-gl-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/60-ledger-company.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/90-uoms.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/baseline/91-company-packaging.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/company.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/credit-terms.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/features.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/bootstrap/segmented-key.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/05-numbering-sequences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/10-reason-codes.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/20-in-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/30-availability-rules.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/40-posting-classes.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/50-warehouse.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/51-warehouse-locations.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/52-warehouse-defaults.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/53-tax-categories.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/54-item-classes.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/56-so-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/57-po-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/58-order-types.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/60-ar-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/61-ap-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/62-ca-preferences.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/63-cash-account.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/64-payment-methods.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/65-statement-cycles.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/70-vendor-classes.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/71-customer-classes.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/75-vendors.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/76-customers.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/80-stock-items-parts.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/82-stock-items-kits.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/85-kit-specifications.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/90-roles.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/91-users.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/master/92-role-users.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/10-financial-year.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/20-master-calendar.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/setup/30-open-periods.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/config → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-config}/views/10-trial-balance.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/10-seed-capital.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/20-buy.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/30-build.yaml +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/acu-scenario}/40-sell.yaml +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/env +0 -0
- {acumatica_cli-0.34.0 → acumatica_cli-0.36.0}/src/acumatica_cli/templates/gitignore +0 -0
- {acumatica_cli-0.34.0/src/acumatica_cli/templates/overlays/default-24.200.001/scenario → acumatica_cli-0.36.0/src/acumatica_cli/templates/overlays/default-24.200.001/acu-scenario}/30-build.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: acumatica-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.36.0
|
|
4
4
|
Summary: Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data
|
|
5
5
|
Author: Konstantin Borovik
|
|
6
6
|
Author-email: Konstantin Borovik <kb@lab5.ca>
|
|
@@ -38,18 +38,18 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
|
|
|
38
38
|
|
|
39
39
|
| You can | Command | Effect |
|
|
40
40
|
| ------- | ------- | ------ |
|
|
41
|
-
| Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
|
|
41
|
+
| Seed a tenant from YAML | `apply` | Idempotent PUT of `acu-config/` into the live tenant |
|
|
42
42
|
| Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
|
|
43
|
-
| Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
|
|
44
|
-
| Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
|
|
43
|
+
| Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `acu-config/{bootstrap,baseline,setup,master}/` |
|
|
44
|
+
| Run transaction scripts | `run` | Forward documents from `acu-scenario/` (capital, buy, build, sell) |
|
|
45
45
|
| Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
|
|
46
46
|
| Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
|
|
47
47
|
| Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
|
|
48
48
|
| Prove a cold rebuild | `tenant create` then `apply` then `run` then `diff` | Compose on a fresh tenant. No wrap command. |
|
|
49
49
|
| Snapshot a site offline | `survey inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
|
|
50
|
-
| Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `
|
|
50
|
+
| Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `--config` writes `findings/` only |
|
|
51
51
|
| Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
|
|
52
|
-
| Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
|
|
52
|
+
| Scaffold a data repo | `config init` | Full `acu-config/`, `acu-scenario/`, `.env` tree |
|
|
53
53
|
| Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
|
|
54
54
|
|
|
55
55
|
Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
|
|
@@ -72,13 +72,13 @@ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
|
|
|
72
72
|
acu config check # read-only preflight
|
|
73
73
|
acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
|
|
74
74
|
# or hosted: acu --tenant DEV bootstrap
|
|
75
|
-
acu --tenant DEV apply config
|
|
76
|
-
acu --tenant DEV run scenario
|
|
77
|
-
acu --tenant DEV diff config
|
|
78
|
-
acu --tenant DEV state
|
|
75
|
+
acu --tenant DEV apply acu-config # seed acu-config/{bootstrap,baseline,setup,master}/
|
|
76
|
+
acu --tenant DEV run acu-scenario # once capital → buy → build → sell
|
|
77
|
+
acu --tenant DEV diff acu-config # prove zero drift (exit 2 on drift)
|
|
78
|
+
acu --tenant DEV state acu-config/views # capture state/ trial-balance
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
apply / diff / run / state require an explicit data path.
|
|
82
82
|
|
|
83
83
|
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
84
84
|
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
@@ -88,8 +88,8 @@ acu config init --host customer.acumatica.com my-erp
|
|
|
88
88
|
cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
|
|
89
89
|
acu config check # REST preflight; ssh probe is skipped
|
|
90
90
|
acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
|
|
91
|
-
acu --tenant DEV apply config
|
|
92
|
-
acu --tenant DEV diff config
|
|
91
|
+
acu --tenant DEV apply acu-config
|
|
92
|
+
acu --tenant DEV diff acu-config
|
|
93
93
|
# offline UI fallback when REST publish is blocked:
|
|
94
94
|
acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
|
|
95
95
|
```
|
|
@@ -110,43 +110,41 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
110
110
|
│ └── recycle [--yes] restart site app pool (tenant map + free API slots)
|
|
111
111
|
│
|
|
112
112
|
├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
|
|
113
|
-
├── apply [--dry-run]
|
|
114
|
-
├── diff
|
|
115
|
-
├── run [--dry-run]
|
|
116
|
-
├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run]
|
|
113
|
+
├── apply [--dry-run] <FILES...> push YAML via REST (idempotent PUT upserts)
|
|
114
|
+
├── diff <FILES...> drift check vs the live tenant (exit 2 on drift)
|
|
115
|
+
├── run [--dry-run] <FILES...> execute transaction scenario YAML (exit 1 on any miss)
|
|
116
|
+
├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] <FILES...>
|
|
117
117
|
│ capture derived state into state/ (not seed)
|
|
118
118
|
├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
|
|
119
119
|
│ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
|
|
120
|
-
│ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
|
|
120
|
+
│ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
|
|
121
121
|
│ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
|
|
122
122
|
│ │ offline snapshot artifact → inventory/ (not seed)
|
|
123
123
|
│ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
|
|
124
|
-
│ inventory/ + optional config
|
|
124
|
+
│ inventory/ + optional --config DIR → findings/ only
|
|
125
125
|
├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
|
|
126
126
|
│
|
|
127
127
|
└── config configuration ops
|
|
128
|
-
├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
|
|
128
|
+
├── init [--host HOST] [DIR] scaffold full data repo (acu-config/, acu-scenario/, .env)
|
|
129
129
|
├── show print the resolved config as a complete .env
|
|
130
130
|
└── check preflight: discovery, secrets, REST, endpoints, SSH
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
`apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
- `run` defaults to `scenario/`.
|
|
139
|
-
- `state` defaults to `config/views/`; writes go to `state/` (`--out`).
|
|
135
|
+
A dir with SEED_DIRS children (`bootstrap|baseline|setup|master`) expands those subdirs in that order. Typed path is used as given (`acu apply acu-config`, or `acu apply config/` if that dir exists).
|
|
136
|
+
|
|
137
|
+
`--out` defaults: `state` → `state/`; `survey extract` → `acu-config/` (SEED_DIRS into that root); `survey inventory` → `inventory/`; `survey reconcile` → `findings/`; `schema` → `schemas/`.
|
|
140
138
|
|
|
141
139
|
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
142
|
-
`config/views` and `state` keep Period pinned.
|
|
140
|
+
`acu-config/views` and `state` keep Period pinned.
|
|
143
141
|
|
|
144
|
-
`survey extract`
|
|
142
|
+
`survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
|
|
145
143
|
|
|
146
144
|
`survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
|
|
147
145
|
`survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
148
146
|
|
|
149
|
-
`survey reconcile` compares `inventory/` to optional
|
|
147
|
+
`survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
|
|
150
148
|
It never writes seed.
|
|
151
149
|
|
|
152
150
|
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
@@ -166,19 +164,52 @@ Do not confuse them with each other or with `state`:
|
|
|
166
164
|
|
|
167
165
|
| Command | Plane | Input | Writes | Role |
|
|
168
166
|
| ------- | ----- | ----- | ------ | ---- |
|
|
169
|
-
| `survey extract` | REST (live) | tenant via contract API | `config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
|
|
167
|
+
| `survey extract` | REST (live) | tenant via contract API | `acu-config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
|
|
170
168
|
| `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
|
|
171
|
-
| `survey reconcile` | Offline | `inventory/` + optional
|
|
172
|
-
| `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
173
|
-
| `apply` | REST (live) | seed YAML under `config/` | tenant | **Sole** tenant writer (keyed PUT) |
|
|
169
|
+
| `survey reconcile` | Offline | `inventory/` + optional `--config DIR` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
|
|
170
|
+
| `state` | REST (live) | `acu-config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
171
|
+
| `apply` | REST (live) | seed YAML under `acu-config/` | tenant | **Sole** tenant writer (keyed PUT) |
|
|
174
172
|
|
|
175
173
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
176
174
|
Binary `.adb` snapshots are rejected (XML only).
|
|
177
175
|
|
|
176
|
+
### Machine-readable output (`--output json`)
|
|
177
|
+
|
|
178
|
+
`acu --output json <diff|apply|run|state> ...` prints one JSON document on stdout; progress and result lines move to stderr.
|
|
179
|
+
Exit codes do not change (`diff` still exits 2 on drift), and other commands ignore the flag.
|
|
180
|
+
|
|
181
|
+
`diff`:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"command": "diff", "tenant": "DEV", "base_url": "https://...", "drift": 1,
|
|
186
|
+
"files": [{
|
|
187
|
+
"file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
|
|
188
|
+
"records": 2,
|
|
189
|
+
"drifts": [{
|
|
190
|
+
"file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
|
|
191
|
+
"keys": {"UOM": "KG"}, "field": "Description", "kind": "changed",
|
|
192
|
+
"source": "Kilogram", "live": "kg",
|
|
193
|
+
"text": "UnitsOfMeasure [KG].Description: source='Kilogram' live='kg'"
|
|
194
|
+
}]
|
|
195
|
+
}]
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
- `kind`: `changed`, `missing`, `extra` (detail row), `not_returned` or `not_applied` (setup action).
|
|
200
|
+
- `field`: path below the record (e.g. `Details[A].Qty`); `""` when the record itself is missing.
|
|
201
|
+
- `source` / `live`: set only for `changed`.
|
|
202
|
+
|
|
203
|
+
- `apply`: `{command, tenant, mode (all|plan|changed|dry_run), ok, failed, counts, errors, stopped, not_applied, files: [{file, entity, ok, errors}]}`; `counts` keys `create`, `update`, `unchanged`, `invoke`, `put`.
|
|
204
|
+
- `run`: `{command, tenant, counts: {passed, failed, skipped, not_run}, scenarios: [{file, outcome, misses, error?}], not_run}`; `misses` = failed expectation lines.
|
|
205
|
+
- `state`: `{command, tenant, mode (write|diff|assert), exit, changed, views: [{view, file, rows, status (wrote|changed|unchanged), differences}]}`.
|
|
206
|
+
|
|
178
207
|
## The data repo
|
|
179
208
|
|
|
180
209
|
Your configuration lives in its own git repo.
|
|
181
|
-
`acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
|
|
210
|
+
`acu config init` scaffolds a **single full seed** under `acu-config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `acu-scenario/`, observer `acu-config/views/`, and README.
|
|
211
|
+
|
|
212
|
+
It does not write a customization tree.
|
|
182
213
|
|
|
183
214
|
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
184
215
|
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
@@ -187,38 +218,36 @@ There is no `--flavor`.
|
|
|
187
218
|
|
|
188
219
|
| Path | What it holds |
|
|
189
220
|
| ---- | ------------- |
|
|
190
|
-
| `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
191
|
-
| `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
192
|
-
| `config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
193
|
-
| `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
194
|
-
| `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
195
|
-
| `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
221
|
+
| `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
222
|
+
| `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
223
|
+
| `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
224
|
+
| `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
225
|
+
| `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
226
|
+
| `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
196
227
|
| `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
|
|
197
228
|
| `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
|
|
198
229
|
| `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
|
|
199
230
|
| `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
|
|
200
231
|
|
|
201
|
-
Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
|
|
202
|
-
|
|
203
232
|
Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
|
|
204
233
|
Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
|
|
205
234
|
|
|
206
235
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
207
|
-
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
236
|
+
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
208
237
|
|
|
209
238
|
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
210
239
|
|
|
211
|
-
Features synthesize to `config/bootstrap/features.yaml`.
|
|
240
|
+
Features synthesize to `acu-config/bootstrap/features.yaml`.
|
|
212
241
|
Existing files skip unless `--force`; empty live sets skip.
|
|
213
242
|
|
|
214
243
|
Row failures continue (exit 1 only if any row failed).
|
|
215
244
|
Drift stays with `diff`.
|
|
216
245
|
|
|
217
246
|
```sh
|
|
218
|
-
acu --tenant DEV survey extract --
|
|
219
|
-
git diff config/ # review extract delta before commit
|
|
220
|
-
acu --tenant DEV apply config
|
|
221
|
-
acu --tenant DEV diff config
|
|
247
|
+
acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
|
|
248
|
+
git diff acu-config/ # review extract delta before commit
|
|
249
|
+
acu --tenant DEV apply acu-config # replay extracted seed
|
|
250
|
+
acu --tenant DEV diff acu-config # expect exit 0
|
|
222
251
|
```
|
|
223
252
|
### Seed `endpoint:` symbols
|
|
224
253
|
|
|
@@ -286,7 +315,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
286
315
|
|
|
287
316
|
| Piece | Role |
|
|
288
317
|
| ----- | ---- |
|
|
289
|
-
| Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
|
|
318
|
+
| Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
|
|
290
319
|
| `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
|
|
291
320
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
292
321
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
@@ -294,21 +323,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
294
323
|
**Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
|
|
295
324
|
No `--overlay` flag.
|
|
296
325
|
|
|
297
|
-
|
|
298
|
-
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
326
|
+
Pass overlay trees as extra explicit paths when you need them.
|
|
299
327
|
|
|
300
328
|
Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
|
|
301
|
-
Explicit path args disable auto-compose.
|
|
302
329
|
|
|
303
330
|
```sh
|
|
304
|
-
# ACU_API_VERSION=24.200.001
|
|
305
|
-
acu apply
|
|
306
|
-
acu
|
|
307
|
-
acu
|
|
308
|
-
|
|
309
|
-
# explicit path args (no auto) — later path wins same keys
|
|
310
|
-
acu apply config/ overlays/default-24.200.001/
|
|
311
|
-
acu diff config/ overlays/default-24.200.001/
|
|
331
|
+
# ACU_API_VERSION=24.200.001 — this overlay is scenario-only
|
|
332
|
+
acu apply acu-config
|
|
333
|
+
acu diff acu-config
|
|
334
|
+
acu run acu-scenario overlays/default-24.200.001/acu-scenario/
|
|
312
335
|
```
|
|
313
336
|
|
|
314
337
|
Add a future half by creating `overlays/default-<new-half>/` with the
|
|
@@ -391,7 +414,7 @@ Per-bug contract probes fold onto those tenants.
|
|
|
391
414
|
Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
|
|
392
415
|
|
|
393
416
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
394
|
-
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
417
|
+
The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
|
|
395
418
|
|
|
396
419
|
```sh
|
|
397
420
|
gmake e2e # whole tier, three files
|
|
@@ -402,7 +425,7 @@ gmake e2e FILE=test_extract_roundtrip # extract inverse
|
|
|
402
425
|
|
|
403
426
|
### CLI test-seed soak
|
|
404
427
|
|
|
405
|
-
This checkout carries a CLI test seed at repo-root `config/` and `scenario/` (no `config
|
|
428
|
+
This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
|
|
406
429
|
Soak the live CLI tenant from here with `--tenant ACUCLI`.
|
|
407
430
|
|
|
408
431
|
Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
@@ -411,10 +434,10 @@ Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
|
411
434
|
That path is not the soak.
|
|
412
435
|
|
|
413
436
|
```sh
|
|
414
|
-
uv run acu --tenant ACUCLI apply
|
|
415
|
-
uv run acu --tenant ACUCLI run
|
|
416
|
-
uv run acu --tenant ACUCLI diff
|
|
417
|
-
uv run acu --tenant ACUCLI state
|
|
437
|
+
uv run acu --tenant ACUCLI apply acu-config
|
|
438
|
+
uv run acu --tenant ACUCLI run acu-scenario
|
|
439
|
+
uv run acu --tenant ACUCLI diff acu-config
|
|
440
|
+
uv run acu --tenant ACUCLI state acu-config/views
|
|
418
441
|
```
|
|
419
442
|
|
|
420
443
|
## License
|
|
@@ -20,18 +20,18 @@ YAML in git is the source of truth; the live tenant is the target. `apply` is th
|
|
|
20
20
|
|
|
21
21
|
| You can | Command | Effect |
|
|
22
22
|
| ------- | ------- | ------ |
|
|
23
|
-
| Seed a tenant from YAML | `apply` | Idempotent PUT of `config/` into the live tenant |
|
|
23
|
+
| Seed a tenant from YAML | `apply` | Idempotent PUT of `acu-config/` into the live tenant |
|
|
24
24
|
| Detect drift | `diff` | Compare seed YAML to live (exit 2 when they diverge) |
|
|
25
|
-
| Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `config/{bootstrap,baseline,setup,master}/` |
|
|
26
|
-
| Run transaction scripts | `run` | Forward documents from `scenario/` (capital, buy, build, sell) |
|
|
25
|
+
| Pull live config into YAML | `survey extract` | Inverse of `apply` — GET into `acu-config/{bootstrap,baseline,setup,master}/` |
|
|
26
|
+
| Run transaction scripts | `run` | Forward documents from `acu-scenario/` (capital, buy, build, sell) |
|
|
27
27
|
| Capture derived balances | `state` | Inquire trial-balance etc. into `state/` (not seed) |
|
|
28
28
|
| Create and destroy tenants | `tenant` | SSH control plane: list / create / delete / recycle |
|
|
29
29
|
| Publish the Bootstrap contract | `bootstrap` | REST publish of AcuBootstrap (or `--export` zip for the UI) |
|
|
30
30
|
| Prove a cold rebuild | `tenant create` then `apply` then `run` then `diff` | Compose on a fresh tenant. No wrap command. |
|
|
31
31
|
| Snapshot a site offline | `survey inventory` | SM203520 XML ZIP or `ac.exe export xml` writes `inventory/` |
|
|
32
|
-
| Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `
|
|
32
|
+
| Cross-check snapshot vs seed | `survey reconcile` | `inventory/` plus optional `--config` writes `findings/` only |
|
|
33
33
|
| Dump the contract schema | `schema` | OpenAPI `swagger.json` for the pinned endpoint |
|
|
34
|
-
| Scaffold a data repo | `config init` | Full `config/`, `scenario/`, `.env` tree |
|
|
34
|
+
| Scaffold a data repo | `config init` | Full `acu-config/`, `acu-scenario/`, `.env` tree |
|
|
35
35
|
| Preflight a target | `config check` | Discovery, secrets, REST, endpoints, SSH |
|
|
36
36
|
|
|
37
37
|
Seed YAML covers features, company, credit terms, subaccounts, chart of accounts, ledger, UOMs, financial year / calendar / periods, numbering sequences, inventory and distribution masters, roles, and users.
|
|
@@ -54,13 +54,13 @@ cd my-erp # edit .env: ACU_PASSWORD, ACU_TENANT
|
|
|
54
54
|
acu config check # read-only preflight
|
|
55
55
|
acu tenant create --login DEV # create + bootstrap (SSH; --id optional)
|
|
56
56
|
# or hosted: acu --tenant DEV bootstrap
|
|
57
|
-
acu --tenant DEV apply config
|
|
58
|
-
acu --tenant DEV run scenario
|
|
59
|
-
acu --tenant DEV diff config
|
|
60
|
-
acu --tenant DEV state
|
|
57
|
+
acu --tenant DEV apply acu-config # seed acu-config/{bootstrap,baseline,setup,master}/
|
|
58
|
+
acu --tenant DEV run acu-scenario # once capital → buy → build → sell
|
|
59
|
+
acu --tenant DEV diff acu-config # prove zero drift (exit 2 on drift)
|
|
60
|
+
acu --tenant DEV state acu-config/views # capture state/ trial-balance
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
apply / diff / run / state require an explicit data path.
|
|
64
64
|
|
|
65
65
|
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
66
66
|
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
@@ -70,8 +70,8 @@ acu config init --host customer.acumatica.com my-erp
|
|
|
70
70
|
cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
|
|
71
71
|
acu config check # REST preflight; ssh probe is skipped
|
|
72
72
|
acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
|
|
73
|
-
acu --tenant DEV apply config
|
|
74
|
-
acu --tenant DEV diff config
|
|
73
|
+
acu --tenant DEV apply acu-config
|
|
74
|
+
acu --tenant DEV diff acu-config
|
|
75
75
|
# offline UI fallback when REST publish is blocked:
|
|
76
76
|
acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
|
|
77
77
|
```
|
|
@@ -92,43 +92,41 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
92
92
|
│ └── recycle [--yes] restart site app pool (tenant map + free API slots)
|
|
93
93
|
│
|
|
94
94
|
├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
|
|
95
|
-
├── apply [--dry-run]
|
|
96
|
-
├── diff
|
|
97
|
-
├── run [--dry-run]
|
|
98
|
-
├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run]
|
|
95
|
+
├── apply [--dry-run] <FILES...> push YAML via REST (idempotent PUT upserts)
|
|
96
|
+
├── diff <FILES...> drift check vs the live tenant (exit 2 on drift)
|
|
97
|
+
├── run [--dry-run] <FILES...> execute transaction scenario YAML (exit 1 on any miss)
|
|
98
|
+
├── state [--out DIR] [--diff] [--assert-unchanged] [--dry-run] <FILES...>
|
|
99
99
|
│ capture derived state into state/ (not seed)
|
|
100
100
|
├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
|
|
101
101
|
│ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
|
|
102
|
-
│ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
|
|
102
|
+
│ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
|
|
103
103
|
│ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
|
|
104
104
|
│ │ offline snapshot artifact → inventory/ (not seed)
|
|
105
105
|
│ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
|
|
106
|
-
│ inventory/ + optional config
|
|
106
|
+
│ inventory/ + optional --config DIR → findings/ only
|
|
107
107
|
├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
|
|
108
108
|
│
|
|
109
109
|
└── config configuration ops
|
|
110
|
-
├── init [--host HOST] [DIR] scaffold full data repo (config/, scenario/, .env)
|
|
110
|
+
├── init [--host HOST] [DIR] scaffold full data repo (acu-config/, acu-scenario/, .env)
|
|
111
111
|
├── show print the resolved config as a complete .env
|
|
112
112
|
└── check preflight: discovery, secrets, REST, endpoints, SSH
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
`apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- `run` defaults to `scenario/`.
|
|
121
|
-
- `state` defaults to `config/views/`; writes go to `state/` (`--out`).
|
|
117
|
+
A dir with SEED_DIRS children (`bootstrap|baseline|setup|master`) expands those subdirs in that order. Typed path is used as given (`acu apply acu-config`, or `acu apply config/` if that dir exists).
|
|
118
|
+
|
|
119
|
+
`--out` defaults: `state` → `state/`; `survey extract` → `acu-config/` (SEED_DIRS into that root); `survey inventory` → `inventory/`; `survey reconcile` → `findings/`; `schema` → `schemas/`.
|
|
122
120
|
|
|
123
121
|
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
124
|
-
`config/views` and `state` keep Period pinned.
|
|
122
|
+
`acu-config/views` and `state` keep Period pinned.
|
|
125
123
|
|
|
126
|
-
`survey extract`
|
|
124
|
+
`survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
|
|
127
125
|
|
|
128
126
|
`survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
|
|
129
127
|
`survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
130
128
|
|
|
131
|
-
`survey reconcile` compares `inventory/` to optional
|
|
129
|
+
`survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
|
|
132
130
|
It never writes seed.
|
|
133
131
|
|
|
134
132
|
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
@@ -148,19 +146,52 @@ Do not confuse them with each other or with `state`:
|
|
|
148
146
|
|
|
149
147
|
| Command | Plane | Input | Writes | Role |
|
|
150
148
|
| ------- | ----- | ----- | ------ | ---- |
|
|
151
|
-
| `survey extract` | REST (live) | tenant via contract API | `config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
|
|
149
|
+
| `survey extract` | REST (live) | tenant via contract API | `acu-config/{bootstrap,baseline,setup,master}/` | Inverse of `apply` — seed YAML |
|
|
152
150
|
| `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
|
|
153
|
-
| `survey reconcile` | Offline | `inventory/` + optional
|
|
154
|
-
| `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
155
|
-
| `apply` | REST (live) | seed YAML under `config/` | tenant | **Sole** tenant writer (keyed PUT) |
|
|
151
|
+
| `survey reconcile` | Offline | `inventory/` + optional `--config DIR` | `findings/` only | Cross-check gaps/deltas — never mutates seed or tenant |
|
|
152
|
+
| `state` | REST (live) | `acu-config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
153
|
+
| `apply` | REST (live) | seed YAML under `acu-config/` | tenant | **Sole** tenant writer (keyed PUT) |
|
|
156
154
|
|
|
157
155
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
158
156
|
Binary `.adb` snapshots are rejected (XML only).
|
|
159
157
|
|
|
158
|
+
### Machine-readable output (`--output json`)
|
|
159
|
+
|
|
160
|
+
`acu --output json <diff|apply|run|state> ...` prints one JSON document on stdout; progress and result lines move to stderr.
|
|
161
|
+
Exit codes do not change (`diff` still exits 2 on drift), and other commands ignore the flag.
|
|
162
|
+
|
|
163
|
+
`diff`:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"command": "diff", "tenant": "DEV", "base_url": "https://...", "drift": 1,
|
|
168
|
+
"files": [{
|
|
169
|
+
"file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
|
|
170
|
+
"records": 2,
|
|
171
|
+
"drifts": [{
|
|
172
|
+
"file": "acu-config/baseline/10-uoms.yaml", "entity": "UnitsOfMeasure",
|
|
173
|
+
"keys": {"UOM": "KG"}, "field": "Description", "kind": "changed",
|
|
174
|
+
"source": "Kilogram", "live": "kg",
|
|
175
|
+
"text": "UnitsOfMeasure [KG].Description: source='Kilogram' live='kg'"
|
|
176
|
+
}]
|
|
177
|
+
}]
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
- `kind`: `changed`, `missing`, `extra` (detail row), `not_returned` or `not_applied` (setup action).
|
|
182
|
+
- `field`: path below the record (e.g. `Details[A].Qty`); `""` when the record itself is missing.
|
|
183
|
+
- `source` / `live`: set only for `changed`.
|
|
184
|
+
|
|
185
|
+
- `apply`: `{command, tenant, mode (all|plan|changed|dry_run), ok, failed, counts, errors, stopped, not_applied, files: [{file, entity, ok, errors}]}`; `counts` keys `create`, `update`, `unchanged`, `invoke`, `put`.
|
|
186
|
+
- `run`: `{command, tenant, counts: {passed, failed, skipped, not_run}, scenarios: [{file, outcome, misses, error?}], not_run}`; `misses` = failed expectation lines.
|
|
187
|
+
- `state`: `{command, tenant, mode (write|diff|assert), exit, changed, views: [{view, file, rows, status (wrote|changed|unchanged), differences}]}`.
|
|
188
|
+
|
|
160
189
|
## The data repo
|
|
161
190
|
|
|
162
191
|
Your configuration lives in its own git repo.
|
|
163
|
-
`acu config init` scaffolds a **single full seed** under `config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `scenario/`, observer `config/views/`, and README.
|
|
192
|
+
`acu config init` scaffolds a **single full seed** under `acu-config/` (features, company, credit terms, expanded COA, masters) plus lifecycle `acu-scenario/`, observer `acu-config/views/`, and README.
|
|
193
|
+
|
|
194
|
+
It does not write a customization tree.
|
|
164
195
|
|
|
165
196
|
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
166
197
|
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
@@ -169,38 +200,36 @@ There is no `--flavor`.
|
|
|
169
200
|
|
|
170
201
|
| Path | What it holds |
|
|
171
202
|
| ---- | ------------- |
|
|
172
|
-
| `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
173
|
-
| `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
174
|
-
| `config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
175
|
-
| `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
176
|
-
| `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
177
|
-
| `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
203
|
+
| `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
204
|
+
| `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
205
|
+
| `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
206
|
+
| `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
207
|
+
| `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
208
|
+
| `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
178
209
|
| `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
|
|
179
210
|
| `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
|
|
180
211
|
| `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
|
|
181
212
|
| `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
|
|
182
213
|
|
|
183
|
-
Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
|
|
184
|
-
|
|
185
214
|
Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
|
|
186
215
|
Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
|
|
187
216
|
|
|
188
217
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
189
|
-
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
218
|
+
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
190
219
|
|
|
191
220
|
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
192
221
|
|
|
193
|
-
Features synthesize to `config/bootstrap/features.yaml`.
|
|
222
|
+
Features synthesize to `acu-config/bootstrap/features.yaml`.
|
|
194
223
|
Existing files skip unless `--force`; empty live sets skip.
|
|
195
224
|
|
|
196
225
|
Row failures continue (exit 1 only if any row failed).
|
|
197
226
|
Drift stays with `diff`.
|
|
198
227
|
|
|
199
228
|
```sh
|
|
200
|
-
acu --tenant DEV survey extract --
|
|
201
|
-
git diff config/ # review extract delta before commit
|
|
202
|
-
acu --tenant DEV apply config
|
|
203
|
-
acu --tenant DEV diff config
|
|
229
|
+
acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
|
|
230
|
+
git diff acu-config/ # review extract delta before commit
|
|
231
|
+
acu --tenant DEV apply acu-config # replay extracted seed
|
|
232
|
+
acu --tenant DEV diff acu-config # expect exit 0
|
|
204
233
|
```
|
|
205
234
|
### Seed `endpoint:` symbols
|
|
206
235
|
|
|
@@ -268,7 +297,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
268
297
|
|
|
269
298
|
| Piece | Role |
|
|
270
299
|
| ----- | ---- |
|
|
271
|
-
| Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
|
|
300
|
+
| Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
|
|
272
301
|
| `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
|
|
273
302
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
274
303
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
@@ -276,21 +305,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
276
305
|
**Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
|
|
277
306
|
No `--overlay` flag.
|
|
278
307
|
|
|
279
|
-
|
|
280
|
-
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
308
|
+
Pass overlay trees as extra explicit paths when you need them.
|
|
281
309
|
|
|
282
310
|
Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
|
|
283
|
-
Explicit path args disable auto-compose.
|
|
284
311
|
|
|
285
312
|
```sh
|
|
286
|
-
# ACU_API_VERSION=24.200.001
|
|
287
|
-
acu apply
|
|
288
|
-
acu
|
|
289
|
-
acu
|
|
290
|
-
|
|
291
|
-
# explicit path args (no auto) — later path wins same keys
|
|
292
|
-
acu apply config/ overlays/default-24.200.001/
|
|
293
|
-
acu diff config/ overlays/default-24.200.001/
|
|
313
|
+
# ACU_API_VERSION=24.200.001 — this overlay is scenario-only
|
|
314
|
+
acu apply acu-config
|
|
315
|
+
acu diff acu-config
|
|
316
|
+
acu run acu-scenario overlays/default-24.200.001/acu-scenario/
|
|
294
317
|
```
|
|
295
318
|
|
|
296
319
|
Add a future half by creating `overlays/default-<new-half>/` with the
|
|
@@ -373,7 +396,7 @@ Per-bug contract probes fold onto those tenants.
|
|
|
373
396
|
Each run scaffolds a synthetic single-org company from the packaged `acu config init` templates into a temporary directory, copies the real `.env` into it, and runs the installed `acu` binary from there — no data repo, no pre-existing fixtures on the instance.
|
|
374
397
|
|
|
375
398
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
376
|
-
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
399
|
+
The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
|
|
377
400
|
|
|
378
401
|
```sh
|
|
379
402
|
gmake e2e # whole tier, three files
|
|
@@ -384,7 +407,7 @@ gmake e2e FILE=test_extract_roundtrip # extract inverse
|
|
|
384
407
|
|
|
385
408
|
### CLI test-seed soak
|
|
386
409
|
|
|
387
|
-
This checkout carries a CLI test seed at repo-root `config/` and `scenario/` (no `config
|
|
410
|
+
This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
|
|
388
411
|
Soak the live CLI tenant from here with `--tenant ACUCLI`.
|
|
389
412
|
|
|
390
413
|
Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
@@ -393,10 +416,10 @@ Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
|
393
416
|
That path is not the soak.
|
|
394
417
|
|
|
395
418
|
```sh
|
|
396
|
-
uv run acu --tenant ACUCLI apply
|
|
397
|
-
uv run acu --tenant ACUCLI run
|
|
398
|
-
uv run acu --tenant ACUCLI diff
|
|
399
|
-
uv run acu --tenant ACUCLI state
|
|
419
|
+
uv run acu --tenant ACUCLI apply acu-config
|
|
420
|
+
uv run acu --tenant ACUCLI run acu-scenario
|
|
421
|
+
uv run acu --tenant ACUCLI diff acu-config
|
|
422
|
+
uv run acu --tenant ACUCLI state acu-config/views
|
|
400
423
|
```
|
|
401
424
|
|
|
402
425
|
## License
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "acumatica-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.36.0"
|
|
4
4
|
description = "Acumatica ERP Config-as-Code: tenant provisioning, baseline config, and reference data"
|
|
5
5
|
authors = [{ name = "Konstantin Borovik", email = "kb@lab5.ca" }]
|
|
6
6
|
license = "PolyForm-Noncommercial-1.0.0"
|