Skip to content

feat(dm): nothing posts .directMessagesOpenMessage — the deep-link seam has no producer #77

Description

@Adron

Follow-up from PR #69 (G22), recorded during the 2026-09-13 tracker reconciliation.

The gap

PR #69 built and tested the DM deep-link consumer:

  • App/Features/DirectMessages/DirectMessagesRootView.swift:79 — receives .directMessagesOpenMessage and opens the thread
  • App/Features/DirectMessages/DirectMessagesRootView.swift:300 — the notification name

The resolver is covered by tests. But nothing posts the notification. There is no direct-message NotificationKind, and no URL-scheme route produces one. The seam is live, correct, and unreachable.

Why it was left

It is the right half to build first — the consumer is what the feature needs regardless of which producer eventually arrives, and guessing the producer would have meant inventing a notification taxonomy the server does not confirm.

What a producer would be, in likely order

  1. A DM NotificationKind — if the server emits DM notifications, mapping that kind to this notification is the natural producer and makes the bell open the thread.
  2. A URL scheme routeinterlinedlist://dm/{id}, alongside the existing share-link routing.
  3. A push payload — blocked behind spike: can a notarized Developer-ID pkg receive APNs pushes - G9 #59 (can a notarized Developer-ID pkg receive APNs at all).

First step

Probe GET /api/notifications for a DM-shaped kind. If the server already emits one, this is a small mapping change. If it does not, this issue becomes a backend ask and should fold into #58.

Acceptance

  • At least one real producer posts .directMessagesOpenMessage.
  • Opening from that producer lands on the right thread, tested end to end.
  • If no producer is reachable, the seam is documented as intentionally dormant rather than left looking wired.

Probe result (2026-09-15) — the producer exists, and it is candidate 1

This issue's "first step" was: "Probe GET /api/notifications for a DM-shaped kind. If the server already emits one, this is a small mapping change. If it does not, this issue becomes a backend ask and should fold into #58."

It does. GET /api/user/notification-preferences returns the server's own event catalogue:

dig · push · follow · mention · reply · direct_message · share · integration_reconnect

direct_message is a first-class notification event with push and inApp channels. So this is candidate 1 — a DM NotificationKind — and it does not fold into #58.

What landed already

PR #96 adds NotificationKind.directMessage, because the probe that found this also found a much larger defect: the client's whole notification vocabulary was wrong. It matched bare tokens ("dig", "mention") where the server sends prefixed ones ("message_dig", "message_mention"), so all 37 notifications on the recon account fell to .other — filed and fixed as #95.

What is still open here

The producer is deliberately not wired. No DM notification has been observed — the recon account has never received a DM — so the exact type token on a DM row is unconfirmed. .directMessage accepts direct_message, message_direct and dm, and the deep-link post is the one step that waits for a real row.

That is a smaller and better-defined remainder than this issue started with: not "does a producer exist" but "confirm one token, then post the notification."

Remaining work

  1. Receive a DM on the recon account and capture the notification row — the token, and whichever key carries the conversation or message id.
  2. Tighten NotificationKind's DM spellings to the real one.
  3. Map that row's target to a DM conversation (NotificationTarget currently falls through to routePath for .directMessage, since inventing a metadata key would produce a target that silently points nowhere).
  4. Post .directMessagesOpenMessage from the notification tap, and test it end to end.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparityWeb-parity gap with the InterlinedList web app

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions