Changelog
Release history
Every published release, written for users. The full technical detail lives in the source repository.
- v2.4.0Latest
StatHall goes free and open-source — no subscription, donations and self-hosting
What’s changing for you
StatHall takes an important turn: there is no pricing and no subscription anymore. The project fully embraces what it is: a useful tool, offered simply, without a binding service relationship.
Three paths, no commitment
- Free hosted instance —
app.stathall.comstays free, within reasonable usage limits (“fair-use”) that protect the shared infrastructure. The service is provided “as-is”, with no availability guarantee and no contractual support. - Open-source self-hosting — StatHall’s code is released as open-source (AGPL-3.0 license). If you need more than fair-use, or prefer to keep your data on your own infra, run your own instance with Docker Compose — no limits, no dependency.
- Donations — funding the project is now voluntary: Buy Me A Coffee and GitHub Sponsors. No strings attached.
What about the Pro tier / payments?
The paid Pro tier and card payments are removed. No more “upgrade to Pro”, no monthly subscription, no sales contract (the terms of sale are gone). Instead, a “How it works” page simply explains the model.
Need a higher quota, a specific connector, or a hand? Get in touch — we look at it case by case, with no commitment.
Founding supporters
Early Buy Me A Coffee supporters keep lifetime recognition and an extended quota profile. Thank you.
Under the hood
- Removal of the payment integration and related data.
- Existing quota limits become fair-use guardrails, with no pricing attached.
- Free hosted instance —
- v2.3.0Grouped Inbox by type + Team / All / Demo filter for admins
What’s new for you
Two major additions to declutter the cockpit when you track many targets, plus a long-awaited keyboard detail.
The Inbox now groups items intelligently
Until now every entry showed separately: a release shipped on iOS and Android meant 2 rows, and a recurring anomaly flooded the feed. The Inbox now applies a grouping rule tailored to each type:
- New versions — a single tile per version, listing the
impacted OS with their release date (e.g.
v1.2.1 · iOS 05/17 · Android 05/18). Sorting uses the most recent date. - AI summaries — a single tile per target per day (the Apple / Google / Global scopes are merged, the most complete one is shown).
- Anomalies — when the same anomaly recurs for a target, a single
tile shows an occurrence counter (
N×) and the date of the last occurrence, with the highest severity. Expandable to act on each occurrence; a one-off anomaly stays a regular actionable card.
Team / All / Demo filter, everywhere (admin accounts)
An administrator overseeing several accounts was flooded by other teams’ feeds and by demo targets. A new global selector now appears at the top of the screen for admin accounts, with three modes:
- Team — only your internal team’s targets (default).
- All — all real targets, excluding demos.
- Demo — demo targets only (debug / showcase).
The filter starts on Team at every new session, then your choice is remembered for the current session and applies everywhere: Inbox, catalogue, applications, servers, dashboards, the rail’s alert counter and the target picker. Demos no longer pollute the standard view.
Keyboard shortcut on Windows / Linux
The shortcut to open search already worked with Ctrl+K on Windows and Linux, but the interface only showed the macOS version (⌘K). The keyboard hint now adapts to your system:
⌘Kon Mac,Ctrl+Kelsewhere.On mobile
The mobile app aligns its Inbox with these rules: anomalies grouped by type (counter + last occurrence) and summaries grouped by day. Versions were already grouped by OS.
Under the hood
- No database migration.
- Grouping rules centralised server-side for the web cockpit.
- New versions — a single tile per version, listing the
impacted OS with their release date (e.g.
- v2.0.0-mobile-rc.10Mobile rc.10 — notifications settings rebuilt + alignment with SPA
What changes for you (mobile)
Mobile iteration 2.0.0-rc.10 completes the UX/UI rebuild aligned with the “Lecteur Mobile” design and the SPA V2.2.x. Two crashes are fixed, the notifications settings screen becomes functional, and the vocabulary is aligned with the SPA (“AI Summary” → “Pulse”).
2 Sentry crashes fixed
- Tap on “Notification settings” in Account crashed the app at page
open (
XamlParseExceptionon a missing resource key). Three internal references fixed, the screen now opens cleanly. - 30-day trend on an app’s detail view crashed at chart render in some contexts (25 Sentry events). Root cause: uninitialised X axis labels passed to the charts library. Array now properly seeded with empty strings, no more crash.
Notification settings now usable
The granular “Settings per event type” screen is now openable from Account → dedicated row. It exposes a 6 types × 3 channels grid (P0/P1/P2/AI summaries/Versions/System × Push/Mail/Quiet), a quiet hours section (DND with time range, P0 always allowed) and a test push button with immediate toast feedback. Icons per type (red/amber/ indigo alerts, purple sparkles for Pulse, etc.) now render correctly.
AppPickerSheet: apps vs servers + anomaly badge
The “Choose a target” sheet now visually distinguishes applications (rocket icon, indigo soft background) from servers (server icon, grey soft background). The bare “0” to the right of each target is replaced by a red “N anom.” badge, visible only when the target has open anomalies — nothing otherwise (readability). Labels go from “Choose an app / All apps” to “Choose a target / All targets” to reflect the polymorphic (apps + servers) list since V2 LOT 2.
Vocabulary aligned with the SPA — “Pulse”
The SPA V2.2.1 renamed “AI Summary” to “Pulse” (Pulse reviews, Pulse app, Pulse server). The mobile app follows in rc.10: Inbox filter “Summaries” → “Pulses”, teaser card ”✦ AI Summary” → ”✦ Pulse”, page title “AI Summary” → “Pulse”, “Summary history” → “Pulses history”. Consistent across SPA Inbox and mobile.
Activity timeline backed by richer history
The mobile Activity screen previously showed only release 2.0.0-rc.7 (the last one recorded in DB). The backend now seeds 72 deployment history entries (12 backend versions × 6 services: api, frontend, marketing, worker-default, worker-sync, beat) covering the past 22 days (V2.0.0-rc.8 → V2.2.9). The mobile Activity screen now shows a realistic history alongside the store releases of demo apps.
Under the hood
- Backend adds the
kindfield (application | server) to the mobileAppCardschema, propagated fromSupervisedTarget.kind. Lets the mobile app distinguish polymorphic targets. - New CLI
seed-demo-release-events(idempotent, skipped when ≥ 30 rows already in DB) to enrich the Activity history. - Mobile bumped to
2.0.0-rc.10/ build 41. Android build = 0 errors, 455 xUnit tests green. - No DB migration.
- Tap on “Notification settings” in Account crashed the app at page
open (
- v2.2.3Polymorphic favorites + in-app inbox — your custom cockpit
What changes for you
This release turns the left rail into a real personal cockpit: pin your apps, servers, favorite pages, and receive notifications in a centralized in-app inbox.
Pin any screen
The ⭐ button now appears in every page header: on app pages, server pages, target tabs (Reviews, Crashes, AI…), and global pages (Activity, Catalogue, AI Digest, Rules). One click pins the screen to your rail; one more click unpins it.
Glanceable pastilles
Rail vignettes (40×40 px) carry two visual cues:
- Type icon top-left (rocket for app, server for server, shield for admin view, filter for Inbox filter…)
- Purpose icon centered (MessageSquare for Reviews, AlertOctagon for Crashes, Sparkles for AI digest, etc.)
- Initials at the bottom to distinguish multiple favorites of the same type (DF, AS, PW…)
On hover, a rich popover shows the full label, category, target tab and three actions (Open / Rename / Unpin).
In-app inbox
The bell at the bottom of the rail becomes functional: an unread count badge (polling every 30 s), one click opens a side drawer with all your workspace notifications.
Sources at launch:
- Anomalies opened (P0/P1) — notify owners and co-owners
- Anomalies acknowledged by another user — notify watchers
- Anomalies resolved by another user — notify watchers
For each notification you can: mark as read (click), delete (✕), mark all read, clear all read. Clicking opens the target page directly.
Live counter sync
When you mark an anomaly notification as read, the bell badge decrements immediately. When you acknowledge an anomaly in Inbox, the ⚠ P0 badge syncs. Both counters stay consistent via automatic cache invalidation.
Under the hood
- New alembic migration
c1f7e2b8d4a6(polymorphic favorites:kind,target_url,target_id,target_section) - New alembic migration
c1f7e2b8d4a7(user_notificationstable with own-user RLS + partial index on unread) - 6 REST endpoints for the inbox (list, unread-count, read, mark-all-read, delete, clear-read)
insert_notificationhooks inservices/anomalies.py(dedicated session, isolated from main transaction)- 18 additional backend tests — 506 tests passing total
This release is backward-compatible: your existing pinned views (Inbox filter) stay intact (default
kind=inbox_filter). - v2.2.0-rc.1« Inbox + Scope » UX overhaul — Inbox is home, hierarchical groups, « / » shell mode
What changes for you
After four rapid cockpit iterations in 24 hours (V2.1.0), StatHall ships a deep UX overhaul driven by an external ergonomic audit. The « Inbox + Scope » pattern rests on three pillars: triage first, keyboard command, scope by group.
Inbox = home (replaces Global overview)
The landing screen is now the Inbox: a triage list of open anomalies. You know in 5 seconds what deserves your attention this morning — no need to scroll a dashboard to spot reds.
- Enriched statuses: open / acknowledged / snoozed / resolved. You can snooze an anomaly until tomorrow and it automatically pops back into the Inbox when the window expires.
- Empty = « All quiet »: if nothing’s pending, the Inbox says so plainly instead of rendering a dashboard to scan.
/portfolioredirects to/inbox— your bookmarks keep working.Unified combobox with « / » shell mode
The target picker in the topbar becomes a central combobox combining three modes:
- Idle display = « you are here » (current target, active scope, or current view).
- Free mode (⌘K or click) = favorites, recent, scopes, groups, actions, fuzzy multi-token search.
- Shell mode (starts with
/) = Unix-like path grammar./demo-fitness/cra+ Tab + Enter → you land on Demo Fitness, Crashes tab./lab/lab-debian/→ catalogue scoped to Lab Debian. Tab completes the longest common prefix or cycles through matches.
The
?shortcut opens the full cheat sheet. Stop click-clicking to navigate — type the path.Hierarchical target groups
You can now group targets in a tree:
Client > Solution / Environment > targets. Free semantics — client account, product line, env prod/staging/dev, whatever.- A target can belong to multiple groups (product × environment matrix supported).
- Access rights are inherited automatically to descendant groups and their members (on by default; opt-out per group).
- All main views (Inbox, Catalogue, Activity, AI digest, Rules) are filtered by the global scope — pick « Acme » in the combobox and everything narrows down to that client.
- The scope lives in the URL (
?scope=group:acme), so a link preserves the full context.
5 main views
- Inbox (
/inbox): anomaly triage, statuses, filters, detail drawer. - Activity (
/activity): unified timeline of releases, anomaly transitions, system events, grouped by day. - Catalogue (
/catalogue): targets grid withgroupBy = group / type / health, replaces/apps+/servers. - Global AI digest (
/ai): weekly cross-scope digest aggregating everything you can see — critical anomalies, releases, app sentiment, server patterns. - Rules (
/rules): 9 default anomaly rules editable by admins. Inherit along the group tree.
Per-target AI summary — Reviews AND Activity
The « AI summary » tab on an app now has a Reviews / Activity sub-toggle:
- Reviews = store review summary (sentiment, pros/cons, reported bugs) — like before, migrated from the old Summaries tab.
- Activity = new: textual summary of events, crashes, anomalies, recurring patterns of the target.
Servers get an equivalent « AI summary — Activity » tab (systemd / apt events, reboots).
Email opt-in: a new block in
/account/email-subscriptionslets you opt in to receive the global digest and per-target summaries by email at your chosen cadence (never / weekly / monthly). The generation cadence target-side stays in the hands of the target’s owner (admin panel of the app / server / group).Admin mode clearly separated
When you enter the admin panel, a purple banner « Admin mode » appears in the topbar and a dedicated 3-group sidebar (Management / Product / System) takes the main navigation slot. A dedicated button lets you exit back to your daily supervision. No more confusion between the two spaces.
Personal pinned views
You can pin a filtered Inbox view (e.g. « P0 from Acme client ») and recall it with one click from the rail. Pinned views are persisted in the database, available across all your devices.
Under the hood
- The 5-item rail replaces V2.1’s 4 entries (Overview, All apps, All servers, Anomalies). Overview views are reachable via the combobox.
- The « Read-only » banner becomes a discreet, dismissible note (per session).
- The version number in the topbar opens an integrated changelog drawer.
Nothing to do on your end — the new ergonomics applies on your next sign-in. Legacy
/portfolio/apps/servers/apps/.../summariesredirect to the new routes. - v2.2.2Inbox + Scope finish line — cross-source AI summaries, live anomaly rules, mobile responsive
What changes for you
The V2.2 “Inbox + Scope” redesign ships in its final form: this release adds everything that was still missing to make the version production-stable and usable on the go.
Cross-source AI summaries
Four new AI endpoints power the UI:
- Weekly AI digest (cross-scope): automatic brief every Monday morning with TLDR, hotspots and watch-list across all your supervised targets.
- App pulse — global view: per-app health digest (strengths, weaknesses, top recommendation).
- Reviews pulse: 3 adaptive columns Global / iOS / Android depending on the app’s platforms, each with sentiment, positives, negatives, bugs reported, feature requests, tags and verbatims.
- Server pulse: 7-day activity summary (incidents, highlights, operational recommendation).
All summaries are cached server-side for 1 hour. Without an LLM provider configured, the UI shows a structured fallback (no blank page).
Anomaly rules applied in real time
The anomaly rules you edit from
/rulesare now read directly by the detection engine (cascade target > group > type > all). A new Preview button lets you simulate “how many anomalies would this rule have raised over the past 30 days” before saving — calibrate your thresholds with confidence.Enriched
/command bar- Member targets: in path mode
/lab/lab-debian/, the menu now lists targets that are members of the group, not just sub-groups. - Inline group editing: press ⌘+. on a group node to rename, move or delete the group without leaving the command bar.
Polished Catalogue & Activity
- Catalogue: each card now shows the latest released version of the app (Apple or Play, whichever is most recent).
- Activity: new 5-column strip above the feed (Events 7d · Anomalies · Releases · System · today-by-hour sparkline).
- AI summary: last-generated timestamp shown in relative format (“2h ago”) with a live indicator during regeneration.
Shared pinned views
You can now share a pinned view with the rest of your workspace: tick “Share this view” when pinning. A small 👁 icon distinguishes public views in the rail. Read-only for other members.
Mobile responsive
The interface is now usable comfortably below 1024 px: a slide-over drawer replaces the side rails, accessible via the hamburger in the top-left. Tablet and mobile no longer lose any functionality.
Under the hood
- New alembic migration
c1f7e2b8d4a5(pinned_views.is_publiccolumn + extended RLS policy for public reads). - Cross-source LLM generation via the providers you’ve already configured (DeepSeek / OpenAI), no hidden cost.
- Beat job Monday 06:00 UTC:
email.send_global_ai_digestsenriched with actual content (tldr, hotspots, watch list) instead of a placeholder. - Refactored global scope to React Context (memoization + cross-page consistency).
- Test suite: 488 backend tests + 58 frontend tests + Playwright e2e scaffolding. No regression on V2.1 screens.
This release stabilizes V2.2 in its final form; we recommend updating as soon as possible.
- v2.2.4App owners can finally edit their own apps + filterable Apps/Servers admin
What changes for you
This release fixes a bug that prevented non-super-admin app owners from editing their own apps, and overhauls the Apps/Servers admin console with a per-user filter for clarity when a workspace hosts several teams.
Own an app? The “Configure” button works at last
If you are owner or co-owner of an app, the Configure button in the app header now opens the proper options page: data sources, health settings, team, AI summary, danger zone. No more silent redirect to the home — the trap hit every click on Configure before.
Same fix for servers: the Configure button correctly routes owners to the server config page without going through global admin.
Apps / Servers admin overhaul
The Admin › Apps and Admin › Servers pages gain:
- An owner filter bar Team / All / User. By default you only see apps and servers owned by the StatHall team (super-admins). Pick a user to switch to their apps/servers.
- A search field on name or slug.
- A sortable Owner column with the owner’s email + a TEAM (indigo) or CLIENT (purple) badge computed automatically.
- A live “N results” counter on the right.
The filter state is persisted in the URL: share
/admin/apps?owner=42to point straight to a user’s apps.”Viewer” label renamed to “User”
On the Admin › Users page, the global
userrole displayed as “Viewer”. The label was misleading: a user can be owner of their apps and have full rights on them. The new label User is more neutral.Inbox: each anomaly now shows its target
Every Inbox row now shows
Application · App nameorServer · Server nameunder the type. The “Open context” button correctly routes to the app Anomalies page or the server overview (no more broken link for servers).Group Members panel overhaul
On a group page, the Members tab now only shows effective members (no more mixing with the full list of visible targets). A ”+ Add targets” button opens a modal with search, app/server filters, multi-select and “Select all visible results” bulk action.
Under the hood
- 0 DB migration, purely frontend fix + backend permissions preserved (Postgres RLS unchanged).
- New reusable
UserPickerComboboxcomponent (keyboard-first: arrows, Enter, Esc). - New
useGroup(id)hook for group members resolution. - 58 frontend tests green.
- v2.2.5Group-by-group — actually works now
What changes for you
The catalogue’s “Group by: Group” mode finally renders one section per group with the matching targets. Until now the toggle collapsed everything into a single “All” section — the feature was inert since V2.2.0-rc.1.
Sections per group + Ungrouped
In
/catalogue, pick Group in the “Group by” selector. You now see:- One section per group you administer or have access to, with the matching target cards inside.
- A final “Ungrouped” section for orphan targets (not attached to any group).
A target belonging to multiple groups appears in each matching section (standard “group-by” semantics).
Under the hood
- The
GET /groupsendpoint now exposes the direct member list for each node (single aggregated SQL query, RLS-aware). - No DB migration, no breaking change: API payload is additive.
- v2.2.6Catalogue grouped by default + collapsible tree + group admin for its owners
What changes for you
Three improvements that make day-to-day group usage feel natural.
Catalogue opens straight in “Grouped by group”
If you can see at least one group, the catalogue defaults to the Group by: Group mode. If you prefer another mode (Type / Health), your choice is persisted in the URL (
?gb=type) and takes precedence over the auto default.Tree view expanded by default
Group sections are rendered with indentation and a collapsible chevron. The whole tree is expanded on first render. You can collapse each branch individually, or use the “Expand all / Collapse all” buttons in the toolbar.
Collapsing is cascading: collapsing a parent automatically hides its descendants.
Own a group? You can administer it
The ⚙ Configure button appears in each group section header where you have write access (owner, direct co-owner, or owner of an ancestor group with inheritance enabled). One click opens the group config page (General · Members · Access · AI Summary) — without going through super-admin admin.
Super-admin group admin stays available at
/admin/groupsfor cross-account operations.Under the hood
- A
can_writefield is added to each group node in the API (single batch SQL query for all visible groups). - New
/groups/:id/configroute not gated byRequireAdmin— Postgres RLS guarantees server-side access control. - No DB migration.
- A
- v2.2.7Web Inbox — anomalies + summaries + versions in one stream
What changes for you
The SPA Inbox now mirrors the mobile app: a unified chronological stream mixing anomalies, AI summaries and newly detected versions. Each row opens the relevant tab on the target directly.
4 sorting tabs at the top
- All — full chronological feed (default).
- Anomalies — anomalies only (status + severity filters available).
- Summaries — weekly AI summaries only.
- Versions — newly detected releases only.
The active tab is persisted in the URL (
?kind=).Easy to scan at a glance
Each feed card carries:
- A left color stripe: red P0, amber P1, indigo Summary, purple Version.
- A badge: severity for anomalies, ✨ Summary for AI, 🏷 Version for releases.
- A pre-formatted title (“Crashes en hausse — Demo Travel App”, “Weekly AI summary”, “v1.2.1 published”).
- A context subtitle: platform/version for anomaly, themes for summary, platform for version.
Per-kind “Open context” link
The detail panel on the right shows kind-specific content and a button that routes to the right target tab:
- App anomaly → app’s Anomalies page
- Server anomaly → server overview
- Summary → app’s Pulse Reviews tab (
/ia-reviews) - Version → app’s Versions page
For anomalies, the Acknowledge / Snooze / Resolve actions stay available.
Filters and tabs
When you pick Anomalies (or All), a Status selector appears in the filter bar (Open / Acknowledged / Snoozed / Resolved / All) — the status option was moved from tabs to the filter row, for parity with mobile.
The Period filter (24h / 3d / 7d / 30d) stays visible at all times.
Under the hood
- New
GET /api/v1/inboxendpoint — cross-source feed withkinds,anomaly_status,window_days,limitparameters. - The backend service aggregates 3 sources into a single response sorted DESC by occurrence date.
- The mobile BFF keeps its separate endpoint unchanged (cursor pagination, etc.).
- 60 s auto-polling on the SPA.
- v2.2.8Catalogue tree — VS Code style path coalescing
What changes for you
Small ergonomic pass on the catalogue tree view: chains of empty ancestors are now coalesced into a single breadcrumb line, à la VS Code rendering
src/components/layouts/as one row when no intermediate folder has a direct file.Before / After
On a hierarchy
Client > Solution > Env > debian/ubuntuwhere only the leaf groups (debian, ubuntu) have direct targets, you now see:▾ Client › Solution › Env 8 included ⚙ ▾ debian 4 targets ⚙ [cards × 4] ▾ ubuntu 4 targets ⚙ [cards × 4]instead of 6 chained structural rows.
Dynamic cases
- If you add a target directly to “Client”, Client stops coalescing and gets its own row with cards.
- If a new group appears at the same level as Solution, the parent Client becomes a divergence point again (its row appears, the subtrees keep coalescing).
- Groups fully empty (no direct member, no descendant with
content) are hidden from the catalogue. They remain visible
in
/admin/groupsif you want to configure them.
⚙ Configure button
The Configure icon keeps pointing to the last segment of the breadcrumb (the group actually represented by the row). To configure a coalesced ancestor, go through
/admin/groups.Under the hood
buildTreeSectionsalgorithm rewritten in 2 passes (prune + emit).- Cascading collapse is preserved.
- No DB migration, frontend-only.
- v2.2.9Inbox — server anomalies visible + tighter rail + denser cards
What changes for you
Three user feedback items handled in one pass to perfect the cockpit’s visual consistency.
Server anomalies are back in the Inbox
Since the Inbox redesign in v2.2.7, only app anomalies (crashes, ratings, negative reviews) appeared in the feed. Server anomalies (CPU/RAM/disk/load over thresholds) were invisible, creating a mismatch with the rail’s 5 P0 badge that still counted them.
Now the rail counter matches the Inbox “critical” counter, and server anomalies appear as “Système metric élevée — Server name”. Click → server overview.
Better-anchored notification pill + larger rail icons
The red badge on the Inbox icon was positioned relative to the button (40×40 px), so it “floated” away from the actual icon. It is now anchored directly on the icon corner, with a ring that detaches it from the background.
The main rail icons (Inbox / Activity / Catalogue / AI Summary / Rules / Admin / Bell) go from 18 to 20 px with a thicker stroke. More readable on every screen.
More contrasted target tile health dots
The status dots on catalogue tiles (8×8 px) are scaled up to 10×10 px and surrounded by a colored halo. The 4 states (red disconnected, amber stale, green connected, gray pending) are finally distinguishable at a glance.
Consistent LED on the server header
The colored dot in a server header (next to the name) now matches the actual state — it used to stay green regardless of situation, which could falsely suggest a healthy server while it was actually “pending” or “disconnected”. The rendering is now identical between the header and the catalogue tile.
Agent update available — dedicated purple color
New visual signal: a connected server running on an agent version strictly older than the latest one observed across your portfolio shows a purple LED (instead of green). The color is dedicated — distinct from orange (silent server) and blue (pending status) — to avoid any confusion.
Example: if your
Runner-Seb-Nucand others run v1.0.5 whiledemo-prod-debianstays on v1.0.0, the latter shows purple in the catalogue.On the server detail (overview), the Agent version field shows a small purple
↑ v1.0.5badge next to the version number, with a tooltip recalling the target version.Dedicated blue LED for “Pending”
Servers in pending state (never connected) used to show a gray LED on the catalogue while the detail page showed a blue pill (
Pending). The two representations are now aligned on the same blue color (brand-blue), distinct from purple (agent update) and indigo (CTA).Color legend in the catalogue
An inline legend was added below the catalogue filter bar to remind what each dot means:
- Connected · healthy (green)
- Silent · watch (orange)
- Agent update available (purple)
- Disconnected · critical (red)
- Pending · never connected (blue)
- Unknown · no data (solid gray, visible like a true dot)
The counters at the top of the page (small colored dots next to “N targets”) also get a hover tooltip for the same info. The Health filter in the toolbar adds a new “Pending” option to narrow down to never-connected servers (useful during pre-deployment).
More tiles per row
The catalogue grid gains +1 column per screen size: on very wide screens you now see 6 tiles per row instead of 5, on medium screens 3 instead of 2, etc. Roughly 17% width gain per tile.
Under the hood
server_metric_highanomaly type now accepted by the SPA Inbox endpoint.- Tile dot:
h-2.5 w-2.5+ coloredring-2, no clipping in truncated names (fix for the overflow reported by user). - No DB migration.
19/05 patch — user feedback batch
A second batch of fixes shipped same day on 2.2.9 (no version bump).
Reviews — search + version filter actually work
The reviews search bar only searched within review content; typing
28.3.1or a username never matched anything. It now also looks through the title, author and version string. The Version filter dropdown was visual-only — the selection was never sent to the server. Picking28.3.1now actually filters the list.The version picker has been rebuilt: multi-select combobox with inline search, semver-descending order (newest releases on top), and we dropped the
· iOS / · Androidsuffix (the version string is universal, the adjacent Platform selector does the OS targeting). You can tick several versions and the list becomes the union.All Reviews filters now live in the URL (
?q=…&version=…&platform=… &rating=…): bookmark a view, share a link, or land here pre-filtered when coming from the Versions page.Versions → Reviews in one click
On an app’s Versions page, each row’s review counter is now a direct link to
/apps/:slug/reviews?version=X&platform=Y. No more copying the version into the filter manually.Bonus: opening a “Version published” card from the Inbox now opens the app’s Versions page pre-filtered and auto-expanded on the matching version (already shipped earlier in 2.2.9, repeat for clarity).
Inbox — same-day summaries deduplicated
AI summaries (Apple, Google, Global review scopes) generated on the same date showed up as three side-by-side rows for the same app. We now keep the Global summary (it covers Apple+Google) ; the individual scopes are still reachable from Reviews pulse.
Reviews pulse (app) — screen no longer blank
The 3-column view (Global / iOS / Android) was looking for a summary whose dates matched exactly the last 30 days. Since archived summaries cover fixed windows (7d, 30d ending on a fixed date…), the match almost always failed and every column rendered “No summary available”. It now picks the latest successful summary per scope and shows the actual period covered (“Period: DD/MM → DD/MM”).
Global AI digest — date range + richer chips
The Global AI digest header now shows the date range covered (
from DD/MM to DD/MM) on top of the “This week / Previous week / Month” label.The target chips at the bottom were thin (just a name + an icon). They now show the open P0/P1 anomaly count (red
⚠ Nbadge when0, red-bordered chip) and the latest known version. Sorted descending: targets with the most open critical anomalies come first.
Groups accessible to owners
App/server owners can now browse and manage their groups from
/groups(new entry in the “Global views” sidebar). Creating a root group is still super-admin-only (backend returns 403 otherwise), but creating sub-groups, editing, deleting, and managing members no longer requires going through the admin panel.Anomaly rules — clearer message when table is empty
The Anomaly rules page used to flatly say “0 rules · 0 active” when the table was empty, with no hint as to why (the 9 default rules should have been seeded by the V2.2 migration). It now shows an explanatory banner with the CLI command to run on the API container:
python -m app.cli seed-anomaly-rules(idempotent thanks to a unique index on the natural key).Ownership transfer email — Outlook + button polish
The square logo in the email header rendered blank on Outlook (the semi-transparent white tint is ignored → falls back to solid white, so the white “S” was invisible). We added a dark indigo Outlook fallback ; non-Outlook clients still get the original translucent overlay.
The “View the app” button in the ownership-transfer email has been rebuilt as a bulletproof button (table +
mso-padding-alt) so it keeps its padding on Outlook 2007-2019. Added a→arrow for intent clarity.Under the hood
- Backend
GET /apps/{id}/reviewsnow accepts repeated?version=(multi-values). Theqparam searches acrosscontent + title + author + version_string. AIDigestpayload exposesperiod_from+period_to. Target chips enriched withopen_critical+last_version.app/services/inbox.pydeduplicates summaries by(target_id, date(generated_at))with priorityglobal > apple > google.- New CLI
seed-anomaly-rules(idempotent via a partial unique indexuq_anomaly_rules_natural_key). - 0 DB migration; no new secret nor new dependency.
19-20/05 patch 2 — super-admin confidentiality + co-owner delete + mobile icons
Break-glass is now mandatory for super-admins
Before: a super-admin could browse and configure any application or server without asking for access, including ones they aren’t part of the team for. The “Request temporary access” button was there but purely cosmetic.
Now: a super-admin who isn’t either the owner or a co-owner of a target must request a temporary access (break-glass) to browse it just as much as to edit it. Without an active grant, the URL
/apps/:slugor/servers/:slugreturns 404. The owner gets an email every time a request is made, and every action taken by the super-admin is audited.The admin pages (users, plans, audit log, system) stay freely accessible — the restriction only applies to per-target screens.
Co-owners cannot delete an app or server
The backend already blocked deletion (owner-only), but the UI left the “Delete” button active for co-owners — the click failed with a silent error. The button is now disabled for co-owners, with an explanatory note: “Owner-only action”. To delete an app where you are a co-owner, ask the owner or request a transfer first.
Mobile — icons aligned with the SPA
The target picker on mobile showed a rocket for apps and a server rack for servers. The SPA already uses the 📱 + 🖥 emojis for the same distinction. Both now align on 📱 (application) + 🖥 (server), with the Aurora-colored square kept to differentiate visually.
To roll out on iPhone via
./scripts/deploy-ios-device.shwhen ready — mobile version 2.0.0-rc.12 (build 43). - v2.0.0-rc.8Mobile app — new 5-tab cockpit and design system refresh
What’s new for you
A more cohesive mobile app
The StatHall Mobile app (iOS + Android) receives a full visual refresh. Navigation between screens is smoother, titles and cards now share a common style (Inter Tight type, Aurora palette), and the native iOS navigation bar is finally aligned with the rest of the app.
A 5-tab cockpit
The navigation bar goes from 3 to 5 tabs:
Inbox · Targets · Health · Activity · Account. The “Apps” tab reverts to its generic name “Targets” and shows all your applications and servers by default — you can filter afterwards if needed.New “Health” tab
At a glance, see the global health score of your portfolio, broken down into three dimensions (tech / business / adoption), and the list of targets that need attention first (score under 70).
New “Activity” tab
A real-time timeline combines deployments, store version detections (iOS / Android), and agent events (systemd, APT security updates…) into a single feed. Filter by type to focus on what matters.
App ↔ server links visible in the app
On an application page, a “Linked servers” section lists the servers hosting it (
hosted_onrelationship). Conversely, the server page shows a shortcut to the parent app. Tap any card to jump straight to its details.Under the hood
A few new backend touch-points feed these screens (health overview, activity feed, target links) with no impact on your existing data. The aggregation runs entirely within your tenant — nothing leaves your perimeter.
No action required — this version reaches the mobile app automatically on your next open.
- v2.0.0-rc.7StatHall V2 — universal cockpit, Pro plan, and super-dashboard
What’s new for you
A Pro plan to support the project
This release introduces the Pro tier at €12/month (VAT not applicable, art. 293 B of the French Tax Code), positioned as participation in infrastructure costs rather than a commercial product with an SLA. The Free tier stays unchanged for standard usage. Founding supporters automatically receive 6 months Pro free.
The super-dashboard
A new view brings all your supervised targets — applications and servers — together on a single board. You can now link an app to a server (
hosted_on,depends_on,relatedrelationships) to see the overall health of a group of interdependent services at a glance.Consumption tracking and access codes
A new Usage page details your daily consumption (API calls, ingest events, emails) and quota status. A new Access Code page lets you redeem a promo or grant — handy for early adopters and ambassadors.
Zero-downtime deployments
Under the hood, StatHall updates now deploy via rolling restart (new container starts before the old one stops), with automatic rollback on failure. A new Release History page in the admin traces each deployment.
Expanded documentation
Three new product pages detail Unix servers, the super-dashboard and the push-only agent. Quickstart guides target mobile devs, DevOps and freelancers. The Security page is updated with agent principles.
Strengthened security posture
Daily off-site encrypted backups (weekly / monthly rotation over 3 months), a Traefik maintenance page displayed during downtime, and traceable deployment history to ease diagnosis.
As always, these changes roll out gradually and remain backward compatible with your existing data. No action required.
- v2.1.0-rc.2Sidebar overhaul — persistent Rail + contextual Panel
What’s new for you
A redesigned left sidebar
The left sidebar of the web cockpit is fully redesigned with two columns:
- Persistent thin rail (56px) with global navigation icons: Overview, All apps, All servers. Always visible — switch views in one click from anywhere.
- Contextual panel (200px) to the right of the rail that adapts
to the route automatically:
- inside an app → app sub-nav (Dashboard, Reviews, Crashes, Versions, Roadmap, Anomalies, AI summary)
- inside a server → server sub-nav (Overview, Events)
- in admin panel → 3 groups (Management / Product / System)
- on overview routes → Portfolio / Apps / Servers shortcuts
- on profile → Account, Feedback, Donate
No need to use the top target picker to navigate between supervised targets anymore — one click on a rail icon does it.
Critical anomalies badge
A new ⚠️ button in the rail shows a red badge with the count of open P0 anomalies across all your targets. Click → jumps to the cross-target view to ack them.
Permanent admin shortcut
For administrators, a dedicated ⚙️ button in the rail leads to
/adminin one click from anywhere.Ergonomic improvements (shipped same day)
- More compact cards on “All apps” and “All servers” views: denser grid (up to 5 cards per row on wide screens).
- Clickable KPI tiles on those views: click “Connected” to filter the grid to only show connected servers. Same for “Anomalies”, “Demo”, “Pinned”.
- Clickable Portfolio KPIs: “Applications” → /apps, “Servers” → /servers, “Open anomalies” → Anomalies view.
Under the hood
- A single shell replaces the 5 previous layouts (app, server, admin, global views, profile) — simpler to maintain.
- The menu stays keyboard-accessible and screen-reader compatible (navigation role, tooltips, visible focus).
No action required — the new ergonomics applies automatically on your next sign-in.
- v2.1.0-rc.1Universal cockpit — ergonomic overhaul
What’s new for you
Three overview dashboards to supervise everything
The web cockpit gains three new user dashboards, accessible directly from the target picker at the top:
- Overview (
/portfolio) — a glance at everything: aggregated KPIs, top critical anomalies, your apps and servers side by side. - All apps (
/apps) — the complete list of your mobile apps with search, stats, and quick access to cross-app reviews and cross-app anomalies as secondary tabs. - All servers (
/servers) — the complete list of your Unix servers with Connected / Silent / Disconnected stats.
Each card is clickable and takes you straight to the relevant app or server dashboard.
A smarter target picker
The top picker (“Pick a target”) gets four new features:
- Global views at the top of the menu: one-click to the three global dashboards.
- Favorites — pin your most-used targets via the star on hover, they always stay at the top of the menu.
- Recent — your 5 most recently visited targets are remembered automatically.
- Health dot on each target: green if all is well, orange for caution, red for critical anomaly. Plus a discreet grey dot when data hasn’t been synchronized for more than 24h.
The menu stays readable even if you supervise dozens of targets, thanks to cmdk search + pinning.
Reorganized admin sidebar
For administrators, the admin panel (
/admin) is now organized in three clear thematic groups:- Management: Apps, Servers, Users, Approvals.
- Product: Pricing plans, Access codes.
- System: System, Audit, Push diagnostics.
No more duplication between the sidebar and the top-right user menu — the latter now only keeps a single
Admin panelshortcut.Admin screens up to visual standard
The Pricing plans, Access codes, and Push diagnostics pages finally adopt the Aurora Valhalla design that’s consistent with the rest of the SPA: tables inside cards, standardized inputs and buttons, illustrated empty states.
Under the hood
- An
Agenttab in the server sidebar (user view) had no actual purpose (token management is admin-only) and has been removed. - A broken visual token (
bg-surface-card) that made some cards invisible has been fixed throughout the application.
No action required on your side — the new ergonomics applies automatically on your next sign-in.
- Overview (
- v2.0.0-rc.6StatHall now supervises your Unix servers too
What changes for you
A new target type: Unix server
StatHall is no longer limited to mobile applications: you can now add your Unix servers to your cockpit. A lightweight agent, installed in a single command, pushes your system metrics (CPU, RAM, disk), events (systemd services, APT security updates) and aggregated journald logs to the cockpit — without ever opening an inbound port on your server.
A dedicated server dashboard
For each connected server:
- Agent state in real time — connected, stale, or offline.
- System identity declared by the agent (hostname, distribution, kernel, CPU, RAM, timezone).
- System metrics over 24 hours, pre-aggregated per-minute on the agent side to stay lightweight.
- Recent events (service stops, restarts, available security updates).
- Logs from journald grouped by template with occurrence counter.
Mobile app: new “Targets” tab
The companion mobile app now displays your applications and your servers side by side in a unified “Targets” tab. You can view the server dashboard in read-only mode from your phone — useful for a quick check when you’re away from your desk.
For whom this changes
- Everyone: new “Targets” tab replaces “Apps” in the mobile app (the filter lets you find the app-only view).
- Administrators: ability to add server targets from the SPA console (Admin → Servers).
- No action required on existing applications — your mobile-app supervision continues exactly as before.
Under the hood
- Agent auth via opaque Fernet token, encrypted at rest, strictly bound to a single server (hostname binding).
- TimescaleDB storage + continuous aggregates 1 min / 5 min / 1 h to keep history lightweight.
- Mobile API now
v2(clean cutover, no parallel coexistence). - Over 500 automated tests added in this release.
- v2.0.0-rc.5Clear labels on review themes
What changes for you
No more technical identifiers in the “Top themes” card
Right after it was fixed, the “Top review themes” card was showing the technical identifiers of the themes (
praise,bug,ux,pricing…) instead of readable labels.This is corrected: themes now display with clear, translated labels — “positive”, “performance”, “feature request”… — in both French and English.
Who’s affected
Every app-dashboard user. A display change only — nothing to do on your end.
- v2.0.0-rc.4A real adoption score + the "Top review themes" card fixed
What changes for you
An adoption score based on the active-users trend
The dashboard’s adoption gauge showed “no data”. It now relies on a real measure: the trend in daily active users over the last 7 days, compared to the previous 7 days. Steady, rising or falling — you see at a glance whether the app is gaining or losing ground.
It’s an independent signal: it sits next to the health score without changing it. When the history is too short to compare two periods, the gauge stays empty rather than inventing a number.
The “Top review themes” card surfaces data again
The card that summarises the recurring themes in your reviews — bugs, pricing, usability, feature requests… — was empty for every app. It’s fixed and once again shows the dominant themes with their average rating.
Who’s affected
Every app-dashboard user. The data appears automatically.
- v2.0.0-rc.3A consistent health score everywhere — dashboard, list and mobile
What changes for you
The same score, wherever you look at it
An app’s dashboard could show a different health score than the one in your app list or in the mobile app — sometimes off by a factor of two. The reason: the dashboard was recomputing its own formula on its side.
From now on, the health score has a single source of truth. The number shown on an app’s dashboard is exactly the same as in the portfolio list and on mobile.
The score respects your app’s profile
If you’ve set a health profile for an app (e-commerce, game, utility…), the score now takes the relevant-reviews filter into account: only reviews that actually talk about the app count, not off-topic ones. An app can thus go from a raw rating of 3.5★ to a relevant rating of 4.5★.
A slightly less harsh crash scale
The way the crash-free session rate is scored has been softened: roughly 1 % of crashing sessions no longer tips an app into the red.
Who’s affected
Every web and mobile user. The recalculation is automatic.
- v2.0.0-rc.2The health score better reflects the reality of your apps
What changes for you
A fairer health score for long-running apps
An app’s health score was unfairly penalising applications that have been running for months. Two of its components counted raw volumes — the total number of known crashes, the number of negative reviews — against fixed caps. An app with a naturally large history ended up in the red even though it was doing fine.
From now on:
- the “crash” signal relies solely on the crash-free session rate — a percentage, which doesn’t depend on the app’s age;
- negative reviews are counted as a proportion of recent reviews, not as an absolute number.
The result: a healthy app shows a healthy score, regardless of how long it’s been around.
The status of older issues reconciles more faithfully
Along the way, issues marked as resolved in the crash-tracking tool are now better reconciled inside StatHall — the displayed status reflects reality more faithfully.
Who’s affected
Every web and mobile user. The score recalculates automatically — nothing to do on your end.
- v2.0.0-rc.1The V2 foundations: a base ready to supervise far more than your apps
What changes for you
Nothing — and that’s on purpose.
This release lays the technical foundations of StatHall V2. Behind the scenes, the tool has been rebuilt so it can soon supervise far more than mobile applications: Unix servers first, then databases, websites and containers — all in the same cockpit.
Your apps, exactly as before
Every application, connector, review, crash, AI summary and history is unchanged. Nothing to do on your end, nothing to reconfigure: the web interface and the mobile app work identically. The work in this release is entirely internal.
What it sets up
StatHall is moving from “the unified cockpit for your mobile apps” to the universal supervision cockpit. The next step, already underway: a Unix server target type, with a lightweight agent you install in a single command.
Who’s affected
Nobody, today. This release is a foundation step: it ships no visible new feature — it makes the ones coming next possible.
- v1.0.0-rc.27Ownership transfer, scoped super-administrator access, more respectful emails and login
Highlights
A sprint driven by a single question: how do we best respect users and their data? Three complementary tracks:
- you can now transfer ownership of an app without going through the account-deletion wizard;
- the access scope of StatHall super-administrators is framed to match our GDPR commitments (data minimization, traceability, immediate notification);
- small day-to-day respect tweaks: leaner email footer, clear login message when your account is pending approval, refreshed Terms and Privacy Policy reflecting it all.
Transfer app ownership
When you no longer want to be the principal owner of an app:
- Go to App · Team, then click Transfer ownership.
- Pick a recipient among the app’s co-owners or active super-administrators.
- The recipient becomes principal owner and you keep a co-owner access so you don’t lose sight of the app during the handover. You and the new owner receive a confirmation email.
The legacy flow for transferring ownership before account deletion is unchanged — the action is just available standalone from the Team tab now.
Super-administrator access scope
To match our privacy commitments, StatHall super-administrators now only see the technical metadata of an app they are not a member of: name, slug, configured connectors, sync status. Business data — user reviews, AI summaries, anomalies, crashes, detailed metrics — is only accessible to them under one of these conditions:
- they are the owner of the app;
- they were added as a co-owner or viewer by a team member;
- they grant themselves temporary access (1 to 72 hours) for technical work. In that case, you receive an immediate email with the saved reason and the expiration date, and you can revoke it in one click from your app’s page.
All temporary accesses are recorded in the app’s audit trail: you know who connected, when, why, and for how long.
Forced transfer on third-party request (death, dismissal…)
When StatHall must transfer an app at the request of a third party — an heir, an HR department after the owner has left, official support — the super-administrator can now attach a supporting document (PDF, PNG or JPEG, 5 MB max) at the moment of the forced transfer: death certificate, HR attestation, power of attorney, etc.
The supporting document is:
- optional but strongly recommended to materialize the proof of the request;
- kept encrypted at rest for 3 years, aligned with the retention of other sensitive events;
- identified by an SHA-256 hash recorded in the audit log, guaranteeing it cannot be tampered with after the fact without detection;
- accessible to super-administrators for audit. The previous owner
can request a copy at any time by writing to
contact@stathall.com— this is the official contestation channel.
Legal basis: legitimate interest (proof of operation, anti-fraud), documented in the Privacy Policy §2.4.
More respectful, more polished emails
- Full design refresh: every StatHall email now ships with an Aurora-coloured hero (indigo → purple gradient) carrying the wordmark and a contextual subtitle (“Security”, “Weekly summary”, “GDPR · Article 15”…). A thin multi-tone accent line bridges the hero to the content, the CTA stays on the brand primary colour. Immediate visual identity in any mail client (Gmail, Outlook, Apple Mail, Proton, etc.).
- Leaner footer: we removed the name + address + SIRET block from the bottom of all our emails. The only legal link that remains is Privacy (so you can always reach the data-protection policy from your inbox). The individual-publisher disclosure remains available on the legal pages of the site.
- “Buy me a coffee” block removed from emails: we’re preparing a premium tier and don’t want to mix the “support the project” and “service being monetized” signals in the same inbox. The support button stays available in the web app sidebar and on the dedicated page of the site.
More respectful login
- Dedicated message for pending-approval accounts: if you try to log in with an account whose public signup request has not yet been approved by an administrator, you now see a clear message (“Your account is pending approval”) instead of “Invalid credentials”. The message is only revealed once your password is correct — no extra information is exposed to an attacker who would be probing.
Legal documents refresh
- Terms of Service (section 3): new access-role breakdown reflecting the super-administrator restriction, plus a dedicated section on ownership transfer and one on temporary “break-glass” access.
- Privacy Policy (section 2): explicit mention of the minimization principle applied to super-administrators, plus dedicated sections on ownership transfers and temporary accesses (with immediate notification to the owner and 30-day audit retention).
Behind the scenes
- New audit entries for every transfer (standalone or forced) and for every temporary super-administrator access.
- The audit log keeps the history of temporary accesses for 30 days after expiration.
- No action required for existing owners: your apps keep their configuration, members, and business data intact.
- v1.0.0-rc.26AI history, mobile Inbox reliability, email redesign, publisher info
What’s new
A UX sprint on the AI history tab on the web, a reliability fix for the Summaries card in the mobile Inbox, a visual redesign of transactional emails, alignment of the mobile AI Summary tab order with the web, and an update to the legal pages.
For users — web
- Regenerate button on every row of the AI history table. It opens the generation dialog with the period and scope already filled in. Run the summary again as-is, or switch the scope (iOS, Android, Global) before confirming.
- Delete button on every row, with an explicit confirmation dialog. The summary is permanently removed but can be regenerated later (the underlying reviews stay in the database).
- “Generate missing report” dialog: the dark overlay now covers the entire page (previously a band stayed visible at the top). The dialog also gains full keyboard navigation (Tab, Esc to close).
- Clearer error messages: if you pick a period with no reviews for the requested scope, the message explains the case instead of a cryptic “HTTP 404”.
For users — mobile
- More reliable Inbox: only summaries that actually have content appear under the “Summaries” tab. Attempts that produced no content (for example because no reviews came in that week) no longer surface as blank cards.
- Clearer Summary card: the exact generation date and time now appears in plain text under the app name (“May 11 · 02:00”), in addition to the relative counter already shown top-right (“20h”). No more mental math.
- Title fallback: if a summary has no generated title, the card shows “New weekly summary” instead of an empty area.
- AI Summary tabs: now ordered Global · Apple · Google, matching the web. Global remains the default selected scope.
- Summaries stack in the Inbox: a single card per week now — summarising the scopes available (“Apr 30 · Global · iOS · Android”). A tap opens the AI Summary screen where you can switch scopes via the tabs, just like on the web. No more three identical-looking cards sharing the same date.
- Versions stack in the Inbox: same treatment applied to version releases. A cross-platform version (iOS + Android) now shows as one card “v1.1.0” with two lines “iOS · May 15” + “Android · May 18”. A single-OS version still shows with one line. A tap opens the app’s Versions timeline.
- ASC/DESC sort in the Inbox: new pill button in the header (”↓ Newest” / ”↑ Oldest”). You can now reverse the feed order to bring the oldest items to the top. Infinite scroll remains smooth in both directions. For merged stacks (Summaries by week, Versions by release), the card sits at the group’s most recent date regardless of the chosen direction.
- Smoother Inbox reading:
- Versions are now positioned in the feed at their actual release date (the one shown on the card), not their ingestion date. A release shipped 2 months ago but backfilled recently no longer incorrectly jumps to the top.
- Scrolling down (loading older entries) no longer interrupts your position: new entries are appended at the tail instead of rebuilding the whole list.
- Fix “pull-to-refresh” spinning forever: on the Inbox and 5 other lists (Anomalies, Reviews, Crashes, Apps, Notifications), the spinner never stopped after a pull. Fixed — it now disappears as soon as the list is refreshed.
Emails — visual redesign
- All emails now share the same look: StatHall header, signature, a link to support the project, and legal details in the footer. For optional emails (anomaly alerts, weekly digest), a “Manage my preferences” link appears at the bottom — it does not show on essential emails (signup verification, password reset, etc.).
- Signup:
- The activation link still expires after 24 hours.
- Administrators now receive the notification of a new request after the person has verified their email (no longer the moment they submit the form). Less noise in the admin inbox, focus on accounts actually waiting.
- An automated email alerts the team when a wave of unverified signups is detected.
Legal pages
Added to both the Terms of Service and Privacy Policy:
- Publisher: Sébastien Soulier, individual entrepreneur (French micro-entrepreneur regime)
- Address: 12 Rue Georges Brassens, 32600 Lias, France
- SIRET: 10483848700015
Last updated: May 11, 2026.
For organisations
No data-schema impact. Summary-deletion actions are recorded in the audit log like every sensitive action.
- v1.0.0-rc.25Security posture hardening
What’s in this release
A technical pass: no new feature, but a full alignment on the 2026 cybersecurity standards across the web, mobile and infrastructure layers.
The work focused on foundations that must remain invisible at use: transport protocols, browser headers, cache policies, session handling, logs and telemetry. All of this stays transparent for you — the posture is simply more robust.
For end users
No action required. Your existing sessions, preferences and configurations keep working as before. A transparent update of your account credentials parameters is applied on your next sign-in.
For organizations
For on-premise customers and security officers, a detailed audit is kept in our internal documentation. The cybersecurity standards applicable to all future changes are formalized and enforced continuously.
- v1.0.0-rc.24Account deletion — full GDPR overhaul (app transfer, anonymization, 2FA)
What changes for you
The Delete my account flow (Account page → Privacy section) has been fully redesigned. This release ships 6 improvements on security and GDPR compliance.
New choice: permanent deletion or anonymization
You can now pick between:
- Permanent deletion: everything is wiped (profile, preferences, connector credentials, notes, sessions). Historical behavior. Your account vanishes completely from StatHall.
- Anonymization: your email, name, password and preferences are wiped, but your contributions (notes attached to apps, anomalies you acknowledged, tagged reviews) stay on the platform — no longer attributable to you. Useful if you contributed and don’t want to erase the useful traces.
App ownership transfer before deletion
If you own one or several apps, the wizard now offers to transfer ownership to an existing co-owner or super-admin before closing your account. No more need to delete each app manually: pick a recipient in a dropdown and one click does it.
Two-factor authentication required to delete
If TOTP 2FA is enabled on your account, the wizard requires the 6-digit code from your authenticator app (or a recovery code) on top of your password. Prevents an attacker who has your password but not your 2FA device from initiating a deletion.
14-day retraction window (down from 30)
The window during which you can cancel a deletion is reduced from 30 to 14 days. Aligns with current practice (Apple Account Deletion, GitHub) while staying within French CNIL recommendations (7-30 days).
Account locked during retraction + cancel via email
During those 14 days you can no longer log into your account (login returns a dedicated error). Cancellation is done only via the link sent by email when you scheduled the deletion. Click the “Cancel request” button in that email — you land on a confirmation page, that’s it.
Confirmation email after effective wipe
Once the 14 days elapse and the wipe is effective, you receive a final confirmation email matching the chosen mode:
- “Your StatHall account has been deleted”
- “Your StatHall account has been anonymized”
Not mandated by GDPR but a courtesy — you have certainty the request was honored.
Under the hood
- 1 Alembic migration adding two columns to the
userstable:delete_mode(NULL/'delete'/'anonymize') anddelete_cancel_token(random 256-bit token for the email link). - 4 new API endpoints: list transfer candidates, execute transfer, delete with mode + TOTP, public cancel-by-token. The historical auth-required cancel endpoint is preserved for special accounts.
- Server-side login guard: dedicated 403
account_pending_deletionduring the grace period, exception for the Apple/Google review technical account. - Structured audit log: new actions
account.anonymize.executed,account.delete.cancel_by_token,account.delete.transfer_ownership, all retained 3 years (proof of right-to-be-forgotten exercise). - Frontend 3-step wizard (Mode → Transfer → Confirm), new public page
/account/cancel-deletion?token=..., FR and EN translations. - Mobile: no change (mobile redirects to web for deletion since
rc.19). Aligned versions: mobile + backend + SPA + marketing all
bump to
1.0.0-rc.24.
No action required from you. If you had a scheduled deletion before this release, it keeps running normally with the historical behavior (permanent deletion, 30-day window preserved for those cases).
- v1.0.0-rc.23Share buttons — proper LinkedIn + X official logos
What changes for you
On the Donate pages (on the website, in the web app, and in the mobile app), the « Share on LinkedIn » and « Share on X » buttons looked a bit dull — either plain text, or a generic monochrome icon. Fixed: the buttons now sport the real official logos of both platforms, with their exact brand colors:
- LinkedIn: LinkedIn-blue button (
#0A66C2) with the official logo. - X: black button with the official X logo (inverted to white on the website’s dark themes, to keep contrast).
The mobile button also said
« X / Twitter »: we dropped the legacy « Twitter » mention, it now simply says« X »(aligned with the platform’s official rebrand).No other feature changes — this is a purely visual release.
Under the hood
- SPA: using the
simple-iconspackage (already installed for connector logos since V3.S10), no new dependency. Internal<BrandIcon>component that renders the SVG path withfill-currentto automatically follow the button’s text color. - Marketing: SVG paths inlined directly in the Astro markup (no dependency added — static site, minimal bundle).
- Mobile MAUI: 2 new vector SVG files in
Resources/Images/(official Simple Icons logos under CC0 license), compiled to multi-density MauiImage by the build. - Consistency renames: the mobile
ShareTwitterCommandbecomesShareXCommand, the intent URL switches tohttps://x.com/intent/post(canonical X URL since 2024 — the old URL was already redirecting, but using the right one is cleaner). - Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.23.
Note that the
<meta name="twitter:card">tag stays as-is in the site<head>— it’s the standard Open Graph convention for share previews, X still documents it under that name (renaming it would break the preview rendering inside feeds). - LinkedIn: LinkedIn-blue button (
- v1.0.0-rc.22Security hardening — stronger browser protections
What changes for you
This release is exclusively focused on security hardening of the website and web app, following an external penetration test performed on 2026-05-10. No new feature, no visible change in the interface — you won’t notice anything in your daily use.
Why it matters
When your browser opens
stathall.com, it receives a series of technical instructions that define what it is allowed to load: which scripts, which images, which servers it can connect to. Without those guard-rails, a vulnerability in one of the libraries used by the site could let an attacker inject malicious code.We tightened all those protections, on both the app (
stathall.com) and the marketing site (www.stathall.com).Concretely
- Strict resource loading policy: the browser now refuses to execute any script, load any font, or connect to any server that isn’t explicitly allowlisted. Only Cloudflare Turnstile (the anti-bot challenge on signup and reset-password forms) is allowed on top of our own domain.
- Strengthened cross-site isolation: your StatHall tab can no longer be spied on by another tab opened on a third-party site.
- The server version is no longer disclosed — an attacker can’t target a vulnerability tied to a specific version number anymore.
Under the hood
- Traefik reverse-proxy config (serving
stathall.com+www.stathall.com) extended:Content-Security-Policy,Cross-Origin-Opener-Policy,Cross-Origin-Resource-Policy, and the upstreamServerheader is now stripped. server_tokens offadded to the nginx configs of both the app container and the marketing container.- Caddy config (used by on-premise deployments and local dev) aligned with the same cross-site protections.
- COEP
require-corpnot enabled: would break the Cloudflare Turnstile iframe on authentication forms. - Aligned versions: mobile + backend + SPA frontend + marketing all
bump to
1.0.0-rc.22.
Alongside this sprint, three DNS actions remain to be performed on the Infomaniak side (DKIM configuration, cleanup of obsolete TXT records) — with no user-visible impact.
- v1.0.0-rc.21Fix « Delete my account » crash in the app + immediate mobile sign-out on web deletion
What changes for you
« Delete my account » no longer crashes
In the mobile app, tapping Account → Delete my account was raising a navigation error. The cause: the internal route name collided with the Account tab. Fixed — the redirect page now opens cleanly, and its « Continue on stathall.com » button opens your browser as expected.
Server list on login: back to swipe-only
The icon to the right of each environment in the login screen was rendering as a red question mark on some phones — the icon font didn’t always map the trash glyph. We removed that explicit icon: deleting an environment is now done only via left swipe (Edit · Delete), like on iOS Settings or Mail. The hint under the list reminds you: « Swipe a server left to edit or delete it ».
Tapping the row switches to that server, with no ambiguity.
Account deletion: immediate sign-out across all your devices
When you delete your account from the website, all your active mobile sessions are now invalidated in the same operation. Before: a device that still held a refresh token could theoretically keep refreshing its access for the 30-day grace window. Now: all mobile refresh tokens and all push devices are revoked at the same time the deletion is scheduled. Your mobile apps will require fresh authentication immediately, even during the grace period.
This logic lives in a single place server-side — any deletion (web today, future channels if any) triggers the same behaviour.
Under the hood
- Mobile: route
account-delete(flat) instead ofaccount/delete(which was being interpreted as the Account section → Shell error). User-visible XAML unchanged. - Backend: revocation of
MobileRefreshTokenon deletion was moved from the caller to theschedule_deletionservice itself. Centralisation: one code path to audit. - Dedicated pytest covering the
device + refresh tokenscascade on SPA deletion. - Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.21.
- Mobile: route
- v1.0.0-rc.20Explicit « Support » button in headers, and mobile deletion endpoints retired from the backend
What changes for you
The « Support » button is now explicit
On the Inbox and Apps headers of the mobile app, the gradient circle with the coffee icon has become a wider pill with the word « Support » next to the cup. No more guessing what the button does — the intent is spelled out.
It’s the same wording as the button in the website’s sidebar.
Account deletion no longer exposed by the mobile app (server side)
Following the rc.19 decision to redirect account deletion to the web browser, the corresponding server endpoints have been removed from the mobile backend:
POST /api/mobile/v1/me/delete→ removed.POST /api/mobile/v1/me/export-request→ removed.
This is more than cosmetic cleanup: the attack surface is genuinely reduced. The mobile app can no longer, even with a compromised token, trigger an account deletion or an export. Both sensitive operations are only reachable through the SPA web (
/api/v1/account/delete,/api/v1/account/export) where the dedicated path is in place with step-up auth + grace period.The associated rate limits and schemas have also been removed. The personal audit console (
GET /me/audit, read-only) remains available for the mobile A13 screen.Under the hood
- Backend: 2 endpoints removed, ~250 lines of dead code dropped
in
me.py, schemasMobileDeleteAccountBody+MobileExportRequestResponseremoved, related rate limits removed, 6 corresponding pytest tests removed. - Mobile:
IApiClient.DeleteMeAsync+RequestDataExportAsync- record
AccountDeleteRequestremoved.
- record
- SPA web: no change — the deletion flow remains intact under My Account → Privacy & GDPR.
- Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.20.
- v1.0.0-rc.19Account deletion: web redirect from the mobile app
What changes for you
Account deletion happens on stathall.com
The mobile app no longer offers account deletion directly inside the app. When you tap Delete my account on the Account screen, the app shows a short explanation page then redirects you to stathall.com → My account in your browser. The actual deletion is finalised there.
It’s a security decision, not a regression:
- Account deletion is irreversible (with a 30-day grace period, but ultimately: irreversible).
- An action this critical deserves a dedicated path in the browser, where you have your usual environment to verify, export your data, re-authenticate your identity.
- The mobile app still covers everything else: profile, preferences, sessions, sign-out. Only the final deletion is moved out.
Concretely, on the web page you’ll be able to:
- Export your data if you wish (GDPR article 15 — a full copy of everything related to you).
- Confirm your identity (password + 2FA if enabled).
- Trigger the deletion — a 30-day grace period applies before complete erasure, during which you can still change your mind.
Compliance
This design has been explicitly accepted since 2022 under the Apple App Store Review Guidelines 5.1.1(v) and the Play Store requirements: a clearly indicated link to a web deletion page replaces in-app delete.
Under the hood
- The mobile app no longer reaches a backend deletion endpoint from the mobile API: that attack surface is removed.
- Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.19.
- v1.0.0-rc.18Support StatHall always one tap away, email pre-filled at login, and public changelog tidied up
What changes for you
Support StatHall directly from Inbox and Apps
A coffee icon in a purple-gradient circle now appears at the top of the Inbox and Apps tabs in the mobile app, right next to the search magnifier. A tap takes you to the Support page, exactly like the dedicated button in the website’s sidebar. No need to dig into Account to find it — it’s right where you naturally look when using the app.
The icon now uses the standard ☕ emoji for identical rendering on iOS and Android, with no dependency on an icon font.
Email pre-filled when you switch environments
When you tap a saved environment from the Setup or Login screen and that profile is tied to an email (format
Production - your@email.com), the app automatically pre-fills the email field on the login screen. You only have to type your password — one less step.If you start typing in the field before the app has had time to pre-fill it, your input is preserved — the app never overwrites you.
Public changelog tidied up
The public history at www.stathall.com/changelog now only lists release-candidate versions (rc.1 to rc.18). Earlier development versions (alpha, pre-1.0) have been removed: they documented internal steps before the first public deployment and brought nothing to an end user.
The result: a clean chronological history that starts at the first public stathall.com deployment and moves forward release by release without breaks.
Under the hood
- No backend or database changes.
- Mobile: new Support icon with handler in the Inbox and Apps views. No embedded WebView — external links always open in the system browser.
- Marketing: changelog sort logic stays as in rc.15 (descending date then release number). 26 files removed from the repo, 0 file added.
- Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.18.
- v1.0.0-rc.17Support StatHall directly from the mobile app + public changelog review
What changes for you
Support StatHall from the mobile app
The mobile app gains a Support StatHall page in the Account tab, right above the sign-out button. A subtle purple gradient card with a coffee icon — discreet but visible. You can’t miss it when you open your settings, without it interrupting your usage.
Tap it, and you land on a dedicated page that explains:
- What your support funds (infra & hosting, AI model costs for weekly summaries, development time).
- The transparency commitment: no « premium » feature tier. Every StatHall feature stays free and identical whether you donate or not. Your support funds the service’s existence, not a privileged access.
- An alternative for those who can’t donate: spreading the word to other devs or product managers via LinkedIn or X / Twitter is just as valuable.
Donations go through Buy Me a Coffee like on the website — one-off or recurring, starting at a few euros. The button opens your system browser; the app never touches your payment method directly.
Public changelog tightened
This release also includes a full pass over this page’s entries (rc.1 → rc.16) to remove internal details that didn’t belong in public — server file paths, module or migration names, precise validation parameters, tooling identifiers. The user-facing content stays intact; only the technical specifics that could have guided an attack were removed.
For self-hosted teams
The
VITE_DONATE_BMCoption you configure on the SPA still works exactly as before. The new mobile page hard-codes the official StatHall BMC handle — it’s not per-instance configurable for now (rationale: if you self-host, there’s no reason to surface a donate button for StatHall to your users). If that’s a problem for your deployment, please open an issue.Under the hood
- No backend or database changes.
- Mobile: new Support page + entry card in the Account tab. The main tap delegates to the system browser to preserve your privacy (no embedded WebView).
- Aligned versions: mobile + backend + SPA frontend + marketing
all bump to
1.0.0-rc.17.
- v1.0.0-rc.16Connected devices management is now on the web app — revoke your mobile sessions from My Account
What changes for you
Manage your mobile devices from the browser too
Until rc.15, the « Connected devices » list was only reachable from the mobile app (Account → Devices). If you lost your phone, or wanted to check your open sessions from your workstation, you had to grab your device — slightly paradoxical.
Now, app.stathall.com → My Account → Security displays the exact same list, with:
- The Apple or Smartphone icon depending on platform.
- The user-given device name (« Sebastien’s iPhone »).
- A combined OS · model subtitle (« iOS 26.4 · iPhone16,1 »).
- Relative time since last activity (« Seen 2 min ago », « Seen yesterday », « Seen 3 d »…).
- A Revoke button per device, with inline confirmation (title + risk description + Confirm/Cancel buttons).
When you revoke a device, its session becomes invalid immediately, no more notifications can reach it, and the user must sign back in to access data.
It’s the exact same flow as mobile, now available from both sides.
Security group description expanded
The Security group in My Account now reads « Two-factor authentication (2FA), backup codes and connected devices » instead of « Two-factor authentication (2FA) and backup codes », to reflect the new screen.
- v1.0.0-rc.15Public changelog sort fix — the latest release now correctly sits at the top
What changes for you
The latest release is back at the top
On the /changelog page, multiple releases shipped on the same day (rc.6 through rc.15, all dated 2026-05-10) could appear in the wrong order — rc.9 surfaced above rc.14.
Now the sort considers the release-candidate number whenever several entries share the same release date. The latest release is always on top, no matter how many ship on a single day.
- v1.0.0-rc.14Redesigned « Connected devices » card: platform icon, combined OS + model, and relative time (« seen 2 min ago »)
What changes for you
The « Connected devices » list becomes readable
Before rc.14, each device in Account → Connected devices displayed its name followed by three raw lines: a lowercase platform (« ios »), a
10/05/2026 12:22date, and a red « Revoke » link with no framing. Hard to spot your iPhone at a glance when you have multiple sessions.Now each card shows:
- A 44 × 44 pt indigo capsule with the Apple or Smartphone icon depending on platform — immediate visual cue.
- The device name as a bold title.
- A combined « OS · model » subtitle (e.g. « iOS 26.4 · iPhone16,1 ») — see the platform and exact model in one glance.
- Relative time (« Seen 2 min », « Seen yesterday », « Seen 3 d »…) instead of an absolute date to decode.
- The « This device » badge clearly positioned top-right when it’s the current session.
- A framed Revoke button in red rather than a plain link — destructive action is visually recognisable.
Spacing between cards bumps to 10 pt to breathe, and the empty state message is updated to reflect rc.12 (the app now registers the device at login automatically — no need to grant push first for it to appear).
- v1.0.0-rc.13Defensive validation on stored sessions + changelog gap-fill
What changes for you
Stored sessions: defensive validation
The app uses your locally-stored session credentials to automatically rename your server profiles with your email. Before rc.13, the reader didn’t check the consistency of the data — safe in practice but not robust against storage corruption or edge cases.
Now several structural checks are applied before any use: if any fails, the app keeps the historical profile name rather than altering it with invalid data.
Changelog gap-fill rc.7 → rc.11
The marketing site previously only displayed rc.6 and rc.12 — every intermediate iteration (rc.7 through rc.11) has now been added to the public changelog, in both French and English. You can now follow the full history of the mobile app, from the expandable Inbox stacks (rc.7) to the full server management refactor (rc.11).
- v1.0.0-rc.12Your iPhone now shows up in 'Connected devices' even without push + security hardening + version alignment across the stack
What changes for you
Your iPhone shows up under « Connected devices » even without push
Before rc.12, your device only appeared under Account → Devices after you had granted iOS / Android push permission. If you refused it or simply hadn’t gotten to the prompt yet, the list stayed empty even though you were logged in. Now the app registers your device at login with or without push permission — your install is always visible, and notifications turn on automatically the day you grant the permission.
The current device is also recognised as such — useful for multi-device management and to avoid accidentally signing out the very device you’re cleaning up from.
Hardened security
- Link validation: a link opening the app is now only accepted if it points at a known domain (the SaaS or a registered self-hosted environment).
- Clean device revocation on logout: your mobile session is invalidated server-side at the same time you sign out — no more notifications can reach a device you’ve signed out from.
- Diagnostics sent to Sentry: emails and technical identifiers present in traces are automatically masked before upload.
Stability
- Several UI handlers that could silently die on error are now traced without interrupting the app.
- Components that subscribe to global events now unsubscribe cleanly on teardown → no more memory leak after navigating Inbox / Apps / Account back-and-forth.
iOS HIG / Material 3 standards
- Tap targets bumped to 48 dp on Android (vs 44 pt iOS, unchanged) per Material Design 3.
- Safe-area insets applied to the missing detail screens — content no longer slips under the Dynamic Island / Android notch.
- Semantic heading hierarchy added (Inbox, Apps, Account) so VoiceOver / TalkBack announce page structure correctly.
Versions aligned across the stack
This release realigns mobile + backend + SPA frontend + marketing site on the same
1.0.0-rc.12. No more version drift between the app and the service. - v1.0.0-rc.11Delete servers from the Setup screen, polished swipe in the server list, and automatic rename of existing profiles
What changes for you
Delete from the pre-auth Setup screen
Before rc.11, deleting an environment was only possible from the login (with an active account) or from Account → Servers (post-auth). If you landed on the initial Setup screen with several existing profiles, you couldn’t clean up before signing in.
Now the « Continue with an existing server » list on the Setup screen exposes the same swipe-to-delete as the other screens — swipe left to reveal the red Delete button with confirmation. If it’s the last profile remaining, the app offers a Reset everything action that wipes everything and sends you back to the empty Setup screen.
Polished server list (iOS Settings-style)
The Account → Servers screen is reworked to look like native iOS Settings: single rounded container, flat rows with separators, comfortable minimum row height. Left-swipe reveals Edit (indigo) and Delete (red) in standard slide-over mode (no auto-execute on full swipe). No more colour bleed or rounded corners clipping awkwardly during the drag.
Automatic rename of existing profiles
If you had several profiles created before rc.9 (without an email suffix in their name), they were stuck with their historical name. Now every time you open the login screen, the app detects the account linked to each profile and automatically renames it to
"{base} - {email}".It works for stathall.com as well as for any custom server (« Test » on localhost, on-premise environments, etc.). The rename is idempotent: if the suffix is already present, the app does nothing.
- v1.0.0-rc.10The Delete button becomes explicit — no more guessing you had to swipe
What changes for you
A visible 🗑 icon on each server
The swipe-to-delete shipped in rc.9 worked, but many users didn’t realise they had to swipe to reveal the action. Now every non-active profile in the « Switch to another server » list shows a red trash icon of 44 × 44 pt on the right — tap to confirm and delete. The swipe is still available as a bonus, but the action is immediately visible for everyone.
« Manage servers » as the main entry point
The « Edit server » button under the active block becomes « Manage servers » — its action sheet now contains:
- Continue with stathall.com (when not yet configured)
- Edit current server
- Add an environment
- Manage servers (new) → opens the full Account → Servers page with full CRUD, ability to delete the active profile after switching, or reset everything.
The hint under the list is rewritten to spell out the three paths: « Tap a row to switch · 🗑 to delete · Edit server → Manage servers for the full list ».
- v1.0.0-rc.9Anti-duplicate on the server list: one profile per (URL × email) pair, even if you sign in multiple times
What changes for you
No more « Production » profiles piling up
If you tapped Continue with stathall.com several times from the login screen (e.g. after reinstalling the app), a new « Production » profile would appear each time, all with the same URL — eventually the « Switch to another server » list became unreadable.
Now, after every successful login, your active profile is automatically renamed « Production - your@email.com », and any profile with the same URL and email is consolidated. If you sign in again with the same email, the existing profile is reused instead of creating a new one.
If another person signs into the same server from the same device (rare in practice, common in QA), they get their own separate profile — no collision.
Swipe-to-delete on the server list from login
The « Switch to another server » list on the login screen now exposes the same actions as Account → Servers: swipe left on a row to reveal Edit (indigo) and Delete (red) with confirmation. No need to go into Settings to clean up.
- v1.0.0-rc.8Robust back navigation, accessibility up to Apple HIG standards, and an Inbox that no longer jumps while loading
What changes for you
The back button always works
Before rc.8, some back paths could leave the app stuck on an error screen — typically when you came in from a push notification or a deep-link into an anomaly detail. This release makes back navigation robust across the whole app, with an explicit fallback to the source tab. No more freeze, no more dead screen.
Inbox: no more scroll jump while loading
When you scrolled the Inbox while pagination was loading new items, your scroll position could jump back to the top. Now your position stays stable even if the source changes while you read.
Accessibility — Apple HIG / Material Design standards
- Icon buttons (search, settings, back) bump to the minimum recommended by Apple (« Touch Targets ») and Material 3 (« Accessibility »).
- Semantic labels and descriptions are enriched so VoiceOver / TalkBack announce each action correctly.
Roadmap: the Gantt rendering lands
The Roadmap screen for an app now shows DEV / TNR / REL phases as proportional colored bars, with a vertical red line marking the current instant — see at a glance where each version stands.
Settings: Servers and Devices get dedicated pages
Before, Account → Settings mixed everything. Now Servers (stathall.com / on-prem environment management) and Connected devices (devices with push) each have a dedicated page, with swipe-to-delete and native confirmation.
Versions: platform auto-detection
On the Versions screen of an app, if you’ve only configured iOS or only Android, the app automatically detects which platform has data and switches to it on open. The unused platform’s toggle is greyed out.
AI Summary: navigable history
The AI Summary screen of an app now shows a horizontal row of past summaries at the bottom — tap to re-read any of the recent summaries. No more digging in the web app.
- v1.0.0-rc.7Inbox is easier to read — your summaries and new versions are now grouped automatically by app
What changes for you
Expandable stacks in the Inbox
When you track several apps, the Inbox could get noisy — each app emits its weekly summary and declares its new versions, drowning out the actual anomalies. From now on, summaries and versions for the same app collapse automatically into a single « 3 updates · App X » row you tap to expand.
Anomalies are never collapsed: they stay individually visible because those are the ones you need to act on quickly.
UX cleanup
The Apps tab drops the « Portfolio » segmented control that didn’t add value on small screens: we list your apps directly, with their health badge, no extra tab to pick.
This release also includes internal fixes to smooth iOS deploys on recent system versions.
- v1.0.0-rc.6Mobile app redesign: a unified Inbox, links that open the app, and at-a-glance health scores
What changes for you
A mobile app rebuilt around your Inbox
The StatHall app for iOS and Android moves from five tabs to three: Inbox · Apps · Account. The Inbox becomes the landing screen and aggregates everything that needs your attention across all your apps in a single feed: anomalies, AI summaries and detected releases. Filter by type with a chip row, swipe to acknowledge in two taps, switch scope (all apps / one app) through a bottom sheet with search.
The Account tab finally groups profile, preferences, security & GDPR and support into four clear cards.
Your StatHall links open the native app when installed
When you get a StatHall URL via email, Slack or SMS — like
https://app.stathall.com/apps/my-app/anomalies/123— your phone opens the native app directly on the right anomaly if it’s installed, without bouncing through the browser. Otherwise the web page loads as usual.This is what Apple calls Universal Links and Google calls App Links. Nothing to do on your end — it works as soon as the rc.6 app is installed on your device.
A visual health score per app
The app detail screen now shows a circular HealthGauge that summarises overall health, broken down into three progress-bar sub-scores: technical (crashes, ANRs, performance), business (ratings, reviews, revenue for paid apps), adoption (downloads, MAU, retention). You spot in two seconds what’s dragging an app’s score down.
Releases timeline and roadmap, on mobile
Two new screens accessible from an app’s detail:
- Versions — iOS/Android timeline with release dates and crash-free deltas between consecutive versions.
- Roadmap — Gantt swimlane (DEV / TNR / REL) in read-only mode to follow upcoming milestones without opening the web app.
Better push notification management
A new Notifications screen lists every push received with timestamp and read / unread state. If system notifications are disabled at the OS level, an inline banner reminds you to open Settings — you no longer miss a critical alert because permission was accidentally denied.
Who’s affected
Every StatHall mobile user on iOS and Android will receive the rc.6 update through TestFlight (iOS) and Internal Testing (Play Store). No server-side migration on your end — the new screens populate automatically.
On the web, nothing visibly changes this time: rc.6 is a 100 % mobile sprint.
Known limitations
- The Roadmap screen on mobile is read-only — to add or edit a release, open the web app.
- Universal Links activate on the server side as soon as the iOS and Android signing identifiers are configured. If you see a link open in Safari/Chrome instead of the app, the device hasn’t re-fetched the association file yet (Apple refreshes it every 24 h).
- v1.0.0-rc.5Android store crashes, deep-links to your tools, « new / regression / spike » badges on every issue
What changes for you
Your Android crashes, even without Crashlytics
StatHall now ingests Android crashes directly from Play Vitals (the console that feeds your Play Store listing). Every user with an active Google Play connector sees error clusters (crash + ANR + non-fatal) appear automatically under the Crashes tab, with nothing to add or configure.
On iOS, Apple doesn’t offer an equivalent public API — you stay on Sentry or Crashlytics for iOS details.
One click to open the source console
Every crash issue now sports an external icon to the right of its title. A click takes you straight to the issue page in Sentry, Firebase Console or Play Console — the exact same issue, opened in the tool you use to fix it.
The URL is built from the information already saved on the connector. For Play Console, a new optional field « Play developer ID » appears on the Google form: it’s the numeric ID visible in your console URL. Without it, everything else works — we just hide the Play icon.
Crashlytics + Play Vitals: a single line per crash
When the same Android crash is reported by both Crashlytics and Play Vitals, StatHall automatically merges the two rows into one. The canonical row is the one with the most occurrences; you see both external icons side-by-side to jump between tools, plus a small « Correlated » badge to explain the match.
Matching uses two steps: an exact match on the normalised title, then a fallback on semantic similarity for cases where labels diverge.
Four badges to skim faster
Every crash issue can now carry up to four visual badges:
- New — issue first seen in the last 7 days.
- Regression — issue that had been resolved then resurfaced. Reported directly by Sentry.
- Spike — recent occurrence volume meaningfully above the 14-day baseline. Auto-detection with hysteresis to avoid false flicker.
- First seen in vX.Y.Z — issue that appeared in your latest release. First signal of a potential regression tied to the release.
The badges are designed so you can spot, at a glance, what deserves attention in a long crash list.
Small UI cleanups
- The old « Access » tab in app settings was removed: it duplicated « Team », which covers everything (members, invitations, viewer / co-owner roles) in a single view.
- The « Add version » button appeared three times on the roadmap (header, Gantt toolbar, empty state). The Gantt-toolbar duplicate was removed — only one occurrence is visible now.
Who this changes things for
Any team with an active Google Play connector. Play Vitals crashes appear automatically on the next sync. Badges and deep-links are visible from the first refresh of the Crashes tab.
To enable the direct link to Play Console on crashes, open Sources → Google → Play developer ID and paste the numeric ID from your console URL.
Known limits
- iOS remains asymmetric: Apple doesn’t expose a stable public API for detailed crash issues. For iOS crashes, we rely on Sentry or Crashlytics.
- The Play Vitals API doesn’t expose the « regression » concept on Google’s side. The « Regression » badge therefore only lights up on issues sourced from Sentry for now.
- v1.0.0-rc.4AI Summary rethought: token at the app level, configurable auto-generation, clearer reading experience
Same-day patches
A handful of follow-ups went to prod on May 6th right after the initial rc.4 tag — they all still carry the
rc.4tag:- Editing just the monthly quota or preferred model without re-typing the API key now works. Before: saving was impossible unless the key was re-entered. After: the key stays optional in edit mode; the server keeps the encrypted key it already has.
- Simplified LLM Key card: removed the now-redundant “Edit” button, the reveal eye only appears once at least one character is typed, richer placeholder.
- Weekly summary toggle now persists across refreshes. Older accounts (with a legacy frequency field) stay active automatically.
- Default auto-pregeneration moved to Sunday 23:59 UTC (instead of Monday 00:00 UTC) — more consistent semantics: the report is generated right before midnight Sunday and covers the week that just ended (Mon→Sun).
- « How it works » caption rewritten to spell out the covered window with two concrete examples, no more vague reference to the “default config”.
- « Saved » visual confirmation on every user-facing Save button — a green pill that auto-hides after 2.5s.
What actually changes
AI Summary — per-app configurable auto-generation
- The LLM token now belongs to the app, not the user. Before: every user had to drop their own DeepSeek or OpenAI API key in their account; in practice, in a team, either nobody did it or one person carried it individually. Now: the key is configured once by the app owner, in the app settings → AI tab. It’s masked behind asterisks (you’ll never see the key in clear again after entering it), with a « Test connection » button to validate authentication before the first cycle.
- Weekly auto-pregeneration configurable at the app level: on/off toggle, day-of-week + UTC time, plus checkboxes for generated scopes (Global, iOS, Android — pick any combination). The covered window is the 7 fully elapsed days before generation (default: Monday 00:00 UTC to Sunday 23:59 UTC). No more relying on someone clicking « Generate » every Monday.
- Estimated cost displayed right in the auto-generation configuration screen: number of LLM calls per cycle + this month’s running total against the declared quota.
- No more manual generation for users. The summary screen becomes a pure reading view: you navigate previously pre-generated reports, you don’t trigger them.
Reading summaries — clearer UX
- Explicit day counter on the period selector: « From 20/04/2026 to 26/04/2026 inclusive = 7 days ». The inclusivity of the end date is materialised in the text to avoid the ambiguity that made people think a 20→26 range covered only 6 days.
- Auto-snap to the closest pre-generated report. When you pick a range that doesn’t exactly match any pre-generated report, a « Go to closest report » button appears with a clear message — no silent surprise.
- Better empty states: weeks with no reviews render as « No reviews this week » instead of a blank page.
Email preferences — simplified toggle
- The user no longer picks the send day of the weekly summary. The day is imposed by each app’s pregen configuration — it’s consistent: the digest goes out as soon as the report is ready. Users keep a yes/no toggle to subscribe / unsubscribe per app.
- Old account-level API keys are marked as deprecated via an explicit warning banner. You can delete them in one click from your account; they no longer have any effect on summaries.
AI history for admins
- New « AI History » tab in app settings (super-admin only). Paginated table of every generation attempt — successes, empty weeks, missing keys, provider errors or quota exhaustion. Each row shows the date, covered period, scope, origin (auto / admin manual), status, review count and actual cost.
- « Generate missing report » button: lets an admin fill a gap (LLM outage, quota exceeded one week, key absent at cycle time) without replaying an already-published report. The generated report is tagged « admin manual » in the history for traceability.
Performance — Faster Dashboard and app list
- App dashboard: the « Top themes 30d » widget loads significantly faster on high-review-volume apps. Expected gain: -40 to -60 % on dashboard load latency.
- Admin app list: the « earliest sync date » query is now aggregated in a single pass instead of one per app. Gain: -20 to -30 % on list latency, proportional to app count.
- Navigation cache: dashboard and portfolio screens keep their data cached for 60 seconds (instead of 30) and 5 minutes in memory after switching screens. No more redundant refetch when navigating between tabs.
Migration
- No automatic copy of existing user-level LLM keys to the app level. Project decision: we want to force an explicit gesture from the owner to confirm which key is used for which app. Apps without an app-level key won’t get a pre-generated summary until reconfiguration.
- Admin audit tool to list, per app, its owner and the state of key configuration. Lets an admin notify the right owners post-deploy in minutes.
Who this matters to
Any team that was using AI Summary so far. Before rc.4, the LLM cost depended on one person’s key in the team, and generation had to be triggered manually every week. After: cost is managed at the app level, generation runs by itself on the configured day, and the team discovers the report by opening the screen.
What’s next
- Effective removal of legacy user-level keys: shipped same day in rc.4.1.
- Configurable cadence beyond weekly (bi-weekly / monthly) if users ask for it on review volumes that justify it.
- On-demand generation for owners (not just super-admins).
- v1.0.0-rc.3App dashboard redesign, Play Store scraper bumped to 16 markets, fairer tagging and faster dashboard
What actually shipped
App dashboard — noticeably faster
- An app’s dashboard no longer loads KPIs for every other app in the workspace just to keep one. Before: opening the dashboard ran several useless queries per workspace app, then filtered in application code — latency grew linearly with app count. Now: the filter is applied at the data layer, only the relevant app is computed.
Play Store scraper — 5 markets → 16 (Americas, Europe, French overseas)
- More Play Store markets queried at each backfill to capture reviews exclusive to regional storefronts (a review posted from Brazil doesn’t necessarily surface in the French or US feed). Coverage now: Europe (FR, GB, DE, ES, IT, NL, PL, PT) + Americas (US, CA, BR, MX) + French overseas (Guadeloupe, Martinique, Réunion, Guyane). Oceania intentionally excluded.
- No depth gain in time : Google caps the public feed at about 6 weeks regardless of market. That’s why we don’t have full Android history like we do on Apple.
- No duplicates despite multiple markets: a review seen first in one market isn’t reprocessed when the scraper moves to the next.
- Backfill counter fixed: the « Recent jobs » card used to display fetch counts (inflated by cross-market re-runs of the same review). It now reflects reviews actually added to the database — consistent with the « Android reviews » dashboard card.
Review tagging — no more bogus « bug » on stock complaints
- The tagger no longer confuses real-world and the app.
Before: a review like « out of stock for days » got labelled
bug+perf+UX. After: if the text isn’t about the app, thebug/uxpills don’t light up. - Three new business labels for retail / delivery / restaurant
apps:
stock(out of stock, unavailable),delivery(delay, driver, store pickup),customer_service(support, call center, in-store welcome). Shown in a separate « Off-app » family, visually distinct (slate pill). - Contextual suppression of remaining false positives: if a business label clearly dominates app labels, low-scored app pills are auto-removed.
- Hardened e-commerce health profile: reviews tagged stock / delivery / customer_service are now explicitly excluded from the business health score.
- Retag of existing reviews: an admin can reapply the new rules to history with a single command.
App dashboard — denser first view, faster to read
- Beefed-up « Average rating » card: the big 7d number is now
flanked by two baselines on the right — the 30d average and the
global average across all reviews in the database. Below each
number, the review count (
n=…) makes the statistical fragility of the 7d number explicit on low-volume apps — fewer than 5 reviews and the 7d value greys out. - Four new widgets on the dashboard:
- Replies 30d — share of reviews that received a reply from the support team.
- Last release — relative date per iOS / Android platform, with a ⚠ badge if more than 90 days without a release.
- Open anomalies — compact P0 / P1 / P2 grid of anomalies still in flight.
- Top review themes (30d) — the 8 most recurring themes with the average rating per theme. See at a glance that « payment » sits at 4.2★ while « crash login » sits at 1.8★.
- Layout reorganised by reading order: health → ratings → adoption proxy → review quality → tech / ops. ~40 % less scroll.
Coming next sprint
- Active users per version × OS with impact weighting (a regression on a 1 % adoption release matters less than one on the dominant release). Deferred to validate each source in a dedicated window.
Google Play backfill — bucket dropped
- The Google Cloud Storage bucket disappears from the Google Play connector. Before: you had to provision and authorise a bucket via Play Console, copy its name into the connector form — in practice almost nobody got past that step. Now: no bucket to configure.
- Historical reviews: pulled from the public Play Store listing across five markets (FR, US, DE, ES, IT) in parallel, with auto-deduplication. On repeated backfills we stop as soon as we hit a review already in the database.
- Historical downloads: pulled from Google’s official API, with about a year of history available. Same service account, zero new permission to grant.
- Connector docs rewritten. The Google install guide now fits in three steps instead of five.
Who this matters to
Anyone trying to backfill an Android app’s history in StatHall. Before rc.3, the « GCS bucket » screen literally blocked onboarding. Now, as soon as the service account validates, the historical imports are available under Synchronisation with no extra config.
Owned limits
- Public review scraping fetches what the Play Store exposes publicly (typically a few thousand recent reviews per market). For apps with a very long history, the older tail can no longer be backfilled.
- Install history is capped at about a year by the official API. Earlier than that is impossible on Google’s side.
- Scraping is a best-effort mechanism — Google can shut it down without notice. The official API remains the only guaranteed source for ≤ 7-day reviews.
- v1.0.0-rc.2Connector chain UX fix — visible feedback, no more silent failures
What actually shipped
- Fix « Never signed in » on invitation-created accounts. When a new user accepted an invitation and set their password inline, their account showed up in the admin list but with « Never signed in » in the last-login column — even though they had just completed onboarding with an active session. The acceptance date is now recorded as the first sign-in, consistent with the regular login flow.
- Connector test now responds. When you tapped Test connection on a connector (Sentry, Apple, Google, Firebase) and it failed, the screen stayed blank — no message, no sign the request had even been sent. A red banner now systematically appears with the cause: invalid credentials, network down, server error, or rate-limit.
- The Install button no longer closes silently. If saving credentials fails, the form stays open with an explicit error banner.
- No more bogus « Android package missing » warning. The Google Play form showed this message wrongly, even when the package was filled in at the previous step.
- Silent rate-limit hotfix. An uncaught exception was returning silent 500s on some rate-limited calls. Fixed.
- Sources > Advanced tab clarified. The two cards (Google Play and Apple App Store Connect) were indistinguishable. Each card now shows its official logo + the connector name, and the historical-import title spells out the source. The Apple card only appears once the vendor number is filled in (without it, Sales Reports backfills failed silently).
- Translation key display bug: some strings on the Sources tab rendered as raw untranslated keys. Fixed.
- GitHub logo now visible in dark mode (Sentry too): the icon was near-black on dark grey, contrast ratio too low. The logo square background is now permanently white — App Store / Play Store convention, preserves brand recognition in dark mode.
- Google Play GCS bucket merged into the Google card. Before: separate card under Sources > Advanced. Now: integrated field on the Google form, like Apple’s vendor number. « Install » persists credentials + bucket in a single click.
- Historical imports moved under Synchronisation. Google + Apple backfill tools aren’t really « config » — they’re one-shot syncs. They now live at the bottom of the Synchronisation tab, visible only when the source is ready to backfill.
Who this matters to
Anyone trying to wire a Sentry, Apple App Store Connect, Google Play or Firebase connector to an app — roughly 100 % of the onboarding path. The silent bug made the experience kafkaesque: you clicked, nothing happened, you didn’t know what to do. rc.2 fixes that upstream (bundle ID propagation) and downstream (errors surface in the UI).
- v1.0.0-rc.1First public deployment — app.stathall.com + www.stathall.com
What actually shipped
- StatHall is live. The product now runs at
app.stathall.com(SPA + API) and the marketing site — the one you’re reading — atwww.stathall.com. No functional change compared to the lastalpha: this RC marks the move from staging to production. - Deployment tooling hardened. A fresh install now goes through without manual intervention, even on a host that already runs other sites.
- Marketing site bundled in the deploy. The site is built and served on every release, fully static, with no tracker injected.
- No database schema change this sprint. Pure go-live and consolidation.
What’s next
- Production soak to watch the real-world behaviour of connectors on live apps.
- Stable
v1.0.0tag once the security checklist clears.
- StatHall is live. The product now runs at