Skip to content

Remove the signalType compatibility shim once 6.0.2+129 is off the installed base #70

Description

@BurningAXE

Signal types were folded into the help-tag vocabulary (helpNeededTags[0] is now a case's category — see docs/SPECIFICATION.md §4.4). The client stopped writing signalType, but 6.0.2+129 and earlier still write it and no tags, and keep doing so for as long as they stay installed. Three pieces of compatibility code exist purely for those builds. This issue is to delete them once that installed base is gone.

They are not a migration. They are a live code path, which is why they went in at all: without them a Blood-donation report from a shipped build pushes as "Rescue needed", because helpNeededTagsOf substitutes the fallback for anything untagged — the server discarding a category the client still sends and still means.

What to delete

1. functions/src/tags.ts

  • RETIRED_SIGNAL_TYPE_TAGS
  • the legacy branch of primarySignalTag() — it collapses to helpNeededTagsOf(data)[0]
  • signalHeadline() can then be inlined back to helpTagHeadline(helpNeededTagsOf(data)[0])

2. functions/src/index.ts

  • the signalType mirror written onto inbox entries in handleSignalCreated
  • the signalType?: number field on the InboxEntry interface

Shipped builds render the inbox row from signalType and fall back to the stored English body without it, so removing this early shows Bulgarian users English text.

3. firestore.rulesusers/{userId}/notifications/{notificationId} create

  • drop 'signalType' from the keys().hasOnly([...]) allow-list
  • drop the !('signalType' in request.resource.data) || ... is int clause
  • helpNeededTags can become required rather than optional-if-present

⚠️ This one is the dangerous half. That rule is the client write path for the arrival catch-up, and NearbySignalChecker swallows a denial — so tightening it while old builds are live makes inbox entries silently stop appearing, with no error anywhere. It is why the allow-list accepts both shapes today.

4. Tests that pin the shim (they should fail loudly when it goes, and be deleted with it)

  • firestore-tests/rules.test.js: accepts the shape the currently-shipped build writes, accepts an entry carrying neither field, accepts both fields at once, as the server mirrors them
  • functions/src/__tests__/recipientSelection.test.ts: the signalHeadline — the phased-release path and primarySignalTag suites

5. docs/SPECIFICATION.md §4.4 — the "live path, not a migration" table describes exactly these three; remove it and the deploy-order note that goes with it.

Also removable, separately

lib/src/widgets/my_notifications_page.dart falls back to the stored English body for inbox rows written before the merge (they carry a signalType int and no tags). Those rows expire on the 90-day inbox TTL, so this can go one quarter after the change shipped — independently of the installed base.

When

When telemetry shows no meaningful traffic from builds predating the tag release. Crashlytics/analytics by app version is the signal; the fan-out's structured log line (functions/src/index.ts, the one with tier counts) will also show untagged signals falling to zero.

Do the client-facing rules tightening (item 3) as its own deploy, after the rest, and re-read the live ruleset afterwards — a rules deploy replaces the whole ruleset, and we have already lost a block that way once (see the 2026-08-15 entry in docs/SPECIFICATION.md).

Verified working

The shim was device-verified on 6.0.2+129 against production: a signalType: 2 signal with no tags pushed as "Blood donation needed — …", not "Rescue needed". Worth re-running that check in reverse when removing it — the same signal should then read "Rescue needed", confirming there is nothing left depending on the old field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions