-- Contact form submissions. -- -- `subject` is stored as free text (a slug from a known list), not an ENUM. -- ENUMs need a migration every time an option is added; the list of enquiry -- types will change more often than the schema should. The controller -- validates against the allowed set, so bad values never reach here. -- -- Anti-spam and audit columns live alongside the message: a honeypot outcome, -- the origin IP, and the user agent. These make it possible to review what got -- flagged without a separate log. CREATE TABLE IF NOT EXISTS `cja_contact` ( `contact_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(160) NOT NULL, `email` varchar(255) NOT NULL, `subject` varchar(60) NOT NULL DEFAULT 'other', `message` text NOT NULL, -- lifecycle so the inbox is workable, not just a dump `status` enum('new','read','replied','spam','archived') NOT NULL DEFAULT 'new', -- audit / anti-spam `ip` varchar(45) DEFAULT NULL, -- v4 or v6 `user_agent` varchar(255) DEFAULT NULL, `referrer` varchar(255) DEFAULT NULL, `created_at` datetime NOT NULL DEFAULT current_timestamp(), `updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`contact_id`), KEY `idx_cja_contact_status` (`status`, `created_at`), KEY `idx_cja_contact_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;