Database Schema Designer
Run ID: 69cb1e1f61b1021a29a860292026-03-31Development
PantheraHive BOS
BOS Dashboard

This document outlines a comprehensive and detailed study plan designed to equip you with the theoretical knowledge and practical skills required to become a proficient Database Schema Designer. This plan will guide you through foundational concepts to advanced design principles, enabling you to create robust, efficient, and scalable database schemas for diverse application needs.


Database Schema Designer: Comprehensive Study Plan

1. Program Overview and Goal

Goal: To master the principles and practices of database schema design, enabling the creation of optimized, scalable, and maintainable relational (and introductory NoSQL) database structures. By the end of this program, you will be able to translate complex business requirements into effective database models and implement them using industry-standard tools and languages.

Target Audience: Aspiring database administrators, backend developers, data engineers, and anyone looking to deepen their understanding of data modeling and database design.

Duration: 10 Weeks

2. Weekly Schedule and Learning Objectives

This 10-week schedule provides a structured path through the core concepts of database schema design. Each week builds upon the previous, ensuring a progressive learning experience.


Week 1: Fundamentals of Databases & Relational Model

  • Learning Objectives:

* Understand the fundamental purpose and types of databases (RDBMS vs. NoSQL overview).

* Grasp the core concepts of the Relational Model: tables, rows, columns, domains.

* Identify and differentiate various types of keys: Primary Key, Foreign Key, Candidate Key, Super Key.

* Familiarize with common SQL data types and their appropriate usage.

* Basic SQL DDL (Data Definition Language) commands: CREATE DATABASE, CREATE TABLE (initial exposure).

  • Key Topics: Database purpose, RDBMS vs. NoSQL, Relational Algebra (brief), Relational Model components, SQL data types, Key concepts.

Week 2: Entity-Relationship (ER) Modeling

  • Learning Objectives:

* Model real-world entities, attributes, and relationships effectively using ER diagrams.

* Understand and correctly apply cardinality (one-to-one, one-to-many, many-to-many) and ordinality (optional, mandatory) in relationships.

* Differentiate between strong and weak entities, and understand their representation.

* Represent composite and multi-valued attributes in ER diagrams.

