Skip to content

feat: maintenance mode — degrade to a dashboard overlay on DB outages instead of 500s - #91

Merged
Bonobo791 merged 2 commits into
mainfrom
feat-maintenance-mode
Aug 5, 2026
Merged

feat: maintenance mode — degrade to a dashboard overlay on DB outages instead of 500s#91
Bonobo791 merged 2 commits into
mainfrom
feat-maintenance-mode

Conversation

@Bonobo791

@Bonobo791 Bonobo791 commented Aug 5, 2026

Copy link
Copy Markdown
Owner

User description

What

When Turso 502s (or any DB connectivity failure hits), the site no longer shows bare 500s. Public pages render as normal; signed-in pages get the app shell with a maintenance state (maintainer decision, overriding the previous deliberate-500 contract).

How it works

New degradation signal: locals.dbDown.

  • hooks.server.ts: a raw DB error in the migration-guard check or the session lookup no longer throws 500 — it logs loudly server-side, sets locals.dbDown = true, and lets routing continue. The migration-gap 503 is unchanged (deploy-ordering condition, not an outage), and /api/cron stays loud (machine-facing; a silent success would hide failed runs).
  • (app)/+layout.server.ts: dbDown short-circuits before the /login redirect — returns { user, orgs: [], maintenance: true }. No bounce to /login (which would look like a logout), no consent/org queries that would throw.
  • (app)/dashboard/+page.server.ts: dbDown short-circuits before requireUser; the three data queries are also wrapped so an intermittent mid-load failure degrades to the same maintenance: true payload instead of an error page.
  • +layout.svelte: minimal null-user guards (optional chaining) so the shell type-checks and renders during an outage. The actual maintenance overlay UI is frontend lane — handoff issue filed separately.

Tests (failing first — 7 red before the fix)

  • hooks: guard failure and session failure both degrade (resolve called, dbDown === true, console.error called, no throw); migration-gap 503 still propagates; /login renders during an outage. The two old "fails loudly with a 500" tests were rewritten to the new contract — intentional behavior change ordered by the maintainer.
  • (app) layout: outage returns the maintenance payload instead of redirecting, and short-circuits before the consent query.
  • dashboard: dbDown returns the empty maintenance payload without tripping requireUser; a mid-load DB failure (patched libsql execute) degrades the same way and logs.

Gate

468/468 tests · svelte-check 0 errors · adapter-netlify build green.

Follow-up (not in this PR)

  • Frontend handoff: the maintenance overlay component consuming data.maintenance in (app)/+layout.svelte, plus hiding the account nav when data.user is null. Issue to be filed and routed to the frontend agent.
  • Form actions during an outage still error on submit (their writes genuinely can't succeed); the overlay tells the user not to click. Subpage loads (queue/log/rules) hit directly mid-outage can still throw — the layout-level flag lets the overlay cover them; their error rendering is the frontend agent's call.

CodeAnt-AI Description

Replace database outage errors with a maintenance experience

What Changed

  • Database connectivity failures now render the application shell and maintenance state instead of a bare 500 or an apparent sign-out
  • Signed-in users keep access to the maintenance view, while visitors without a session cookie still go to login
  • Dashboard, team, queue, rules, and activity-log pages return safe maintenance data instead of failing with authentication or database errors
  • Intermittent dashboard failures degrade to maintenance mode and remain logged for operators
  • Deliberate data-integrity failures still fail loudly instead of being mistaken for outages
  • Users can sign out during an outage; the session cookie is cleared even when the server cannot remove the session record

Impact

✅ Fewer database-outage 500 pages
✅ No false logout during database outages
✅ Sign-out remains available during outages

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@cla-bot cla-bot Bot added the cla-signed label Aug 5, 2026
@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 0f4a78a Aug 05, 2026 · 14:20 14:23
✅ Reviewed your PR 97a5422 Aug 05, 2026 · 13:05 13:08

@netlify

netlify Bot commented Aug 5, 2026

Copy link
Copy Markdown

Deploy Preview for moderaty ready!

Name Link
🔨 Latest commit 0f4a78a
🔍 Latest deploy log https://app.netlify.com/projects/moderaty/deploys/6a73469d42ab1a0008a12f9b
😎 Deploy Preview https://deploy-preview-91--moderaty.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 90
Accessibility: 97
Best Practices: 100
SEO: 100
PWA: -
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 5, 2026
@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Sequence Diagram

This PR replaces bare server errors with a maintenance state for app requests when database access fails. The request continues to the app shell, while dashboard loading also degrades safely if an outage begins mid-load.

sequenceDiagram
    participant User
    participant Hook
    participant Database
    participant App
    participant Dashboard

    User->>Hook: Request app page
    Hook->>Database: Check migrations and session
    alt Database outage
        Database-->>Hook: Connection failure
        Hook->>App: Continue with maintenance signal
        App-->>User: Render app shell in maintenance state
    else Database available
        Database-->>Hook: Session result
        Hook->>App: Continue with user session
        App->>Dashboard: Load dashboard data
        alt Outage during dashboard load
            Database-->>Dashboard: Connection failure
            Dashboard-->>User: Render empty maintenance state
        else Load succeeds
            Dashboard-->>User: Render dashboard
        end
    end
Loading

Generated by CodeAnt AI

@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 0f4a78a4
Scan Time: 2026-08-05 14:26:25 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review Summary

This PR successfully implements a maintenance mode feature that gracefully degrades service during database outages instead of showing 500 errors. The implementation is comprehensive with proper error handling, test coverage (468/468 passing), and follows the maintainer's design decisions.

Key Changes Reviewed

  • hooks.server.ts: Database failures in migration guard and session lookup now set locals.dbDown instead of throwing 500 errors
  • (app)/+layout.server.ts: Short-circuits with maintenance payload when locals.dbDown is true, preventing redirect loops
  • (app)/+layout.svelte: Optional chaining prevents null reference errors when user is null during outages
  • dashboard/+page.server.ts: Wraps queries in try-catch to handle intermittent failures mid-load
  • Comprehensive test coverage for all degradation scenarios

Gate Status

✅ All 468 tests passing
✅ svelte-check reports 0 errors
✅ adapter-netlify build successful

The implementation correctly handles database outages without introducing security vulnerabilities or logic errors. The code is ready to merge.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread src/hooks.server.ts
Comment on lines 72 to 77
} catch (e) {
console.error('session lookup failed:', e);
throw error(500, 'something went wrong on our side — please retry');
event.locals.dbDown = true;
event.locals.user = null;
}
return resolve(event);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛑 Logic Error: Failure to set the cookie after session renewal. When resolution?.renewed is true and a token exists, the new expiry timestamp is set in the cookie but the response bypasses the normal flow, preventing the cookie from being sent to the client. Line 77 unconditionally returns resolve(event) even when database failures occur, but the cookie update at line 64-70 happens inside the success path, so the cookie should be set correctly. However, when a database error occurs in the catch block (line 72), the early return at line 76 doesn't have the updated cookie.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@Amazon-Q-Developer[bot] Not valid. The cookie update at L64-70 only runs when getSessionUser() RESOLVES with renewed: true. When the DB fails, getSessionUser() throws before any renewal happens — there is no new expiry to persist (the renewal UPDATE itself never reached the DB), so there is nothing to write to the cookie. The catch path correctly sets dbDown and leaves the stale-but-still-valid cookie untouched; on recovery the session resolves normally again. No change.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Bonobo791, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e85e6cc2-8d88-44d5-a7c3-525ba7524d32

