Erreur de migration de 4.7.14 à 5.6.11

Bonjour,

J’essaye de mettre à jour une instance ancienne.
Parti de 4.7.8, la migration s’est faite sans soucis vers 4.7.14.
Mais quand j’ai demandé la migration vers 5.6.11 (étape suivante fournie par https://hub.fab-manager.com/api/versions/next_step?version=4.7.14) il part en erreur :

Your RubyGems version (3.0.3.1) has a bug that prevents `required_ruby_version` from working for Bundler. Any scripts that use `gem install bundler` will break as soon as Bundler drops support for your Ruby version. Please upgrade RubyGems to avoid future breakage and silence this warning by running `gem update --system 3.2.3`
2025-09-27T19:22:11.835Z pid=1 tid=nmwjlojk1 uniquejobs=client until_executed=uniquejobs:cc0574218e68e72b42b613c67a256545 INFO: Adding dead VersionCheckWorker job 131b967896e57e7a0ad69502
== 20210416073410 CreatePaymentGatewayObjects: migrating ======================
-- create_table(:payment_gateway_objects)
   -> 0.7707s
== 20210416073410 CreatePaymentGatewayObjects: migrated (0.7708s) =============

== 20210416083610 MigrateStripeIdsToPaymentGatewayObjects: migrating ==========
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

Invalid footprint for invoice 1
/usr/src/app/lib/integrity/archive_helper.rb:27:in `block in check_footprints'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/relation/delegation.rb:71:in `each'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/relation/delegation.rb:71:in `each'
/usr/src/app/lib/integrity/archive_helper.rb:23:in `check_footprints'
/usr/src/app/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb:10:in `up'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:817:in `exec_migration'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:798:in `block (2 levels) in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:797:in `block in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in `with_connection'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:796:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:977:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1292:in `block in execute_migration_in_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1343:in `block in ddl_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/transactions.rb:212:in `transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1343:in `ddl_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1291:in `execute_migration_in_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1263:in `block in migrate_without_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1262:in `each'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1262:in `migrate_without_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1210:in `block in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1363:in `with_advisory_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1210:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1036:in `up'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1011:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/tasks/database_tasks.rb:172:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/railties/databases.rake:60:in `block (2 levels) in <main>'
/usr/local/bundle/gems/sentry-ruby-5.7.0/lib/sentry/rake.rb:26:in `execute'
/usr/local/bundle/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:491:in `exec'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:34:in `dispatch'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:28:in `start'
/usr/local/bundle/gems/bundler-2.4.6/exe/bundle:45:in `block in <top (required)>'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/usr/local/bundle/gems/bundler-2.4.6/exe/bundle:33:in `<top (required)>'
/usr/local/bundle/bin/bundle:23:in `load'
/usr/local/bundle/bin/bundle:23:in `<main>'

Caused by:
Invalid footprint for invoice 1
/usr/src/app/lib/integrity/archive_helper.rb:27:in `block in check_footprints'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/relation/delegation.rb:71:in `each'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/relation/delegation.rb:71:in `each'
/usr/src/app/lib/integrity/archive_helper.rb:23:in `check_footprints'
/usr/src/app/db/migrate/20210416083610_migrate_stripe_ids_to_payment_gateway_objects.rb:10:in `up'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:817:in `exec_migration'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:798:in `block (2 levels) in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:797:in `block in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:416:in `with_connection'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:796:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:977:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1292:in `block in execute_migration_in_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1343:in `block in ddl_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
/usr/local/bundle/gems/activesupport-5.2.8.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/transactions.rb:212:in `transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1343:in `ddl_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1291:in `execute_migration_in_transaction'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1263:in `block in migrate_without_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1262:in `each'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1262:in `migrate_without_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1210:in `block in migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1363:in `with_advisory_lock'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1210:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1036:in `up'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/migration.rb:1011:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/tasks/database_tasks.rb:172:in `migrate'
/usr/local/bundle/gems/activerecord-5.2.8.1/lib/active_record/railties/databases.rake:60:in `block (2 levels) in <main>'
/usr/local/bundle/gems/sentry-ruby-5.7.0/lib/sentry/rake.rb:26:in `execute'
/usr/local/bundle/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:58:in `load'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:58:in `kernel_load'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli/exec.rb:23:in `run'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:491:in `exec'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:34:in `dispatch'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/cli.rb:28:in `start'
/usr/local/bundle/gems/bundler-2.4.6/exe/bundle:45:in `block in <top (required)>'
/usr/local/bundle/gems/bundler-2.4.6/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/usr/local/bundle/gems/bundler-2.4.6/exe/bundle:33:in `<top (required)>'
/usr/local/bundle/bin/bundle:23:in `load'
/usr/local/bundle/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
[ ❌ ] Something went wrong while migrating the database, please check the logs above.

Une idée de la manière de me sortir de l’ornière ?

PS : je suis parti d’une copie, donc je peux recommencer, par exemple s’il y a une autre version pivot à privilégier.

Je crois que j’ai compris : je n’ai pas lancé les commandes d’upgrade.

En effet, j’ai imaginé (pas bien lu la doc) que les upgrade se faisaient automatiquement, d’où le script en https://hub.fab-manager.com/api/versions/next_step?version=4.7.14

Du coup, ça me fait une nouvelle piste pour essayer d’avancer.

Je me suis codé un outil pour récupérer la liste des commandes.

C’est du Rust car… je m’exerce au Rust.

En utilisant l’API next_step?version=4.7.14 on indique 5.6.11.

Je ne comprends pas pourquoi l’URL propose de faire un bond de la 4.7.14 à 5.6.11, alors qu’en parcourant le Changelog on trouve 52.

Comment fonctionne le service web ? Pourquoi il propose cette version et pas les intermédiaires ?

Bonjour,

En fait, compte tenu des modifications importantes apportées à Fabmanager, nous devrions procéder à une mise à niveau progressive. Je propose les étapes suivantes pour migrer de la version 4.7.14 à la version la plus récente :

  1. mise à jour vers 5.6.11
    Ajout de RAILS_LOG_TO_STDOUT=true dans le fichier config/env
    Lancer la commande dans la dossier de fabmanager:
    \curl -sSL upgrade.fab-manager.com | bash -s -- -p "rails fablab:fix_invoice_items" -p "rails fablab:fix:invoice_items_in_error" -p "rails fablab:chain:all" -s "rename-adminsys" -s "mount-proof-of-identity-files" -s "set-docker-user" -s "use-relative-paths" -c "rails db:seed" -c "rails fablab:stripe:set_gateway" -c "rails fablab:maintenance:rebuild_stylesheet" -c "rails fablab:fix:invoices_without_names_and_email" -c "rails fablab:setup:set_admins_group" -c "rails fablab:es:build_stats" -t 5.6.11
  2. mise à jour vers 6.0.13
    lancer la commande:
    \curl -sSL upgrade.fab-manager.com | bash -s -- -s "rename-supporting-document" -s "mount-auth-provider" -c "rails db:seed" -c "rails fablab:fix_availabilities" -c "rails fablab:setup:build_places_cache" -c "rails fablab:fix:cart_operator" -c "rails fablab:fix:pack_minutes_used" -c "rails fablab:maintenance:rebuild_stylesheet" -c "rails fablab:auth:write_provider" -c "rails fablab:restore_order_number" -c "rails fablab:fix_references" -c "rails fablab:maintenance:clean_abuse_notifications" -c "rails fablab:es:build_stats" -t 6.0.13
  3. mise à jour vers 6.2.0
    lancer la commande:
    \curl -sSL upgrade.fab-manager.com | bash -s -- -c "rails db:seed" -c "rails fablab:es:build_stats" -t 6.2.0
  4. mise à jour vers la dernière version
    lancer la commande:
    \curl -sSL upgrade.fab-manager.com | bash -s -- -c "rails db:seed" -c "rails fablab:setup:build_places_cache" -c "rails fablab:fix:stripe_coupon_duration" -c "rails fablab:openlab:bulk_export" -c "rails fablab:openlab:bulk_update" -c "rails fablab:setup:build_accounting_lines" -c "rails fablab:maintenance:regenerate_statistics[2014,1]"

N’oubliez pas de faire un backup avant lancer la mise à jour.
Merci

Merci mille fois, je vais tester tout ça.

Pour ma curiosité : comment passe-t’on du ChangeLog/liste de Releases à ces commandes avec listes d’arguments ?

Perso, j’avais extrait ce qui suit :

Update to release v5.0.0:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.0.0 -p "rails fablab:chain:all" -c "rails fablab:stripe:set_gateway" -c "rails fablab:maintenance:rebuild_stylesheet" -s "rename-adminsys"
Update to release v5.0.4:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.0.4 -c "rails db:seed"
Update to release v5.0.10:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.0.10 -c "rails fablab:maintenance:regenerate_statistics[2021,6]"
Update to release v5.1.0:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.1.0 -c "rails db:seed" -c "rails fablab:maintenance:rebuild_stylesheet"
Update to release v5.1.5:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.1.5 -c "rails fablab:es:generate_stats[2021-06-01]"
Update to release v5.1.11:
\curl -sSL upgrade.fab.mn | bash -s  -- -t 5.1.11 -c "rails db:seed"
Update to release v5.3.1:
\curl -sSL upgrade.fab.mn | bash -s  -- -t 5.3.1 -c "rails db:seed"
Update to release v5.3.2:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.3.2 -c "rails fablab:maintenance:regenerate_statistics[2020,04]"
Update to release v5.3.3:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.3.3 -c "rails fablab:maintenance:regenerate_statistics[2020,04]"
Update to release v5.3.6:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.3.6 -c "rails fablab:maintenance:regenerate_statistics[2021,07]" -s "cve-2021-44228"
Update to release v5.3.8:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.3.8 -c "rails fablab:fix:invoices_without_names_and_email"
Update to release v5.3.12:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.3.12 -c "rails fablab:openlab:bulk_export" -c "rails fablab:openlab:bulk_update"
Update to release v5.4.0:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.0 -c "rails db:seed" -c "rails fablab:maintenance:rebuild_stylesheet" -s "mount-proof-of-identity-files"
Update to release v5.4.4:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.4 -s "use-relative-paths"
Update to release v5.4.5:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.5 -s "set-docker-user"
Update to release v5.4.17:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.17 -c "rails fablab:maintenance:regenerate_statistics[2022,07]"
Update to release v5.4.21:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.21 -c "rails fablab:maintenance:regenerate_statistics[2022,08]"
Update to release v5.4.22:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.4.22 -c "rails fablab:maintenance:regenerate_statistics[2021,06]"
Update to release v5.4.23:
\curl -sSL upgrade.fab.mn | bash
Update to release v5.5.0:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.5.0 -c "rails db:seed" -c "rails fablab:setup:set_admins_group" -c "rails fablab:maintenance:regenerate_statistics[2021,6]"
Update to release v5.5.8:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.5.8 -e "RAILS_LOG_TO_STDOUT=true"
Update to release v5.6.0:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.0 -c "rails fablab:setup:build_accounting_lines" -c "rails db:seed"
Update to release v5.6.1:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.1 -p "rails fablab:fix_invoice_items"
Update to release v5.6.6:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.6 -p "rails fablab:fix:invoice_items_in_error" -p "rails fablab:fix_invoice_items"
Update to release v5.6.9:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.9 -c "rails db:seed" -c "rails fablab:es:build_stats" -c "rails fablab:maintenance:regenerate_statistics[2014,1]"
Update to release v5.6.10:
\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.10 -c "rails db:seed"

J’ai enchainé ces commandes avec des listes d’arguments manuellement. N’hésitez pas à utiliser ces commandes, car elles permettent d’éviter de répéter les mêmes arguments.

1 « J'aime »

(Désolé pour la latence, c’est un sujet sur lequel je ne consacre que peu de temps et beaucoup de ce temps est pris par des essais sur une configuration de test)

En rejouant toute la procédure depuis une version représentative, la commande pour passer de la 4.7.14 à 5.6.11 échoue. L’échec se situe au niveau des commandes de traitement des invoices. Et l’erreur indique une colonne absente.

En prenant soin de mieux comprendre le sens de tous les paramètres de la commande de mise à jour, je fini par suspecter un coupable : -p vs -c. En effet, le -p permet de lancer la commande AVANT la migration de la BD alors que le -c la lance après. Or, ici, il semblerait bien que le modèle de données ne convienne pas à la fonction de fix des invoices. J’ai donc tenté une inversion : de -p je suis passé à -c pour les deux commandes concernées.

Voici donc la ligne de commande que j’ai utilisé et qui a fonctionné.

\curl -sSL upgrade.fab.mn | bash -s -- -t 5.6.11 -p "rails fablab:chain:all" -c "rails fablab:stripe:set_gateway" -c "rails fablab:maintenance:rebuild_stylesheet" -s "rename-adminsys" -c "rails db:seed" -s "cve-2021-44228" -c "rails fablab:fix:invoices_without_names_and_email" -c "rails fablab:openlab:bulk_export" -c "rails fablab:openlab:bulk_update" -s "mount-proof-of-identity-files" -s "use-relative-paths" -s "set-docker-user" -c "rails fablab:setup:set_admins_group" -e "RAILS_LOG_TO_STDOUT=true" -c "rails fablab:setup:build_accounting_lines" -c "rails fablab:fix:invoice_items_in_error" -c "rails fablab:fix_invoice_items" -c "rails fablab:es:build_stats"