* Utilize common ERD notations (e.g., Crow's Foot, Chen) for clear communication.

  • Key Topics: Entities, Attributes (simple, composite, multi-valued, derived), Relationships (degree, cardinality, ordinality), Weak entities, ERD notations.

Week 3: Normalization - Part 1 (1NF, 2NF, 3NF)

  • Learning Objectives:

* Identify and explain common database anomalies (insertion, deletion, update).

* Understand the concept of functional dependencies and how to identify them.

* Apply the rules of First Normal Form (1NF), Second Normal Form (2NF), and Third Normal Form (3NF) to a database schema.

* Transform an unnormalized schema into 3NF to reduce data redundancy and improve data integrity.

  • Key Topics: Data anomalies, Functional dependencies, Transitive dependencies, 1NF, 2NF, 3NF, Normalization process.

Week 4: Normalization - Part 2 (BCNF, 4NF, 5NF) & Denormalization

  • Learning Objectives:

* Understand the conditions and application of Boyce-Codd Normal Form (BCNF).

* Identify and resolve multivalued dependencies, leading to Fourth Normal Form (4NF).

* Briefly understand Join Dependencies and Fifth Normal Form (5NF).

* Evaluate when and why denormalization might be a suitable strategy for performance optimization.

* Choose the appropriate normal form for a given design scenario.

  • Key Topics: BCNF, Multivalued dependencies, 4NF, Join dependencies, 5NF (brief), Denormalization strategies.

Week 5: SQL DDL & Schema Implementation

  • Learning Objectives:

* Translate a logical ER model into a physical database schema using SQL DDL commands.

* Master CREATE TABLE, ALTER TABLE, and DROP TABLE statements.

* Implement various constraints: PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK, DEFAULT.

* Understand the purpose and types of indexes (clustered vs. non-clustered, B-tree) and when to apply them.

* Create and manage views for simplified data access and security.

  • Key Topics: CREATE/ALTER/DROP TABLE, Constraints, Indexes, Views, Schemas (database objects grouping).

Week 6: Advanced Schema Design Concepts

  • Learning Objectives:

* Design schemas to effectively handle hierarchical data (e.g., categories, organizational structures) using methods like Adjacency List, Nested Set, and Closure Table.

* Implement strategies for managing temporal data (e.g., versioning, audit trails).

* Consider schema implications for storing and querying geospatial data.

* Integrate JSON/XML data types within relational schemas where appropriate.

* Understand polymorphic associations and their design patterns.

  • Key Topics: Hierarchical data patterns, Temporal data, Geospatial data, JSON/XML data types, Polymorphic associations.

Week 7: Performance Considerations & Indexing Strategies

  • Learning Objectives:

* Understand the basics of query optimization and how schema design impacts performance.

* Analyze query execution plans (EXPLAIN statement) to identify bottlenecks.

* Develop effective indexing strategies based on query patterns and data distribution.

* Explore table partitioning and sharding as scalability techniques.

* Design schemas with data archiving and purging in mind.

  • Key Topics: Query optimization, EXPLAIN plans, Index types and selection, Partitioning, Sharding (overview), Data archiving.

Week 8: Security & Scalability in Schema Design

  • Learning Objectives:

* Design schemas that support robust user roles and permission models.

* Understand how data encryption (at rest and in transit) impacts schema considerations.

* Explore how schema design choices influence horizontal scaling (sharding) and replication strategies.

* Implement strategies for auditing and logging data access and modifications.

* Consider multi-tenancy implications for schema design.

  • Key Topics: User roles and permissions, Data encryption, Multi-tenancy, Auditing, Replication, Horizontal scaling impact.

Week 9: NoSQL Schema Design Principles (Introduction)

  • Learning Objectives:

* Gain an introductory understanding of different NoSQL database types (Document, Key-Value, Column-Family, Graph).

* Differentiate between "schema-less" and "schema-on-read" approaches.

* Understand the common patterns of denormalization and data duplication in NoSQL for performance.

* Identify appropriate use cases for NoSQL databases compared to traditional RDBMS.

* Design basic schemas for document and key-value stores.

  • Key Topics: NoSQL types, Schema-less vs. schema-on-read, Denormalization in NoSQL, Consistency models (brief), Use cases.

Week 10: Project & Review

  • Learning Objectives:

* Apply all learned concepts to a comprehensive, real-world database schema design project.

* Articulate and justify design choices based on business requirements, performance, and scalability.

* Review common database design anti-patterns and best practices.

* Develop a professional-grade database design document.

  • Key Topics: Full project implementation, Design documentation, Anti-patterns, Best practices, Q&A.

3. Recommended Resources

Leverage a mix of foundational texts, practical guides, online courses, and official documentation to solidify your understanding.

  • Books:

Foundational: Database System Concepts* by Silberschatz, Korth, Sudarshan.

Relational Theory: SQL and Relational Theory: How to Write Accurate SQL Code* by C.J. Date.

Practical Design: SQL Antipatterns: Avoiding the Pitfalls of Database Programming* by Bill Karwin.

Advanced/Distributed: Designing Data-Intensive Applications* by Martin Kleppmann.

  • Online Courses:

* Coursera/edX: Look for "Database Management Systems" courses from top universities (e.g., Stanford, University of Michigan).

* Udemy/Pluralsight: Search for courses on "Database Design," "SQL DDL," "ER Modeling," and specific RDBMS (e.g., PostgreSQL, MySQL).

* Khan Academy: "Introduction to SQL" (good for beginners).

  • Documentation:

* Official documentation for your chosen RDBMS (e.g., PostgreSQL, MySQL, SQL Server) for DDL syntax, data types, and indexing specifics.

  • Tools:

* ERD Tools:

* Online: draw.io, Lucidchart, dbdiagram.io

* Desktop: MySQL Workbench (for MySQL), pgAdmin (for PostgreSQL)

* Database Clients: DBeaver (multi-database), pgAdmin (PostgreSQL), MySQL Workbench (MySQL), SQL Server Management Studio (SQL Server), DataGrip (JetBrains).

* SQL Fiddle: For quickly

gemini Output

Database Schema Design Output: E-commerce System

This document presents a comprehensive and detailed database schema design for a simplified e-commerce system. The design emphasizes data integrity, scalability, and performance, following industry best practices. This output is suitable for direct implementation in a relational database management system (RDBMS) like PostgreSQL.


1. Introduction & Project Context

This deliverable provides the logical and physical database schema for a foundational e-commerce platform. The design aims to manage core entities such as users, products, categories, orders, and order items. The generated code includes Data Definition Language (DDL) statements for creating tables, defining relationships, and applying constraints, ensuring a robust and maintainable database foundation.

Key Design Goals:

  • Data Integrity: Enforce consistency and accuracy through primary keys, foreign keys, unique constraints, and check constraints.
  • Scalability: Design for future growth with appropriate data types and indexing strategies.
  • Performance: Optimize common query patterns with strategic indexing.
  • Readability & Maintainability: Provide clear naming conventions, comments, and a logical structure.
  • Extensibility: Allow for future additions without significant schema refactoring.

2. Conceptual Model: Core Entities and Relationships

At a high level, the e-commerce system revolves around the following key entities and their relationships:

  • Users: Individuals who interact with the system (customers, administrators).
  • Products: Items available for purchase.
  • Categories: Classifications for products (e.g., Electronics, Clothing, Books).
  • Orders: Records of purchases made by users.
  • Order Items: Details of individual products within an order, including quantity and price at the time of purchase.

Relationships:

  • A User can place multiple Orders.
  • A Product belongs to one Category.
  • An Order can contain multiple Order Items.
  • An Order Item references one Product and belongs to one Order.

3. Logical Model: Detailed Table Design

This section outlines the detailed structure of each table, specifying columns, data types, and constraints.

Table: users

  • Purpose: Stores user account information.
  • Columns:

* user_id (PK, UUID): Unique identifier for the user.

* username (UNIQUE, VARCHAR(50)): User's chosen username for login.

* email (UNIQUE, VARCHAR(100)): User's email address, used for communication and login.

* password_hash (VARCHAR(255)): Hashed password for security.

* first_name (VARCHAR(50)): User's first name.

* last_name (VARCHAR(50)): User's last name.

* address (TEXT): User's primary shipping/billing address.

* phone_number (VARCHAR(20)): User's contact phone number.

* is_admin (BOOLEAN, DEFAULT FALSE): Flag to identify administrative users.

* created_at (TIMESTAMPTZ): Timestamp when the user account was created.

* updated_at (TIMESTAMPTZ): Timestamp of the last update to the user account.

Table: categories

  • Purpose: Organizes products into logical groups.
  • Columns:

* category_id (PK, UUID): Unique identifier for the category.

* name (UNIQUE, VARCHAR(100)): Name of the category (e.g., "Electronics").

* description (TEXT): Optional description for the category.

* created_at (TIMESTAMPTZ): Timestamp when the category was created.

* updated_at (TIMESTAMPTZ): Timestamp of the last update to the category.

Table: products

  • Purpose: Stores details about items available for sale.
  • Columns:

* product_id (PK, UUID): Unique identifier for the product.

* name (VARCHAR(255)): Name of the product.

* description (TEXT): Detailed description of the product.

* price (NUMERIC(10, 2)): Current selling price of the product.

* stock_quantity (INTEGER): Current quantity of the product in stock.

* category_id (FK to categories.category_id): The category this product belongs to.

* image_url (VARCHAR(255)): URL to the product's primary image.

* is_available (BOOLEAN, DEFAULT TRUE): Flag indicating if the product is currently available for purchase.

* created_at (TIMESTAMPTZ): Timestamp when the product was added.

* updated_at (TIMESTAMPTZ): Timestamp of the last update to the product.

Table: orders

  • Purpose: Records customer purchases.
  • Columns:

* order_id (PK, UUID): Unique identifier for the order.

* user_id (FK to users.user_id): The user who placed the order.

* order_date (TIMESTAMPTZ): Date and time the order was placed.

* total_amount (NUMERIC(10, 2)): Total cost of the order (calculated from order items).

* status (VARCHAR(50), DEFAULT 'pending'): Current status of the order (e.g., 'pending', 'processing', 'shipped', 'delivered', 'cancelled').

* shipping_address (TEXT): Shipping address for this specific order (can differ from user's default).

* billing_address (TEXT): Billing address for this specific order.

* created_at (TIMESTAMPTZ): Timestamp when the order record was created.

* updated_at (TIMESTAMPTZ): Timestamp of the last update to the order record.

Table: order_items

  • Purpose: Links products to specific orders, storing details at the time of purchase.
  • Columns:

* order_item_id (PK, UUID): Unique identifier for the order item.

* order_id (FK to orders.order_id): The order this item belongs to.

* product_id (FK to products.product_id): The product purchased.

* quantity (INTEGER): Quantity of the product purchased in this order item.

* price_at_purchase (NUMERIC(10, 2)): Price of the product at the time of purchase (important for historical accuracy).

* created_at (TIMESTAMPTZ): Timestamp when the order item was created.

* updated_at (TIMESTAMPTZ): Timestamp of the last update to the order item.


4. Physical Model: Production-Ready SQL DDL Code (PostgreSQL)

The following DDL script is designed for PostgreSQL, utilizing its robust features for data types, UUID generation, and indexing.


-- SQL DDL Script for E-commerce Database Schema (PostgreSQL)
-- Version: 1.0
-- Date: 2023-10-27

-- Ensure UUID extension is available for primary keys
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- -------------------------------------------------------------------
-- Table: users
-- Description: Stores information about registered users.
-- -------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS users (
    user_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Unique identifier for the user
    username VARCHAR(50) UNIQUE NOT NULL,               -- User's chosen username, must be unique
    email VARCHAR(100) UNIQUE NOT NULL,                 -- User's email address, must be unique
    password_hash VARCHAR(255) NOT NULL,                -- Hashed password for security
    first_name VARCHAR(50) NOT NULL,                    -- User's first name
    last_name VARCHAR(50) NOT NULL,                     -- User's last name
    address TEXT,                                       -- User's primary shipping/billing address
    phone_number VARCHAR(20),                           -- User's contact phone number
    is_admin BOOLEAN DEFAULT FALSE,                     -- Flag to identify administrative users
    created_at TIMESTAMPTZ DEFAULT NOW(),               -- Timestamp of user creation
    updated_at TIMESTAMPTZ DEFAULT NOW()                -- Timestamp of last update
);

-- Index for faster lookups by email and username
CREATE INDEX idx_users_email ON users (email);
CREATE INDEX idx_users_username ON users (username);


-- -------------------------------------------------------------------
-- Table: categories
-- Description: Organizes products into logical groups.
-- -------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS categories (
    category_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Unique identifier for the category
    name VARCHAR(100) UNIQUE NOT NULL,                   -- Name of the category, must be unique
    description TEXT,                                    -- Optional description for the category
    created_at TIMESTAMPTZ DEFAULT NOW(),                -- Timestamp of category creation
    updated_at TIMESTAMPTZ DEFAULT NOW()                 -- Timestamp of last update
);

-- Index for faster lookups by category name
CREATE INDEX idx_categories_name ON categories (name);


-- -------------------------------------------------------------------
-- Table: products
-- Description: Stores details about items available for sale.
-- -------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS products (
    product_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Unique identifier for the product
    name VARCHAR(255) NOT NULL,                         -- Name of the product
    description TEXT,                                   -- Detailed description of the product
    price NUMERIC(10, 2) NOT NULL CHECK (price >= 0),   -- Current selling price, must be non-negative
    stock_quantity INTEGER NOT NULL CHECK (stock_quantity >= 0), -- Current quantity in stock, non-negative
    category_id UUID NOT NULL,                          -- Foreign key to categories table
    image_url VARCHAR(255),                             -- URL to the product's primary image
    is_available BOOLEAN DEFAULT TRUE,                  -- Flag if product is currently available
    created_at TIMESTAMPTZ DEFAULT NOW(),               -- Timestamp of product creation
    updated_at TIMESTAMPTZ DEFAULT NOW(),               -- Timestamp of last update

    -- Foreign key constraint to categories table
    CONSTRAINT fk_category
        FOREIGN KEY (category_id)
        REFERENCES categories (category_id)
        ON DELETE RESTRICT -- Prevent deleting a category if products are linked
        ON UPDATE CASCADE  -- Update category_id in products if category_id changes
);

-- Indexes for faster lookups and joins
CREATE INDEX idx_products_name ON products (name);
CREATE INDEX idx_products_category_id ON products (category_id);
CREATE INDEX idx_products_price ON products (price);
CREATE INDEX idx_products_availability ON products (is_available);


-- -------------------------------------------------------------------
-- Table: orders
-- Description: Records customer purchases.
-- -------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS orders (
    order_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Unique identifier for the order
    user_id UUID NOT NULL,                              -- Foreign key to users table
    order_date TIMESTAMPTZ DEFAULT NOW(),               -- Date and time the order was placed
    total_amount NUMERIC(10, 2) NOT NULL CHECK (total_amount >= 0), -- Total cost of the order
    status VARCHAR(50) NOT NULL DEFAULT 'pending',      -- Current status of the order
    shipping_address TEXT NOT NULL,                     -- Shipping address for this order
    billing_address TEXT NOT NULL,                      -- Billing address for this order
    created_at TIMESTAMPTZ DEFAULT NOW(),               -- Timestamp of order creation
    updated_at TIMESTAMPTZ DEFAULT NOW(),               -- Timestamp of last update

    -- Foreign key constraint to users table
    CONSTRAINT fk_user
        FOREIGN KEY (user_id)
        REFERENCES users (user_id)
        ON DELETE RESTRICT -- Prevent deleting a user if they have orders
        ON UPDATE CASCADE  -- Update user_id in orders if user_id changes
);

-- Indexes for faster lookups and joins
CREATE INDEX idx_orders_user_id ON orders (user_id);
CREATE INDEX idx_orders_order_date ON orders (order_date);
CREATE INDEX idx_orders_status ON orders (status);


-- -------------------------------------------------------------------
-- Table: order_items
-- Description: Links products to specific orders, storing details at the time of purchase.
-- -------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS order_items (
    order_item_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- Unique identifier for the order item
    order_id UUID NOT NULL,                                 -- Foreign key to orders table
    product_id UUID NOT NULL,                               -- Foreign key to products table
    quantity INTEGER NOT NULL CHECK (quantity > 0),         -- Quantity of the product purchased, must be positive
    price_at_purchase NUMERIC(10, 2) NOT NULL CHECK (price_at_purchase >= 0), -- Price at time of purchase

    created_at TIMESTAMPTZ DEFAULT NOW(),                   -- Timestamp of order item creation
    updated_at TIMESTAMPTZ DEFAULT NOW(),                   -- Timestamp of last update

    -- Composite unique constraint to prevent duplicate product entries within a single order
    CONSTRAINT uq_order_product UNIQUE (order_id, product_id),

    -- Foreign key constraint to orders table
    CONSTRAINT fk_order
        FOREIGN KEY (order_id)
        REFERENCES orders (order_id)
        ON DELETE CASCADE -- If an order is deleted, its items should also be deleted
        ON UPDATE CASCADE, -- Update order_id in order_items if order_id changes

    -- Foreign key constraint to products table
    CONSTRAINT fk_product
        FOREIGN KEY (product_id)
        REFERENCES products (product_id)
        ON DELETE RESTRICT -- Prevent deleting a product if it's part of an order item
        ON UPDATE CASCADE  -- Update product_id in order_items if product_id changes
);

-- Indexes for faster lookups and joins
CREATE INDEX idx_order_
gemini Output

Database Schema Design: Comprehensive Review and Documentation

This document provides a comprehensive review and detailed documentation of the proposed database schema, designed to support the core functionalities of an e-commerce platform. This deliverable outlines the schema's structure, justifies design choices, addresses performance and security considerations, and provides actionable next steps for implementation.


1. Project Overview

Project Name: E-commerce Platform Database

Purpose: To store and manage all critical data required for an online retail application, including user accounts, product catalogs, order processing, inventory management, and customer reviews.

Key Features Supported:

  • User Registration and Authentication
  • Product Browsing and Search
  • Shopping Cart Functionality
  • Order Placement and Tracking
  • Inventory Management
  • Customer Reviews and Ratings
  • Address Management (Shipping & Billing)

2. Database Schema Summary

The proposed schema is designed following a relational model, optimized for data integrity, query performance, and scalability. It comprises several interconnected tables, each representing a core entity within the e-commerce domain.

High-Level Architecture:

The schema is logically divided into modules:

  • User Management: Handles customer accounts and their associated addresses.
  • Product Management: Manages product information, categories, and inventory.
  • Order Management: Facilitates order creation, tracking, and itemization.
  • Interaction & Feedback: Captures shopping cart contents and customer reviews.

Conceptual Entity-Relationship Diagram (ERD) Overview:

  • Users are the central entity, associated with multiple Addresses, Orders, Shopping Carts, and Reviews.
  • Products belong to Categories and are featured in Order Items and Cart Items, and are the subject of Reviews.
  • Orders contain multiple Order Items, which link back to specific Products.
  • Shopping Carts contain multiple Cart Items, also linking to Products.
  • Categories can have a hierarchical structure (parent-child relationships).

3. Detailed Schema Specification

This section provides a detailed breakdown of each table, including its purpose, columns, data types, constraints, and relationships.

Table: users

  • Purpose: Stores information about registered customers.
  • Columns:

* user_id (UUID / INT, PK): Unique identifier for the user.

* username (VARCHAR(50), UNIQUE, NOT NULL): User's unique login name.

* email (VARCHAR(100), UNIQUE, NOT NULL): User's email address, used for communication and login.

* password_hash (VARCHAR(255), NOT NULL): Hashed and salted password for security.

* first_name (VARCHAR(50)): User's first name.

* last_name (VARCHAR(50)): User's last name.

* default_shipping_address_id (UUID / INT, FK to addresses.address_id): Default shipping address.

* default_billing_address_id (UUID / INT, FK to addresses.address_id): Default billing address.

* created_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP): Timestamp of user creation.

* updated_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP): Last update timestamp.

  • Relationships:

