Skip to content

Add maintenance-mode message to Lexbox UI#2240

Open
rmunn wants to merge 2 commits intodevelopfrom
feat/maintenance-warning-in-ui
Open

Add maintenance-mode message to Lexbox UI#2240
rmunn wants to merge 2 commits intodevelopfrom
feat/maintenance-warning-in-ui

Conversation

@rmunn
Copy link
Copy Markdown
Contributor

@rmunn rmunn commented Apr 10, 2026

Will be enabled by setting an ASP.NET config option, e.g. with an environment variable.

Config has two properties, the message which will be displayed in the UI (and set in a header returned with any API calls, so keep it short) and a ReadOnlyMode boolean which will determine whether non-read-only HTTP requests (POST, PUT, PATCH, and DELETE) will be rejected by the server.

Setting a message without setting ReadOnlyMode is useful for giving advance notice of planned maintenance windows.

This does not yet address #1956 because some FwLite client changes will be needed to address what happens when Lexbox is in maintenance mode, but it does fix #2238 with a message displayed in the Lexbox UI (a banner across the top, in the same place as the "This is a development environment" banner).

Will be enabled by setting an ASP.NET config option, e.g. with an
environment variable.

Config has two properties, the message which will be displayed in the UI
(and set in a header returned with any API calls, so keep it short) and
a ReadOnlyMode boolean which will determine whether non-read-only HTTP
requests (POST, PUT, PATCH, and DELETE) will be rejected by the server.

Setting a message *without* setting ReadOnlyMode is useful for giving
advance notice of planned maintenance windows.
@rmunn rmunn self-assigned this Apr 10, 2026
@github-actions github-actions bot added the 📦 Lexbox issues related to any server side code, fw-headless included label Apr 10, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d5ccd838-29f8-4776-9c08-19a0c3711c04

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

A maintenance mode feature is implemented across both backend services (FwHeadless and LexBox) and the frontend. The change introduces a MaintenanceModeConfig configuration model, middleware that intercepts requests to enforce read-only status and inject maintenance messages, dependency injection registration, and frontend hooks and UI components to display the maintenance banner.

Changes

Cohort / File(s) Summary
Maintenance Mode Configuration Classes
backend/FwHeadless/MaintenanceModeConfig.cs, backend/LexBoxApi/Config/MaintenanceModeConfig.cs
New configuration classes defining ReadOnlyMode (boolean, init-only) and MaintenanceMessage (nullable string, regular setter) properties.
Maintenance Mode Middleware
backend/FwHeadless/MaintenanceModeMiddleware.cs, backend/LexBoxApi/Middleware/MaintenanceModeMiddleware.cs
New middleware that reads configuration per-request, sets maintenance-message response header when a message is configured, and returns HTTP 503 for write operations (POST/PUT/PATCH/DELETE) when read-only mode is enabled.
Backend Dependency Injection Setup
backend/FwHeadless/FwHeadlessKernel.cs, backend/LexBoxApi/LexBoxKernel.cs
Registration of MaintenanceModeConfig options binding to the configuration section with data annotation and startup validation enabled.
Backend Middleware Wiring
backend/FwHeadless/Program.cs, backend/LexBoxApi/Program.cs
Integration of MaintenanceModeMiddleware into the HTTP request pipeline; FwHeadless inserts after version header middleware, LexBox inserts after health checks.
Backend Configuration Defaults
backend/.../appsettings.json, backend/.../appsettings.Development.json
New MaintenanceMode section added to both FwHeadless and LexBox configurations with ReadOnlyMode defaulting to false and MaintenanceMessage to null.
Frontend Maintenance Status Tracking
frontend/src/hooks.client.ts, frontend/src/hooks.server.ts
Client and server hooks now extract the maintenance-message response header and populate maintenanceMessage.value for UI consumption.
Frontend Maintenance Banner
frontend/src/lib/layout/AppBar.svelte
AppBar component imports maintenanceMessage and conditionally renders a centered warning banner when a maintenance message is present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

💻 FW Lite, 📦 Lexbox

Suggested reviewers

  • myieye
  • hahn-kev

