Checkpoint: Ajout de la page de gestion des attestations de formation
Fonctionnalités : - Configuration par formation (génération auto/manuel, envoi auto/manuel) - Affichage de la liste des apprenants inscrits - Upload de documents PDF par apprenant (mode manuel) - Boutons de prévisualisation et d'envoi manuel - Gestion complète des attestations Corrections : - Ajout des colonnes modeAttestation et modeEnvoi dans la table formations - Ajout des colonnes documentUrl, documentS3Key, uploadedBy, uploadedAt, emailEnvoye, dateEnvoiEmail dans la table attestations - Correction de l'erreur SQL en retirant la colonne urlPdf inexistante de la requête
This commit is contained in:
122
.manus/db/db-query-1768248190594.json
Normal file
122
.manus/db/db-query-1768248190594.json
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"query": "DESCRIBE attestations;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute DESCRIBE attestations;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"Field": "id",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "PRI",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": "auto_increment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "inscriptionId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "apprenantId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "sequenceId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "s3Key",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "pdfUrl",
|
||||||
|
"Type": "varchar(1000)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "dateGeneration",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "emailEnvoye",
|
||||||
|
"Type": "tinyint(1)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "0",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "dateEnvoiEmail",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "createdAt",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "documentUrl",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "documentS3Key",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "uploadedBy",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "uploadedAt",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "Field\tType\tNull\tKey\tDefault\tExtra\nid\tint(11)\tNO\tPRI\tNULL\tauto_increment\ninscriptionId\tint(11)\tNO\t\tNULL\t\napprenantId\tint(11)\tNO\t\tNULL\t\nsequenceId\tint(11)\tNO\t\tNULL\t\ns3Key\tvarchar(500)\tNO\t\tNULL\t\npdfUrl\tvarchar(1000)\tNO\t\tNULL\t\ndateGeneration\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\nemailEnvoye\ttinyint(1)\tNO\t\t0\t\ndateEnvoiEmail\ttimestamp\tYES\t\tNULL\t\ncreatedAt\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\ndocumentUrl\tvarchar(500)\tYES\t\tNULL\t\ndocumentS3Key\tvarchar(500)\tYES\t\tNULL\t\nuploadedBy\tint(11)\tYES\t\tNULL\t\nuploadedAt\ttimestamp\tYES\t\tNULL\t\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 56
|
||||||
|
}
|
||||||
52
.manus/db/db-query-1768248196150.json
Normal file
52
.manus/db/db-query-1768248196150.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'attestations' AND TABLE_SCHEMA = DATABASE();",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'attestations' AND TABLE_SCHEMA = DATABASE();",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "inscriptionId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "apprenantId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "sequenceId"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "s3Key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "pdfUrl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "dateGeneration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "emailEnvoye"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "dateEnvoiEmail"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "createdAt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "documentUrl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "documentS3Key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "uploadedBy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "uploadedAt"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "COLUMN_NAME\nid\ninscriptionId\napprenantId\nsequenceId\ns3Key\npdfUrl\ndateGeneration\nemailEnvoye\ndateEnvoiEmail\ncreatedAt\ndocumentUrl\ndocumentS3Key\nuploadedBy\nuploadedAt\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 62
|
||||||
|
}
|
||||||
9
.manus/db/db-query-1768248206994.json
Normal file
9
.manus/db/db-query-1768248206994.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"query": "ALTER TABLE attestations\nADD COLUMN IF NOT EXISTS emailEnvoye BOOLEAN NOT NULL DEFAULT FALSE,\nADD COLUMN IF NOT EXISTS dateEnvoiEmail TIMESTAMP NULL;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute ALTER TABLE attestations\nADD COLUMN IF NOT EXISTS emailEnvoye BOOLEAN NOT NULL DEFAULT FALSE,\nADD COLUMN IF NOT EXISTS dateEnvoiEmail TIMESTAMP NULL;",
|
||||||
|
"rows": [],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 56
|
||||||
|
}
|
||||||
9
.manus/db/db-query-1768248290199.json
Normal file
9
.manus/db/db-query-1768248290199.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT id, apprenantId, sequenceId, inscriptionId FROM attestations LIMIT 5;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT id, apprenantId, sequenceId, inscriptionId FROM attestations LIMIT 5;",
|
||||||
|
"rows": [],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 63
|
||||||
|
}
|
||||||
70
.manus/db/db-query-1768248304174.json
Normal file
70
.manus/db/db-query-1768248304174.json
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT \n apprenants.id, apprenants.nom, apprenants.prenom, apprenants.email,\n inscriptions.id as inscriptionId, inscriptions.sequenceId,\n sequences.nom as sequenceNom,\n attestations.id as attestationId, attestations.documentUrl, attestations.emailEnvoye\nFROM inscriptions\nINNER JOIN apprenants ON inscriptions.apprenantId = apprenants.id\nINNER JOIN sequences ON inscriptions.sequenceId = sequences.id\nLEFT JOIN attestations ON attestations.inscriptionId = inscriptions.id\nWHERE sequences.formationId = 1 AND inscriptions.statut = 'confirmee'\nLIMIT 5;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT \n apprenants.id, apprenants.nom, apprenants.prenom, apprenants.email,\n inscriptions.id as inscriptionId, inscriptions.sequenceId,\n sequences.nom as sequenceNom,\n attestations.id as attestationId, attestations.documentUrl, attestations.emailEnvoye\nFROM inscriptions\nINNER JOIN apprenants ON inscriptions.apprenantId = apprenants.id\nINNER JOIN sequences ON inscriptions.sequenceId = sequences.id\nLEFT JOIN attestations ON attestations.inscriptionId = inscriptions.id\nWHERE sequences.formationId = 1 AND inscriptions.statut = 'confirmee'\nLIMIT 5;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"nom": "JOHANSSON ",
|
||||||
|
"prenom": "Scarlett",
|
||||||
|
"email": "opareige@gmail.com",
|
||||||
|
"inscriptionId": "240001",
|
||||||
|
"sequenceId": "60001",
|
||||||
|
"sequenceNom": "Groupe C",
|
||||||
|
"attestationId": "NULL",
|
||||||
|
"documentUrl": "NULL",
|
||||||
|
"emailEnvoye": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"nom": "JOHANSSON ",
|
||||||
|
"prenom": "Scarlett",
|
||||||
|
"email": "opareige@gmail.com",
|
||||||
|
"inscriptionId": "60001",
|
||||||
|
"sequenceId": "30001",
|
||||||
|
"sequenceNom": "Groupe A",
|
||||||
|
"attestationId": "NULL",
|
||||||
|
"documentUrl": "NULL",
|
||||||
|
"emailEnvoye": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "60001",
|
||||||
|
"nom": "PITT",
|
||||||
|
"prenom": "Brad",
|
||||||
|
"email": "test2@gmail.com",
|
||||||
|
"inscriptionId": "270001",
|
||||||
|
"sequenceId": "60001",
|
||||||
|
"sequenceNom": "Groupe C",
|
||||||
|
"attestationId": "NULL",
|
||||||
|
"documentUrl": "NULL",
|
||||||
|
"emailEnvoye": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "90001",
|
||||||
|
"nom": "TEST",
|
||||||
|
"prenom": "Fred",
|
||||||
|
"email": "test.alerte@example.com",
|
||||||
|
"inscriptionId": "150001",
|
||||||
|
"sequenceId": "30001",
|
||||||
|
"sequenceNom": "Groupe A",
|
||||||
|
"attestationId": "NULL",
|
||||||
|
"documentUrl": "NULL",
|
||||||
|
"emailEnvoye": "NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "90002",
|
||||||
|
"nom": "AUBOISDORMANT",
|
||||||
|
"prenom": "Abel",
|
||||||
|
"email": "alerte2.test@example.com",
|
||||||
|
"inscriptionId": "150002",
|
||||||
|
"sequenceId": "30001",
|
||||||
|
"sequenceNom": "Groupe A",
|
||||||
|
"attestationId": "NULL",
|
||||||
|
"documentUrl": "NULL",
|
||||||
|
"emailEnvoye": "NULL"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "id\tnom\tprenom\temail\tinscriptionId\tsequenceId\tsequenceNom\tattestationId\tdocumentUrl\temailEnvoye\n1\tJOHANSSON \tScarlett\topareige@gmail.com\t240001\t60001\tGroupe C\tNULL\tNULL\tNULL\n1\tJOHANSSON \tScarlett\topareige@gmail.com\t60001\t30001\tGroupe A\tNULL\tNULL\tNULL\n60001\tPITT\tBrad\ttest2@gmail.com\t270001\t60001\tGroupe C\tNULL\tNULL\tNULL\n90001\tTEST\tFred\ttest.alerte@example.com\t150001\t30001\tGroupe A\tNULL\tNULL\tNULL\n90002\tAUBOISDORMANT\tAbel\talerte2.test@example.com\t150002\t30001\tGroupe A\tNULL\tNULL\tNULL\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 62
|
||||||
|
}
|
||||||
122
.manus/db/db-query-1768248607421.json
Normal file
122
.manus/db/db-query-1768248607421.json
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"query": "SHOW COLUMNS FROM attestations;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SHOW COLUMNS FROM attestations;",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"Field": "id",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "PRI",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": "auto_increment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "inscriptionId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "apprenantId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "sequenceId",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "s3Key",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "pdfUrl",
|
||||||
|
"Type": "varchar(1000)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "dateGeneration",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "emailEnvoye",
|
||||||
|
"Type": "tinyint(1)",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "0",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "dateEnvoiEmail",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "createdAt",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "NO",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "CURRENT_TIMESTAMP",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "documentUrl",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "documentS3Key",
|
||||||
|
"Type": "varchar(500)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "uploadedBy",
|
||||||
|
"Type": "int(11)",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Field": "uploadedAt",
|
||||||
|
"Type": "timestamp",
|
||||||
|
"Null": "YES",
|
||||||
|
"Key": "",
|
||||||
|
"Default": "NULL",
|
||||||
|
"Extra": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "Field\tType\tNull\tKey\tDefault\tExtra\nid\tint(11)\tNO\tPRI\tNULL\tauto_increment\ninscriptionId\tint(11)\tNO\t\tNULL\t\napprenantId\tint(11)\tNO\t\tNULL\t\nsequenceId\tint(11)\tNO\t\tNULL\t\ns3Key\tvarchar(500)\tNO\t\tNULL\t\npdfUrl\tvarchar(1000)\tNO\t\tNULL\t\ndateGeneration\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\nemailEnvoye\ttinyint(1)\tNO\t\t0\t\ndateEnvoiEmail\ttimestamp\tYES\t\tNULL\t\ncreatedAt\ttimestamp\tNO\t\tCURRENT_TIMESTAMP\t\ndocumentUrl\tvarchar(500)\tYES\t\tNULL\t\ndocumentS3Key\tvarchar(500)\tYES\t\tNULL\t\nuploadedBy\tint(11)\tYES\t\tNULL\t\nuploadedAt\ttimestamp\tYES\t\tNULL\t\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 67
|
||||||
|
}
|
||||||
13
.manus/db/db-query-1768248643875.json
Normal file
13
.manus/db/db-query-1768248643875.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"query": "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'attestations' AND COLUMN_NAME LIKE '%pdf%';",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'attestations' AND COLUMN_NAME LIKE '%pdf%';",
|
||||||
|
"rows": [
|
||||||
|
{
|
||||||
|
"COLUMN_NAME": "pdfUrl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [],
|
||||||
|
"stdout": "COLUMN_NAME\npdfUrl\n",
|
||||||
|
"stderr": "",
|
||||||
|
"execution_time_ms": 59
|
||||||
|
}
|
||||||
8
.manus/db/db-query-error-1768248183279.json
Normal file
8
.manus/db/db-query-error-1768248183279.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"query": "ALTER TABLE attestations\nADD COLUMN inscriptionId INT NOT NULL AFTER sequenceId,\nMODIFY COLUMN urlPdf VARCHAR(500),\nMODIFY COLUMN s3Key VARCHAR(500),\nADD COLUMN emailEnvoye BOOLEAN NOT NULL DEFAULT FALSE AFTER uploadedAt,\nADD COLUMN dateEnvoiEmail TIMESTAMP NULL AFTER emailEnvoye;",
|
||||||
|
"command": "mysql --batch --raw --column-names --default-character-set=utf8mb4 --host gateway02.us-east-1.prod.aws.tidbcloud.com --port 4000 --user 4CrrYuB5tme73Qo.root --database 7PAT67UmWoxv8vwp8Bbcv6 --execute ALTER TABLE attestations\nADD COLUMN inscriptionId INT NOT NULL AFTER sequenceId,\nMODIFY COLUMN urlPdf VARCHAR(500),\nMODIFY COLUMN s3Key VARCHAR(500),\nADD COLUMN emailEnvoye BOOLEAN NOT NULL DEFAULT FALSE AFTER uploadedAt,\nADD COLUMN dateEnvoiEmail TIMESTAMP NULL AFTER emailEnvoye;",
|
||||||
|
"returncode": 1,
|
||||||
|
"logs": [
|
||||||
|
"ERROR 1060 (42S21) at line 1: Duplicate column name 'inscriptionId'"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -411,8 +411,21 @@ export const attestations = mysqlTable("attestations", {
|
|||||||
id: int("id").autoincrement().primaryKey(),
|
id: int("id").autoincrement().primaryKey(),
|
||||||
apprenantId: int("apprenantId").notNull(),
|
apprenantId: int("apprenantId").notNull(),
|
||||||
sequenceId: int("sequenceId").notNull(),
|
sequenceId: int("sequenceId").notNull(),
|
||||||
urlPdf: varchar("urlPdf", { length: 500 }).notNull(),
|
inscriptionId: int("inscriptionId").notNull(),
|
||||||
s3Key: varchar("s3Key", { length: 500 }).notNull(),
|
urlPdf: varchar("urlPdf", { length: 500 }),
|
||||||
|
s3Key: varchar("s3Key", { length: 500 }),
|
||||||
|
/** URL du document uploadé manuellement */
|
||||||
|
documentUrl: varchar("documentUrl", { length: 500 }),
|
||||||
|
/** Clé S3 du document uploadé manuellement */
|
||||||
|
documentS3Key: varchar("documentS3Key", { length: 500 }),
|
||||||
|
/** ID de l'utilisateur qui a uploadé le document */
|
||||||
|
uploadedBy: int("uploadedBy"),
|
||||||
|
/** Date d'upload du document */
|
||||||
|
uploadedAt: timestamp("uploadedAt"),
|
||||||
|
/** Email envoyé ou non */
|
||||||
|
emailEnvoye: boolean("emailEnvoye").default(false).notNull(),
|
||||||
|
/** Date d'envoi de l'email */
|
||||||
|
dateEnvoiEmail: timestamp("dateEnvoiEmail"),
|
||||||
dateGeneration: timestamp("dateGeneration").defaultNow().notNull(),
|
dateGeneration: timestamp("dateGeneration").defaultNow().notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -145,10 +145,26 @@ export async function getApprenantsWithAttestationStatus(formationId: number) {
|
|||||||
|
|
||||||
const results = await db
|
const results = await db
|
||||||
.select({
|
.select({
|
||||||
apprenant: apprenants,
|
apprenant: {
|
||||||
inscription: inscriptions,
|
id: apprenants.id,
|
||||||
sequence: sequences,
|
nom: apprenants.nom,
|
||||||
attestation: attestations,
|
prenom: apprenants.prenom,
|
||||||
|
email: apprenants.email,
|
||||||
|
},
|
||||||
|
inscription: {
|
||||||
|
id: inscriptions.id,
|
||||||
|
sequenceId: inscriptions.sequenceId,
|
||||||
|
},
|
||||||
|
sequence: {
|
||||||
|
id: sequences.id,
|
||||||
|
nom: sequences.nom,
|
||||||
|
},
|
||||||
|
attestation: {
|
||||||
|
id: attestations.id,
|
||||||
|
documentUrl: attestations.documentUrl,
|
||||||
|
emailEnvoye: attestations.emailEnvoye,
|
||||||
|
dateEnvoiEmail: attestations.dateEnvoiEmail,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.from(inscriptions)
|
.from(inscriptions)
|
||||||
.innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id))
|
.innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id))
|
||||||
|
|||||||
@@ -2312,8 +2312,15 @@ export const appRouter = router({
|
|||||||
getApprenantsWithStatus: adminProcedure
|
getApprenantsWithStatus: adminProcedure
|
||||||
.input(z.object({ formationId: z.number() }))
|
.input(z.object({ formationId: z.number() }))
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
const { getApprenantsWithAttestationStatus } = await import("./gestionAttestationsDb");
|
try {
|
||||||
return getApprenantsWithAttestationStatus(input.formationId);
|
const { getApprenantsWithAttestationStatus } = await import("./gestionAttestationsDb");
|
||||||
|
const results = await getApprenantsWithAttestationStatus(input.formationId);
|
||||||
|
console.log("[gestionAttestations] Found", results.length, "apprenants for formation", input.formationId);
|
||||||
|
return results;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[gestionAttestations] Error fetching apprenants:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Uploader un document d'attestation
|
// Uploader un document d'attestation
|
||||||
|
|||||||
@@ -1,14 +1,53 @@
|
|||||||
import { drizzle } from "drizzle-orm/mysql2";
|
import { drizzle } from "drizzle-orm/mysql2";
|
||||||
import mysql from "mysql2/promise";
|
import { eq, and } from "drizzle-orm";
|
||||||
|
import * as schema from "./drizzle/schema.ts";
|
||||||
|
|
||||||
const connection = await mysql.createConnection(process.env.DATABASE_URL);
|
const { apprenants, inscriptions, sequences, attestations } = schema;
|
||||||
const db = drizzle(connection);
|
|
||||||
|
const db = drizzle(process.env.DATABASE_URL);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await connection.query("SELECT YEAR(NOW()) as annee, MONTH(NOW()) as mois");
|
const results = await db
|
||||||
console.log("Test YEAR/MONTH réussi:", result[0]);
|
.select({
|
||||||
|
apprenant: {
|
||||||
|
id: apprenants.id,
|
||||||
|
nom: apprenants.nom,
|
||||||
|
prenom: apprenants.prenom,
|
||||||
|
email: apprenants.email,
|
||||||
|
},
|
||||||
|
inscription: {
|
||||||
|
id: inscriptions.id,
|
||||||
|
sequenceId: inscriptions.sequenceId,
|
||||||
|
},
|
||||||
|
sequence: {
|
||||||
|
id: sequences.id,
|
||||||
|
nom: sequences.nom,
|
||||||
|
},
|
||||||
|
attestation: {
|
||||||
|
id: attestations.id,
|
||||||
|
documentUrl: attestations.documentUrl,
|
||||||
|
urlPdf: attestations.urlPdf,
|
||||||
|
emailEnvoye: attestations.emailEnvoye,
|
||||||
|
dateEnvoiEmail: attestations.dateEnvoiEmail,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.from(inscriptions)
|
||||||
|
.innerJoin(apprenants, eq(inscriptions.apprenantId, apprenants.id))
|
||||||
|
.innerJoin(sequences, eq(inscriptions.sequenceId, sequences.id))
|
||||||
|
.leftJoin(attestations, eq(attestations.inscriptionId, inscriptions.id))
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(sequences.formationId, 1),
|
||||||
|
eq(inscriptions.statut, "confirmee")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.orderBy(apprenants.nom, apprenants.prenom);
|
||||||
|
|
||||||
|
console.log("Success! Found", results.length, "results");
|
||||||
|
console.log(JSON.stringify(results, null, 2));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erreur:", error.message);
|
console.error("Error:", error.message);
|
||||||
|
console.error("Full error:", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
await connection.end();
|
process.exit(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user