* One-to-many with addresses (via user_id)

* One-to-many with orders (via user_id)

* One-to-one with shopping_cart (via user_id)

* One-to-many with reviews (via user_id)

Table: addresses

  • Purpose: Stores various addresses associated with users (shipping, billing).
  • Columns:

* address_id (UUID / INT, PK): Unique identifier for the address.

* user_id (UUID / INT, FK to users.user_id, NOT NULL): User to whom the address belongs.

* street_address (VARCHAR(255), NOT NULL): Street and house number.

* city (VARCHAR(100), NOT NULL): City.

* state_province (VARCHAR(100)): State or Province.

* postal_code (VARCHAR(20), NOT NULL): Postal or ZIP code.

* country (VARCHAR(100), NOT NULL): Country.

* address_type (ENUM('shipping', 'billing', 'other'), NOT NULL): Type of address.

* is_default (BOOLEAN, NOT NULL, DEFAULT FALSE): Indicates if this is the user's default address for its type.

  • Relationships:

* Many-to-one with users (via user_id)

* Referenced by orders (for shipping and billing addresses).

Table: categories

  • Purpose: Organizes products into hierarchical categories.
  • Columns:

* category_id (UUID / INT, PK): Unique identifier for the category.

* name (VARCHAR(100), UNIQUE, NOT NULL): Name of the category (e.g., "Electronics", "Apparel").

