@wpmoo/toolkit 0.9.25 → 0.9.27

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.
package/dist/templates.js CHANGED
@@ -601,6 +601,62 @@ allow_stage_lifecycle() {
601
601
  [[ "$value" == "1" ]]
602
602
  }
603
603
 
604
+ allow_no_recent_snapshot() {
605
+ local value="\${WPMOO_ALLOW_NO_RECENT_SNAPSHOT:-$(env_file_value WPMOO_ALLOW_NO_RECENT_SNAPSHOT)}"
606
+ [[ "$value" == "1" ]]
607
+ }
608
+
609
+ allow_migrations() {
610
+ local value="\${WPMOO_ALLOW_MIGRATIONS:-$(env_file_value WPMOO_ALLOW_MIGRATIONS)}"
611
+ [[ "$value" == "1" ]]
612
+ }
613
+
614
+ has_recent_snapshot() {
615
+ local dir
616
+ for dir in backups backup snapshots; do
617
+ [[ -d "$dir" ]] || continue
618
+ if find "$dir" -type f \\( -name "*.dump" -o -name "*.sql" -o -name "*.sql.gz" -o -name "*.zip" -o -name "*.tar" -o -name "*.tar.gz" \\) -mtime -1 -print -quit 2>/dev/null | grep -q .; then
619
+ return 0
620
+ fi
621
+ done
622
+ return 1
623
+ }
624
+
625
+ require_recent_snapshot_or_override() {
626
+ local command="$1"
627
+ local env_name
628
+ env_name="$(selected_env)"
629
+ if [[ "$env_name" == "stage" || "$env_name" == "prod" ]]; then
630
+ if ! allow_no_recent_snapshot && ! has_recent_snapshot; then
631
+ echo "Refusing destructive command '$command' in WPMOO_ENV=$env_name without a recent database snapshot. Create a snapshot first or set WPMOO_ALLOW_NO_RECENT_SNAPSHOT=1 to run it intentionally." >&2
632
+ exit 1
633
+ fi
634
+ fi
635
+ }
636
+
637
+ has_migration_risk() {
638
+ local base
639
+ for base in odoo/custom/src/private odoo/custom/src/oca odoo/custom/src/external; do
640
+ [[ -d "$base" ]] || continue
641
+ if find "$base" -type f \\( -path "*/migrations/*/pre-migration.py" -o -path "*/migrations/*/post-migration.py" -o -path "*/migrations/*/end-migration.py" -o -path "*/migration/*/pre-migration.py" -o -path "*/migration/*/post-migration.py" -o -path "*/migration/*/end-migration.py" -o -path "*/scripts/migrate.py" -o -path "*/scripts/migration.py" \\) -print -quit 2>/dev/null | grep -q .; then
642
+ return 0
643
+ fi
644
+ done
645
+ return 1
646
+ }
647
+
648
+ require_migrations_allowed() {
649
+ local command="$1"
650
+ local env_name
651
+ env_name="$(selected_env)"
652
+ if [[ "$env_name" == "stage" || "$env_name" == "prod" ]]; then
653
+ if ! allow_migrations && has_migration_risk; then
654
+ echo "Refusing migration-risk command '$command' in WPMOO_ENV=$env_name. Review detected migration scripts or set WPMOO_ALLOW_MIGRATIONS=1 to run it intentionally." >&2
655
+ exit 1
656
+ fi
657
+ fi
658
+ }
659
+
604
660
  require_stage_lifecycle_allowed() {
605
661
  local command="$1"
606
662
  local env_name
@@ -712,6 +768,7 @@ case "$command" in
712
768
  require_module_args "$command" "$@"
713
769
  require_stage_lifecycle_allowed "$command"
714
770
  require_prod_lifecycle_allowed "$command"
771
+ require_migrations_allowed "$command"
715
772
  run_script ./scripts/install.sh "$@"
716
773
  ;;
717
774
  "update")
@@ -719,18 +776,21 @@ case "$command" in
719
776
  require_module_args "$command" "$@"
720
777
  require_stage_lifecycle_allowed "$command"
721
778
  require_prod_lifecycle_allowed "$command"
779
+ require_migrations_allowed "$command"
722
780
  run_script ./scripts/update.sh "$@"
723
781
  ;;
724
782
  "test")
725
783
  shift
726
784
  validate_test_args "$@"
727
785
  require_prod_lifecycle_allowed "$command"
786
+ require_migrations_allowed "$command"
728
787
  run_script ./scripts/test.sh "$@"
729
788
  ;;
730
789
  "resetdb")
731
790
  shift
732
791
  positional_args "$command" 0 2 "$@"
733
792
  require_destructive_allowed "$command"
