XOPOZ

GPS · Tracking · Encrypted · Teams

Hello,

A new XOPOZ version — 2026.05.16.04 — is now available. The focus of this release is a privacy–first daily telemetry channel (per–day counter rows, no GPS, no per–fix timestamps), a root–cause fix for stale team members lingering on peers' phones after a member quits, a cleaner support–ticket UX with device fingerprint info moved out of the user's description, and several staff and reliability improvements on the backend.

As before, you can install it as a standalone APK from our releases page, or via the Google Play closed testing track — reply to this email to be added to the testing list.

Two ways to get the new version
Google Play is the preferred path (auto–updates from then on) but requires a one–time registration on the closed testing track. The standalone APK installs directly without any whitelisting.

Open on Google Play

https://play.google.com/store/apps/details?id=com.tbr.xopoz

Download standalone APK

https://tiritix.com/xopoz/releases/index.html

For Google Play access, reply to this email and we'll add your Google account to the closed testing track.

Reply to register for Google Play testing

Documentation

The main XOPOZ documentation — setup, teams, encryption model, troubleshooting — is available at:

https://tiritix.com/xopoz

Android App — What's New

Stale team members after quit — root–cause fix
A member who left a shared team could keep appearing on a peer's Teams screen for hours after the server had already removed them, even though every subsequent roster fetch returned the correct list. The cause was that recent refactors had turned the no–since roster endpoint into the authoritative current–member list while the client was still merging it as an additive delta — with no path that ever deleted locally cached rows when the server stopped listing a device. The Teams refresh now treats the no–since response as authoritative for that one team, deletes members and positions that the server no longer lists inside a single atomic transaction, and then re–upserts the current set. The map–fragment delta path (which uses an explicit `since` timestamp) remains additive and is unaffected.

Safety policy — refuse to act on empty server responses
On top of the fix above, the client now treats an empty server response on team queries as a potential server–side bug and refuses to apply it. The no–since contract always echoes the caller's own device for any team the caller is in, so an empty list cannot be a legitimate «you are still in this team but it has no members» state. The wholesale–remove path is also gated: an empty server team list will only collapse the local view if the local cache already holds zero or one team, blocking the catastrophic N → 0 shortcut while keeping the legitimate 1 → 0 transition working. A bogus rejection is recoverable on the next refresh; an erroneous wipe would not be.

Privacy–first daily device telemetry
The app now keeps a single counter row per UTC day with the number of recorded positions, the number of crashes, the number of seconds the app was in the foreground, the app version, and the OS string. No GPS coordinates, no per–fix timestamps, no event log — only aggregate integers, bucketed per day. Completed days are pushed to the backend once on the regular fifteen–minute poll cycle (one POST per past day, marked sent on 204), and today's row keeps accumulating until midnight UTC. The flush runs even for solo devices without team membership, so the operator can spot crash spikes and version distribution without compromising the no–telemetry stance on user activity.

Support ticket UX — device fingerprint moved out of the user's description
Support tickets used to embed a verbose «PHONE INFO» block (device model, OS, app version, network state) directly inside the user's typed description. The same information was already attached as structured metadata to the ticket, so the embedded copy was a duplication that made the user's own prose harder to read and leaked device fingerprint into a user–facing field. The description sent with new tickets is now exactly what the user typed; the structured metadata is unchanged and remains the staff–only forensics channel. Tickets created before this version still carry the legacy embedded block — cosmetic and transitional.

Backend Server — What's New

Daily device telemetry endpoint
A new endpoint accepts the client–side daily counter rows described above and stores them in a dedicated `device_stats` table keyed on `(device, day_utc)`. The write is an idempotent upsert, so a retry of an already–sent day costs nothing and never duplicates. Inputs are validated: a future–dated `day_utc` is rejected outright, the device identifier carried inside the payload must match the session header (mismatches are tagged in the audit log), and the row is FK–bound to the device with cascade delete so an account deletion removes its telemetry trail as well. The privacy boundary is enforced at the schema level: there is no column for coordinates or fix timestamps, only the integer counters and the small string fields (app version, OS).

Staff — cross–user account deletion endpoint
Operators with the STAFF role can now delete another user's account through a dedicated endpoint that resolves the target by security identifier, blocks self–deletion (the regular `/v1/auth/account` route handles that case and produces the right confirmation flow), and then reuses the same cascade path the user–initiated deletion uses. Two audit rows are emitted: the regular `AccountDeleted` row that captures the deleted target, plus a second STAFF–sourced row that captures the actor — so the audit log answers both «who was deleted» and «who pressed the button» without joining tables.

Staff — internal note per user account
User records gain a staff–only annotation field for business context (Google testers, VIP bulk, do–not–contact, follow–up reminders). The note is set through a dedicated endpoint that accepts a raw JSON string and stores it verbatim. It surfaces only in the staff overview view and is never returned by the user–facing profile or any other public endpoint.

Block banned users from login
Authentication on a blacklisted account now returns a structured, deterministic error response instead of being silently degraded or producing inconsistent failures. The check sits ahead of the credential verification step, so a banned account cannot be used to probe password validity either.

Staff telemetry view — daily stats
A new database view aggregates the per–device daily stats into a staff–facing snapshot, joining account context for at–a–glance triage. Used internally for crash–rate spotting and version–adoption monitoring during the beta.

Code quality — CA warning cleanup across the build
The backend solution now compiles clean of code–analysis warnings on the projects covered by the recent refactors. No behavioural change — this only reduces noise in the build output so that real regressions stand out in CI.

Try the New Version

Open the Play Store listing (after replying to register for the closed testing track), or grab the standalone APK directly from our releases page.

Open on Google Play

Download APK

Reply to join Google Play closed testing

Documentation

https://tiritix.com/xopoz

Field reports — bug observations, missing markers, unexpected behaviour, or simply confirmation that everything runs smoothly — are very welcome at xopoz@tiritix.com. The built–in Support screen also lets you attach a log file directly from the app.

Thank you — your feedback is what keeps the quality bar high.

Best regards,

Thierry
Nuremberg, Germany

XOPOZ Manifest

tiritix.com/xopoz · Google Play · APK Releases · xopoz@tiritix.com