* description (TEXT): Detailed description of the category.

* parent_category_id (UUID / INT, FK to categories.category_id): Self-referencing foreign key for hierarchical categories.

  • Relationships:

* One-to-many with products (via category_id)

* Self-referencing for parent-child category relationships.

Table: products

  • Purpose: Stores information about products available for sale.
  • Columns:

* product_id (UUID / INT, PK): Unique identifier for the product.

* name (VARCHAR(255), NOT NULL): Product name.

* description (TEXT): Detailed product description.

* price (DECIMAL(10, 2), NOT NULL, CHECK (price >= 0)): Current selling price.

* stock_quantity (INT, NOT NULL, CHECK (stock_quantity >= 0)): Current quantity in stock.

* category_id (UUID / INT, FK to categories.category_id, NOT NULL): Category the product belongs to.

* image_url (VARCHAR(255)): URL to the primary product image.

* created_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP): Timestamp of product creation.

* updated_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP): Last update timestamp.

  • Relationships:

* Many-to-one with categories (via category_id)

* One-to-many with order_items (via product_id)

* One-to-many with cart_items (via product_id)

* One-to-many with reviews (via product_id)

Table: orders

  • Purpose: Records customer orders.
  • Columns:

* order_id (UUID / INT, PK): Unique identifier for the order.

