Files
inkreach-teable-cli/.agents/skills/inkreach-teable/guides/subscription.md
T
yeuimu 035384131c feat(view-preset): shared view presets with fork-on-edit semantics
Lands the view-preset / server-persisted personal-layer feature that has
been running in production, plus the hotfix for "the same preset shows
different filter configs to different users" (物流问题-已出轨迹 on
tblgsJTXhqwiDpsjeL5 / viwyszJmLQNOLhA9sh5).

Root cause of the divergence:
- usePersonalViewSync implicitly flushed any overlay edit by a
  view|update user INTO the shared preset row (last-writer-wins). Overlays
  are stale snapshots seeded at apply time, so one user's seed silently
  erased colleagues' filter changes (2026-09-17 02:55 the preset lost the
  流转角色=售后 condition), and active overlays never converged because
  preset updates do not propagate.

Fix (semantics: presets are shared definitions, edits are personal):
- fork-on-edit: the first user edit strips the seed markers from the
  overlay (toolbar switches to the personal config); edits only ever
  write the user's personal row
- shared presets change ONLY through the new explicit, confirmed
  "Update to current config" row action (canManage users)
- un-edited preset overlays auto-follow redefinitions: applyPreset stamps
  a presetVersion (preset.lastModifiedTime); when the preset list
  refetches with a newer row the overlay re-seeds. Edited overlays carry
  no markers and are never clobbered. Legacy rows without a version
  re-seed exactly once
- exits strip both seed markers from the persisted personal row

Also lands the pending WIP shipped with the deployed build: select-choice
visibility constraint, personal-view server sync + proxy, grid async
records scope/request tracking, CLI resource display, preset i18n (10
locales), view_preset migrations, docs/skill updates, .zcode gitignore.

Verified end-to-end on the live instance (headless chromium, real
session): apply -> edit flips toolbar to Personal with ZERO shared-row
PUTs; explicit update PUTs the shared row; API-side redefinition
auto-reseeds an un-edited overlay on the next list refetch.
2026-09-17 04:07:30 +00:00

2.3 KiB

Record Subscriptions

Digest/instant email subscriptions over table records. Full CRUD via subscription list/get/create/update/delete/events/send.

Commands

inkreach-teable subscription list
inkreach-teable subscription get <subscriptionId>
inkreach-teable subscription create --name "Daily escalations" --table-id tblXXX [options]
inkreach-teable subscription update <subscriptionId> [options]
inkreach-teable subscription delete <subscriptionId>
inkreach-teable subscription events <subscriptionId>
inkreach-teable subscription send <subscriptionId>      # force a digest send now

Options (create/update)

Option Meaning
--name Display name
--table-id Target table
--no-watch-created / --no-watch-updated Exclude create/update events
--field-ids '<json>' Restrict watched fields
--record-ids '<json>' Restrict watched records
--display-field-id <fld> Field shown in the digest row
--attach-csv / --no-attach-csv Attach matching records as CSV
--filter '<IFilter json>' Scope: only records matching this filter
--trigger-on-enter Notify only on the transition INTO the filter condition (requires --filter); default is state semantics (every matching change)
--send-mode digest|instant Digest (batched on schedule) or instant email
--recipients '<a@x.com,b@y.com>' Email recipients
--no-notify-in-app Disable in-app notification
--schedule-type daily|weekly|hours|minutes Digest schedule kind
--schedule-time HH:mm Daily/weekly fire time
--schedule-weekday 0-6 Weekly day (0 = Sunday)
--schedule-interval n Interval for hours/minutes modes
--inactive Create/update in inactive state

Semantics & gotchas

  • --filter uses the SAME IFilter shape as view filters. Date values: {"mode":"exactDate","exactDate":"2026-08-21","timeZone":"Asia/Shanghai"}. User values are id arrays ("Me" resolves to the subscription creator).
  • Filter fields must be visible to the creator (enforced server-side, fail-closed: unknown operator or deleted field never matches).
  • --trigger-on-enter implements "notify only when it starts matching" (e.g. status turns critical); the default state semantics notify on every matching change.