This commit is contained in:
andre committed 2026-06-12 21:20:23 +01:00
1 parent e68d357177
commit 3e3382df57
65 files changed
+1836 -42

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
-- ─── Events / time-limited landing pages ────────────────────────────────────
-- Backoffice-managed temporary events (promotions, special classes, challenges).
-- Each row drives a banner on the homepage and a branded landing page at
-- /evento/<slug>, visible only while NOW() is inside [publish_from, publish_until]
-- and is_active = 1. Soft-deleted via deleted_at (mirrors the modalidades module).
CREATE TABLE IF NOT EXISTS `events` (
`e_id` INT(11) NOT NULL AUTO_INCREMENT,
`deleted_at` DATETIME DEFAULT NULL,
`slug` VARCHAR(160) NOT NULL,
`title` VARCHAR(180) NOT NULL,
`subtitle` VARCHAR(255) NOT NULL DEFAULT '',
`summary` VARCHAR(400) NOT NULL DEFAULT '',
`description` TEXT DEFAULT NULL,
`hero_image` VARCHAR(160) NOT NULL DEFAULT '',
`cor` VARCHAR(50) NOT NULL DEFAULT '#C2D500',
`location` VARCHAR(200) NOT NULL DEFAULT '',
`event_starts_at` DATETIME DEFAULT NULL,
`event_ends_at` DATETIME DEFAULT NULL,
`publish_from` DATETIME NOT NULL,
`publish_until` DATETIME NOT NULL,
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
`cta_label` VARCHAR(80) NOT NULL DEFAULT '',
`cta_url` VARCHAR(255) NOT NULL DEFAULT '',
`show_lead_form` TINYINT(1) NOT NULL DEFAULT 1,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`e_id`),
UNIQUE KEY `uq_events_slug` (`slug`),
KEY `idx_events_window` (`is_active`, `publish_from`, `publish_until`, `deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Lead/registration submissions captured on each event landing page.
CREATE TABLE IF NOT EXISTS `event_leads` (
`lead_id` INT(11) NOT NULL AUTO_INCREMENT,
`e_id` INT(11) NOT NULL,
`name` VARCHAR(150) NOT NULL,
`email` VARCHAR(190) NOT NULL DEFAULT '',
`phone` VARCHAR(40) NOT NULL DEFAULT '',
`message` VARCHAR(1000) NOT NULL DEFAULT '',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`lead_id`),
KEY `idx_event_leads_event` (`e_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -0,0 +1,22 @@
-- ─── event_leads: consent + provenance + FK (D1) ────────────────────────────
-- event_leads captures PII from a public form. Under the GDPR we must record
-- demonstrable consent and minimise/retain responsibly. Add the consent flag,
-- the exact text the visitor agreed to, and request provenance (IP + UA) so a
-- submission can be evidenced. Also wire the missing FK to events so leads are
-- removed with their event (no orphans).
--
-- NB: filename sorts AFTER migration_20260612_events.sql (which creates the
-- table), so the runner applies them in the right order.
ALTER TABLE `event_leads`
ADD COLUMN IF NOT EXISTS `consent` TINYINT(1) NOT NULL DEFAULT 0 AFTER `message`,
ADD COLUMN IF NOT EXISTS `consent_text` VARCHAR(255) NOT NULL DEFAULT '' AFTER `consent`,
ADD COLUMN IF NOT EXISTS `ip` VARCHAR(45) NOT NULL DEFAULT '' AFTER `consent_text`,
ADD COLUMN IF NOT EXISTS `user_agent` VARCHAR(255) NOT NULL DEFAULT '' AFTER `ip`;
-- Referential integrity: delete leads when their event is hard-deleted.
-- (Has no IF NOT EXISTS in MariaDB; if re-running after a partial apply, drop
-- the constraint first.)
ALTER TABLE `event_leads`
ADD CONSTRAINT `fk_event_leads_event`
FOREIGN KEY (`e_id`) REFERENCES `events` (`e_id`) ON DELETE CASCADE;
@@ -0,0 +1,6 @@
-- ─── Index gallery images by their parent gallery (O1) ──────────────────────
-- gallery.i_project_id is filtered on every gallery view (db_gallery_images) and
-- on delete, but had no index → full table scan. Add one.
ALTER TABLE `gallery`
ADD INDEX IF NOT EXISTS `idx_gallery_project` (`i_project_id`);
@@ -0,0 +1,9 @@
-- ─── horario.hora_inicio: varchar(15) → TIME (O3) ──────────────────────────
-- The column already holds time-of-day strings ("HH:MM") and the app reads it
-- with TIME_FORMAT(hora_inicio, '%H:%i'), so it's semantically a time. Storing
-- it as TIME makes ordering/comparison correct and matches hora_fim (already
-- TIME). Existing "HH:MM" values cast cleanly. If any non-time legacy value
-- exists this ALTER will fail under strict mode — fix that row, then re-run.
ALTER TABLE `horario`
MODIFY `hora_inicio` TIME NOT NULL;
@@ -0,0 +1,8 @@
-- ─── Widen the Maps columns to avoid truncation (D8) ────────────────────────
-- A Google Maps embed (<iframe …>) and a Maps share link are frequently longer
-- than the original varchar(500)/varchar(100), which silently truncated them
-- (breaking the embed). Promote to TEXT / varchar(255).
ALTER TABLE `fitme3070_info`
MODIFY `google_maps` TEXT NOT NULL DEFAULT '',
MODIFY `google_maps_link` VARCHAR(255) NOT NULL DEFAULT '';
@@ -0,0 +1,8 @@
-- ─── Widen modalidades.descricao for rich-text (Summernote) ──────────────────
-- The backoffice now edits this field with the WYSIWYG editor, which produces
-- HTML markup and bypasses the textarea maxlength. varchar(1500) could silently
-- truncate that HTML mid-tag (and the public site renders it raw), so promote it
-- to TEXT. Existing values are preserved by the widening conversion.
ALTER TABLE `modalidades`
MODIFY `descricao` TEXT NOT NULL;
@@ -0,0 +1,7 @@
-- ─── Widen team.description for rich-text (Summernote) ───────────────────────
-- The backoffice now edits this field with the WYSIWYG editor, which emits HTML
-- and bypasses the textarea maxlength. varchar(300) would silently truncate that
-- markup mid-tag, so promote it to TEXT. Stays nullable; existing values kept.
ALTER TABLE `team`
MODIFY `description` TEXT DEFAULT NULL;
@@ -0,0 +1,8 @@
-- ─── Marketing-consent provenance on users (D2) ─────────────────────────────
-- `marketing_consent` is a bare boolean — the GDPR requires demonstrable consent
-- (when and how it was given). Add a timestamp and a source so consent can be
-- proven and audited. Nullable: existing rows have unknown provenance.
ALTER TABLE `users`
ADD COLUMN IF NOT EXISTS `marketing_consent_at` DATETIME DEFAULT NULL AFTER `marketing_consent`,
ADD COLUMN IF NOT EXISTS `marketing_consent_source` VARCHAR(60) DEFAULT NULL AFTER `marketing_consent_at`;
@@ -0,0 +1,15 @@
-- ─── website_offer soft-delete: drop the zero-date (D4) ─────────────────────
-- o_deleted_at was datetime NOT NULL, so "not deleted" rows carried the invalid
-- zero-date '0000-00-00 00:00:00' (rejected under NO_ZERO_DATE/strict mode) and
-- the app had to filter for it explicitly. Make it nullable and normalise the
-- existing zero-dates to NULL, aligning with every other table's deleted_at.
ALTER TABLE `website_offer`
MODIFY `o_deleted_at` DATETIME NULL DEFAULT NULL;
-- Normalise legacy "not deleted" markers to NULL. Comparing against a literal
-- zero-date is itself unsafe under strict mode, so match by year 0 instead.
UPDATE `website_offer`
SET `o_deleted_at` = NULL
WHERE `o_deleted_at` IS NOT NULL
AND YEAR(`o_deleted_at`) = 0;