BareGit

Allow service descriptions to be omitted

Author: MetroWind <chris.corsair@gmail.com>
Date: Sun Sep 20 16:17:45 2026 -0700
Commit: ce1835b1cf57870b0a88c44d83aa9fdc3d20780b

Changes

diff --git a/config.example.yaml b/config.example.yaml
index c2a4fa7..a3f2ca4 100644
--- a/config.example.yaml
+++ b/config.example.yaml
@@ -12,6 +12,7 @@ groups:
     services:
       blog:
         name: Blog
+        # Optional description shown below the service name.
         description: Personal website
         url: https://blog.example/
         interval:
diff --git a/prd.md b/prd.md
index 92c542c..f07ab2a 100644
--- a/prd.md
+++ b/prd.md
@@ -23,6 +23,7 @@ A simple self-hosted service status tracker.
   ```yaml
   some-endpoint-id: # A uniq ID
     name: Blog
+    # Optional description shown in the web UI.
     description: It’s my blog.
     # User-facing URL
     url: https://blog.mws.rocks/
@@ -42,6 +43,7 @@ A simple self-hosted service status tracker.
   ```yaml
   some-endpoint-id: # A uniq ID
     name: VM host
+    # Optional description shown in the web UI.
     description: My VM host
     endpoint:
       protocol: ICMP
diff --git a/src/app.cpp b/src/app.cpp
index eafd36f..19bdf3d 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -231,6 +231,7 @@ mw::E<nlohmann::json> makePageData(const Configuration& configuration,
                 {"id", config.id},
                 {"name", config.name},
                 {"description", config.description},
+                {"has_description", !config.description.empty()},
                 {"status_class", presentation.class_name},
                 {"status_label", presentation.label},
                 {"has_url", config.url.has_value() && !config.url->empty()},
diff --git a/src/configuration.cpp b/src/configuration.cpp
index 0744914..db94928 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -246,8 +246,9 @@ mw::E<ServiceConfig> parseService(Node service, std::string id,
     ServiceConfig result;
     result.id = std::move(id);
     ASSIGN_OR_RETURN(result.name, requiredString(service, "name", context));
-    ASSIGN_OR_RETURN(result.description,
-                     requiredString(service, "description", context));
+    ASSIGN_OR_RETURN(auto description,
+                     optionalString(service, "description", context));
+    result.description = description.value_or("");
     ASSIGN_OR_RETURN(result.url, optionalString(service, "url", context));
     auto endpoint = child(service, "endpoint");
     if(!endpoint.readable() || !endpoint.is_map())
diff --git a/src/service_config.h b/src/service_config.h
index c0c4870..275af11 100644
--- a/src/service_config.h
+++ b/src/service_config.h
@@ -19,6 +19,7 @@ struct ServiceConfig
     /// Display name shown in the web UI.
     std::string name;
     /// Description shown in the web UI.
+    /// Empty when omitted from configuration.
     std::string description;
     /// Protocol and destination used to check this service.
     EndpointConfig endpoint;
diff --git a/static/index.html b/static/index.html
index 2d57b6b..19c05ff 100644
--- a/static/index.html
+++ b/static/index.html
@@ -33,7 +33,9 @@
                 {% endif %}
               </span>
             </div>
+            {% if service.has_description %}
             <p>{{ service.description }}</p>
+            {% endif %}
             <div class="service-history" role="group"
                  aria-label="Last {{ service.history_hours }} hours of status"
                  title="Oldest hour on the left; current hour on the right">
diff --git a/tests/configuration_test.cpp b/tests/configuration_test.cpp
index 1c51ddd..a52344e 100644
--- a/tests/configuration_test.cpp
+++ b/tests/configuration_test.cpp
@@ -75,7 +75,6 @@ TEST(Configuration, LoadsGroupedProtocolSettings)
         "          payload: ping\n"
         "      gateway:\n"
         "        name: Gateway\n"
-        "        description: Network gateway\n"
         "        interval:\n"
         "          value: 1\n"
         "          unit: day\n"
@@ -110,6 +109,7 @@ TEST(Configuration, LoadsGroupedProtocolSettings)
     EXPECT_EQ(std::get<UdpEndpoint>(services[2].endpoint).payload, "ping");
     EXPECT_EQ(services[3].interval, std::chrono::hours(24));
     ASSERT_TRUE(std::holds_alternative<IcmpEndpoint>(services[3].endpoint));
+    EXPECT_TRUE(services[3].description.empty());
 }
 
 TEST(Configuration, RejectsInvalidValues)