📥 Commits

Reviewing files that changed from the base of the PR and between 78ff5cd and 0f4a78a.

📒 Files selected for processing (21)
  • src/app.d.ts
  • src/hooks.server.test.ts
  • src/hooks.server.ts
  • src/lib/server/session.test.ts
  • src/lib/server/session.ts
  • src/routes/(app)/+layout.server.ts
  • src/routes/(app)/+layout.svelte
  • src/routes/(app)/channels/[id]/log/+page.server.ts
  • src/routes/(app)/channels/[id]/log/load.test.ts
  • src/routes/(app)/channels/[id]/queue/+page.server.ts
  • src/routes/(app)/channels/[id]/queue/load.test.ts
  • src/routes/(app)/channels/[id]/rules/+page.server.ts
  • src/routes/(app)/channels/[id]/rules/actions.test.ts
  • src/routes/(app)/dashboard/+page.server.ts
  • src/routes/(app)/dashboard/dashboard.test.ts
  • src/routes/(app)/layout.test.ts
  • src/routes/(app)/org/+page.server.ts
  • src/routes/(app)/org/+page.svelte
  • src/routes/(app)/org/page.server.test.ts
  • src/routes/logout/+page.server.ts
  • src/routes/logout/logout.test.ts

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Degrade to maintenance mode on DB outages via locals.dbDown (no bare 500s)

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Degrade DB connectivity failures to a maintenance state instead of throwing 500s.
• Propagate an outage signal via locals.dbDown and short-circuit app loads.
• Add/adjust tests to codify the new outage contract and logging behavior.
Diagram

