0.1.105 — four user-reported bug fixes
Four small, orthogonal fixes from a user-bug report. Each lands as a separate change inside this round; nothing here is destructive or schema-changing.
1. Casdoor probe log surfaces the probed URL
Symptom (user-reported):
00:10:42 Warning Editor.Auth/casdoor.config.probe:
Casdoor SSO surface unavailable:
Editor.Auth/casdoor.config.probe — API route not found.
The bare "API route not found" string didn't tell the operator
which backend host was missing the route. Same string appeared
whether the SPA was hitting prod, a stale Render deploy, or
localhost with the wrong port — useless for triage.
Fix in editor_app/lib/core/initial_data.dart,
portal_app/lib/core/initial_data.dart, and
planner_app/lib/core/initial_data.dart: the getCasdoorConfig
catch block now resolves
_httpClient?.baseUrl ?? '<unresolved>' and appends
(probed <full URL>) to the warning. The new line shape:
Casdoor SSO surface unavailable:
Editor.Auth/casdoor.config.probe —
API route not found
(probed https://notechondria.trance-0.com/api/v1/auth/casdoor/config/).
So the operator can immediately tell which deploy is stale.
2. "Local drafts only" filter no longer fetches public notes for anonymous users
Symptom: signed-out users picking "Local drafts only" from the all-notes scope dropdown still saw public notes underneath.
Root cause in editor_app/lib/core/note_loading.dart:
// Anonymous users always see public notes (scope=all).
final effectiveScope =
isAuthenticated ? (scope ?? _learnerSearchScope) : 'all';
This silently rewrote 'local' → 'all' for anonymous users, then
listNotes happily returned public-feed rows. Fixed: anonymous
users now respect 'local' (clears _learnerNotes + skips the
backend call) and fall back to 'all' only for the other three
scopes (personal / private / public — none of which apply
signed-out anyway):
final pickedScope = scope ?? _learnerSearchScope;
final effectiveScope = isAuthenticated
? pickedScope
: (pickedScope == 'local' ? 'local' : 'all');
The widget side (learner.dart) already routed effectiveScope == 'local' to showCloudNotes = false, so once the loader respects
the choice, the page updates immediately and the public-notes block
disappears even when local drafts are empty.
3. Default Inbox pinning + sidebar diagnostic breadcrumb
Symptom (user-reported): "Default index folder on side bar is still not rendered on web interface."
Root cause: the sidebar's pinned filter in
editor_app/lib/core/build_helpers.dart only matched courses with
is_default == true. Older builds and some sync paths (manual
_createCategory while offline, archive restore, an older seeder
version that wrote is_default: false, a backend payload that
dropped the flag during a renamed-but-still-Inbox column rewrite)
could leave a row titled "Inbox" with the flag off. The pinned
filter came up empty → category vanished from the top of the
sidebar → user saw an unpinned, draggable Inbox or no Inbox at
all until tapping "Restore default Inbox" in Settings.
Fix:
- New
isCategoryPinned(Map<String, dynamic> course)helper on_AppShellBuildHelpersX. Pins whenis_default == trueOR when the title casefolds to"inbox". Both compact + wide layouts inbuild_helpers.dartroute through it. - New
emitSidebarPinDiagnostics({required total, required pinned})helper on the same extension. Emits a debug-log line per sidebar rebuild withtotal=...andpinned=...counters. Goes towarningwhenpinned == 0 && total > 0— that case is the symptom, recorded the moment it happens. - Filter the Debug Log card by source
Editor.UI/sidebar.pin_diagnosticsto see the breadcrumbs in flight.
How to debug from here: open the editor → Settings → Debug log →
filter by sidebar.pin_diagnostics. Healthy state shows
total=N pinned=1 at debug level. If you see pinned=0 warnings
with total>0, the seed flag got stripped somewhere — tap
"Restore default Inbox" in Settings to reseed; if that doesn't
help, the cloud Course row's is_default is wrong on the backend
and needs a fix on the server side (run a one-shot Course.objects .filter(creator_id=..., title__iexact='inbox').update(is_default=True)).
4. Portal Settings: Debug log card rendered inline
Symptom (user-reported): "On portal app settings page, the debug is not listed as independent widget as the editor settings does."
Editor's settings page rendered DebugLogCard inline as a card on
the main scroll (level filter + terminal + copy + ping). Portal's
hid it behind a "Debug" ListTile that pushed _DebugPage —
fine for focused work but bad for at-a-glance ops.
Fix in portal_app/lib/modules/settings.dart:
- New
_buildInlineDebugCard(BuildContext)method matching the editor's_buildDebugSectionshape exactly: whenwidget.debugLogController != null, render the sharedDebugLogCard; otherwise fall back to a minimal "uiLogs" card. - Mounted on the main settings scroll between
_buildSettingsMenuand_buildLogoutCard. - The existing "Debug"
ListTile→_DebugPagepush is kept so the focused subpage still works.
Verification
flutter analyzeclean acrosseditor_app,portal_app,planner_app. No new errors / warnings from the four fixes.- The Casdoor-probe URL change is a pure log-shape upgrade, so no test surface needed.
- The all-notes filter fix is an inverted condition; the existing
rendering branches in
learner.dartalready cover theeffectiveScope == 'local'path with the empty-state Card. - The Inbox pin fix is purely additive — the
is_default == truecheck still works; we just OR in the title fallback. Existing flow unchanged for healthy data. - The portal debug card mirrors the editor's already-tested code path; no new logic.