New /provisionPhone <storeNumber> command manages the store user's
wired desk phones via the same card pattern as /provisionDect:
multi-select checkbox list that doubles as the display, MACs render
as AA:BB:CC:DD:EE:FF, model dropdown for add (defaults to 7841),
side-by-side Add / Remove-checked actions, and every removal goes
through an explicit confirm card. Adds are idempotent (MACs already
registered are skipped) and bulk MAC input is supported.
DECT handsets are filtered out of the display so /provisionPhone and
/provisionDect coexist cleanly on the same store user without
overlapping responsibilities.
Refactors:
- Extract MAC helpers (normalize/format/display) to src/utils/mac.js
so both DECT and wired-phone flows share one implementation. dect.js
re-exports for backward compat with existing consumers.
- Add parseEmailArg helper; migrate /userInfo to use it.
Tests: pure-logic coverage for WIRED_PHONE_MODELS,
isSupportedWiredModel, filterWiredPhones (DECT/model filter), and
parseEmailArg.
Co-authored-by: Cursor <cursoragent@cursor.com>
New /provisionDect slash command manages DECT basestations and handsets
for a store via a single card: multi-select checkbox list doubles as
the display, MACs render as AA:BB:CC:DD:EE:FF, Add/Remove sit
side-by-side per section, and every removal goes through an explicit
confirm card. Handsets always auto-pair (no bind-to-basestation input)
so they roam.
/finalizeStore now idempotently creates the "Store XXXX" DECT network
(DBS-210) with the per-store default access code, so new stores are
DECT-ready the moment finalize completes. Location-scoped lookup
(findDectNetworkInLocation) handles both the finalize idempotency
check and the /provisionDect fallback for freshly-created empty
networks. Non-critical: a store can still go live if the DECT step
fails, and /provisionDect keeps a recovery "create network" prompt
for legacy stores.
Pure-logic helpers (generateDectAccessCode, MAC normalize/format/
display, dectNetworkName) are unit-tested via node:test.
Co-authored-by: Cursor <cursoragent@cursor.com>
- 30-test suite (node --test, no framework) covering the exact functions
that have regressed in previous rounds:
* parseStoreArg / parseStoreNumber / storeEmail (helpers)
* greetingForBrand (brand fallback)
* formatE911Address / formatSuite (google response reducer)
* parseNextLink (RFC-5988 pagination — now exported)
* runStep success / non-critical / critical / no-bot paths
- test/setup.js stubs required env vars so any src/ module can be
imported cleanly; loaded via --import once per test process
- npm run test wired up; directory form works on Node 20 + 22
- .gitea/workflows/ci.yml runs lint + format:check + test on push/PR
to main, on Node 22 to match the runtime image
- Exclude test/ and .gitea/ from the Docker build context
- Exclude docker/ from bot Prettier scope (remote-agent is its own
sub-project with its own tooling)
Co-authored-by: Cursor <cursoragent@cursor.com>