mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-27 14:57:15 +00:00
eb7f8a200c
IDEA-3906 half A, unit A2.
- Migrations 153 (SQLite) and 122 (Postgres) add item_needs_snoozes, one
row per (user, item), FKs cascading, indexed on item_id.
- A deferral holds until defer_until (an RFC3339 time after now and within
366 days), whatever changes before then (IDEA-3906 A2). A fractional time
is stored rounded up to the next whole second, never early.
- A dismissal holds until something happens after its marker: a live
comment by anyone else newer than seen_comment_at, another such comment
at that same second (seen_comment_ids), or a later status transition
(MAX(status_transitions.seq); items.seq and updated_at don't move on a
comment). The user's own human comments never break it; an agent's
comments under their credentials do, and so does the user's own status
change. Imported comments are history and never break it.
- The marker comes from the client, clamped to the server's values so it
can only claim less was seen. No marker means the current state.
- PUT|DELETE /api/v1/workspaces/{ws}/items/{slug}/needs/snooze, beside
stars and watches: requireItemVisible (404 when hidden) and no edit
check, so viewers and item-grant guests may snooze. Read-scoped tokens
are refused by tokenScopeAllows. DELETE is idempotent.
- nulcolumns classifies the table's TEXT columns as server-written.
- A migrate-to-pg marked SQLite file refuses snooze writes: the table joins
migratedRefusalTables, since models.WorkspaceExport does not carry it.
TestMigratedDatabaseRefusesNeedsSnoozeWrites drives the store's own verbs
rather than iterating the list, so removing the entry goes red.
- Workspace purge relies on the FK cascade; the purge census
(wsChildTables, seedFullWorkspace) now counts item_needs_snoozes.
- docs/api.md documents the endpoint.
Claude-Session: https://claude.ai/code/session_018oQ5EErQKHtBJK8yLpcDNF
32 lines
1.3 KiB
Go
32 lines
1.3 KiB
Go
package models
|
|
|
|
// NeedsSnoozeMarker is what a person had seen of an item when they dismissed
|
|
// it from their needs-you inbox (TASK-3918, IDEA-3906): the newest comment
|
|
// by anyone else, the ids of the comments at that same second, and the
|
|
// item's latest status-transition seq. The server clamps a client's marker
|
|
// to its own values, so a marker can only ever claim LESS was seen.
|
|
type NeedsSnoozeMarker struct {
|
|
SeenCommentAt string `json:"seen_comment_at"`
|
|
SeenCommentIDs []string `json:"seen_comment_ids"`
|
|
SeenTransitionSeq int64 `json:"seen_transition_seq"`
|
|
}
|
|
|
|
// NeedsSnooze is one person's dismissal or deferral of one item.
|
|
type NeedsSnooze struct {
|
|
ItemID string `json:"item_id"`
|
|
WorkspaceID string `json:"workspace_id"`
|
|
Kind string `json:"kind"` // NeedsSnoozeDismiss or NeedsSnoozeDefer
|
|
DeferUntil string `json:"defer_until,omitempty"`
|
|
Marker NeedsSnoozeMarker `json:"marker"`
|
|
CreatedAt string `json:"created_at"`
|
|
// Holds reports whether the snooze still hides the item, computed at
|
|
// read time: a deferral until its date, a dismissal until something
|
|
// happens on the item after the marker.
|
|
Holds bool `json:"holds"`
|
|
}
|
|
|
|
const (
|
|
NeedsSnoozeDismiss = "dismiss"
|
|
NeedsSnoozeDefer = "defer"
|
|
)
|