From b861dcbb4655dc705c83e0a2a914f54e40be57c2 Mon Sep 17 00:00:00 2001 From: Julien Gautier Date: Sun, 30 Nov 2025 17:48:57 +0100 Subject: [PATCH] Ajout d'un seeder pour la creation d'article de demonstration --- src/database/seeders/20251127-add-articles.js | 142 ++++++++++++++++++ src/database/seeders/index.js | 3 +- 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/database/seeders/20251127-add-articles.js diff --git a/src/database/seeders/20251127-add-articles.js b/src/database/seeders/20251127-add-articles.js new file mode 100644 index 0000000..72dfe82 --- /dev/null +++ b/src/database/seeders/20251127-add-articles.js @@ -0,0 +1,142 @@ +'use strict'; + +const slug = require('slug'); + +const ANIMAL_TAGS = ['Lion', 'Eagle', 'Dolphin', 'Tiger', 'Wolf']; + +const AUTHOR_ID = '642c4459666702637dcb5066'; + +const ARTICLES = [ + { + title: 'Introduction aux écosystèmes marins', + description: 'Découvrez la fascinante diversité des créatures qui vivent sous les vagues.', + body: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`, + tags: ['Dolphin', 'Eagle', 'Wolf'] + }, + { + title: 'Les prédateurs de la savane africaine', + description: 'Exploration des majestueux chasseurs du continent africain.', + body: `Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.`, + tags: ['Lion', 'Tiger', 'Wolf'] + }, + { + title: 'L\'intelligence animale au-delà de nos attentes', + description: 'Comment les animaux développent des stratégies complexes de survie et d\'interaction.', + body: `At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.`, + tags: ['Eagle', 'Dolphin', 'Lion'] + } +]; + +module.exports = { + async up(queryInterface, Sequelize) { + try { + // Create tags first (ignore duplicates) + for (const tagName of ANIMAL_TAGS) { + try { + await queryInterface.insert( + queryInterface.sequelize.models.tag || null, + 'tag', + { name: tagName, createdAt: new Date(), updatedAt: new Date() } + ); + } catch (err) { + // Tag already exists, ignore + } + } + + // Get transaction for consistency + const transaction = await queryInterface.sequelize.transaction(); + + try { + // Create articles + for (const articleData of ARTICLES) { + const { tags: articleTags, ...articleFields } = articleData; + + // Generate unique slug + const baseSlug = slug(articleFields.title, { lower: true }); + let finalSlug = baseSlug; + let counter = 1; + + // Check for existing slug + let existing = true; + while (existing) { + const found = await queryInterface.sequelize.query( + `SELECT id FROM article WHERE slug = ? LIMIT 1`, + { replacements: [finalSlug], transaction, raw: true } + ); + if (found[0].length === 0) { + existing = false; + } else { + finalSlug = `${baseSlug}-${counter}`; + counter++; + } + } + + // Insert article + const now = new Date(); + await queryInterface.insert( + queryInterface.sequelize.models.article || null, + 'article', + { + slug: finalSlug, + title: articleFields.title, + description: articleFields.description, + body: articleFields.body, + authorId: AUTHOR_ID, + createdAt: now, + updatedAt: now + }, + { transaction } + ); + + // Get inserted article ID + const [insertResult] = await queryInterface.sequelize.query( + `SELECT id FROM article WHERE slug = ? LIMIT 1`, + { replacements: [finalSlug], transaction, raw: true } + ); + + if (insertResult && insertResult[0]) { + const articleId = insertResult[0].id; + + // Get tag names and insert associations + for (const tagName of articleTags) { + const now2 = new Date(); + await queryInterface.insert( + queryInterface.sequelize.models.tagList || null, + 'tagList', + { + articleId: articleId, + tagName: tagName, + createdAt: now2, + updatedAt: now2 + }, + { transaction } + ); + } + } + } + + await transaction.commit(); + console.log('✅ Articles and tags seeded successfully'); + } catch (error) { + await transaction.rollback(); + throw error; + } + } catch (error) { + console.error('❌ Error seeding articles:', error); + throw error; + } + }, + + async down(queryInterface, Sequelize) { + try { + // Delete in correct order due to foreign keys + await queryInterface.sequelize.query('DELETE FROM tagList WHERE 1=1'); + await queryInterface.sequelize.query('DELETE FROM article WHERE 1=1'); + + console.log('✅ Articles seed reverted successfully'); + } catch (error) { + console.error('❌ Error reverting articles seed:', error); + throw error; + } + } +}; diff --git a/src/database/seeders/index.js b/src/database/seeders/index.js index 0abae44..35ea9d0 100644 --- a/src/database/seeders/index.js +++ b/src/database/seeders/index.js @@ -1 +1,2 @@ -console.log('this is placeholder for models'); +// Seeders managed by individual migration files +// See seeders directory for specific seeder implementations