graph TD
  U["Browser request"] --> H["hooks.server.ts"] --> Q{"DB reachable?"}
  Q -->|"Yes"| N["Normal app loads"] --> S["App shell (+layout.svelte)"]
  Q -->|"No"| M["Set locals.dbDown"] --> P["Maintenance payload"] --> S
  H --> DB[("Turso / DB")]
  N --> DB

  subgraph Legend
    direction LR
    _p["Page/server module"] ~~~ _d{"Decision"} ~~~ _db[("Database")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Centralize outage handling in handleError()
  • ➕ Keeps page/server load code simpler by handling DB exceptions in one place
  • ➕ Can ensure consistent UX for all routes without per-page try/catch
  • ➖ Harder to reliably distinguish DB outage errors from app bugs without brittle error typing
  • ➖ Doesn’t prevent wasted downstream DB calls unless paired with a shared outage flag/circuit breaker
2. Return 503 for app pages (no shell render)
  • ➕ Clear HTTP semantics; easy to implement and cache at edges
  • ➕ Avoids needing null-user guards in UI
  • ➖ Worse UX than an in-app maintenance overlay; looks like a crash to users
  • ➖ Doesn’t allow partially functional shell/navigation messaging during outages
3. Introduce a DB circuit breaker module
  • ➕ Prevents repeated failing DB calls during an outage window
  • ➕ Can provide richer metrics/backoff behavior and recovery detection
  • ➖ More moving parts and state management; higher complexity than needed for this change
  • ➖ Still requires a UI contract (e.g., locals.dbDown / maintenance payload)

Recommendation: The PR’s approach (explicit locals.dbDown + early short-circuits in (app) layout/dashboard) is a good balance: it avoids misleading /login redirects, prevents additional DB queries during outages, and preserves a consistent UI surface for a maintenance overlay. Consider a circuit breaker only if repeated DB flapping becomes a recurring operational issue.

Files changed (8) +153 / -58

Enhancement (4) +73 / -49
app.d.tsAdd locals.dbDown outage flag to SvelteKit locals typing +2/-0

Add locals.dbDown outage flag to SvelteKit locals typing

• Extends App.Locals with an optional dbDown boolean. Documents that hooks set this when the database is unreachable to render maintenance instead of a 500.

src/app.d.ts

hooks.server.tsDegrade migration/session DB failures to locals.dbDown + continue routing +15/-8

Degrade migration/session DB failures to locals.dbDown + continue routing

• Stops throwing a generic 500 on unexpected DB failures in migration guard and session lookup. Logs errors server-side, sets locals.dbDown=true and locals.user=null, and allows resolve(event) to proceed; deliberate migration-gap HttpErrors still propagate unchanged.

src/hooks.server.ts

+layout.server.tsShort-circuit app layout load to maintenance payload when dbDown +5/-1

Short-circuit app layout load to maintenance payload when dbDown

• Adds an early return when locals.dbDown is true to avoid /login redirect and any DB-backed consent/org queries. Normal path now explicitly returns maintenance:false alongside user and orgs.

src/routes/(app)/+layout.server.ts

+page.server.tsDegrade dashboard load to maintenance payload on outage or mid-load DB failure +51/-40

Degrade dashboard load to maintenance payload on outage or mid-load DB failure

• Returns an empty maintenance payload when locals.dbDown is set before calling requireUser. Wraps dashboard DB reads in a try/catch so intermittent DB failures during load log loudly and return maintenance:true instead of erroring.

src/routes/(app)/dashboard/+page.server.ts

Bug fix (1) +2 / -2
+layout.svelteGuard shell rendering when user is null during outage +2/-2

Guard shell rendering when user is null during outage

• Switches user-dependent bindings to optional chaining and provides a fallback display label. Ensures the app shell type-checks and renders even when hooks couldn’t populate a session user due to DB outage.

src/routes/(app)/+layout.svelte

Tests (3) +78 / -7
hooks.server.test.tsRewrite hooks DB-failure tests to assert maintenance degradation +30/-7

Rewrite hooks DB-failure tests to assert maintenance degradation

• Updates prior “fail loudly with 500” expectations to the new contract: resolve continues, locals.dbDown is set, locals.user is null, and console.error is called. Adds coverage ensuring /login still renders during an outage and that migration-gap 503 behavior still propagates.

src/hooks.server.test.ts

dashboard.test.tsAdd dashboard tests for outage short-circuit and mid-load DB failure +23/-0

Add dashboard tests for outage short-circuit and mid-load DB failure

• Adds a test ensuring locals.dbDown bypasses requireUser and returns the maintenance payload. Adds a test that forces the DB client to fail mid-load and asserts the same maintenance payload plus server-side logging.

src/routes/(app)/dashboard/dashboard.test.ts

layout.test.tsAdd layout tests for outage maintenance payload and consent-query bypass +25/-0

Add layout tests for outage maintenance payload and consent-query bypass

• Verifies that dbDown returns maintenance data instead of redirecting to /login when user is null. Ensures dbDown also short-circuits even with a verified user, avoiding the consent query path entirely.

src/routes/(app)/layout.test.ts

@codacy-production

codacy-production Bot commented Aug 5, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🔴 Metrics 11 complexity · 10 duplication

Metric Results
Complexity 11 (≤ 100 complexity)
Duplication ⚠️ 10 (≤ 1 duplication)

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Repository owner deleted a comment from codeant-ai Bot Aug 5, 2026
@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

PR Code Suggestions ✨

Previous suggestions up to commit 97a5422
CategorySuggestion                                                                                                                                    SeverityGenerated at (UTC)
Incorrect condition logic
Non-database session errors are incorrectly converted into a signed-out maintenance state

This catch treats every exception from getSessionUser as a database outage. The
session resolver deliberately throws for non-connectivity integrity failures such as
an account with no organization membership; converting those errors into dbDown and
clearing locals.user hides the corruption and changes the documented fail-loudly
behavior into a misleading signed-out maintenance state. Only confirmed database
connectivity failures should take this branch.

src/hooks.server.ts [74-75]

Why it matters? 🤔
  • ⚠️ Corrupt accounts appear signed out during maintenance mode.
  • ⚠️ Organization-membership corruption is hidden from operators.
  • ⚠️ Affected app requests render misleading outage state.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/hooks.server.ts
**Line:** 74:75
**Comment:**
	*Incorrect Condition Logic: This catch treats every exception from `getSessionUser` as a database outage. The session resolver deliberately throws for non-connectivity integrity failures such as an account with no organization membership; converting those errors into `dbDown` and clearing `locals.user` hides the corruption and changes the documented fail-loudly behavior into a misleading signed-out maintenance state. Only confirmed database connectivity failures should take this branch.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 13:08
Incomplete implementation
Child app routes still fail authentication or database queries despite the maintenance layout state

The maintenance branch only short-circuits this layout load; child loads under (app)
still execute with locals.user set to null and call requireUser or ownedChannel,
producing a 401 or another database error instead of the maintenance response. Apply
the outage handling at a shared boundary or update every child load/action that can
run during the degraded state.

src/routes/(app)/+layout.server.ts [34]

Why it matters? 🤔
  • /org returns 401 during database outages.
  • ❌ Channel queue pages fail before maintenance rendering.
  • ❌ Channel rules pages fail before maintenance rendering.
  • ⚠️ Maintenance behavior differs across app routes.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/+layout.server.ts
**Line:** 34:34
**Comment:**
	*Incomplete Implementation: The maintenance branch only short-circuits this layout load; child loads under `(app)` still execute with `locals.user` set to `null` and call `requireUser` or `ownedChannel`, producing a 401 or another database error instead of the maintenance response. Apply the outage handling at a shared boundary or update every child load/action that can run during the degraded state.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 13:08
Database outages render a normal account shell instead of a maintenance state

The outage payload supplies a null user, so this fallback renders the
signed-out-looking label “Account” while the rest of the normal navigation and
sign-out form remain active. Because the layout does not branch on data.maintenance,
users see an ordinary app shell rather than the required maintenance state. Render a
maintenance shell or overlay when data.maintenance is true and disable normal app
actions during the outage.

src/routes/(app)/+layout.svelte [42]

Why it matters? 🤔
  • ❌ Signed-in outage requests show no maintenance indication.
  • ⚠️ Users see misleading Account and normal navigation controls.
  • ⚠️ Team and sign-out actions remain exposed during outages.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/+layout.svelte
**Line:** 42:42
**Comment:**
	*Incomplete Implementation: The outage payload supplies a null user, so this fallback renders the signed-out-looking label “Account” while the rest of the normal navigation and sign-out form remain active. Because the layout does not branch on `data.maintenance`, users see an ordinary app shell rather than the required maintenance state. Render a maintenance shell or overlay when `data.maintenance` is true and disable normal app actions during the outage.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 13:08
Api mismatch
Maintenance data is returned in a shape the dashboard renders as a normal empty state

The new load result returns maintenance: true with empty arrays, but the dashboard
page consumes only chs, stats, and bans and treats an empty chs array as the normal
“No channels connected” state. During either outage path, users therefore receive an
ordinary empty dashboard with active channel-connect and account-deletion controls
instead of a maintenance overlay. Add a maintenance branch in the page consumer or
return a shape that the existing page handles explicitly.

src/routes/(app)/dashboard/+page.server.ts [37]

Why it matters? 🤔
  • ❌ Dashboard outages appear as “No channels connected.”
  • ⚠️ YouTube connection control remains active.
  • ⚠️ Account deletion controls remain visible during outages.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/dashboard/+page.server.ts
**Line:** 37:37
**Comment:**
	*Api Mismatch: The new load result returns `maintenance: true` with empty arrays, but the dashboard page consumes only `chs`, `stats`, and `bans` and treats an empty `chs` array as the normal “No channels connected” state. During either outage path, users therefore receive an ordinary empty dashboard with active channel-connect and account-deletion controls instead of a maintenance overlay. Add a maintenance branch in the page consumer or return a shape that the existing page handles explicitly.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 13:08

Latest suggestions up to commit 0f4a78a
CategorySuggestion                                                                                                                                    SeverityGenerated at (UTC)
Possible bug
Waiting on database cleanup delays cookie removal during an outage

During an outage this still awaits destroySession before deleting the browser
cookie. Since destroySession performs a database delete, an unreachable database can
block until the driver timeout, leaving the stale session cookie in the browser and
delaying the promised logout recovery path. Clear the cookie before the best-effort
database cleanup, or skip the database delete when locals.dbDown is already set.

src/routes/logout/+page.server.ts [39-44]

Why it matters? 🤔
  • ⚠️ Outage logout can wait for database timeout.
  • ⚠️ Stale session cookies delay recovery.
  • ⚠️ /logout redirect is delayed during connectivity failures.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/logout/+page.server.ts
**Line:** 39:44
**Comment:**
	*Possible Bug: During an outage this still awaits `destroySession` before deleting the browser cookie. Since `destroySession` performs a database delete, an unreachable database can block until the driver timeout, leaving the stale session cookie in the browser and delaying the promised logout recovery path. Clear the cookie before the best-effort database cleanup, or skip the database delete when `locals.dbDown` is already set.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 14:23
Incomplete implementation
Mid-load database failures on the queue page still produce a 500 instead of maintenance mode

This guard handles only an outage detected before the page load starts. If the hook
succeeds but ownedChannel or the pending-comments query encounters a database
connectivity failure, the exception still propagates as a 500, unlike the
dashboard's mid-load fallback. Wrap these database operations and return the same
maintenance payload for an intermittent outage.

src/routes/(app)/channels/[id]/queue/+page.server.ts [32]

Why it matters? 🤔
  • ❌ Queue navigation can still return database-error pages.
  • ⚠️ Intermittent outages interrupt review-queue access.
  • ⚠️ Queue behavior differs from dashboard maintenance handling.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/channels/[id]/queue/+page.server.ts
**Line:** 32:32
**Comment:**
	*Incomplete Implementation: This guard handles only an outage detected before the page load starts. If the hook succeeds but `ownedChannel` or the pending-comments query encounters a database connectivity failure, the exception still propagates as a 500, unlike the dashboard's mid-load fallback. Wrap these database operations and return the same maintenance payload for an intermittent outage.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 14:23
Maintenance loads still expose a mutation form that fails with an authentication error during an outage

The maintenance payload still renders the rules page's add-rule form because the
page unconditionally displays it. Submitting that form during an outage invokes
actions.add, which calls ownedChannel with the null outage user and throws a 401
instead of remaining in the maintenance state. Suppress mutation controls when
maintenance is true or explicitly reject these actions with an outage-safe response.

src/routes/(app)/channels/[id]/rules/+page.server.ts [29]

Why it matters? 🤔
  • ❌ Rules form submission returns 401 during database outages.
  • ⚠️ Maintenance state does not cover the rules mutation controls.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/channels/[id]/rules/+page.server.ts
**Line:** 29:29
**Comment:**
	*Incomplete Implementation: The maintenance payload still renders the rules page's add-rule form because the page unconditionally displays it. Submitting that form during an outage invokes `actions.add`, which calls `ownedChannel` with the null outage user and throws a 401 instead of remaining in the maintenance state. Suppress mutation controls when `maintenance` is true or explicitly reject these actions with an outage-safe response.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 14:23
Maintenance data leaves organization mutation controls active even though no authenticated user is available

The outage payload sets user to null, but the organization page still renders the
always-visible Create another team and Leave team forms. Posting either form calls
requireUser(locals) and produces a 401 while the page is supposed to remain in
maintenance mode. Hide all mutation controls in the maintenance state or handle
these actions explicitly as unavailable.

src/routes/(app)/org/+page.server.ts [44]

Why it matters? 🤔
  • ❌ Team mutation submissions return 401 during database outages.
  • ⚠️ Organization maintenance view exposes unusable Create and Leave controls.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** src/routes/(app)/org/+page.server.ts
**Line:** 44:44
**Comment:**
	*Incomplete Implementation: The outage payload sets `user` to null, but the organization page still renders the always-visible Create another team and Leave team forms. Posting either form calls `requireUser(locals)` and produces a 401 while the page is supposed to remain in maintenance mode. Hide all mutation controls in the maintenance state or handle these actions explicitly as unavailable.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Major2026-08-05 14:23

@qodo-code-review

qodo-code-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Maintenance masks data bugs ✓ Resolved 🐞 Bug ≡ Correctness
Description
Blanket exception handling in both hooks.server.ts and dashboard/+page.server.ts misclassifies any
thrown error as a database outage/maintenance condition and continues with a maintenance
payload/state, which incorrectly hides non-DB application/data integrity failures (e.g. the “user
has no organization” invariant) and reduces debuggability by masking real regressions behind
maintenance mode.
Code

src/hooks.server.ts[R73-76]

		console.error('session lookup failed:', e);
-		throw error(500, 'something went wrong on our side — please retry');
+		event.locals.dbDown = true;
+		event.locals.user = null;
	}
