Commit Graph
6 Commits
Author SHA1 Message Date
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
yeuimu e1a91dfa84 feat(cli+skill): make documented field UX real + fix skill doc drift
CLI (packages/inkreach-cli):
- new src/lib/field-normalize.ts: type aliases (sel/num/text/mul/…),
  select string-choices -> {name}, compact --fields 'Name:type:choices'
  expansion, smart type inference from --options shape / --name
  (--type now optional), name->ID resolution for foreignTableName /
  linkFieldName / lookupFieldName (incl. link-field foreignTableId
  backfill + unknown-key stripping), rating/number/button required-
  option defaults
- field create: +--description/--lookup-options/--is-lookup
- field update --options + table create --fields route through the
  normalizer; DEFAULT_ENDPOINT :3000 -> :3003
- 20 unit tests (field-normalize.spec.ts, vitest); live-verified:
  string choices, alias, foreignTableName, lookup-by-names, compact
  format, inference (priority->singleSelect, max:5->rating)

Skill docs (.agents/skills/inkreach-teable):
- ports :3000 -> :3003 everywhere (backend real port; :3000 is an
  unrelated container on this host)
- remove dead hr_admin account; note throwaway signup + real admin
- plugin register: actual URL-based flags; document plugin csp
  list/set; view/dashboard install requires config enable first
- field-types.md marked verified-2026-08 (aliases/inference/name
  resolution now implemented + tested)
- development.md: webpack dist/index.js cache trap; PGPASSWORD
  placeholder instead of wrong literal
2026-08-16 05:58:01 +00:00
yeuimu 10b52db8b2 fix(field): enforce select-visibility guard on the V2 convert path + repair inkreach-cli field routes
- FieldOpenApiV2Service.convertField now calls the shared V1 validator
  (assertSelectVisibilityConfigValid) before executing the update command.
  Previously only the V1 path validated self-reference / dependency cycles,
  so invalid configs could be persisted through V2 (verified live: a
  self-referencing choice was accepted with 200).
- V1 assertSelectVisibilityConfigValid private -> public (shared guard).
- Unit tests: 3 new cases in field-open-api-v2.service.spec.ts (guard
  invoked with exact args; rejects before executing when validator throws;
  called with raw type/options for non-select conversions). 63/63 pass;
  tsc build config 0 errors.
- inkreach-cli: field get/update/delete targeted non-existent /api/field/:id
  routes; now use /api/table/:tableId/field/:fieldId. update --options goes
  through the convert API (the PATCH update API strips options by design).
  New: convertField + getVisibleChoices client methods, field visible-choices
  command (evaluates choice visibility for a record).
2026-08-16 05:31:05 +00:00
yeuimu e1d6b03a61 fix: getRecords action page→take/skip + prisma engine fix + CLI fixes
- getRecords automation action: translate page/pageSize to skip/take
  before calling the records API (which ignores page/pageSize, causing
  pagination to always return first 100 records)
- Add postbuild script to restore correct prisma engine binary after
  nest build (which generates an incompatible engine causing SIGSEGV)
- CLI fixes (from earlier commits):
  - deleteRecords: query params instead of JSON body
  - deleteTable: add /base/{baseId} prefix
2026-08-07 16:55:18 +00:00
yeuimu 3810c33d69 refactor: rename CLI command 'inkreach' -> 'inkreach-teable'
Rename the command (and its config namespace) to match the project name:

- bin:          inkreach        -> inkreach-teable
- program name: inkreach        -> inkreach-teable
- config dir:   ~/.inkreach/    -> ~/.inkreach-teable/
- env vars:     INKREACH_*      -> INKREACH_TEABLE_*
- all docs (SKILL.md, guides, api-reference, AGENTS.md, design doc, install.sh)

Unchanged (intentional):
- npm package name: @inkreach/teable-cli
- package directory: packages/inkreach-cli/
- skill name: inkreach-teable-ops
- organization/authors: 'inkreach' (npm scope @inkreach)

Existing config auto-migrated (~/.inkreach -> ~/.inkreach-teable). Verified
end-to-end: auth status, workflow list (636), build clean.
2026-08-05 10:14:26 +08:00
yeuimu 5fa843df05 feat: add inkreach CLI + inkreach-teable-ops skill
A self-built CLI and companion agent skill for operating a deployed
inkreach-teable instance — configuring tables, fields, records, views, and
the project's OWN automation engine.

Why not the official 'teable' CLI:
  inkreach-teable's automation is self-built with a different contract:
  - conditions (not filter), fieldIds (not watchFieldIds)
  - recordCondition (not recordMatchesConditions)
  - webhook route /api/webhook/{baseId}/{wfId} (not the /base//workflow/ form)
  - scheduledTime backend honors only timing.type + timing.interval
  The official CLI targets the upstream contract and 404s/misconfigures here.
  Table/field/record/view APIs ARE upstream-compatible, but automation is not.

inkreach CLI (packages/inkreach-cli/):
  - Node.js + commander, zero extra runtime deps
  - Uses node:http (NOT fetch — Node 24 fetch drops Authorization header)
  - Commands: auth (login/status/token), base/table/field/record/view,
    workflow (list/get/create/update/delete/activate/deactivate/test),
    trigger set (8 types, builds correct config keys), action add/update/delete
    (6 types), secret, runs (list/get/rerun), fire (button-click/webhook), sql
  - --json mode for agent parsing; GET->modify->PUT whole-graph for node edits
  - Verified end-to-end: create workflow -> set webhook trigger -> add script
    action -> activate -> fire webhook -> runs list (succeeded)

inkreach-teable-ops skill (.agents/skills/inkreach-teable-ops/):
  - SKILL.md entry: module map, routing rules, 11 key constraints (the real
    contract keys), execution rules, error recovery
  - guides/: cli-reference, automation-guide, tables-fields, instance-access,
    development (build/restart, known gotchas)
  - api-reference/: trigger-types (8 triggers, exact config), action-types
    (6 actions, sandbox globals), field-types (21 types incl. Button)
  - metadata.json + install.sh
2026-08-05 02:04:39 +08:00