0d3cb498a3
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Has been cancelled
Test and Publish Multi-arch Docker Image / test (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Has been cancelled
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Has been cancelled
Validate Renovate Config / Validate Renovate Configuration (push) Has been cancelled
800 lines
18 KiB
Python
800 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Seed the CloudSwag database with demo data.
|
|
Run: python scripts/seed_database.py
|
|
"""
|
|
|
|
import hashlib
|
|
import sqlite3
|
|
from datetime import datetime, timedelta
|
|
from pathlib import Path
|
|
|
|
|
|
def hash_password(password: str) -> str:
|
|
"""Hash password using SHA256 (use bcrypt in production)."""
|
|
return hashlib.sha256(password.encode()).hexdigest()
|
|
|
|
|
|
# Database path
|
|
DB_PATH = Path(__file__).parent.parent / "data" / "swag_store.db"
|
|
|
|
# Schema
|
|
SCHEMA = """
|
|
-- Users (linked to JWT sub claim)
|
|
-- NOTE: salary and ssn_last_four are SENSITIVE - should not be exposed (API3 vulnerability)
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
user_id TEXT PRIMARY KEY,
|
|
email TEXT NOT NULL UNIQUE,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password_hash TEXT NOT NULL,
|
|
full_name TEXT NOT NULL,
|
|
department TEXT,
|
|
office_location TEXT,
|
|
swag_points INTEGER DEFAULT 100,
|
|
salary INTEGER,
|
|
ssn_last_four TEXT,
|
|
role TEXT DEFAULT 'user',
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- Products catalog
|
|
-- NOTE: cost_price, profit_margin, supplier_id are INTERNAL - should not be exposed (API3 vulnerability)
|
|
CREATE TABLE IF NOT EXISTS products (
|
|
product_id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
category TEXT NOT NULL,
|
|
description TEXT,
|
|
price_points INTEGER NOT NULL,
|
|
size TEXT,
|
|
color TEXT,
|
|
stock_quantity INTEGER DEFAULT 0,
|
|
weather_tags TEXT,
|
|
is_active BOOLEAN DEFAULT 1,
|
|
cost_price REAL,
|
|
profit_margin REAL,
|
|
supplier_id TEXT
|
|
);
|
|
|
|
-- Orders (user_id MUST match JWT for access)
|
|
CREATE TABLE IF NOT EXISTS orders (
|
|
order_id TEXT PRIMARY KEY,
|
|
user_id TEXT NOT NULL,
|
|
status TEXT DEFAULT 'pending',
|
|
total_points INTEGER NOT NULL,
|
|
shipping_address TEXT,
|
|
tracking_number TEXT,
|
|
carrier TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
);
|
|
|
|
-- Order line items
|
|
CREATE TABLE IF NOT EXISTS order_items (
|
|
item_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
order_id TEXT NOT NULL,
|
|
product_id TEXT NOT NULL,
|
|
quantity INTEGER DEFAULT 1,
|
|
points_each INTEGER NOT NULL,
|
|
FOREIGN KEY (order_id) REFERENCES orders(order_id),
|
|
FOREIGN KEY (product_id) REFERENCES products(product_id)
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX IF NOT EXISTS idx_orders_user_id ON orders(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
|
|
CREATE INDEX IF NOT EXISTS idx_order_items_order_id ON order_items(order_id);
|
|
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category);
|
|
"""
|
|
|
|
# Demo Users - (user_id, email, username, password, full_name, department, office_location, swag_points, salary, ssn_last_four, role)
|
|
# All demo passwords are "password123"
|
|
# NOTE: salary and ssn_last_four are SENSITIVE data for API3 vulnerability testing
|
|
DEMO_PASSWORD = "password123"
|
|
USERS = [
|
|
(
|
|
"emp_001",
|
|
"alice.johnson@cloudco.com",
|
|
"alice",
|
|
hash_password(DEMO_PASSWORD),
|
|
"Alice Johnson",
|
|
"Engineering",
|
|
"San Francisco, CA",
|
|
150,
|
|
145000,
|
|
"1234",
|
|
"user",
|
|
),
|
|
(
|
|
"emp_002",
|
|
"bob.smith@cloudco.com",
|
|
"bob",
|
|
hash_password(DEMO_PASSWORD),
|
|
"Bob Smith",
|
|
"Marketing",
|
|
"New York, NY",
|
|
200,
|
|
95000,
|
|
"5678",
|
|
"user",
|
|
),
|
|
(
|
|
"emp_003",
|
|
"charlie.brown@cloudco.com",
|
|
"charlie",
|
|
hash_password(DEMO_PASSWORD),
|
|
"Charlie Brown",
|
|
"Sales",
|
|
"Chicago, IL",
|
|
75,
|
|
85000,
|
|
"9012",
|
|
"user",
|
|
),
|
|
(
|
|
"emp_004",
|
|
"diana.prince@cloudco.com",
|
|
"diana",
|
|
hash_password(DEMO_PASSWORD),
|
|
"Diana Prince",
|
|
"HR",
|
|
"Austin, TX",
|
|
300,
|
|
110000,
|
|
"3456",
|
|
"admin",
|
|
),
|
|
(
|
|
"emp_005",
|
|
"eve.wilson@cloudco.com",
|
|
"eve",
|
|
hash_password(DEMO_PASSWORD),
|
|
"Eve Wilson",
|
|
"Finance",
|
|
"Seattle, WA",
|
|
125,
|
|
125000,
|
|
"7890",
|
|
"user",
|
|
),
|
|
]
|
|
|
|
# Products - now with INTERNAL pricing data (cost_price, profit_margin, supplier_id) for API3 vulnerability
|
|
# Format: (product_id, name, category, description, price_points, size, color, stock_quantity, weather_tags, cost_price, profit_margin, supplier_id)
|
|
PRODUCTS = [
|
|
# T-Shirts - cost around $5, 80% margin
|
|
(
|
|
"TSHIRT-BLU-S",
|
|
"CloudCo Logo Tee",
|
|
"apparel",
|
|
"Classic blue tee with embroidered CloudCo logo",
|
|
25,
|
|
"S",
|
|
"Blue",
|
|
50,
|
|
'["mild", "indoor"]',
|
|
5.00,
|
|
0.80,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-BLU-M",
|
|
"CloudCo Logo Tee",
|
|
"apparel",
|
|
"Classic blue tee with embroidered CloudCo logo",
|
|
25,
|
|
"M",
|
|
"Blue",
|
|
75,
|
|
'["mild", "indoor"]',
|
|
5.00,
|
|
0.80,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-BLU-L",
|
|
"CloudCo Logo Tee",
|
|
"apparel",
|
|
"Classic blue tee with embroidered CloudCo logo",
|
|
25,
|
|
"L",
|
|
"Blue",
|
|
60,
|
|
'["mild", "indoor"]',
|
|
5.25,
|
|
0.79,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-BLU-XL",
|
|
"CloudCo Logo Tee",
|
|
"apparel",
|
|
"Classic blue tee with embroidered CloudCo logo",
|
|
25,
|
|
"XL",
|
|
"Blue",
|
|
40,
|
|
'["mild", "indoor"]',
|
|
5.50,
|
|
0.78,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-BLK-M",
|
|
"CloudCo Dark Mode Tee",
|
|
"apparel",
|
|
"Black tee for dark mode enthusiasts",
|
|
30,
|
|
"M",
|
|
"Black",
|
|
40,
|
|
'["mild", "indoor"]',
|
|
6.00,
|
|
0.80,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-BLK-L",
|
|
"CloudCo Dark Mode Tee",
|
|
"apparel",
|
|
"Black tee for dark mode enthusiasts",
|
|
30,
|
|
"L",
|
|
"Black",
|
|
35,
|
|
'["mild", "indoor"]',
|
|
6.25,
|
|
0.79,
|
|
"SUP-APPAREL-001",
|
|
),
|
|
(
|
|
"TSHIRT-WHT-M",
|
|
"CloudCo Minimalist Tee",
|
|
"apparel",
|
|
"Clean white design with subtle logo",
|
|
25,
|
|
"M",
|
|
"White",
|
|
45,
|
|
'["mild", "indoor"]',
|
|
4.75,
|
|
0.81,
|
|
"SUP-APPAREL-002",
|
|
),
|
|
(
|
|
"TSHIRT-WHT-L",
|
|
"CloudCo Minimalist Tee",
|
|
"apparel",
|
|
"Clean white design with subtle logo",
|
|
25,
|
|
"L",
|
|
"White",
|
|
35,
|
|
'["mild", "indoor"]',
|
|
5.00,
|
|
0.80,
|
|
"SUP-APPAREL-002",
|
|
),
|
|
# Hoodies - cost around $15-18, 70% margin
|
|
(
|
|
"HOODIE-GRY-S",
|
|
"CloudCo Zip Hoodie",
|
|
"apparel",
|
|
"Warm zip-up hoodie with embroidered logo",
|
|
50,
|
|
"S",
|
|
"Gray",
|
|
20,
|
|
'["cold", "outdoor"]',
|
|
15.00,
|
|
0.70,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
(
|
|
"HOODIE-GRY-M",
|
|
"CloudCo Zip Hoodie",
|
|
"apparel",
|
|
"Warm zip-up hoodie with embroidered logo",
|
|
50,
|
|
"M",
|
|
"Gray",
|
|
30,
|
|
'["cold", "outdoor"]',
|
|
15.00,
|
|
0.70,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
(
|
|
"HOODIE-GRY-L",
|
|
"CloudCo Zip Hoodie",
|
|
"apparel",
|
|
"Warm zip-up hoodie with embroidered logo",
|
|
50,
|
|
"L",
|
|
"Gray",
|
|
25,
|
|
'["cold", "outdoor"]',
|
|
15.50,
|
|
0.69,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
(
|
|
"HOODIE-GRY-XL",
|
|
"CloudCo Zip Hoodie",
|
|
"apparel",
|
|
"Warm zip-up hoodie with embroidered logo",
|
|
50,
|
|
"XL",
|
|
"Gray",
|
|
15,
|
|
'["cold", "outdoor"]',
|
|
16.00,
|
|
0.68,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
(
|
|
"HOODIE-NVY-M",
|
|
"CloudCo Pullover",
|
|
"apparel",
|
|
"Cozy navy pullover hoodie",
|
|
45,
|
|
"M",
|
|
"Navy",
|
|
20,
|
|
'["cold", "outdoor"]',
|
|
13.50,
|
|
0.70,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
(
|
|
"HOODIE-NVY-L",
|
|
"CloudCo Pullover",
|
|
"apparel",
|
|
"Cozy navy pullover hoodie",
|
|
45,
|
|
"L",
|
|
"Navy",
|
|
25,
|
|
'["cold", "outdoor"]',
|
|
14.00,
|
|
0.69,
|
|
"SUP-APPAREL-003",
|
|
),
|
|
# Hats - cost around $3-5, 75-85% margin
|
|
(
|
|
"HAT-SNAP-BLK",
|
|
"CloudCo Snapback",
|
|
"accessories",
|
|
"Adjustable snapback cap with embroidered logo",
|
|
20,
|
|
None,
|
|
"Black",
|
|
100,
|
|
'["sunny", "outdoor"]',
|
|
4.00,
|
|
0.80,
|
|
"SUP-ACC-001",
|
|
),
|
|
(
|
|
"HAT-SNAP-NVY",
|
|
"CloudCo Snapback",
|
|
"accessories",
|
|
"Adjustable snapback cap with embroidered logo",
|
|
20,
|
|
None,
|
|
"Navy",
|
|
80,
|
|
'["sunny", "outdoor"]',
|
|
4.00,
|
|
0.80,
|
|
"SUP-ACC-001",
|
|
),
|
|
(
|
|
"HAT-BEANIE-GRY",
|
|
"CloudCo Beanie",
|
|
"accessories",
|
|
"Warm knit beanie for cold days",
|
|
15,
|
|
None,
|
|
"Gray",
|
|
80,
|
|
'["cold", "outdoor"]',
|
|
3.00,
|
|
0.80,
|
|
"SUP-ACC-001",
|
|
),
|
|
(
|
|
"HAT-BEANIE-BLK",
|
|
"CloudCo Beanie",
|
|
"accessories",
|
|
"Warm knit beanie for cold days",
|
|
15,
|
|
None,
|
|
"Black",
|
|
70,
|
|
'["cold", "outdoor"]',
|
|
3.00,
|
|
0.80,
|
|
"SUP-ACC-001",
|
|
),
|
|
# Drinkware - cost around $4-8, 75% margin
|
|
(
|
|
"BOTTLE-BLU-20",
|
|
"CloudCo Water Bottle",
|
|
"drinkware",
|
|
"20oz insulated stainless steel bottle",
|
|
20,
|
|
None,
|
|
"Blue",
|
|
150,
|
|
'["hot", "outdoor"]',
|
|
5.00,
|
|
0.75,
|
|
"SUP-DRINK-001",
|
|
),
|
|
(
|
|
"BOTTLE-BLK-20",
|
|
"CloudCo Water Bottle",
|
|
"drinkware",
|
|
"20oz insulated stainless steel bottle",
|
|
20,
|
|
None,
|
|
"Black",
|
|
120,
|
|
'["hot", "outdoor"]',
|
|
5.00,
|
|
0.75,
|
|
"SUP-DRINK-001",
|
|
),
|
|
(
|
|
"MUG-WHT-12",
|
|
"CloudCo Coffee Mug",
|
|
"drinkware",
|
|
"12oz ceramic mug with logo",
|
|
15,
|
|
None,
|
|
"White",
|
|
200,
|
|
'["cold", "indoor"]',
|
|
3.50,
|
|
0.77,
|
|
"SUP-DRINK-002",
|
|
),
|
|
(
|
|
"MUG-BLK-12",
|
|
"CloudCo Coffee Mug",
|
|
"drinkware",
|
|
"12oz ceramic mug - dark mode edition",
|
|
15,
|
|
None,
|
|
"Black",
|
|
150,
|
|
'["cold", "indoor"]',
|
|
3.75,
|
|
0.75,
|
|
"SUP-DRINK-002",
|
|
),
|
|
(
|
|
"TUMBLER-BLK-16",
|
|
"CloudCo Travel Tumbler",
|
|
"drinkware",
|
|
"16oz vacuum-insulated tumbler",
|
|
25,
|
|
None,
|
|
"Black",
|
|
60,
|
|
'["any"]',
|
|
7.50,
|
|
0.70,
|
|
"SUP-DRINK-001",
|
|
),
|
|
# Stickers - very low cost, 90%+ margin
|
|
(
|
|
"STICKER-LOGO-5PK",
|
|
"Logo Sticker Pack",
|
|
"stickers",
|
|
"5 vinyl CloudCo logo stickers",
|
|
5,
|
|
None,
|
|
None,
|
|
500,
|
|
'["any"]',
|
|
0.50,
|
|
0.90,
|
|
"SUP-PRINT-001",
|
|
),
|
|
(
|
|
"STICKER-DEV-10PK",
|
|
"Developer Sticker Pack",
|
|
"stickers",
|
|
"10 coding-themed stickers",
|
|
10,
|
|
None,
|
|
None,
|
|
300,
|
|
'["any"]',
|
|
0.75,
|
|
0.93,
|
|
"SUP-PRINT-001",
|
|
),
|
|
(
|
|
"STICKER-HOLO-3PK",
|
|
"Holographic Sticker Pack",
|
|
"stickers",
|
|
"3 premium holographic stickers",
|
|
8,
|
|
None,
|
|
None,
|
|
150,
|
|
'["any"]',
|
|
1.20,
|
|
0.85,
|
|
"SUP-PRINT-002",
|
|
),
|
|
# Other Accessories
|
|
(
|
|
"BACKPACK-BLK",
|
|
"CloudCo Laptop Backpack",
|
|
"accessories",
|
|
"15-inch laptop backpack with padded compartment",
|
|
75,
|
|
None,
|
|
"Black",
|
|
25,
|
|
'["any", "outdoor"]',
|
|
22.50,
|
|
0.70,
|
|
"SUP-ACC-002",
|
|
),
|
|
(
|
|
"LANYARD-BLU",
|
|
"CloudCo Lanyard",
|
|
"accessories",
|
|
"Badge lanyard with detachable clip",
|
|
5,
|
|
None,
|
|
"Blue",
|
|
400,
|
|
'["any"]',
|
|
0.75,
|
|
0.85,
|
|
"SUP-ACC-003",
|
|
),
|
|
(
|
|
"MOUSEPAD-BLK",
|
|
"CloudCo Desk Pad",
|
|
"accessories",
|
|
"Large extended mousepad with logo",
|
|
15,
|
|
None,
|
|
"Black",
|
|
100,
|
|
'["any", "indoor"]',
|
|
4.50,
|
|
0.70,
|
|
"SUP-ACC-004",
|
|
),
|
|
(
|
|
"SOCKS-LOGO-M",
|
|
"CloudCo Logo Socks",
|
|
"accessories",
|
|
"Comfy crew socks with CloudCo pattern",
|
|
10,
|
|
"M",
|
|
"Blue",
|
|
150,
|
|
'["any"]',
|
|
2.00,
|
|
0.80,
|
|
"SUP-APPAREL-004",
|
|
),
|
|
]
|
|
|
|
|
|
# Orders - dates relative to now
|
|
def get_orders():
|
|
now = datetime.now()
|
|
return [
|
|
# Alice's orders
|
|
(
|
|
"ORD-2024-001",
|
|
"emp_001",
|
|
"delivered",
|
|
45,
|
|
"123 Tech Lane, San Francisco, CA 94105",
|
|
"FX123456789",
|
|
"fedex",
|
|
now - timedelta(days=14),
|
|
),
|
|
(
|
|
"ORD-2024-005",
|
|
"emp_001",
|
|
"shipped",
|
|
70,
|
|
"123 Tech Lane, San Francisco, CA 94105",
|
|
"1Z999AA10123456784",
|
|
"ups",
|
|
now - timedelta(days=3),
|
|
),
|
|
(
|
|
"ORD-2024-010",
|
|
"emp_001",
|
|
"pending",
|
|
25,
|
|
"123 Tech Lane, San Francisco, CA 94105",
|
|
None,
|
|
None,
|
|
now - timedelta(hours=6),
|
|
),
|
|
# Bob's orders
|
|
(
|
|
"ORD-2024-002",
|
|
"emp_002",
|
|
"delivered",
|
|
30,
|
|
"456 Marketing Ave, New York, NY 10001",
|
|
"FX987654321",
|
|
"fedex",
|
|
now - timedelta(days=21),
|
|
),
|
|
(
|
|
"ORD-2024-007",
|
|
"emp_002",
|
|
"confirmed",
|
|
50,
|
|
"456 Marketing Ave, New York, NY 10001",
|
|
None,
|
|
None,
|
|
now - timedelta(days=1),
|
|
),
|
|
# Charlie's orders
|
|
(
|
|
"ORD-2024-003",
|
|
"emp_003",
|
|
"shipped",
|
|
55,
|
|
"789 Sales Blvd, Chicago, IL 60601",
|
|
"1Z999BB20123456785",
|
|
"ups",
|
|
now - timedelta(days=5),
|
|
),
|
|
# Diana's orders
|
|
(
|
|
"ORD-2024-004",
|
|
"emp_004",
|
|
"delivered",
|
|
15,
|
|
"321 HR Street, Austin, TX 78701",
|
|
"FX111222333",
|
|
"fedex",
|
|
now - timedelta(days=30),
|
|
),
|
|
(
|
|
"ORD-2024-008",
|
|
"emp_004",
|
|
"delivered",
|
|
95,
|
|
"321 HR Street, Austin, TX 78701",
|
|
"FX444555666",
|
|
"fedex",
|
|
now - timedelta(days=10),
|
|
),
|
|
# Eve's orders
|
|
(
|
|
"ORD-2024-006",
|
|
"emp_005",
|
|
"pending",
|
|
40,
|
|
"555 Finance Way, Seattle, WA 98101",
|
|
None,
|
|
None,
|
|
now - timedelta(days=2),
|
|
),
|
|
(
|
|
"ORD-2024-009",
|
|
"emp_005",
|
|
"shipped",
|
|
25,
|
|
"555 Finance Way, Seattle, WA 98101",
|
|
"1Z999CC30123456786",
|
|
"ups",
|
|
now - timedelta(days=4),
|
|
),
|
|
]
|
|
|
|
|
|
# Order items
|
|
ORDER_ITEMS = [
|
|
# Alice's first order (delivered) - t-shirt + hat
|
|
("ORD-2024-001", "TSHIRT-BLU-M", 1, 25),
|
|
("ORD-2024-001", "HAT-SNAP-BLK", 1, 20),
|
|
# Alice's second order (shipped) - hoodie + water bottle
|
|
("ORD-2024-005", "HOODIE-GRY-M", 1, 50),
|
|
("ORD-2024-005", "BOTTLE-BLU-20", 1, 20),
|
|
# Alice's third order (pending) - t-shirt
|
|
("ORD-2024-010", "TSHIRT-BLK-M", 1, 25),
|
|
# Bob's first order (delivered) - stickers + mug
|
|
("ORD-2024-002", "STICKER-LOGO-5PK", 2, 5),
|
|
("ORD-2024-002", "MUG-WHT-12", 1, 15),
|
|
("ORD-2024-002", "LANYARD-BLU", 1, 5),
|
|
# Bob's second order (confirmed) - hoodie
|
|
("ORD-2024-007", "HOODIE-NVY-M", 1, 45),
|
|
("ORD-2024-007", "STICKER-DEV-10PK", 1, 5),
|
|
# Charlie's order (shipped) - backpack
|
|
("ORD-2024-003", "BACKPACK-BLK", 1, 75),
|
|
# Diana's first order (delivered) - lanyards
|
|
("ORD-2024-004", "LANYARD-BLU", 3, 5),
|
|
# Diana's second order (delivered) - hoodie + accessories
|
|
("ORD-2024-008", "HOODIE-GRY-L", 1, 50),
|
|
("ORD-2024-008", "HAT-BEANIE-GRY", 1, 15),
|
|
("ORD-2024-008", "MUG-BLK-12", 2, 15),
|
|
# Eve's first order (pending) - tumbler + mousepad
|
|
("ORD-2024-006", "TUMBLER-BLK-16", 1, 25),
|
|
("ORD-2024-006", "MOUSEPAD-BLK", 1, 15),
|
|
# Eve's second order (shipped) - t-shirt
|
|
("ORD-2024-009", "TSHIRT-WHT-M", 1, 25),
|
|
]
|
|
|
|
|
|
def seed_database():
|
|
"""Create and seed the database."""
|
|
# Ensure data directory exists
|
|
DB_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Remove existing database
|
|
if DB_PATH.exists():
|
|
DB_PATH.unlink()
|
|
print(f"Removed existing database: {DB_PATH}")
|
|
|
|
# Create connection
|
|
conn = sqlite3.connect(DB_PATH)
|
|
cursor = conn.cursor()
|
|
|
|
# Create schema
|
|
cursor.executescript(SCHEMA)
|
|
print("Created database schema")
|
|
|
|
# Insert users
|
|
cursor.executemany(
|
|
"INSERT INTO users (user_id, email, username, password_hash, full_name, department, office_location, swag_points, salary, ssn_last_four, role) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
USERS,
|
|
)
|
|
print(f"Inserted {len(USERS)} users")
|
|
|
|
# Insert products (including sensitive cost data for API3 vulnerability)
|
|
cursor.executemany(
|
|
"INSERT INTO products (product_id, name, category, description, price_points, size, color, stock_quantity, weather_tags, cost_price, profit_margin, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
PRODUCTS,
|
|
)
|
|
print(f"Inserted {len(PRODUCTS)} products")
|
|
|
|
# Insert orders
|
|
orders = get_orders()
|
|
cursor.executemany(
|
|
"INSERT INTO orders (order_id, user_id, status, total_points, shipping_address, tracking_number, carrier, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
|
orders,
|
|
)
|
|
print(f"Inserted {len(orders)} orders")
|
|
|
|
# Insert order items
|
|
cursor.executemany(
|
|
"INSERT INTO order_items (order_id, product_id, quantity, points_each) VALUES (?, ?, ?, ?)",
|
|
ORDER_ITEMS,
|
|
)
|
|
print(f"Inserted {len(ORDER_ITEMS)} order items")
|
|
|
|
# Commit and close
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
print(f"\nDatabase created successfully at: {DB_PATH}")
|
|
print("\nDemo accounts:")
|
|
print(" alice (emp_001) - 3 orders")
|
|
print(" bob (emp_002) - 2 orders")
|
|
print(" charlie (emp_003) - 1 order")
|
|
print(" diana (emp_004) - 2 orders")
|
|
print(" eve (emp_005) - 2 orders")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
seed_database()
|