* user_id (UUID / INT, FK to users.user_id, NOT NULL): User who placed the order.

* order_date (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP): Date and time the order was placed.

* total_amount (DECIMAL(10, 2), NOT NULL, CHECK (total_amount >= 0)): Total amount of the order.

* status (ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled'), NOT NULL): Current status of the order.

* shipping_address_id (UUID / INT, FK to addresses.address_id, NOT NULL): Address for shipping.

* billing_address_id (UUID / INT, FK to addresses.address_id, NOT NULL): Address for billing.

* payment_method (VARCHAR(50)): Method used for payment (e.g., "Credit Card", "PayPal").

* tracking_number (VARCHAR(100)): Shipping tracking number.

  • Relationships:

* Many-to-one with users (via user_id)

* Many-to-one with addresses (via shipping_address_id and billing_address_id)

* One-to-many with order_items (via order_id)

Table: order_items

  • Purpose: Details the individual products within an order.
  • Columns:

* order_item_id (UUID / INT, PK): Unique identifier for the order item.

* order_id (UUID / INT, FK to orders.order_id, NOT NULL): Order to which this item belongs.

* product_id (UUID / INT, FK to products.product_id, NOT NULL): Product included in the order.

* quantity (INT, NOT NULL, CHECK (quantity > 0)): Quantity of the product ordered.

* unit_price (DECIMAL(10, 2), NOT NULL, CHECK (unit_price >= 0)): Price of the product at the time of order.

  • Relationships:

* Many-to-one with orders (via order_id)

* Many-to-one with products (via product_id)

  • Composite Unique Constraint: (order_id, product_id) to prevent duplicate products in a single order.

Table: shopping_cart

  • Purpose: Stores the current shopping cart for each user.
  • Columns:

* cart_id (UUID / INT, PK): Unique identifier for the shopping cart.

* user_id (UUID / INT, FK to users.user_id, UNIQUE, NOT NULL): User to whom the cart belongs.

* created_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP): Timestamp of cart creation.

