//! Catalog seed data — run via `cargo loco seed`. use loco_rs::prelude::*; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use crate::{ models::_entities::{categories, products}, shared::slug::slugify, }; // -- Categories ----------------------------------------------------------- struct CategorySeed { name: &'static str, description: &'static str, position: i32, } const CATEGORIES: &[CategorySeed] = &[ CategorySeed { name: "Electronics", description: "Audio, computing, and smart devices", position: 0, }, CategorySeed { name: "Accessories", description: "Cables, adapters, cases, and everyday essentials", position: 1, }, CategorySeed { name: "Home & Office", description: "Ergonomic furniture, lighting, and desk organization", position: 2, }, ]; // -- Products ------------------------------------------------------------- struct ProductSeed { name: &'static str, description: &'static str, price_cents: i64, stock: i32, category_slug: &'static str, sku: Option<&'static str>, } const PRODUCTS: &[ProductSeed] = &[ ProductSeed { name: "Wireless Headphones", description: "Over-ear Bluetooth headphones with active noise cancelling, 30-hour battery life, and plush memory-foam cushions.", price_cents: 7_999, stock: 25, category_slug: "electronics", sku: Some("WH-1000"), }, ProductSeed { name: "Mechanical Keyboard", description: "Tenkeyless mechanical keyboard with hot-swappable switches, per-key RGB backlight, and a detachable USB-C cable.", price_cents: 12_999, stock: 15, category_slug: "electronics", sku: Some("MK-TKL-RGB"), }, ProductSeed { name: "USB-C Hub", description: "7-in-1 USB-C hub with HDMI 4K output, 100 W power delivery pass-through, SD card reader, and three USB-A 3.2 ports.", price_cents: 3_499, stock: 40, category_slug: "accessories", sku: Some("USBC-HUB7"), }, ProductSeed { name: "Laptop Stand", description: "Adjustable aluminium laptop stand with ventilated surface. Supports laptops from 10\u{201d} to 17\u{201d}.", price_cents: 4_999, stock: 30, category_slug: "accessories", sku: Some("LS-ALU-01"), }, ProductSeed { name: "Desk Lamp", description: "LED desk lamp with 5 colour temperatures, stepless brightness control, and a flexible gooseneck arm.", price_cents: 3_999, stock: 20, category_slug: "home-office", sku: Some("DL-5CT"), }, ProductSeed { name: "Ergonomic Mouse", description: "Vertical wireless ergonomic mouse with 6 buttons, adjustable DPI up to 4 000, and a sculpted thumb rest.", price_cents: 5_999, stock: 18, category_slug: "electronics", sku: Some("EM-VW-01"), }, ProductSeed { name: "Webcam Privacy Cover", description: "Ultra-thin sliding webcam cover compatible with laptops, tablets, and external monitors. Pack of 3.", price_cents: 599, stock: 100, category_slug: "accessories", sku: Some("WPC-3PK"), }, ProductSeed { name: "Cable Organizer Set", description: "Silicone cable management kit with 6 magnetic clips, 4 velcro straps, and an under-desk cable tray.", price_cents: 1_299, stock: 50, category_slug: "home-office", sku: Some("COS-MAG"), }, ]; // -- Public API ----------------------------------------------------------- /// Insert starter categories and products. Called from the `seed()` hook. pub async fn seed_catalog(ctx: &AppContext) -> Result<()> { for cat in CATEGORIES { let slug = slugify(cat.name); let exists = categories::Entity::find() .filter(categories::Column::Slug.eq(&slug)) .one(&ctx.db) .await? .is_some(); if exists { continue; } categories::ActiveModel { name: Set(cat.name.to_string()), slug: Set(slug), description: Set(Some(cat.description.to_string())), position: Set(cat.position), published: Set(true), ..Default::default() } .insert(&ctx.db) .await?; } for item in PRODUCTS { let product_slug = slugify(item.name); let exists = products::Entity::find() .filter(products::Column::Slug.eq(&product_slug)) .one(&ctx.db) .await? .is_some(); if exists { continue; } let cat_slug = slugify(item.category_slug); let category = categories::Entity::find() .filter(categories::Column::Slug.eq(&cat_slug)) .one(&ctx.db) .await?; let now = chrono::Utc::now(); products::ActiveModel { name: Set(item.name.to_string()), slug: Set(product_slug), description: Set(Some(item.description.to_string())), price_cents: Set(item.price_cents), currency: Set("EUR".to_string()), sku: Set(item.sku.map(|s| s.to_string())), stock: Set(item.stock), published: Set(true), published_at: Set(Some(now.into())), category_id: Set(category.map(|c| c.id)), ..Default::default() } .insert(&ctx.db) .await?; } Ok(()) }