Poem

🐰 A maintenance mode hops into view,
Read-only barriers blocking what we do,
Headers set, requests caught in flight,
Banners bloom to warn with might,
Lexbox pauses, yet carries on right! 🏗️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a maintenance-mode message feature to the Lexbox UI, which is the primary objective of this PR.
Description check ✅ Passed The description clearly explains the feature's configuration properties, use cases, and scope, relating directly to the changes made in this PR.
Linked Issues check ✅ Passed The PR successfully addresses issue #2238 by implementing all coding requirements: a configurable maintenance message, ReadOnlyMode flag, UI banner in AppBar, response header integration, and server-side request rejection logic.
Out of Scope Changes check ✅ Passed All changes directly support the maintenance-mode feature implementation. No extraneous modifications or unrelated functionality were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/maintenance-warning-in-ui

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

UI unit Tests

10 tests  ±0   10 ✅ ±0   0s ⏱️ ±0s
 3 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit c89b353. ± Comparison against base commit 73e4ecd.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

C# Unit Tests

165 tests  ±0   165 ✅ ±0   18s ⏱️ ±0s
 23 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit c89b353. ± Comparison against base commit 73e4ecd.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
backend/LexBoxApi/Config/MaintenanceModeConfig.cs (1)

3-7: Use an immutable record for consistency with DTO guidance.

This options object is DTO-style and currently mutable at Line 6; making it an immutable record improves safety and consistency.

Refactor example
-public class MaintenanceModeConfig
+public sealed record MaintenanceModeConfig
 {
     public bool ReadOnlyMode { get; init; } = false;
-    public string? MaintenanceMessage { get; set; } = null;
+    public string? MaintenanceMessage { get; init; } = null;
 }

As per coding guidelines: backend/**/*.cs: Use Records for DTOs and immutable data structures in C#.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/LexBoxApi/Config/MaintenanceModeConfig.cs` around lines 3 - 7,
Replace the mutable class MaintenanceModeConfig with an immutable record named
MaintenanceModeConfig; convert the mutable property MaintenanceMessage to an
init-only property (or use positional record parameters) and ensure ReadOnlyMode
remains init-only with its default false value so the DTO is immutable and
consistent with the project's Record-for-DTO guideline.
backend/FwHeadless/MaintenanceModeConfig.cs (1)

3-7: Prefer an immutable record for this options DTO.

This config model is DTO-like and currently mutable (Line 6). Converting to an immutable record aligns better with the backend guideline.

Refactor example
-public class MaintenanceModeConfig
+public sealed record MaintenanceModeConfig
 {
     public bool ReadOnlyMode { get; init; } = false;
-    public string? MaintenanceMessage { get; set; } = null;
+    public string? MaintenanceMessage { get; init; } = null;
 }

