menu 1 2 3 4 5 7 operationnels

This commit is contained in:
2026-08-03 10:02:12 +02:00
parent b2c241797b
commit f37f5b1e45
25 changed files with 2373 additions and 1120 deletions
+89
View File
@@ -0,0 +1,89 @@
"""
Application séquentielle des migrations SQL du dossier `migrations/`
sur la base « bolsa ». À exécuter depuis la racine du projet :
python migrations/apply_migrations.py
Lit la configuration MySQL depuis les variables d'environnement (.env).
N'applique que les fichiers non déjà enregistrés dans la table
`__migrations__` (créée automatiquement).
"""
import os
import sys
from pathlib import Path
import pymysql
from dotenv import load_dotenv
load_dotenv()
MIGRATIONS_DIR = Path(__file__).parent
def get_connection():
return pymysql.connect(
host=os.environ.get("MYSQL_HOST", "db"),
port=int(os.environ.get("MYSQL_PORT", "3306")),
user=os.environ.get("MYSQL_USER", "jfgiraud"),
password=os.environ.get("MYSQL_PASSWORD", ""),
database=os.environ.get("MYSQL_DATABASE", "bolsa"),
charset="utf8mb4",
autocommit=False,
)
def main():
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"CREATE TABLE IF NOT EXISTS `__migrations__` ("
" `id` int NOT NULL AUTO_INCREMENT,"
" `filename` varchar(255) NOT NULL,"
" `applied_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,"
" PRIMARY KEY (`id`),"
" UNIQUE KEY `idx_filename` (`filename`)"
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
)
conn.commit()
cur.execute("SELECT filename FROM `__migrations__`")
applied = {row[0] for row in cur.fetchall()}
sql_files = sorted(
f for f in MIGRATIONS_DIR.glob("*.sql")
if f.name != "schema.sql"
)
if not sql_files:
print("Aucune migration à appliquer.")
return
for sql_file in sql_files:
if sql_file.name in applied:
print(f"[déjà appliquée] {sql_file.name}")
continue
print(f"[application] {sql_file.name}")
sql = sql_file.read_text(encoding="utf-8")
# Découpage sur les ';' pour exécuter instruction par instruction
statements = [s.strip() for s in sql.split(";") if s.strip()]
for stmt in statements:
cur.execute(stmt)
cur.execute(
"INSERT INTO `__migrations__` (filename) VALUES (%s)",
(sql_file.name,),
)
conn.commit()
print(f"[OK] {sql_file.name}")
except Exception as e:
conn.rollback()
print(f"[ERREUR] {e}", file=sys.stderr)
sys.exit(1)
finally:
conn.close()
if __name__ == "__main__":
main()
+110
View File
@@ -0,0 +1,110 @@
-- =====================================================================
# Schéma de la base « bolsa » version de référence (snake_case)
-- =====================================================================
# Tables : login, actions, societe, compte, ordre, ordre_pied
# Encodage : utf8mb4 / utf8mb4_0900_ai_ci
# Ce fichier est exécuté automatiquement par Docker sur une base vierge
# (monté dans /docker-entrypoint-initdb.d/). Sur une base existante, les
# CREATE TABLE IF NOT EXISTS sont sans effet.
-- =====================================================================
CREATE TABLE IF NOT EXISTS `login` (
`id` int NOT NULL AUTO_INCREMENT,
`login` varchar(50) NOT NULL,
`nom` varchar(100) NOT NULL,
`prenom` varchar(100) NOT NULL,
`mail` varchar(255) NOT NULL,
`pass` varchar(255) NOT NULL,
`actif` tinyint(1) DEFAULT NULL,
`creer_le` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`modifie_le` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`reset_token` varchar(255) DEFAULT NULL,
`reset_token_created_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_login` (`login`),
UNIQUE KEY `idx_mail` (`mail`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS `actions` (
`id` int NOT NULL AUTO_INCREMENT,
`isin` varchar(50) NOT NULL,
`ticker` varchar(50) DEFAULT NULL,
`company_name` varchar(255) DEFAULT NULL,
`exchange` varchar(50) NOT NULL,
`pays` varchar(50) NOT NULL,
`currency` varchar(10) NOT NULL,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `isin` (`isin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS `societe` (
`id` int NOT NULL AUTO_INCREMENT,
`nom` varchar(60) NOT NULL,
`forme` varchar(10) NOT NULL,
`capital` int NOT NULL,
`siren` varchar(20) NOT NULL,
`siret` varchar(20) NOT NULL,
`rcs` varchar(50) NOT NULL,
`tva` varchar(50) NOT NULL,
`naf` varchar(10) NOT NULL,
`tel` varchar(30) NOT NULL,
`web` varchar(100) NOT NULL,
`mail` varchar(100) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS `compte` (
`id` int NOT NULL AUTO_INCREMENT,
`id_societe` int NOT NULL,
`date_operation` date NOT NULL,
`debit` decimal(15,2) DEFAULT '0.00',
`credit` decimal(15,2) DEFAULT '0.00',
`libelle` text,
`source` enum('manuel','ordre') NOT NULL DEFAULT 'manuel',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_compte_societe` (`id_societe`),
CONSTRAINT `fk_compte_societe` FOREIGN KEY (`id_societe`)
REFERENCES `societe` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS `ordre` (
`id` int NOT NULL AUTO_INCREMENT,
`id_societe` int NOT NULL,
`isin` varchar(50) NOT NULL,
`plus_value` decimal(19,4) NOT NULL DEFAULT '0.0000',
`date_plus_value` date DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `fk_ordre_societe` (`id_societe`),
KEY `fk_ordre_actions` (`isin`),
CONSTRAINT `fk_ordre_societe` FOREIGN KEY (`id_societe`)
REFERENCES `societe` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_ordre_actions` FOREIGN KEY (`isin`)
REFERENCES `actions` (`isin`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE IF NOT EXISTS `ordre_pied` (
`id` int NOT NULL AUTO_INCREMENT,
`id_entete` int NOT NULL,
`date_op` date NOT NULL,
`quantite` int NOT NULL,
`prix_brut` decimal(19,4) DEFAULT NULL,
`frais_broker` decimal(19,4) DEFAULT NULL,
`frais_etat` decimal(19,4) DEFAULT NULL,
`frais_autre` decimal(19,4) DEFAULT NULL,
`sens` enum('achat','vente') NOT NULL,
`position` enum('long','short') NOT NULL,
`etat` enum('actif','soldé','annulé') NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_ordre_pied_entete` (`id_entete`),
CONSTRAINT `fk_ordre_pied_entete` FOREIGN KEY (`id_entete`)
REFERENCES `ordre` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;