acumatica-cli 0.33.1__tar.gz → 0.35.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.33.1 → acumatica_cli-0.35.0}/PKG-INFO +78 -72
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/README.md +77 -71
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/pyproject.toml +1 -1
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/pyproject.toml.orig +1 -1
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/bootstrap.py +21 -22
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/bootstrap_plugin.cs +1 -1
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/bootstrap_project.xml +22 -9
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/cli.py +136 -188
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/client.py +5 -5
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/config.py +120 -68
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/extract.py +17 -14
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/firstlogin.py +2 -2
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/inventory.py +1 -1
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/reconcile.py +0 -2
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/seed.py +7 -6
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/seed_catalog.yaml +55 -54
- acumatica_cli-0.35.0/src/acumatica_cli/templates/README.md +60 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/05-numbering-sequences.yaml +13 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/templates/overlays/README.md +13 -21
- acumatica_cli-0.35.0/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +17 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/tenant.py +9 -9
- acumatica_cli-0.33.1/src/acumatica_cli/templates/README.md +0 -62
- acumatica_cli-0.33.1/src/acumatica_cli/templates/overlays/default-24.200.001/README.md +0 -12
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/__init__.py +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/models.py +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/output.py +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/run.py +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/snapshot_map.yaml +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/state.py +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/10-subaccounts.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/20-accounts.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/40-ledger.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/50-gl-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/60-ledger-company.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/90-uoms.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/baseline/91-company-packaging.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/bootstrap/company.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/bootstrap/credit-terms.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/bootstrap/features.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/bootstrap/segmented-key.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/10-reason-codes.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/20-in-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/30-availability-rules.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/40-posting-classes.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/50-warehouse.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/51-warehouse-locations.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/52-warehouse-defaults.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/53-tax-categories.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/54-item-classes.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/56-so-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/57-po-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/58-order-types.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/60-ar-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/61-ap-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/62-ca-preferences.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/63-cash-account.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/64-payment-methods.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/65-statement-cycles.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/70-vendor-classes.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/71-customer-classes.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/75-vendors.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/76-customers.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/80-stock-items-parts.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/82-stock-items-kits.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/85-kit-specifications.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/90-roles.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/91-users.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/master/92-role-users.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/setup/10-financial-year.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/setup/20-master-calendar.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/setup/30-open-periods.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/config → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-config}/views/10-trial-balance.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/scenario → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-scenario}/10-seed-capital.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/scenario → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-scenario}/20-buy.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/scenario → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-scenario}/30-build.yaml +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/scenario → acumatica_cli-0.35.0/src/acumatica_cli/templates/acu-scenario}/40-sell.yaml +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/templates/env +0 -0
- {acumatica_cli-0.33.1 → acumatica_cli-0.35.0}/src/acumatica_cli/templates/gitignore +0 -0
- {acumatica_cli-0.33.1/src/acumatica_cli/templates/overlays/default-24.200.001/scenario → acumatica_cli-0.35.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.35.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,14 +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
|
-
|
|
82
|
-
See [docs/demo-seed.md](docs/demo-seed.md) for the entity map, once-guard, apply-order notes, NumberingSequence vs prefs `*NumberingID`, curated *Preferences field depth (V41), and Role/User + password seed rules.
|
|
81
|
+
apply / diff / run / state require an explicit data path.
|
|
83
82
|
|
|
84
83
|
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
85
84
|
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
@@ -89,8 +88,8 @@ acu config init --host customer.acumatica.com my-erp
|
|
|
89
88
|
cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
|
|
90
89
|
acu config check # REST preflight; ssh probe is skipped
|
|
91
90
|
acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
|
|
92
|
-
acu --tenant DEV apply config
|
|
93
|
-
acu --tenant DEV diff config
|
|
91
|
+
acu --tenant DEV apply acu-config
|
|
92
|
+
acu --tenant DEV diff acu-config
|
|
94
93
|
# offline UI fallback when REST publish is blocked:
|
|
95
94
|
acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
|
|
96
95
|
```
|
|
@@ -111,50 +110,46 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
111
110
|
│ └── recycle [--yes] restart site app pool (tenant map + free API slots)
|
|
112
111
|
│
|
|
113
112
|
├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
|
|
114
|
-
├── apply [--dry-run]
|
|
115
|
-
├── diff
|
|
116
|
-
├── run [--dry-run]
|
|
117
|
-
├── 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...>
|
|
118
117
|
│ capture derived state into state/ (not seed)
|
|
119
118
|
├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
|
|
120
119
|
│ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
|
|
121
|
-
│ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
|
|
120
|
+
│ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
|
|
122
121
|
│ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
|
|
123
122
|
│ │ offline snapshot artifact → inventory/ (not seed)
|
|
124
123
|
│ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
|
|
125
|
-
│ inventory/ + optional config
|
|
124
|
+
│ inventory/ + optional --config DIR → findings/ only
|
|
126
125
|
├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
|
|
127
126
|
│
|
|
128
127
|
└── config configuration ops
|
|
129
|
-
├── 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)
|
|
130
129
|
├── show print the resolved config as a complete .env
|
|
131
130
|
└── check preflight: discovery, secrets, REST, endpoints, SSH
|
|
132
131
|
```
|
|
133
132
|
|
|
134
|
-
|
|
133
|
+
`apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
- `run` defaults to `scenario/`.
|
|
140
|
-
- `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/`.
|
|
141
138
|
|
|
142
139
|
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
143
|
-
`config/views` and `state` keep Period pinned
|
|
140
|
+
`acu-config/views` and `state` keep Period pinned.
|
|
144
141
|
|
|
145
|
-
`survey extract`
|
|
142
|
+
`survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
|
|
146
143
|
|
|
147
144
|
`survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
|
|
148
145
|
`survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
149
146
|
|
|
150
|
-
`survey reconcile` compares `inventory/` to optional
|
|
147
|
+
`survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
|
|
151
148
|
It never writes seed.
|
|
152
149
|
|
|
153
150
|
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
154
151
|
It normalizes the join: pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code.
|
|
155
152
|
|
|
156
|
-
See [docs/demo-seed.md](docs/demo-seed.md).
|
|
157
|
-
|
|
158
153
|
`acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
|
|
159
154
|
|
|
160
155
|
Run `acu --help` for the full mental model (workflow, planes, exit codes, command map).
|
|
@@ -169,21 +164,21 @@ Do not confuse them with each other or with `state`:
|
|
|
169
164
|
|
|
170
165
|
| Command | Plane | Input | Writes | Role |
|
|
171
166
|
| ------- | ----- | ----- | ------ | ---- |
|
|
172
|
-
| `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 |
|
|
173
168
|
| `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
|
|
174
|
-
| `survey reconcile` | Offline | `inventory/` + optional
|
|
175
|
-
| `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
176
|
-
| `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) |
|
|
177
172
|
|
|
178
173
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
179
174
|
Binary `.adb` snapshots are rejected (XML only).
|
|
180
175
|
|
|
181
|
-
See [docs/ac-exe.md](docs/ac-exe.md) for export / SM203520 notes and [docs/demo-seed.md](docs/demo-seed.md) for the extract/state/inventory map.
|
|
182
|
-
|
|
183
176
|
## The data repo
|
|
184
177
|
|
|
185
178
|
Your configuration lives in its own git repo.
|
|
186
|
-
`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.
|
|
179
|
+
`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.
|
|
180
|
+
|
|
181
|
+
It does not write a customization tree.
|
|
187
182
|
|
|
188
183
|
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
189
184
|
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
@@ -192,39 +187,36 @@ There is no `--flavor`.
|
|
|
192
187
|
|
|
193
188
|
| Path | What it holds |
|
|
194
189
|
| ---- | ------------- |
|
|
195
|
-
| `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
196
|
-
| `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
197
|
-
| `config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
198
|
-
| `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
199
|
-
| `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
200
|
-
| `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
190
|
+
| `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
191
|
+
| `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
192
|
+
| `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
193
|
+
| `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
194
|
+
| `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
195
|
+
| `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
201
196
|
| `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
|
|
202
197
|
| `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
|
|
203
198
|
| `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
|
|
204
199
|
| `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
|
|
205
200
|
|
|
206
|
-
Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
|
|
207
|
-
|
|
208
201
|
Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
|
|
209
202
|
Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
|
|
210
203
|
|
|
211
204
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
212
|
-
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
205
|
+
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
213
206
|
|
|
214
207
|
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
215
|
-
The demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
|
|
216
208
|
|
|
217
|
-
Features synthesize to `config/bootstrap/features.yaml`.
|
|
209
|
+
Features synthesize to `acu-config/bootstrap/features.yaml`.
|
|
218
210
|
Existing files skip unless `--force`; empty live sets skip.
|
|
219
211
|
|
|
220
212
|
Row failures continue (exit 1 only if any row failed).
|
|
221
213
|
Drift stays with `diff`.
|
|
222
214
|
|
|
223
215
|
```sh
|
|
224
|
-
acu --tenant DEV survey extract --
|
|
225
|
-
git diff config/ # review extract delta before commit
|
|
226
|
-
acu --tenant DEV apply config
|
|
227
|
-
acu --tenant DEV diff config
|
|
216
|
+
acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
|
|
217
|
+
git diff acu-config/ # review extract delta before commit
|
|
218
|
+
acu --tenant DEV apply acu-config # replay extracted seed
|
|
219
|
+
acu --tenant DEV diff acu-config # expect exit 0
|
|
228
220
|
```
|
|
229
221
|
### Seed `endpoint:` symbols
|
|
230
222
|
|
|
@@ -268,7 +260,7 @@ Secrets, REST where, and the Default contract pin live in one `.env` file (`ACU_
|
|
|
268
260
|
Leftover `matrix.yaml` is ignored and never loaded.
|
|
269
261
|
|
|
270
262
|
```sh
|
|
271
|
-
ACU_BASE_URL=http://
|
|
263
|
+
ACU_BASE_URL=http://erp.example.com/AcumaticaERP # REST where (required)
|
|
272
264
|
ACU_API_VERSION=25.200.001 # Default contract half
|
|
273
265
|
ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
|
|
274
266
|
# ACU_SSH omitted → defaults to Administrator@ + resolved base_url host
|
|
@@ -292,7 +284,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
292
284
|
|
|
293
285
|
| Piece | Role |
|
|
294
286
|
| ----- | ---- |
|
|
295
|
-
| Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
|
|
287
|
+
| Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
|
|
296
288
|
| `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
|
|
297
289
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
298
290
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
@@ -300,21 +292,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
300
292
|
**Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
|
|
301
293
|
No `--overlay` flag.
|
|
302
294
|
|
|
303
|
-
|
|
304
|
-
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
295
|
+
Pass overlay trees as extra explicit paths when you need them.
|
|
305
296
|
|
|
306
297
|
Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
|
|
307
|
-
Explicit path args disable auto-compose.
|
|
308
298
|
|
|
309
299
|
```sh
|
|
310
|
-
# ACU_API_VERSION=24.200.001
|
|
311
|
-
acu apply
|
|
312
|
-
acu
|
|
313
|
-
acu
|
|
314
|
-
|
|
315
|
-
# explicit path args (no auto) — later path wins same keys
|
|
316
|
-
acu apply config/ overlays/default-24.200.001/
|
|
317
|
-
acu diff config/ overlays/default-24.200.001/
|
|
300
|
+
# ACU_API_VERSION=24.200.001 — this overlay is scenario-only
|
|
301
|
+
acu apply acu-config
|
|
302
|
+
acu diff acu-config
|
|
303
|
+
acu run acu-scenario overlays/default-24.200.001/acu-scenario/
|
|
318
304
|
```
|
|
319
305
|
|
|
320
306
|
Add a future half by creating `overlays/default-<new-half>/` with the
|
|
@@ -391,16 +377,36 @@ GitHub Actions on tag `v*` re-runs CI, builds sdist+wheel, publishes to PyPI via
|
|
|
391
377
|
Configuration is one file: a decrypted `.env` at the repo root names the instance — `ACU_BASE_URL`, `ACU_TENANT`, `ACU_PASSWORD` (and optional `ACU_SSH`; omitted defaults to `Administrator@` + base-url host).
|
|
392
378
|
`gmake e2e` refuses to start without it.
|
|
393
379
|
|
|
394
|
-
The tier is
|
|
380
|
+
The tier is three pipeline files: provision (apply/diff), scenario (run/state), and extract round-trip.
|
|
381
|
+
Per-bug contract probes fold onto those tenants.
|
|
382
|
+
|
|
395
383
|
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.
|
|
396
384
|
|
|
397
385
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
398
|
-
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
386
|
+
The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
|
|
387
|
+
|
|
388
|
+
```sh
|
|
389
|
+
gmake e2e # whole tier, three files
|
|
390
|
+
gmake e2e FILE=test_provision_lifecycle # apply/diff + folded probes
|
|
391
|
+
gmake e2e FILE=test_scenario_lifecycle # scenario + state + kit alloc
|
|
392
|
+
gmake e2e FILE=test_extract_roundtrip # extract inverse
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### CLI test-seed soak
|
|
396
|
+
|
|
397
|
+
This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
|
|
398
|
+
Soak the live CLI tenant from here with `--tenant ACUCLI`.
|
|
399
|
+
|
|
400
|
+
Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
401
|
+
|
|
402
|
+
`gmake e2e` still scaffolds from packaged `config init` templates into a tmp dir.
|
|
403
|
+
That path is not the soak.
|
|
399
404
|
|
|
400
405
|
```sh
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
406
|
+
uv run acu --tenant ACUCLI apply acu-config
|
|
407
|
+
uv run acu --tenant ACUCLI run acu-scenario
|
|
408
|
+
uv run acu --tenant ACUCLI diff acu-config
|
|
409
|
+
uv run acu --tenant ACUCLI state acu-config/views
|
|
404
410
|
```
|
|
405
411
|
|
|
406
412
|
## 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,14 +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
|
-
|
|
64
|
-
See [docs/demo-seed.md](docs/demo-seed.md) for the entity map, once-guard, apply-order notes, NumberingSequence vs prefs `*NumberingID`, curated *Preferences field depth (V41), and Role/User + password seed rules.
|
|
63
|
+
apply / diff / run / state require an explicit data path.
|
|
65
64
|
|
|
66
65
|
**Hosted Acumatica (no SSH):** the tenant already exists; set a blank `ACU_SSH=` in `.env`.
|
|
67
66
|
The scaffold omits the key — without it, acu defaults to `Administrator@<ACU_BASE_URL host>` for SSH boxes.
|
|
@@ -71,8 +70,8 @@ acu config init --host customer.acumatica.com my-erp
|
|
|
71
70
|
cd my-erp # edit .env: ACU_TENANT, ACU_PASSWORD; add ACU_SSH=
|
|
72
71
|
acu config check # REST preflight; ssh probe is skipped
|
|
73
72
|
acu --tenant DEV bootstrap # publish AcuBootstrap via REST only
|
|
74
|
-
acu --tenant DEV apply config
|
|
75
|
-
acu --tenant DEV diff config
|
|
73
|
+
acu --tenant DEV apply acu-config
|
|
74
|
+
acu --tenant DEV diff acu-config
|
|
76
75
|
# offline UI fallback when REST publish is blocked:
|
|
77
76
|
acu bootstrap --export AcuBootstrap.zip # import + publish on SM204505
|
|
78
77
|
```
|
|
@@ -93,50 +92,46 @@ acu [--tenant NAME] [--url URL] [--ssh USER@HOST] [--api-version V]
|
|
|
93
92
|
│ └── recycle [--yes] restart site app pool (tenant map + free API slots)
|
|
94
93
|
│
|
|
95
94
|
├── bootstrap [--export PATH] publish AcuBootstrap (REST); --export = offline zip
|
|
96
|
-
├── apply [--dry-run]
|
|
97
|
-
├── diff
|
|
98
|
-
├── run [--dry-run]
|
|
99
|
-
├── 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...>
|
|
100
99
|
│ capture derived state into state/ (not seed)
|
|
101
100
|
├── survey existing-tenant dual-reader (never L1 extract/inventory/reconcile)
|
|
102
101
|
│ ├── extract [--out DIR] [--only NAME]... [--force] [--dry-run]
|
|
103
|
-
│ │ inverse of apply into config/{bootstrap,baseline,setup,master}/
|
|
102
|
+
│ │ inverse of apply into acu-config/{bootstrap,baseline,setup,master}/
|
|
104
103
|
│ ├── inventory [--out DIR] [--force] [--dry-run] ARTIFACT
|
|
105
104
|
│ │ offline snapshot artifact → inventory/ (not seed)
|
|
106
105
|
│ └── reconcile [--inventory DIR] [--config DIR] [--out DIR] [--force] [--dry-run]
|
|
107
|
-
│ inventory/ + optional config
|
|
106
|
+
│ inventory/ + optional --config DIR → findings/ only
|
|
108
107
|
├── schema [--out DIR] dump the endpoint's OpenAPI schema (swagger.json)
|
|
109
108
|
│
|
|
110
109
|
└── config configuration ops
|
|
111
|
-
├── 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)
|
|
112
111
|
├── show print the resolved config as a complete .env
|
|
113
112
|
└── check preflight: discovery, secrets, REST, endpoints, SSH
|
|
114
113
|
```
|
|
115
114
|
|
|
116
|
-
|
|
115
|
+
`apply` / `diff` / `run` / `state` require an explicit data path. Zero args print that command's help and do not call HTTP.
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- `run` defaults to `scenario/`.
|
|
122
|
-
- `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/`.
|
|
123
120
|
|
|
124
121
|
Scenario YAML may use `${current_period}` (host-local `MMyyyy`) on steps, expect params, and `once.present` params.
|
|
125
|
-
`config/views` and `state` keep Period pinned
|
|
122
|
+
`acu-config/views` and `state` keep Period pinned.
|
|
126
123
|
|
|
127
|
-
`survey extract`
|
|
124
|
+
`survey extract` writes SEED_DIRS into `--out` (default `acu-config/`).
|
|
128
125
|
|
|
129
126
|
`survey inventory` and `survey reconcile` are offline (no REST, SSH, or password).
|
|
130
127
|
`survey inventory` turns an SM203520 Settings XML ZIP or `ac.exe export xml` folder into `inventory/`.
|
|
131
128
|
|
|
132
|
-
`survey reconcile` compares `inventory/` to optional
|
|
129
|
+
`survey reconcile` compares `inventory/` to optional `--config DIR` and writes `findings/` only.
|
|
133
130
|
It never writes seed.
|
|
134
131
|
|
|
135
132
|
Optional `snapshot_map.yaml` (data-repo root, or package defaults) maps DAC tables to catalog entities.
|
|
136
133
|
It normalizes the join: pad-trim, key/field aliases, Account/Sub FK CD resolve, enum label to code.
|
|
137
134
|
|
|
138
|
-
See [docs/demo-seed.md](docs/demo-seed.md).
|
|
139
|
-
|
|
140
135
|
`acu --completion` emits a completion script for bash, zsh, or fish — source it from your shell profile.
|
|
141
136
|
|
|
142
137
|
Run `acu --help` for the full mental model (workflow, planes, exit codes, command map).
|
|
@@ -151,21 +146,21 @@ Do not confuse them with each other or with `state`:
|
|
|
151
146
|
|
|
152
147
|
| Command | Plane | Input | Writes | Role |
|
|
153
148
|
| ------- | ----- | ----- | ------ | ---- |
|
|
154
|
-
| `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 |
|
|
155
150
|
| `survey inventory` | Offline | SM203520 Settings XML ZIP or `ac.exe export xml` folder | `inventory/` (`summary.yaml` + `tables/`) | Full-table snapshot IR — not seed |
|
|
156
|
-
| `survey reconcile` | Offline | `inventory/` + optional
|
|
157
|
-
| `state` | REST (live) | `config/views/` | `state/` | Derived balances/totals — not seed, not inventory |
|
|
158
|
-
| `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) |
|
|
159
154
|
|
|
160
155
|
`inventory/` and `findings/` are engagement outputs: not SEED_DIRS, never loaded by `apply`/`diff`, not scaffolded by `config init`.
|
|
161
156
|
Binary `.adb` snapshots are rejected (XML only).
|
|
162
157
|
|
|
163
|
-
See [docs/ac-exe.md](docs/ac-exe.md) for export / SM203520 notes and [docs/demo-seed.md](docs/demo-seed.md) for the extract/state/inventory map.
|
|
164
|
-
|
|
165
158
|
## The data repo
|
|
166
159
|
|
|
167
160
|
Your configuration lives in its own git repo.
|
|
168
|
-
`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.
|
|
161
|
+
`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.
|
|
162
|
+
|
|
163
|
+
It does not write a customization tree.
|
|
169
164
|
|
|
170
165
|
The Bootstrap endpoint contract is package SoT (`bootstrap_project.xml` inside the CLI — `Bootstrap/1.4.0`).
|
|
171
166
|
`config init` never writes `project.xml`, and data repos must not keep one (a present file hard-errors on bootstrap/publish).
|
|
@@ -174,39 +169,36 @@ There is no `--flavor`.
|
|
|
174
169
|
|
|
175
170
|
| Path | What it holds |
|
|
176
171
|
| ---- | ------------- |
|
|
177
|
-
| `config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
178
|
-
| `config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
179
|
-
| `config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
180
|
-
| `config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
181
|
-
| `scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
182
|
-
| `config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
172
|
+
| `acu-config/bootstrap/` | virgin-tenant config: features, company, credit terms (no `project.xml`) |
|
|
173
|
+
| `acu-config/baseline/` | reference data: subaccounts, COA, ledger, UOMs |
|
|
174
|
+
| `acu-config/setup/` | one-time actions: financial year, master calendar, open periods |
|
|
175
|
+
| `acu-config/master/` | inventory/distribution masters: numbering (`05-…`) before prefs, warehouse, items, parties + Role/User (`90-roles` then `91-users` then `92-role-users`) |
|
|
176
|
+
| `acu-scenario/` | lifecycle txns for `acu run`: once capital, then buy, build, sell |
|
|
177
|
+
| `acu-config/views/` | observer views for `acu state` (`inquire:` / `entity:` / `gi:`; not SEED_DIRS) |
|
|
183
178
|
| `state/` | committed derived-state observations (evidence, not seed; money/qty fixed-point) |
|
|
184
179
|
| `inventory/` | engagement: offline snapshot tables from `acu survey inventory` (not seed; not SEED_DIRS) |
|
|
185
180
|
| `findings/` | engagement: `acu survey reconcile` cross-check output (never apply path) |
|
|
186
181
|
| `.env` | secrets + where (`ACU_BASE_URL`) + pin (`ACU_API_VERSION`) |
|
|
187
182
|
|
|
188
|
-
Legacy data repos may still keep root `bootstrap/`…`master/`; bare `apply`/`diff` prefer `config/` when present and never merge both trees.
|
|
189
|
-
|
|
190
183
|
Files in each directory apply alphabetically; the numbered prefixes (`10-`, `20-`, and so on) encode dependency order.
|
|
191
184
|
Commit seed YAML; keep `.env` out of git (scaffold `.gitignore` already lists it).
|
|
192
185
|
|
|
193
186
|
Seed YAML is state: `apply` upserts it, `diff` proves it.
|
|
194
|
-
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
187
|
+
`acu survey extract` is the inverse of `apply`: GET live tenant rows into seed YAML under `acu-config/{bootstrap,baseline,setup,master}/` (hard-cut).
|
|
195
188
|
|
|
196
189
|
Packaged `seed_catalog.yaml` is the sole extract registry (entity, endpoint, keys, file, strip/include, filter-split).
|
|
197
|
-
The demo entity map in [docs/demo-seed.md](docs/demo-seed.md) mirrors those catalog paths.
|
|
198
190
|
|
|
199
|
-
Features synthesize to `config/bootstrap/features.yaml`.
|
|
191
|
+
Features synthesize to `acu-config/bootstrap/features.yaml`.
|
|
200
192
|
Existing files skip unless `--force`; empty live sets skip.
|
|
201
193
|
|
|
202
194
|
Row failures continue (exit 1 only if any row failed).
|
|
203
195
|
Drift stays with `diff`.
|
|
204
196
|
|
|
205
197
|
```sh
|
|
206
|
-
acu --tenant DEV survey extract --
|
|
207
|
-
git diff config/ # review extract delta before commit
|
|
208
|
-
acu --tenant DEV apply config
|
|
209
|
-
acu --tenant DEV diff config
|
|
198
|
+
acu --tenant DEV survey extract --force # refresh acu-config/** from live tenant
|
|
199
|
+
git diff acu-config/ # review extract delta before commit
|
|
200
|
+
acu --tenant DEV apply acu-config # replay extracted seed
|
|
201
|
+
acu --tenant DEV diff acu-config # expect exit 0
|
|
210
202
|
```
|
|
211
203
|
### Seed `endpoint:` symbols
|
|
212
204
|
|
|
@@ -250,7 +242,7 @@ Secrets, REST where, and the Default contract pin live in one `.env` file (`ACU_
|
|
|
250
242
|
Leftover `matrix.yaml` is ignored and never loaded.
|
|
251
243
|
|
|
252
244
|
```sh
|
|
253
|
-
ACU_BASE_URL=http://
|
|
245
|
+
ACU_BASE_URL=http://erp.example.com/AcumaticaERP # REST where (required)
|
|
254
246
|
ACU_API_VERSION=25.200.001 # Default contract half
|
|
255
247
|
ACU_TENANT=LAB5 # sign-in name of the tenant API sessions use
|
|
256
248
|
# ACU_SSH omitted → defaults to Administrator@ + resolved base_url host
|
|
@@ -274,7 +266,7 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
274
266
|
|
|
275
267
|
| Piece | Role |
|
|
276
268
|
| ----- | ---- |
|
|
277
|
-
| Trunk seed | Canonical `config/` + `scenario/` (newest supported Default half) |
|
|
269
|
+
| Trunk seed | Canonical `acu-config/` + `acu-scenario/` (newest supported Default half) |
|
|
278
270
|
| `.env` pin | Per-checkout `ACU_BASE_URL` + `ACU_API_VERSION` |
|
|
279
271
|
| Optional overlays | Surgical seed deltas keyed by Default half (e.g. `overlays/default-24.200.001/`) |
|
|
280
272
|
| OpenAPI | Live `acu schema` dump only (gitignored); never multi-version swagger trees in package or data repo |
|
|
@@ -282,21 +274,15 @@ Version fan-out is **not** long-running product branches (`acu-25r1`, `acu-26r1`
|
|
|
282
274
|
**Overlays** live under `overlays/default-<api_version>/` (scaffolded by `acu config init`).
|
|
283
275
|
No `--overlay` flag.
|
|
284
276
|
|
|
285
|
-
|
|
286
|
-
`acu run` replaces same-basename scenario files from the pin overlay.
|
|
277
|
+
Pass overlay trees as extra explicit paths when you need them.
|
|
287
278
|
|
|
288
279
|
Pin = resolved `api_version` (`--api-version`, else `ACU_API_VERSION`, else code default).
|
|
289
|
-
Explicit path args disable auto-compose.
|
|
290
280
|
|
|
291
281
|
```sh
|
|
292
|
-
# ACU_API_VERSION=24.200.001
|
|
293
|
-
acu apply
|
|
294
|
-
acu
|
|
295
|
-
acu
|
|
296
|
-
|
|
297
|
-
# explicit path args (no auto) — later path wins same keys
|
|
298
|
-
acu apply config/ overlays/default-24.200.001/
|
|
299
|
-
acu diff config/ overlays/default-24.200.001/
|
|
282
|
+
# ACU_API_VERSION=24.200.001 — this overlay is scenario-only
|
|
283
|
+
acu apply acu-config
|
|
284
|
+
acu diff acu-config
|
|
285
|
+
acu run acu-scenario overlays/default-24.200.001/acu-scenario/
|
|
300
286
|
```
|
|
301
287
|
|
|
302
288
|
Add a future half by creating `overlays/default-<new-half>/` with the
|
|
@@ -373,16 +359,36 @@ GitHub Actions on tag `v*` re-runs CI, builds sdist+wheel, publishes to PyPI via
|
|
|
373
359
|
Configuration is one file: a decrypted `.env` at the repo root names the instance — `ACU_BASE_URL`, `ACU_TENANT`, `ACU_PASSWORD` (and optional `ACU_SSH`; omitted defaults to `Administrator@` + base-url host).
|
|
374
360
|
`gmake e2e` refuses to start without it.
|
|
375
361
|
|
|
376
|
-
The tier is
|
|
362
|
+
The tier is three pipeline files: provision (apply/diff), scenario (run/state), and extract round-trip.
|
|
363
|
+
Per-bug contract probes fold onto those tenants.
|
|
364
|
+
|
|
377
365
|
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.
|
|
378
366
|
|
|
379
367
|
Scratch tenants (`E2E`, `E2EA`, `E2EB`, `E2ESCEN`) are created on the way in and always deleted on the way out, so nothing persists.
|
|
380
|
-
The packaged full `config init` seed (under `config/`) is the only scaffold.
|
|
368
|
+
The packaged full `config init` seed (under `acu-config/`) is the only scaffold.
|
|
369
|
+
|
|
370
|
+
```sh
|
|
371
|
+
gmake e2e # whole tier, three files
|
|
372
|
+
gmake e2e FILE=test_provision_lifecycle # apply/diff + folded probes
|
|
373
|
+
gmake e2e FILE=test_scenario_lifecycle # scenario + state + kit alloc
|
|
374
|
+
gmake e2e FILE=test_extract_roundtrip # extract inverse
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### CLI test-seed soak
|
|
378
|
+
|
|
379
|
+
This checkout carries a CLI test seed at repo-root `acu-config/` and `acu-scenario/` (no customization YAML under `acu-config/`).
|
|
380
|
+
Soak the live CLI tenant from here with `--tenant ACUCLI`.
|
|
381
|
+
|
|
382
|
+
Never use tenant `CNBN`. Never `cd` the sibling GitOps repo for CLI soak.
|
|
383
|
+
|
|
384
|
+
`gmake e2e` still scaffolds from packaged `config init` templates into a tmp dir.
|
|
385
|
+
That path is not the soak.
|
|
381
386
|
|
|
382
387
|
```sh
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
388
|
+
uv run acu --tenant ACUCLI apply acu-config
|
|
389
|
+
uv run acu --tenant ACUCLI run acu-scenario
|
|
390
|
+
uv run acu --tenant ACUCLI diff acu-config
|
|
391
|
+
uv run acu --tenant ACUCLI state acu-config/views
|
|
386
392
|
```
|
|
387
393
|
|
|
388
394
|
## License
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "acumatica-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.35.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"
|