* updated_at (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP): Last update timestamp.

  • Relationships:

* One-to-one with users (via user_id)

* One-to-many with cart_items (via cart_id)

Table: cart_items

  • Purpose: Details the individual products within a shopping cart.
  • Columns:

* cart_item_id (UUID / INT, PK): Unique identifier for the cart item.

* cart_id (UUID / INT, FK to shopping_cart.cart_id, NOT NULL): Shopping cart to which this item belongs.

* product_id (UUID / INT, FK to products.product_id, NOT NULL): Product in the cart.

* quantity (INT, NOT NULL, CHECK (quantity > 0)): Quantity of the product in the cart.

  • Relationships:

* Many-to-one with shopping_cart (via cart_id)

* Many-to-one with products (via product_id)

  • Composite Unique Constraint: (cart_id, product_id) to prevent duplicate products in a single cart.

Table: reviews

  • Purpose: Stores product reviews and ratings submitted by users.
  • Columns:

* review_id (UUID / INT, PK): Unique identifier for the review.

* product_id (UUID / INT, FK to products.product_id, NOT NULL): Product being reviewed.

* user_id (UUID / INT, FK to users.user_id, NOT NULL): User who submitted the review.

* rating (INT, NOT NULL, CHECK (rating >= 1 AND rating <= 5)): Rating from 1 to 5 stars.

* comment (TEXT): Textual review comment.

* review_date (TIMESTAMP WITH TIME ZONE, NOT NULL, DEFAULT CURRENT_TIMESTAMP): Date and time the review was submitted.

  • Relationships:

* Many-to-one with products (via product_id)

* Many-to-one with users (via user_id)

  • Composite Unique Constraint: (product_id, user_id) to allow only one review per user per product.

4. Design Justifications & Best Practices

Normalization Level

The schema is designed to adhere to at least the Third Normal Form (3NF). This minimizes data redundancy, improves data integrity, and simplifies data maintenance. For example:

  • User information is separated from address information, and addresses can be shared by users or used for different purposes (shipping/billing).
  • Product
database_schema_designer.md
Download as Markdown
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}