From 325188eb9bd157fc62df36e73e75a5a1d5df81da Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza <8016841+diegosouzapw@users.noreply.github.com> Date: Thu, 25 Jun 2026 07:25:59 -0300 Subject: [PATCH] feat(combos): add editable per-combo description field persisted via /api/combos (#5005) (#5011) * feat(combos): add editable per-combo description field persisted via /api/combos (#5005) * docs(changelog): restore #3981/#5003/#4665 entries eaten by merge --------- Co-authored-by: Diego Rodrigues de Sa e Souza --- CHANGELOG.md | 1 + config/quality/file-size-baseline.json | 2 +- src/app/(dashboard)/dashboard/combos/page.tsx | 29 ++++++ src/i18n/messages/en.json | 2 + src/shared/validation/schemas/combo.ts | 3 + tests/unit/combo-description-5005.test.ts | 91 +++++++++++++++++++ 6 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 tests/unit/combo-description-5005.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f4750ed3f..581102f839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ _In development — bullets added per PR; finalized at release._ - **feat(providers):** update volcengine-ark model list, adding DeepSeek-V4-Flash and DeepSeek-V4-Pro. (thanks @kenlin8827) +- **feat(combos):** add an editable per-combo `description` field. The routing-combo form now has a Description input, persisted in the combo `data` blob via `/api/combos` (POST/PUT) and round-tripped through GET — no new DB column ([#5005](https://github.com/diegosouzapw/OmniRoute/issues/5005)). ### 🔧 Bug Fixes diff --git a/config/quality/file-size-baseline.json b/config/quality/file-size-baseline.json index 46d0145309..7daf81bcf0 100644 --- a/config/quality/file-size-baseline.json +++ b/config/quality/file-size-baseline.json @@ -165,7 +165,7 @@ "src/app/(dashboard)/dashboard/cache/page.tsx": 845, "src/app/(dashboard)/dashboard/cli-code/components/CodexToolCard.tsx": 900, "src/app/(dashboard)/dashboard/cloud-agents/page.tsx": 922, - "src/app/(dashboard)/dashboard/combos/page.tsx": 4456, + "src/app/(dashboard)/dashboard/combos/page.tsx": 4485, "src/app/(dashboard)/dashboard/costs/CostOverviewTab.tsx": 1495, "src/app/(dashboard)/dashboard/costs/quota-share/components/PoolWizard.tsx": 1007, "src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx": 2570, diff --git a/src/app/(dashboard)/dashboard/combos/page.tsx b/src/app/(dashboard)/dashboard/combos/page.tsx index b64dcbd959..985ad22758 100644 --- a/src/app/(dashboard)/dashboard/combos/page.tsx +++ b/src/app/(dashboard)/dashboard/combos/page.tsx @@ -1947,6 +1947,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders, combo const isExpertMode = normalizeComboConfigMode(comboConfigMode) === "expert"; const createDraftStateRef = useRef(getEmptyCreateDraftSnapshot()); const [name, setName] = useState(combo?.name || ""); + const [description, setDescription] = useState(combo?.description || ""); const [models, setModels] = useState(() => { return (combo?.models || []).map((m) => normalizeModelEntry(m)); }); @@ -2007,6 +2008,7 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders, combo ); setName(nextCombo?.name || ""); + setDescription(nextCombo?.description || ""); setModels((nextCombo?.models || []).map((m) => normalizeModelEntry(m))); setStrategy(nextCombo?.strategy || comboDefaults?.strategy || "priority"); setConfig(nextConfig); @@ -2738,6 +2740,14 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders, combo strategy, }; + // Per-combo description (#5005). Free-text, optional, persisted in combo data. + if (description.trim()) { + saveData.description = description.trim(); + } else if (isEdit) { + // Editing: send null to explicitly clear a previously-set description. + saveData.description = null; + } + // Include config only if any values are set const configToSave = sanitizeComboRuntimeConfig(config); // Add round-robin specific fields to config @@ -2924,6 +2934,25 @@ function ComboFormModal({ isOpen, combo, onClose, onSave, activeProviders, combo )} + {/* Description (#5005) — optional free-text note for this combo */} +
+ +