Relevance

●● Moderate

Touches maintainer-approved outage degrade; but narrowing catches to DB errors may be accepted for
correctness.

PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
In hooks.server.ts, the catch around getSessionUser() unconditionally sets locals.dbDown = true for
any exception and allows the request to continue, even though getSessionUser() can throw
non-database invariant errors such as missing organization membership; this means those
application/data issues are incorrectly presented as maintenance. Similarly,
dashboard/+page.server.ts wraps its load logic in a broad try/catch that returns a maintenance
payload on all exceptions without checking error type, so non-DB failures (including programming
errors or deliberate HttpErrors) are also downgraded to maintenance instead of surfacing as proper
failures.

src/hooks.server.ts[59-77]
src/lib/server/session.ts[106-114]
src/routes/(app)/dashboard/+page.server.ts[33-85]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Multiple request/code paths downgrade *any* exception into a DB-outage/maintenance state: `handle()` in `hooks.server.ts` maps all `getSessionUser()` failures to `locals.dbDown = true` and continues, and the dashboard page server `load` returns `{ maintenance: true }` for any caught error. This misclassifies non-database application/data-integrity problems (and potentially deliberate HttpErrors) as maintenance, hiding actionable errors and masking regressions.

## Issue Context
`getSessionUser()` can throw errors unrelated to DB connectivity (e.g. missing org membership), which should propagate loudly (or as deliberate `HttpError`s) rather than being treated as an outage. The intended degradation path is for DB connectivity/intermittent DB outages only, not arbitrary exceptions during session lookup or dashboard load.

