mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-26 06:19:49 +00:00
docs(store): push prose describes the enqueue, registration and dispatcher as owed, not built (TASK-3937 part A r4 L1)
Ruled a fix once part B could not merge in the same window as A (r4 hunter L1). 155's header, migrated.go's push-delivery notes and the settings model now say the enqueue is part B's, registration TASK-3938's and the dispatcher TASK-3939's. nulExcluded's push reasons gain a header saying they are the writers' contract, and each names the unit that owes it: device columns TASK-3938, queue columns part B, the claim and send columns TASK-3939. user_notification_settings keeps TASK-3937; PutNotificationSettings writes it today. Claude-Session: https://claude.ai/code/session_01JRXHP9ZVfEN3YEuzmucxP3
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package models
|
||||
|
||||
// NotificationSettings are a person's recipient-side push filters (TASK-3937).
|
||||
// The dispatcher (TASK-3939) is to apply them; the enqueue does not, so
|
||||
// changing one never rewrites the queue.
|
||||
// The dispatcher (TASK-3939) is to apply them and the enqueue (TASK-3937
|
||||
// part B) is not to, so changing one will never rewrite the queue.
|
||||
type NotificationSettings struct {
|
||||
PushEnabled bool `json:"push_enabled"`
|
||||
NotifyAssigned bool `json:"notify_assigned"`
|
||||
|
||||
@@ -114,9 +114,9 @@ const MigratedMarker = "PAD_MIGRATED_TO_POSTGRES"
|
||||
// database. Refusing them would claim a loss the migration never promised
|
||||
// to prevent.
|
||||
// - PUSH DELIVERY STATE (push_devices, user_notifications; TASK-3937):
|
||||
// a device row is bound to the session that registered it, and the
|
||||
// migration does not carry sessions, so every device is re-registered
|
||||
// after the operator signs in again; the queue is delivery state, not a
|
||||
// a device row is bound to the session that registers it (TASK-3938),
|
||||
// and the migration does not carry sessions, so every device is to
|
||||
// re-register after the operator signs in again; the queue is delivery state, not a
|
||||
// person's data: a lost row is one push not sent. (Its dispatcher and
|
||||
// 7-day sweep land with TASK-3939; until then nothing reads or deletes
|
||||
// it.) Both are excluded as "push-delivery" in migratedExcludedTables,
|
||||
@@ -282,8 +282,8 @@ var migratedExcludedTables = map[string]string{
|
||||
"sqlite_sequence": "bookkeeping",
|
||||
|
||||
// PUSH DELIVERY STATE (TASK-3937): a device row is bound to a session the
|
||||
// migration does not carry, so it is re-registered after sign-in; a queue
|
||||
// row lost is one push not sent. user_notification_settings is refused.
|
||||
// migration does not carry, so it is to re-register after sign-in
|
||||
// (TASK-3938); a queue row lost is one push not sent. user_notification_settings is refused.
|
||||
"push_devices": "push-delivery",
|
||||
"user_notifications": "push-delivery",
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
-- Migration 155: push notifications (TASK-3937, PLAN-3908 phase 2 unit 1).
|
||||
--
|
||||
-- push_devices: one row per signed-in app session that registered a push
|
||||
-- token. Every token is an FCM registration token (iOS routes through FCM),
|
||||
-- push_devices: one row per signed-in app session that registers a push
|
||||
-- token (the register endpoint lands with TASK-3938; nothing writes this
|
||||
-- table yet). Every token is an FCM registration token (iOS routes through FCM),
|
||||
-- so there is no environment column: FCM picks the APNs gateway itself.
|
||||
-- platform stays because the FCM payload differs per platform. The row dies
|
||||
-- with its session or its user.
|
||||
--
|
||||
-- user_notifications: the per-event push queue. A row is written ONLY for a
|
||||
-- user who has at least one device, on the transaction of the write that
|
||||
-- caused it. dedupe_key makes the enqueue idempotent per (user, key). item_id
|
||||
-- and comment_id carry no foreign key: the dispatcher skips a row whose
|
||||
-- subject is gone, and retention removes the rest. Retention is NOT in this
|
||||
-- user_notifications: the per-event push queue. Nothing writes it yet: the
|
||||
-- enqueue is TASK-3937 part B, and it is to write a row ONLY for a user who
|
||||
-- has at least one device, on the transaction of the write that caused it.
|
||||
-- dedupe_key is what makes that enqueue idempotent per (user, key). item_id
|
||||
-- and comment_id carry no foreign key: the dispatcher is to skip a row whose
|
||||
-- subject is gone, and retention to remove the rest. Retention is NOT in this
|
||||
-- migration: the 7-day sweep lands with the dispatcher (TASK-3939), and until
|
||||
-- then nothing deletes a queue row. workspace_id cascades, so a purged
|
||||
-- workspace leaves no queue behind. actor_user_id is indexed because deleting
|
||||
@@ -18,7 +20,7 @@
|
||||
--
|
||||
-- user_notification_settings: a person's recipient-side filters. No row means
|
||||
-- the defaults. The dispatcher (TASK-3939) is to apply them; the enqueue
|
||||
-- does not.
|
||||
-- (part B) is not to.
|
||||
--
|
||||
-- workspace_read_cursors (149) stays separate: it must exist for every user,
|
||||
-- with or without a device, and this queue is to be deleted after 7 days.
|
||||
|
||||
@@ -303,7 +303,8 @@ var nulColumns = []nulColumn{
|
||||
{"item_verifications", "created_by", classText},
|
||||
{"item_verifications", "agent_name", classText},
|
||||
|
||||
// push_devices (TASK-3937): all three arrive in a registration request body.
|
||||
// push_devices (TASK-3937): all three are to arrive in a registration
|
||||
// request body, whose endpoint lands with TASK-3938.
|
||||
{"push_devices", "connection_id", classText},
|
||||
{"push_devices", "token", classText},
|
||||
{"push_devices", "app_version", classText},
|
||||
@@ -433,27 +434,34 @@ func NULProtectedColumns() []nulColumn {
|
||||
// column someone looked at and excluded" — without it, the test's only options
|
||||
// on an unlisted column are to fail on every known exclusion or to ignore the
|
||||
// class entirely.
|
||||
//
|
||||
// The push_devices and user_notifications reasons (TASK-3937) state the
|
||||
// CONTRACT their writers must keep, and none of those writers exists yet: the
|
||||
// device register endpoint is TASK-3938, the enqueue is TASK-3937 part B, and
|
||||
// the dispatcher's claim and send columns are TASK-3939. Each names the unit
|
||||
// that owes it. user_notification_settings is written today, by
|
||||
// PutNotificationSettings.
|
||||
var nulExcluded = map[string]string{
|
||||
"push_devices.id": "server-minted device UUID (TASK-3937, migration 155)",
|
||||
"push_devices.user_id": "the authenticated user's server-minted UUID (TASK-3937)",
|
||||
"push_devices.session_id": "server-minted session id read from the authenticated session (TASK-3937)",
|
||||
"push_devices.platform": "fixed enum ios | android, a CHECK constraint (TASK-3937)",
|
||||
"push_devices.created_at": "server timestamp from now() (TASK-3937)",
|
||||
"push_devices.updated_at": "server timestamp from now() (TASK-3937)",
|
||||
"user_notifications.id": "server-minted notification UUID (TASK-3937, migration 155)",
|
||||
"user_notifications.user_id": "server-minted user UUID read from items and comments rows (TASK-3937)",
|
||||
"user_notifications.workspace_id": "server-minted workspace UUID from the written row (TASK-3937)",
|
||||
"user_notifications.item_id": "server-minted item UUID from the written row (TASK-3937)",
|
||||
"user_notifications.comment_id": "server-minted comment UUID from the written row (TASK-3937)",
|
||||
"user_notifications.kind": "fixed server constant, a CHECK constraint (TASK-3937)",
|
||||
"user_notifications.actor_user_id": "server-minted user UUID of the authenticated writer (TASK-3937)",
|
||||
"user_notifications.dedupe_key": "server-built from a fixed kind and server-minted ids and timestamps (TASK-3937)",
|
||||
"user_notifications.created_at": "server timestamp from now() (TASK-3937)",
|
||||
"user_notifications.push_state": "fixed server constant, a CHECK constraint (TASK-3937)",
|
||||
"push_devices.id": "server-minted device UUID (TASK-3938, migration 155)",
|
||||
"push_devices.user_id": "the authenticated user's server-minted UUID (TASK-3938)",
|
||||
"push_devices.session_id": "server-minted session id read from the authenticated session (TASK-3938)",
|
||||
"push_devices.platform": "fixed enum ios | android, a CHECK constraint (TASK-3938)",
|
||||
"push_devices.created_at": "server timestamp from now() (TASK-3938)",
|
||||
"push_devices.updated_at": "server timestamp from now() (TASK-3938)",
|
||||
"user_notifications.id": "server-minted notification UUID (TASK-3937 part B, migration 155)",
|
||||
"user_notifications.user_id": "server-minted user UUID read from items and comments rows (TASK-3937 part B)",
|
||||
"user_notifications.workspace_id": "server-minted workspace UUID from the written row (TASK-3937 part B)",
|
||||
"user_notifications.item_id": "server-minted item UUID from the written row (TASK-3937 part B)",
|
||||
"user_notifications.comment_id": "server-minted comment UUID from the written row (TASK-3937 part B)",
|
||||
"user_notifications.kind": "fixed server constant, a CHECK constraint (TASK-3937 part B)",
|
||||
"user_notifications.actor_user_id": "server-minted user UUID of the authenticated writer (TASK-3937 part B)",
|
||||
"user_notifications.dedupe_key": "server-built from a fixed kind and server-minted ids and timestamps (TASK-3937 part B)",
|
||||
"user_notifications.created_at": "server timestamp from now() (TASK-3937 part B)",
|
||||
"user_notifications.push_state": "fixed server constant, a CHECK constraint (TASK-3939)",
|
||||
"user_notifications.skip_reason": "fixed server constant set by the dispatcher (TASK-3939)",
|
||||
"user_notifications.claim_token": "server-minted UUID (TASK-3937)",
|
||||
"user_notifications.claimed_at": "server timestamp from now() (TASK-3937)",
|
||||
"user_notifications.sent_at": "server timestamp from now() (TASK-3937)",
|
||||
"user_notifications.claim_token": "server-minted UUID (TASK-3939)",
|
||||
"user_notifications.claimed_at": "server timestamp from now() (TASK-3939)",
|
||||
"user_notifications.sent_at": "server timestamp from now() (TASK-3939)",
|
||||
"user_notification_settings.user_id": "the authenticated user's server-minted UUID (TASK-3937, migration 155)",
|
||||
"user_notification_settings.updated_at": "server timestamp from now() (TASK-3937)",
|
||||
"workspace_import_status.workspace_id": "server-minted workspace UUID, a foreign key to workspaces(id) (TASK-896, migration 131)",
|
||||
|
||||
Reference in New Issue
Block a user