Skip to content

dashboard

The authenticated landing page. Renders a small system overview: total users, active users in the last 7 days, installed module list, Python version, and health-check results.

It's intentionally simple — a place for new installs to land that proves the pipeline is wired up. Replace it (or set SM_MODULES_ENABLED without dashboard) once you have your own home page.

ModuleMeta

FieldValue
nameDashboard
route_prefix/api/dashboard
view_prefix/dashboard
depends_on["Users"]

Routes

View

Method + pathInertia componentPermission
GET /dashboard/Dashboard/Homeauthenticated user (any role)
GET /dashboard/doctorDashboard/Doctorauthenticated user (any role)

/dashboard/doctor is a browser mirror of make doctor — it shows the same module list, static checks, dev-server and environment info from the stats payload. The route itself only requires login; its sidebar link is admin-only (see Menu).

API

Method + pathReturnsPermission
GET /api/dashboard/statsdict (see below)authenticated user (any role)

/api/dashboard/stats is what the page itself calls; you can hit it from your own UI or scripts. Response shape:

json
{
  "total_users": 12,
  "active_users_7d": 3,
  "module_count": 8,
  "system_info": {
    "python_version": "3.12.4",
    "modules": ["Auth", "Users", ...],
    "health_checks": {"database": "ok", "redis": "ok"}
  }
}

The result is cached process-wide for 30 seconds. If you mutate something that should change the numbers (e.g. seed users from a script), call dashboard.stats.invalidate_stats_cache() to clear it on the next call.

LabelURLIconSectionOrder
Dashboard/dashboard/homeSIDEBAR10
Doctor/dashboard/doctorstethoscopeADMIN_SIDEBAR90

Permissions

(none registered) — the page is gated by authentication only, via the users module's AuthMiddleware.

Inertia pages

  • Dashboard/Home.tsx — single page rendering the stats card, system info card, and welcome card. Kept simple on purpose so it's a useful starting template for a custom landing page.
  • Dashboard/Doctor.tsx — the make doctor mirror (module list, static checks, dev-server + environment info).

Locales

Top-level keys in dashboard/locales/en.json:

  • home.title, home.welcome_message, home.description
  • home.stats.total_users, home.stats.active_users, home.stats.modules
  • home.system_info_title, home.system_info.python_version, home.system_info.health_checks, home.system_info.modules
  • home.welcome_card_title, home.description_body

Extending it

The bundled dashboard renders a fixed set of cards — dashboard/stats.py returns a hardcoded shape and the module exposes only register_routes + register_menu_items. This is intentional: there is no register_dashboard_cards hook or card/widget registry, and the module deliberately keeps no extension surface so it stays a small, predictable landing template rather than a framework subsystem to maintain.

To show app-specific tiles, build your own dashboard page in your module rather than contributing to this one:

  • Add an Inertia view route + page (register_routespages/Home.tsx) and a sidebar entry (register_menu_items), exactly like any other module page.
  • Make it the post-login landing page by pointing users.login_redirect_url at your route (see Replacing it). You can drop the bundled dashboard entirely via SM_MODULES_ENABLED minus dashboard.
  • Your page can still reuse this module's data — call GET /api/dashboard/stats for the system overview alongside your own module's endpoints.

Resolved as by design (GH #203): consumer modules build their own dashboard page; the bundled one is not a contribution point.

Replacing it

If you want a different post-login landing page, set users.login_redirect_url in the admin settings UI (or via smpy settings import-from-env from SM_USERS_LOGIN_REDIRECT_URL) to your route. You can keep the dashboard module installed for the menu entry, or set SM_MODULES_ENABLED without dashboard to drop it entirely. The users module auto-detects whether dashboard is installed; if not, it redirects to the first other module that exposes view routes (e.g. the GIS module on apps like smpy_gis), falling back to / only as a last resort.

Released under the MIT License.