## Fix Focus Areas
- src/hooks.server.ts[60-76]
- src/lib/server/session.ts[106-114]
- src/routes/(app)/dashboard/+page.server.ts[33-85]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. App pages still throw 401 ✓ Resolved 🐞 Bug ☼ Reliability
Description
The (app) layout returns maintenance data when locals.dbDown is set, but child (app) routes (e.g.
/org) still call requireUser()/ownedChannel() without checking dbDown, so outage requests can still
throw 401 instead of returning a maintenance payload. This undermines the “overlay instead of
errors” behavior for non-dashboard app routes.
Code

src/routes/(app)/+layout.server.ts[R34-36]

+	if (locals.dbDown) return { user: locals.user, orgs: [], maintenance: true };
	if (!locals.user) throw redirect(302, '/login');
	if (!(await hasCurrentConsent(locals.user.id))) throw redirect(302, '/consent');
-	return { user: locals.user, orgs: await listOrgMemberships(locals.user.id) };
Relevance

●● Moderate

PR text implies non-dashboard routes may still throw; team might defer to frontend overlay rather
than fix now.

PR-#84

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The layout now explicitly allows the app shell to load in dbDown state, but nested routes like /org
and ownedChannel() still unconditionally call requireUser(), which throws when locals.user is
null—exactly the outage shape created by hooks.

src/routes/(app)/+layout.server.ts[33-37]
src/routes/(app)/org/+page.server.ts[40-46]
src/lib/server/ownership.ts[43-50]
src/hooks.server.ts[72-77]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`(app)/+layout.server.ts` now returns a maintenance payload when `locals.dbDown` is set, but many nested `(app)` server loads and actions still immediately call `requireUser(locals)` (directly or via `ownedChannel()`), which throws 401 when `locals.user` is null during outages.

## Issue Context
Only dashboard load was updated to short-circuit on `locals.dbDown`. Other `(app)` routes can still fail with 401/error responses during outages.

## Fix Focus Areas
- src/routes/(app)/+layout.server.ts[33-37]
- src/routes/(app)/org/+page.server.ts[40-46]
- src/lib/server/ownership.ts[43-50]

