Notechondria
Version: 0.1.20 Build Date: 2026-04-15T00:00
What's Changed
Docs — per-app server split + storage model (URGENT)
-
The old single-file
docs/server/backend.mdis now an overview that delegates to three per-app deep dives, each with example request/response payloads:docs/server/creators.md— accounts, sessions, OAuth, API keys, settings, identity-code verification.docs/server/notes.md— notes, courses, planner events, calendar feeds, recycle bin, attachments, activity heatmap, version history. Includes thenotes/services.pyhelper inventory.docs/server/mcp.md— MCP tool surface, 21 tools, API-key auth, 39 tests.
-
New
docs/development/storage_model.mddocuments how user data is laid out across PostgreSQL + R2 (backend) andSharedPreferences(frontend). Covers the seven keys per app (local_settings,local_drafts,local_courses,local_stats,local_cache,local_logs,session), the frontend-backend reconciliation points, and the "local_draftsvslocal_cache" distinction. -
docs/SUMMARY.mdindexes the new per-app server docs + the storage-model doc.
Login window shows API base domain (3 apps)
-
The Login dialog's previously-empty or generic description line
now reads
Signing in to <host>, derived from the user's currentapi_base_url. Applies in editor / planner / portal via a shared_apiHostSubtitle(apiBaseUrl)helper and a newapiBaseUrlparameter on each app's_AuthHub.
Settings — API base URL locked when signed in (3 apps)
-
The API base URL
TextFieldin Settings is nowenabled: falsewhen_isAuthenticated, wrapped in aTooltipthat explains "Log out before changing the API base URL. A logged-in token is only valid against its issuing backend." The input also shows a helper lineLocked while signed in. Log out to change.
App preferences rename
-
The editor app's settings section previously titled "Editor
preferences" is now "App preferences" — same content, same auto-save
behavior, but neutral wording so the widget can be reused across
editor / planner / portal once the "Global reusable components"
refactor in
docs/TODO.mdlands. -
frontend/AGENTS.mdbullet updated accordingly.
Bug fixes (editor_app)
-
Session expired silently ("Initial load used offline fallback:
Invalid token") — when the initial data load hits a DRF
Invalid token/Authentication credentials were not provided/token_not_validerror, the app now clears the persisted session (_token,_profile, andnotechondria.session) and logsSession expired — signed out. Please sign in again.instead of silently dropping into offline mode with a stale identity. -
OAuth bind 401 with confusing "Use /api/v1/auth/bind/google/"
backend message — the bind callback path in
frontend/editor_app/lib/app_shell.dart_handleOAuthCallbackused to fall through to the plain login endpoint withintent=bindwhen_tokenwas null (session expired between clicking the button and the OAuth provider redirecting back). The backend rightly refused that with the pointer at the bind endpoint. The frontend now short-circuitsintent == 'bind' && _token == nullwith a user-visible "Sign in first, then try linking the account again" snackbar, so the user gets a coherent error instead of an apparent backend bug.
Files Changed
Docs
docs/server/backend.md— slimmed to an overview pointing at the three per-app docs.docs/server/creators.md— new (detailedcreatorsapp doc).docs/server/notes.md— new (detailednotesapp doc).docs/server/mcp.md— new (MCP server doc).docs/development/storage_model.md— new (storage model).docs/SUMMARY.md— re-indexed server + development sections.
Frontend
VERSION— bumped 0.1.19 → 0.1.20.frontend/editor_app/lib/core/helpers.dart,frontend/planner_app/lib/core/helpers.dart,frontend/portal_app/lib/core/helpers.dart—_kAppVersiondefault bumped to match.frontend/editor_app/lib/components/auth_dialogs.dart— added_apiHostSubtitlehelper +apiBaseUrlparameter on_AuthHub; Login dialog uses the subtitle.frontend/planner_app/lib/modules/settings.dart— same helper + parameter inline (planner keeps_AuthHubin this file, not in a separatecomponents/file).frontend/portal_app/lib/modules/settings.dart— same.frontend/editor_app/lib/modules/settings.dart— wiredapiBaseUrlinto_AuthHub; renamed "Editor preferences" to "App preferences"; wrapped the API baseTextFieldin aTooltipand setenabled: !_isAuthenticated.frontend/planner_app/lib/modules/settings.dart— same lock-tooltip treatment on the API baseTextField.frontend/portal_app/lib/modules/settings.dart— same.frontend/editor_app/lib/app_shell.dart— invalid-token detection- session clear in the initial-load path; bind-without-token
short-circuit in
_handleOAuthCallback.
- session clear in the initial-load path; bind-without-token
short-circuit in
frontend/AGENTS.md— reflects the "App preferences" rename.
Notes / follow-ups
- The two bug fixes above are in editor_app only this round.
Planner and portal have the same offline-fallback and bind
callback paths (inlined in their respective
app_shell.dart); they should get the same treatment in a follow-up round. - The "Global reusable components" URGENT TODO item (shared
Sidebar/Navigation, Debug window, Login window, App preferences)
is still pending — the rename and shared
_apiHostSubtitlehelper are the only steps toward it this round. - The splash animation / chemistry work and the debug-log terminal UI remain open in TODO.md.