Improve script

This commit is contained in:
julien committed 2026-11-03 15:18:09 +01:00
1 parent a57fa574eb
commit 2d72b20cad
5 files changed
+107 -167

No files matched your search

View File
Whitespace-only changes.
+54 -12
View File
@@ -34,12 +34,27 @@ openssl rand -hex 64
Ne pas versionner le fichier `.env`.
### Base de données
En développement, la base est créée dans :
```text
db/development.sqlite3
```
Ce chemin est utilisé par défaut. Il est possible de le modifier
avec la variable d'environnement `DATABASE_PATH`.
Le chemin indiqué est relatif au fichier `lib/database.rb`.
Créer ou mettre à jour la base de données :
```sh
bundle exec ruby bin/migrate
```
### Serveur
Démarrer le serveur de développement :
```sh
@@ -50,22 +65,25 @@ Créer des comptes de test depuis le site :
http://[::1]:9292/create-account
Les personnes physiques et les personnes morales peuvent créer
un compte. L'adresse électronique doit être vérifiée avant de
pouvoir se connecter.
Les personnes physiques et les personnes morales peuvent créer un compte.
L'adresse électronique doit être vérifiée avant de pouvoir se connecter.
Pour tester l'espace du Noyau, désigner un ou plusieurs comptes
de test depuis le terminal :
### Initialisation du Noyau
Pour tester l'espace du Noyau, désigner un ou plusieurs comptes de test
depuis le terminal :
```sh
bundle exec ruby bin/initialize-core
```
En développement, un seul membre suffit. Cette commande peut
être réexécutée pour ajouter d'autres membres au Noyau.
En développement, un seul membre suffit. Cette commande peut être
réexécutée pour ajouter d'autres membres au Noyau.
La date de l'assemblée est demandée lors de l'exécution.
### Shell interactif
Pour ouvrir un shell interactif :
```sh
@@ -80,6 +98,7 @@ et définit `RACK_ENV=production`.
Le fichier d'environnement doit notamment définir :
```dotenv
DATABASE_PATH=../db/netig.sqlite3
SESSION_SECRET=...
RODAUTH_HMAC_SECRET=...
RODAUTH_DOMAIN=netig.net
@@ -87,11 +106,34 @@ BASE_URL=https://netig.net
SMTP_PASSWORD=...
```
Générer les deux secrets avec `openssl rand -hex 64`.
Générer les deux secrets avec :
```sh
openssl rand -hex 64
```
Ne pas versionner le fichier contenant ces variables.
Créer ou mettre à jour la base de données dans le conteneur
applicatif avant de démarrer la nouvelle version :
### Base de données
La base de production est stockée dans :
```text
db/netig.sqlite3
```
Le chemin `../db/netig.sqlite3` est relatif au fichier
`lib/database.rb`. Il désigne donc le dossier `db/` à la racine
du projet.
Le dossier `db/` doit être conservé entre les déploiements et rester
accessible en écriture par l'utilisateur qui exécute Puma.
Il doit également être inclus dans les sauvegardes.
Créer ou mettre à jour la base de données dans le conteneur applicatif,
avec les mêmes variables d'environnement que l'application, avant
de démarrer la nouvelle version :
```sh
bundle exec ruby bin/migrate
@@ -111,8 +153,8 @@ bundle exec ruby bin/initialize-core
```
Cette commande doit être exécutée une seule fois en production.
Elle exige au moins trois personnes physiques disposant d'un
compte vérifié.
Elle exige au moins trois personnes physiques disposant d'un compte
vérifié.
Elle enregistre leurs adhésions comme acceptées et leur attribue
la qualité de membre du Noyau.
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env ruby
require "dotenv/load" if ENV.fetch("RACK_ENV", "development") == "development"
require_relative "../lib/database"
abort "Usage: ruby bin/add-core-member EMAIL" unless ARGV.one?
email = ARGV.first.strip.downcase
abort "Adresse électronique manquante." if email.empty?
begin
DB.transaction do
verified_status_id = DB[:account_statuses]
.where(name: "Verified")
.get(:id)
raise "Statut Verified introuvable." unless verified_status_id
account = DB[:accounts]
.where(Sequel.function(:lower, :email) => email)
.first
raise "Compte introuvable : #{email}" unless account
raise "Adresse électronique non vérifiée : #{email}" unless
account[:status_id] == verified_status_id
member = DB[:members].where(account_id: account[:id]).first
raise "Fiche membre introuvable." unless member
raise "Une personne physique est requise." unless
member[:kind] == "individual"
raise "Ce membre appartient déjà au Noyau." if member[:core_member]
membership = DB[:memberships]
.where(member_id: member[:id], status: "accepted")
.first
raise "Ce membre doit avoir une adhésion acceptée." unless membership
updated = DB[:members]
.where(id: member[:id], core_member: false)
.update(core_member: true)
raise "Impossible d'ajouter ce membre au Noyau." unless updated == 1
end
rescue StandardError => e
abort "Erreur : #{e.message}"
end
puts "#{email} a été ajouté au Noyau."
-155
View File
@@ -1,155 +0,0 @@
#!/usr/bin/env ruby
require "dotenv/load" if ENV.fetch("RACK_ENV", "development") == "development"
environment = ENV.fetch("RACK_ENV", "development")
abort "Environnement non pris en charge." unless
%w[development production].include?(environment)
require "date"
require "io/console"
require_relative "../lib/database"
console = IO.console or abort "Terminal interactif requis."
if environment == "production" &&
DB[:members].where(core_member: true).count.positive?
abort "Un Noyau existe déjà."
end
verified_status_id = DB[:account_statuses]
.where(name: "Verified")
.get(:id)
abort "Statut Verified introuvable." unless verified_status_id
find_member = lambda do |email|
account = DB[:accounts]
.where(Sequel.function(:lower, :email) => email)
.first
abort "Compte introuvable : #{email}" unless account
abort "Adresse électronique non vérifiée : #{email}" unless
account[:status_id] == verified_status_id
member = DB[:members]
.where(account_id: account[:id])
.first
abort "Fiche membre introuvable : #{email}" unless member
abort "Une personne physique est requise : #{email}" unless
member[:kind] == "individual"
member
end
console.print "Date de l'assemblée (AAAA-MM-JJ) : "
date_input = console.gets&.strip
unless date_input&.match?(/\A\d{4}-\d{2}-\d{2}\z/)
abort "Format attendu : AAAA-MM-JJ."
end
begin
assembly_date = Date.iso8601(date_input)
rescue Date::Error
abort "Date invalide."
end
abort "La date ne peut pas être dans le futur." if
assembly_date > Date.today
assembly_datetime = Time.utc(
assembly_date.year,
assembly_date.month,
assembly_date.day
)
console.puts
console.puts "Saisissez les adresses électroniques des membres désignés."
console.puts "Une adresse par ligne. Entrée pour terminer."
console.puts
emails = []
loop do
console.print "Adresse électronique : "
email = console.gets&.strip&.downcase
break if email.to_s.empty?
abort "Adresse déjà saisie : #{email}" if emails.include?(email)
emails << email
end
minimum_members = environment == "production" ? 3 : 1
abort "Au moins #{minimum_members} membre(s) sont nécessaires." if
emails.length < minimum_members
members = emails.map do |email|
[email, find_member.call(email)]
end
console.puts
console.puts "Environnement : #{environment}"
console.puts "Date de l'assemblée : #{assembly_date}"
console.puts
console.puts "Membres du Noyau :"
members.each do |email, member|
name = "#{member[:first_name]} #{member[:last_name]}"
console.puts " #{name} (#{email})"
end
console.puts
console.print "Confirmer l'initialisation ? [o/N] "
abort "Opération annulée." unless %w[o oui].include?(
console.gets&.strip&.downcase
)
if environment == "production" &&
DB[:members].where(core_member: true).count.positive?
abort "Un Noyau existe déjà."
end
DB.transaction do
members.each do |_email, member|
membership = DB[:memberships]
.where(
member_id: member[:id],
status: %w[pending accepted]
)
.first
if membership && membership[:status] == "pending"
DB[:memberships]
.where(id: membership[:id])
.update(
status: "accepted",
decided_at: assembly_datetime,
recorded_by: nil
)
elsif membership.nil?
DB[:memberships].insert(
member_id: member[:id],
status: "accepted",
requested_at: assembly_datetime,
decided_at: assembly_datetime,
recorded_by: nil
)
end
DB[:members]
.where(id: member[:id])
.update(core_member: true)
end
end
puts "Membres du Noyau enregistrés (#{members.length})."
+2
View File
@@ -11,6 +11,8 @@ class Netig
account_unverified_status_value 1
account_open_status_value 2
normalize_login(&:downcase)
email_from "NETig <noreply@netig.net>"
title_instance_variable :@page_title