## Suggested fix
1. Add an early `if (locals.dbDown) return { maintenance: true, ... }` short-circuit to other key `(app)` page loads (at minimum `/org` and commonly-hit channel pages), mirroring dashboard.
2. Alternatively, introduce a shared helper (e.g. `requireUserOrMaintenance(locals)`) and migrate route loads/actions to use it.
3. Add tests for at least one non-dashboard `(app)` load (e.g. `/org`) asserting it returns a maintenance payload when `locals.dbDown` is true, not 401.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Logout blocked in outage ✓ Resolved 🐞 Bug ≡ Correctness
Description
In maintenance mode, locals.user is forced to null, but the (app) layout still renders a POST
/logout form; the /logout action calls requireUser(locals) first, so it 401s and cannot clear the
cookie during an outage. This creates a broken recovery path where the UI offers logout but the
server refuses it.
Code

src/routes/(app)/+layout.svelte[R42-45]

+		<span class="muted">{data.user?.displayName ?? 'Account'}</span>
		<form method="POST" action="/logout">
			<button class="btn secondary small" type="submit">Sign out</button>
		</form>
Relevance

●● Moderate

Logout failing in outage may be considered acceptable (actions can’t run) but could be fixed; no
precedent.

PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The (app) layout always renders a logout form, but during dbDown the layout data can include
user:null; the /logout action requires a non-null locals.user before deleting the cookie, so
outage-mode logout fails with 401.

src/routes/(app)/+layout.svelte[25-46]
src/routes/(app)/+layout.server.ts[33-37]
src/routes/logout/+page.server.ts[29-36]
src/hooks.server.ts[72-77]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
During DB outages, the app layout renders with `data.user === null` but still shows a logout form. Submitting it hits `/logout`, whose action requires `locals.user` and fails before cookie deletion.

## Issue Context
On outage, identity cannot be resolved (by design). Users should still be able to clear their session cookie (even if DB-backed session deletion cannot run).

## Fix Focus Areas
- src/routes/(app)/+layout.svelte[41-46]
- src/routes/logout/+page.server.ts[29-36]
- src/routes/(app)/+layout.server.ts[33-37]

## Suggested fix
Choose one (or both):
1. UI guard: In `(app)/+layout.svelte`, only render the logout form when `data.user` is non-null (and/or when `!data.maintenance`).
2. Server robustness: In `/logout` action, remove `requireUser(locals)` and always delete `SESSION_COOKIE` unconditionally; optionally attempt `destroySession(token)` in a try/catch when a token exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. locals.dbDown bypasses redirects ✓ Resolved 📘 Rule violation ≡ Correctness
Description
The (app) root layout now returns a maintenance payload when locals.dbDown is true, which allows
requests with locals.user === null to avoid the required /login redirect and also skips the
consent check. This violates the requirement that authenticated layout routing must always enforce
auth + consent redirects based on locals.user/hasCurrentConsent.
Code

src/routes/(app)/+layout.server.ts[34]

+	if (locals.dbDown) return { user: locals.user, orgs: [], maintenance: true };
Relevance

●● Moderate

Redirect bypass appears intentional for dbDown; but compliance-style requirement could force
change—no clear precedent.

PR-#25

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2436641 requires (app) layout loads to redirect to /login when locals.user is
falsy and to /consent when hasCurrentConsent is false, without alternative bypass branches. The
added if (locals.dbDown) return ... branch in src/routes/(app)/+layout.server.ts creates an
explicit bypass of both redirects.