As per coding guidelines: backend/**/*.cs: Use Records for DTOs and immutable data structures in C#.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/FwHeadless/MaintenanceModeConfig.cs` around lines 3 - 7, Replace the
mutable class MaintenanceModeConfig with an immutable record named
MaintenanceModeConfig and make ReadOnlyMode and MaintenanceMessage immutable
(init-only) with the same default values; update the declaration so the DTO is a
record type (preserving the property names ReadOnlyMode and MaintenanceMessage
and their defaults) to follow backend/**/*.cs guideline for records as DTOs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/FwHeadless/appsettings.json`:
- Around line 12-15: The JSON configuration section is named "MaintenanceMode"
but the code in FwHeadlessKernel.cs calls
.BindConfiguration("MaintenanceModeConfig"), causing the binding to fail; fix by
making names match: either rename the JSON key from "MaintenanceMode" to
"MaintenanceModeConfig" in appsettings.json, or change the C# call in
FwHeadlessKernel.cs from .BindConfiguration("MaintenanceModeConfig") to
.BindConfiguration("MaintenanceMode") so the binder picks up the section; update
whichever side you choose and ensure the POCO/usage still matches the chosen
section name.

In `@backend/FwHeadless/FwHeadlessKernel.cs`:
- Around line 24-27: The binding key string passed to
AddOptions<MaintenanceModeConfig>() is incorrect: replace the configuration key
"MaintenanceModeConfig" with "MaintenanceMode" in the
services.AddOptions<MaintenanceModeConfig>().BindConfiguration(...) call (this
same change should also be applied to the analogous call in LexBoxKernel where
AddOptions<MaintenanceModeConfig>() is used) so the MaintenanceModeConfig
options are bound to the actual "MaintenanceMode" configuration section.

In `@backend/LexBoxApi/appsettings.json`:
- Around line 49-52: The configuration section name in appsettings.json is
"MaintenanceMode" but LexBoxKernel.cs binds to "MaintenanceModeConfig"; open the
LexBoxKernel class and change the configuration binding key from
"MaintenanceModeConfig" to "MaintenanceMode" (e.g., update the call that
configures or binds the MaintenanceMode/maintenance config in LexBoxKernel.cs so
it matches the JSON section name).

In `@backend/LexBoxApi/LexBoxKernel.cs`:
- Around line 61-64: The options binding is using the wrong section name; update
the BindConfiguration call used with
services.AddOptions<MaintenanceModeConfig>() to reference the actual appsettings
section ("MaintenanceMode" instead of "MaintenanceModeConfig") so the
MaintenanceModeConfig options are populated (keep the existing
ValidateDataAnnotations() and ValidateOnStart() calls intact).

---

Nitpick comments:
In `@backend/FwHeadless/MaintenanceModeConfig.cs`:
- Around line 3-7: Replace the mutable class MaintenanceModeConfig with an
immutable record named MaintenanceModeConfig and make ReadOnlyMode and
MaintenanceMessage immutable (init-only) with the same default values; update
the declaration so the DTO is a record type (preserving the property names
ReadOnlyMode and MaintenanceMessage and their defaults) to follow
backend/**/*.cs guideline for records as DTOs.

In `@backend/LexBoxApi/Config/MaintenanceModeConfig.cs`:
- Around line 3-7: Replace the mutable class MaintenanceModeConfig with an
immutable record named MaintenanceModeConfig; convert the mutable property
MaintenanceMessage to an init-only property (or use positional record
parameters) and ensure ReadOnlyMode remains init-only with its default false
value so the DTO is immutable and consistent with the project's Record-for-DTO
guideline.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 24eff584-e695-47e9-9c44-15f82bcd4e33

📥 Commits

Reviewing files that changed from the base of the PR and between 73e4ecd and 74e729f.

📒 Files selected for processing (15)
  • backend/FwHeadless/FwHeadlessKernel.cs
  • backend/FwHeadless/MaintenanceModeConfig.cs
  • backend/FwHeadless/MaintenanceModeMiddleware.cs
  • backend/FwHeadless/Program.cs
  • backend/FwHeadless/appsettings.Development.json
  • backend/FwHeadless/appsettings.json
  • backend/LexBoxApi/Config/MaintenanceModeConfig.cs
  • backend/LexBoxApi/LexBoxKernel.cs
  • backend/LexBoxApi/Middleware/MaintenanceModeMiddleware.cs
  • backend/LexBoxApi/Program.cs
  • backend/LexBoxApi/appsettings.Development.json
  • backend/LexBoxApi/appsettings.json
  • frontend/src/hooks.client.ts
  • frontend/src/hooks.server.ts
  • frontend/src/lib/layout/AppBar.svelte

@rmunn
Copy link
Copy Markdown
Contributor Author

rmunn commented Apr 10, 2026

Perhaps we should just use the app_offline.htm file that ASP.NET already has. If there's an app_offline.htm file in the app's root directory, then ASP.NET serves that file for any requests instead of running the app's code. So maintenance windows involve uploading app_offline.htm, then deleting it when the maintenance window is completed.

@rmunn
Copy link
Copy Markdown
Contributor Author

rmunn commented Apr 10, 2026

@rmunn
Copy link
Copy Markdown
Contributor Author

rmunn commented Apr 10, 2026

Perhaps put this into WebServiceDefaults.Extensions...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add maintenance warning banner

1 participant