if not ids: errors.append("Select at least one subject line") if len(ids) > cfg.MAX_SUBJECTS: errors.append(f"Max {cfg.MAX_SUBJECTS} subject variations") strategy = data.get("subject_rotation") if strategy not in VALID_ENUMS["subject_rotation"]: errors.append("Invalid subject rotation strategy") if step == 4: ids = data.get("template_ids") or [] if not ids: errors.append("Select at least one template") mode = data.get("template_sequence_mode") if mode not in VALID_ENUMS["template_sequence_mode"]: errors.append("Invalid template sequence mode") if step == 5: mode = data.get("attach_mode", "none") if mode not in VALID_ENUMS["attach_mode"]: errors.append("Invalid attachment mode") elif mode != "none" and not (data.get("attach_pdf_template_id") or data.get("attachment_id")): errors.append("Select a template/attachment for PDF or file mode") if step == 6: vc = data.get("variable_config") or {} try: if "amount_min" in vc and "amount_max" in vc: if float(vc["amount_min"]) > float(vc["amount_max"]): errors.append("Amount min must be <= max") if "shipping_min" in vc and "shipping_max" in vc: if float(vc["shipping_min"]) > float(vc["shipping_max"]): errors.append("Shipping min must be <= max") except (TypeError, ValueError): errors.append("Ranges must be numeric") if step == 7: if not data.get("account_ids"): errors.append("Select at least one Gmail account") elif len(data["account_ids"]) > cfg.MAX_GMAIL_ACCOUNTS_PER_CAMPAIGN: errors.append(f"Max {cfg.MAX_GMAIL_ACCOUNTS_PER_CAMPAIGN} accounts")