Rule 2436641: Enforce auth + consent redirects in root layout using locals.user and hasCurrentConsent
src/routes/(app)/+layout.server.ts[30-37]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/routes/(app)/+layout.server.ts` introduces an early return when `locals.dbDown` is true, which bypasses the required `/login` redirect when `locals.user` is falsy and bypasses the `hasCurrentConsent` redirect.

## Issue Context
Compliance requires auth + consent redirects to be enforced in the `(app)` root layout using `locals.user` and `hasCurrentConsent`.

## Fix Focus Areas
- src/routes/(app)/+layout.server.ts[34-37]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Compliance rules (platform): 78 rules

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread src/routes/(app)/+layout.server.ts Outdated
Comment thread src/hooks.server.ts
Comment thread src/routes/(app)/+layout.svelte
Comment thread src/routes/(app)/+layout.server.ts Outdated
…e-gated maintenance shell, child-load short-circuits
@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:L This PR changes 100-499 lines, ignoring generated files labels Aug 5, 2026
@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@Bonobo791

Copy link
Copy Markdown
Owner Author

Triage of all bot reviews (fixes in 0f4a78a; each valid finding got a failing test BEFORE its fix per repo rule):

Valid — fixed:

  • @qodo-code-review[bot] "Maintenance masks data bugs" / @CodeAnt-AI "Incorrect condition logic": session integrity failures (account-has-no-org) now throw a deliberate error(500) HttpError; hooks + dashboard catches rethrow HttpErrors before degrading. Only genuine DB failures become maintenance.
  • @qodo-code-review[bot] "dbDown bypasses redirects": the maintenance shell now requires a session cookie; cookie-less outage requests follow the normal /login redirect.
  • @qodo-code-review[bot] "Logout blocked in outage": logout skips requireUser under dbDown, always clears the cookie, destroys the row best-effort (loud log on failure).
  • @qodo-code-review[bot] "App pages still throw 401" / @CodeAnt-AI "Incomplete implementation": /org and channels/[id]/{queue,log,rules} loads short-circuit on dbDown with maintenance payloads.

Not valid / out of scope:

  • @Amazon-Q-Developer[bot] (hooks cookie-after-renewal): invalid — a failed getSessionUser() never produced a renewal to persist; replied inline.
  • @CodeAnt-AI frontend findings (maintenance shell instead of normal nav; dashboard renders empty state instead of overlay): correct observations, deliberately out of scope — the overlay UI is the frontend handoff tracked in issue [frontend] Maintenance overlay for DB outages (consumes data.maintenance from PR #91) #92. This PR ships the backend contract (maintenance: true payloads that never 500/401).
  • @codacy-production duplication (8 clones): test-fixture boilerplate shared across route tests, consistent with the suite's existing pattern; no production-code duplication.
  • @sonarqubecloud gate passed; @coderabbitai rate-limited (no review produced).

Gate after fixes: 475/475 tests, svelte-check 0 errors, Netlify build clean.

@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Question: valid — fixed:

  • @qodo-code-review[bot] "maintenance masks data bugs" / @CodeAnt-AI "incorrect condition logic": session integrity failures (account-has-no-org) now throw a deliberate error(500) httperror; hooks + dashboard catches rethrow httperrors before degrading. only genuine db failures become maintenance.
  • @qodo-code-review[bot] "dbdown bypasses redirects": the maintenance shell now requires a session cookie; cookie-less outage requests follow the normal /login redirect.
  • @qodo-code-review[bot] "logout blocked in outage": logout skips requireuser under dbdown, always clears the cookie, destroys the row best-effort (loud log on failure).
  • @qodo-code-review[bot] "app pages still throw 401" / @CodeAnt-AI "incomplete implementation": /org and channels/[id]/{queue,log,rules} loads short-circuit on dbdown with maintenance payloads.

not valid / out of scope:

  • @Amazon-Q-Developer[bot] (hooks cookie-after-renewal): invalid — a failed getsessionuser() never produced a renewal to persist; replied inline.
  • @CodeAnt-AI frontend findings (maintenance shell instead of normal nav; dashboard renders empty state instead of overlay): correct observations, deliberately out of scope — the overlay ui is the frontend handoff tracked in issue [frontend] Maintenance overlay for DB outages (consumes data.maintenance from PR #91) #92. this pr ships the backend contract (maintenance: true payloads that never 500/401).
  • @codacy-production duplication (8 clones): test-fixture boilerplate shared across route tests, consistent with the suite's existing pattern; no production-code duplication.
  • @sonarqubecloud gate passed; @coderabbitai rate-limited (no review produced).

gate after fixes: 475/475 tests, svelte-check 0 errors, netlify build clean.

Answer:
The addressed findings are valid and the fixes align with the stated maintenance-mode contract:

  • Database failures in the migration guard and session lookup now resolve the request, set locals.dbDown, clear the potentially unknown user, and log server-side.
  • Deliberate HttpErrors, including the no-organization integrity failure, still propagate as 500s.
  • The app layout only bypasses /login when a session cookie is present.
  • Dashboard and the affected child loads avoid requireUser/ownership queries during an outage.
  • Logout remains usable and clears the cookie even when the database cannot delete the session row.

The frontend observations are also correctly out of scope for this PR because the backend now exposes a consistent maintenance: true payload for the frontend overlay work.

One residual consideration: the hooks classify every non-HttpError thrown by getSessionUser() or the migration guard as a database outage. That means an unexpected programming error or another plain application error could be masked as maintenance. If the project needs the stronger guarantee that only connectivity failures degrade, the database layer should expose a typed/classified connectivity error and hooks should check that type. Based on the current contract and tests, however, this is not a regression specific to the reviewed scenarios.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- Commit summary ---'
git show --stat --oneline --decorate --no-renames 0f4a78a

echo
echo '--- Files changed by commit ---'
git diff-tree --no-commit-id --name-only -r 0f4a78a

echo
echo '--- dbDown and HttpError branches in changed TypeScript/Svelte files ---'
git diff-tree --no-commit-id --name-only -r 0f4a78a \
  | grep -E '\.(ts|svelte)$' \
  | while IFS= read -r file; do
      echo "### $file"
      rg -n -C 3 '(dbDown|HttpError|error\(500|requireUser|destroy|deleteSession|session)' "$file" || true
    done

echo
echo '--- Issue `#92` ---'
gh issue view 92 --repo Bonobo791/Moderaty --json number,title,state,body,url

Length of output: 41324


@Bonobo791 I verified commit 0f4a78a.

The inspected changes match the triage:

  • Deliberate session-integrity HttpError values now propagate from hooks.server.ts and the dashboard loader.
  • Only non-HTTP database failures set locals.dbDown.
  • The maintenance shell requires SESSION_COOKIE. Cookie-less requests still redirect to /login.
  • Logout clears SESSION_COOKIE during an outage. Session-row deletion is best-effort and logs failures.
  • /org and the channel queue, log, and rules loaders return maintenance payloads before authentication checks.
  • The associated regression tests are present.

Issue #92 is open and correctly tracks the frontend overlay and null-user navigation behavior. This PR can remain limited to the backend maintenance contract.

I did not independently run the reported test, type-check, or build gate in this environment.


✏️ Learnings added
Learnt from: Bonobo791
URL: https://github.com/Bonobo791/Moderaty/pull/91

Timestamp: 2026-08-05T14:22:01.609Z
Learning: For Moderaty database outages, `src/hooks.server.ts` and server loaders must rethrow deliberate SvelteKit `HttpError` values, including the `error(500, 'account has no organization — contact support')` session-integrity failure. Only non-HTTP database connectivity errors may set `locals.dbDown` and return maintenance data.

