Team evidence · noindex

Risks, known issues & incidents

What can go wrong, and what already did?

Risks, known issues, and incidents

This is the register. One list. When something blows up at an event, add an incident at the bottom. Do not start a new document.

Inconsistencies found in code (19 Aug 2026)

IDRiskWhy it bites on the floorLayers that collide
RISK-001Two live scan enginesHome laser uses processBadgeScan (801, duplicate check before API). Camera uses useBadgeScanner (503, duplicate check after API, different charset). Same Redux arrays.Home vs SCANQR
RISK-002801 vs 503Home “no save, pick another space” is 801. Header sync, space sync, camera, Dashboard look for 503. If the server sends only one of these, one path queues and the other refuses.Contract
RISK-003408 meaning differsHome: 408 → save offline. Dashboard laser (dead UI): 408 → no save. Bulk sync: 408 → mark Timeout synched: true (leaves retry queue).Scan vs sync
RISK-004Duplicate state: arrays + counterstotalCount / unsyncCount incremented on write. Home UI recounts from arrays. Camera still shows/uses counters. Drift after bulk sync or account filter.Redux
RISK-005userToken never writtenAPI always reads AsyncStorage bearer. Login never sets it. Dead interceptor. Confusing in 401 debates.Auth
RISK-006Two “am I online” implementationsLogin/logout/space: isInternetConnected (NetInfo reachability). Home scan: Google 204 ping, 10s debounce. Dashboard: isConnected only. Same user can be “online” for login and “offline” for scan.Network helpers
RISK-007Success copy for unsynced scansOperator hears success; server never got the lead. Leads to “mobile stored it, backend missing it.” Both can be true.Product + contract
RISK-008No persist transactionredux-persist writes a JSON blob. Kill mid-write can corrupt or drop last scan. No SQLite rollback.Persistence
RISK-009Bulk sync is not atomicSequential HTTP. Kill mid-loop = mixed state. 403/404 during sync marked final (synched: true) so they disappear from retry — Excel may show Restricted.Sync
RISK-010Shared badge vault across loginsLogout keeps arrays. Filter by user_id/event_id. Legacy rows with both ids missing attach to the current session (accountBadgeFilter). Wrong-account Excel possible on old data.Persistence + filter
RISK-011Dead Dashboard still in routesThird scan implementation. If an old build or hidden navigate hits it, behavior diverges again.Navigation
RISK-012Client JWT secrets in the APKPer-client HS256 secrets ship in clients.ts. Xporience secret differs from the shared ADNEC/DMG/Terrapinn secret. Anyone who extracts them can mint tokens for that host.Security — backend must not trust client JWT as proof of user
RISK-013Hardcoded hidden-export passwordexportAllSpaceData.ts contains a client-side password. Do not publish it on the operator guide.Security
RISK-014assigned_badges unused in scanStored at space select; Home processBadgeScan does not check a local allow-list. Restriction is 100% backend sync_status / 403.Unclear ownership of “assigned”
RISK-015API helpers swallow throwsuplaodBadgesAPI returns err instead of throwing. Easy to treat an error as a 200 if a caller checks the wrong field.Network
RISK-016Camera vs Home validationHome allows @ in badge regex; camera validateBadge.ts does not. Same badge can fail camera and pass laser.Validation
RISK-017No request idCannot correlate mobile “we sent generateLead” with backend logs without timestamp + badge + device_id.Observability
RISK-018Docs site public vs this folderThese pages are noindex but on the same site. Do not put secrets here. Restrict the path if the site is public.Process
RISK-019Mixing client backendsOne persist blob. Unsynced rows for client A must not POST to client B. Switch guard + client_id tagging prevent this; legacy rows without client_id are treated as DMG.Persistence + network
RISK-020Host WAF vs OkHttp User-AgentSome hosts (e.g. reg.xporience.com) return HTML 403 to default OkHttp UA. App sends AccessControlApp/1.0 (ReactNative). If infra changes allowlists, login can look “broken” again with HTML 403.Infra + mobile headers

Stale-read risks

  • Space list is not Redux; pull-to-refresh is the screen remount/fetch. A space removed on backend can still sit in user.data.space_name until the user changes space.
  • Home isOnline can be up to 10 seconds behind.
  • Device never re-fetches leads from server. Excel is not “backend truth.”

Unclear ownership (ask before assuming intent)

  1. Why camera was not switched to processBadgeScan.
  2. Whether production API emits 801, 503, or both.
  3. Whether delayed offline visited_date is accepted or rejected by backend.
  4. Whether Conference users should be allowed unlimited same-day scans.
  5. Whether 403/404 during sync should stay retryable or become final Excel rows.

Incident log

Copy the template. One row or one block per event. Classification must be one of: Mobile / Backend / Contract / Data / Infrastructure / Device.

Template

Incident ID: INC-YYYY-NNN
Date:
Environment: Production / Staging
Event / space:
App version / build:
Feature: Login | Space | Scan-laser | Scan-camera | Sync | Export | Logout
User action:
Expected (quote scenario matrix row):
Actual:
Path: Home laser / Camera / Sync header / Space switch
Operation: userLogin | getSpaceList | generateLead
HTTP status:
Body code:
message:
sync_status:
Duration:
Device online flags: NetInfo vs scan isOnline
Classification:
Root cause:
Resolution:
Preventive action:
Owner:
Status: Open | Investigating | Resolved

Never paste EPTOKEN, passwords, or Authorization headers. Badge number + last 4 of device_id is enough.

Register

IDDateFeatureClassificationStatusOne-line cause
—————Add the first production incident here

Diagnostics inside the app

Yes — add an internal Diagnostics screen (Settings / hidden tap), not on the operator happy path.

Show only:

  • Environment, app version, build, API base URL
  • user_id, event_id, space_id, space_name, type
  • Network: NetInfo connected / reachable / Home isOnline
  • Last API: operation, HTTP status, body code, message, sync_status, ms, timestamp
  • Queue: unsynced count for current space (from arrays, not unsyncCount)
  • Copy report / export last N metadata lines / clear log

Do not log passwords, tokens, excel password, Authorization.

This is not built yet. Until it is, the incident template above is the process.

What not to do

  • Do not create folders 01–14. New facts go into one of the five docs.
  • Do not fix RISK-001 in the heat of an event without a decision row.
  • Do not tell backend “we never save on 5xx” — Home does save offline on 5xx.