793
+ require_recent_snapshot_or_override "$command"
734
794
  run_script ./scripts/resetdb.sh "$@"
735
795
  ;;
736
796
  "snapshot")
@@ -749,6 +809,7 @@ case "$command" in
749
809
  restore_args+=("$@")
750
810
  if [[ "\${restore_args[0]:-}" != "--dry-run" ]]; then
751
811
  require_destructive_allowed "$command"
812
+ require_recent_snapshot_or_override "$command"
752
813
  fi
753
814
  run_script ./scripts/restore-snapshot.sh "\${restore_args[@]}"
754
815
  ;;
@@ -23,7 +23,7 @@ not validate staging or production deployments.
23
23
  | Doctor checks | Metadata, compose files, scripts, source repo paths, and local tooling checks behave as expected. | `npx @wpmoo/toolkit doctor` or `./moo doctor` |
24
24
  | Doctor safe fixes | Safe file-level fixes are applied only with `--fix`, then doctor runs again and reports any remaining manual issues. | `npx @wpmoo/toolkit doctor --fix` |
25
25
  | Generated Postgres checks | For PostgreSQL 18 environments, doctor validates db mount targets avoid old PG image-specific paths and can normalize safe targets with `--fix`. | `npx @wpmoo/toolkit doctor`, `npx @wpmoo/toolkit doctor --fix` |
26
- | PostgreSQL diagnostics | Optional read-only database health/performance diagnostics report database count, sessions currently running queries with `pg_stat_activity.state = 'active'`, total database size, slow-query readiness, extension visibility, and selected settings without failing doctor when the database is unavailable. | `npx @wpmoo/toolkit doctor --postgres`, `npx @wpmoo/toolkit doctor --json --postgres` |
26
+ | PostgreSQL diagnostics | Optional read-only, advisory-only database health and performance diagnostics (no automatic tuning), covering active/idle-in-transaction sessions, table health signals, WAL/capacity context, unused-index hints, and slow-query readiness. JSON mode emits a versioned PostgreSQL contract with optional fields when a metric is unavailable. | `npx @wpmoo/toolkit doctor --postgres`, `npx @wpmoo/toolkit doctor --json --postgres` |
27
27
  | Source repo add/remove | Source repository registration and submodule lifecycle behave correctly. | `npx @wpmoo/toolkit add-repo ...`, `npx @wpmoo/toolkit remove-repo ...` |
28
28
  | Source manifest sync | Source repo metadata, `.gitmodules`, and `odoo/custom/manifests/sources.yaml` stay aligned. | `npx @wpmoo/toolkit source list`, `npx @wpmoo/toolkit source sync` |
29
29
  | Module add/remove | Module skeleton files include manifest, model, access CSV, explicit view XML, action/menu XML, post-install test scaffold, and selected source repo registration. Existing scaffold files are not overwritten. | `npx @wpmoo/toolkit add-module ...`, `npx @wpmoo/toolkit remove-module ...` |
@@ -76,16 +76,16 @@ is involved, use PostgreSQL upgrade tooling first.
76
76
 
77
77
  Use `doctor --postgres` when the database container is running and you want
78
78
  read-only PostgreSQL diagnostics. The check uses fixed diagnostic queries for
79
- database count, sessions currently running queries where
80
- `pg_stat_activity.state` is `active`, aggregate database size, slow-query
81
- logging readiness,
82
- `pg_stat_statements` availability, and `shared_buffers`. If the database is
83
- unavailable, doctor reports a warning instead of failing the whole environment
84
- check.
85
- JSON output preserves `checks` and `warnings` while adding a structured
86
- `postgres` object when `--postgres` is requested.
87
- Incomplete or malformed PostgreSQL metric rows are reported as unavailable
88
- diagnostics.
79
+ database count, sessions currently running queries where `pg_stat_activity.state`
80
+ is `active`, long transactions / idle-in-transaction sessions, table health
81
+ signals, unused index advisor signals, WAL and capacity visibility, and
82
+ slow-query logging readiness (`log_min_duration_statement` and
83
+ `pg_stat_statements` visibility). If the database is unavailable, doctor reports
84
+ a warning instead of failing the whole environment check.
85
+
86
+ `doctor --json --postgres` keeps output stable by exposing a versioned PostgreSQL
87
+ diagnostics contract. The contract is intentionally permissive: fields are optional
88
+ and omitted or marked unavailable when a running database does not expose them.
89
89
 
90
90
  ## Safe reset policy
91
91
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wpmoo/toolkit",
3
- "version": "0.9.25",
3
+ "version": "0.9.27",
4
4
  "description": "WPMoo Toolkit for development, staging, and production lifecycle workflows.",
5
5
  "type": "module",
6
6
  "repository": {