Learnt from: Bonobo791
URL: https://github.com/Bonobo791/Moderaty/pull/91

Timestamp: 2026-08-05T14:22:01.609Z
Learning: In Moderaty PR `#91`, the backend maintenance-mode contract is intentionally separate from the frontend UI. GitHub issue `#92` owns the `src/routes/(app)/+layout.svelte` maintenance overlay and null-user navigation behavior. Backend loaders return `maintenance: true`, empty data, and can have `user: null` during an outage.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@qodo-code-review

Copy link
Copy Markdown

Triage of all bot reviews (fixes in 0f4a78a; each valid finding got a failing test BEFORE its fix per repo rule):

Valid — fixed:

  • @qodo-code-review[bot] "Maintenance masks data bugs" / @CodeAnt-AI "Incorrect condition logic": session integrity failures (account-has-no-org) now throw a deliberate error(500) HttpError; hooks + dashboard catches rethrow HttpErrors before degrading. Only genuine DB failures become maintenance.
  • @qodo-code-review[bot] "dbDown bypasses redirects": the maintenance shell now requires a session cookie; cookie-less outage requests follow the normal /login redirect.
  • @qodo-code-review[bot] "Logout blocked in outage": logout skips requireUser under dbDown, always clears the cookie, destroys the row best-effort (loud log on failure).
  • @qodo-code-review[bot] "App pages still throw 401" / @CodeAnt-AI "Incomplete implementation": /org and channels/[id]/{queue,log,rules} loads short-circuit on dbDown with maintenance payloads.

Not valid / out of scope:

  • @Amazon-Q-Developer[bot] (hooks cookie-after-renewal): invalid — a failed getSessionUser() never produced a renewal to persist; replied inline.
  • @CodeAnt-AI frontend findings (maintenance shell instead of normal nav; dashboard renders empty state instead of overlay): correct observations, deliberately out of scope — the overlay UI is the frontend handoff tracked in issue [frontend] Maintenance overlay for DB outages (consumes data.maintenance from PR #91) #92. This PR ships the backend contract (maintenance: true payloads that never 500/401).
  • @codacy-production duplication (8 clones): test-fixture boilerplate shared across route tests, consistent with the suite's existing pattern; no production-code duplication.
  • @sonarqubecloud gate passed; @coderabbitai rate-limited (no review produced).

Gate after fixes: 475/475 tests, svelte-check 0 errors, Netlify build clean.

Thanks for the triage. The fixes address all four Qodo findings: finding 1 (integrity errors rethrow as HttpError), finding 2 (app loads short-circuit during outages), finding 3 (logout clears the cookie during outages), and finding 4 (the maintenance path requires a session cookie). The added regression coverage and the reported 475/475 tests, clean svelte-check, and Netlify build confirm the intended backend contract. There are currently no active Qodo findings; the frontend overlay work can remain tracked separately in issue #92.

@Bonobo791

Copy link
Copy Markdown
Owner Author

Acknowledging the verification round — thanks @CodeAnt-AI, @coderabbitai, @qodo-code-review[bot]. No active findings remain.

@CodeAnt-AI's residual consideration (a typed/classified DB-connectivity error so ONLY connectivity failures can degrade, rather than any non-HttpError) is a fair hardening idea but new scope beyond the reviewed findings — noting it here as a possible maintainer follow-up rather than expanding this PR.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@Bonobo791 Acknowledged. No active findings remain for PR #91.

Keeping typed DB-connectivity error classification outside this PR is reasonable. It can be tracked as a separate hardening item if you want a follow-up issue.

🐇✅

You are interacting with an AI system.

@Bonobo791
Bonobo791 merged commit 3df8cdc into main Aug 5, 2026
16 of 20 checks passed
@Bonobo791
Bonobo791 deleted the feat-maintenance-mode branch August 5, 2026 14:25
@codeant-ai

codeant-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Question: acknowledging the verification round — thanks , @coderabbitai, @qodo-code-review[bot]. no active findings remain.

's residual consideration (a typed/classified db-connectivity error so only connectivity failures can degrade, rather than any non-httperror) is a fair hardening idea but new scope beyond the reviewed findings — noting it here as a possible maintainer follow-up rather than expanding this pr.

Answer:
The residual consideration is valid and should be recorded as a follow-up rather than blocking this PR.

Currently, the degradation path treats every non-HttpError as a database outage. That could convert unrelated defects—such as programming errors, malformed data, or unexpected service failures—into maintenance mode and hide them from users and monitoring. A future hardening change could introduce a typed/classified connectivity error and only set locals.dbDown for errors known to represent DB connectivity failures, while preserving loud propagation for all other exceptions.

Given the maintainer’s explicit behavior change and the current test coverage, this is not an active finding for this PR.

@qodo-code-review

Copy link
Copy Markdown

Acknowledging the verification round — thanks @CodeAnt-AI, @coderabbitai, @qodo-code-review[bot]. No active findings remain.

@CodeAnt-AI's residual consideration (a typed/classified DB-connectivity error so ONLY connectivity failures can degrade, rather than any non-HttpError) is a fair hardening idea but new scope beyond the reviewed findings — noting it here as a possible maintainer follow-up rather than expanding this PR.

Thanks for the verification update. Confirmed: findings 1–4 are implemented, and there are no active Qodo findings remaining. The typed/classified connectivity-error handling is a reasonable maintainer follow-up but is outside this PR’s reviewed scope.

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

Labels

cla-signed size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant