Reliability / correctness:
- Always arm the graceful-shutdown safety timeout. Previously
`shutdown(force=true)` (called from uncaughtException) skipped the
timeout entirely, so a hung `framework.stop()` after a crash would
wedge the process until Docker's SIGKILL. Now uses 3s when forced,
8s otherwise, and .unref()s so it never blocks a clean exit.
- Attach a `.catch()` to `framework.start()` so a bad Webex token or
WebSocket handshake failure produces a clear "Webex framework failed
to start" error line instead of a bare Unhandled Rejection while the
bot silently stays dead.
- Rename MDM timestamp labels from "(EDT)" to "(ET)" since the
formatter uses DST-aware America/New_York (half the year it's EST).
Cleanup:
- Drop `body-parser` in favor of the built-in `express.json()`
(Express 4.16+). Removes one direct dep; still present as a
transitive dep of express itself.
- Remove orphaned JSDoc block referring to a helper that no longer
exists.
- Delete legacy `query-offline.js` (marked deprecated since the bot
`offline` command shipped) and remove its `APPSPACE_API_TOKEN` /
`APPSPACE_BASE_URL` env vars from `.env.example` and the
`offline:legacy` npm script from `package.json`.
Config / metadata:
- Add `"engines": { "node": ">=20" }` to package.json so npm warns on
the wrong Node version instead of just the README saying so.
- Document `SMOKE_TEST=true` in `.env.example`.
Docs:
- Rewrite README to document the `restart-offline` command (iOS
Supervised requirement, 50-device cap, concurrency, audit log
fields, fresh-at-execute semantics), the ET-not-EDT labeling,
structured error logging, character-budget rendering, and the
new CI workflow. Refresh the TODO section to reflect what has
actually shipped.
CI:
- Add `.gitea/workflows/ci.yml` with two jobs: syntax check
(`node --check` on index.js and mdm.js) and a Docker smoke test
that builds the production image, boots it with dummy credentials
+ SMOKE_TEST=true, and waits up to 30s for the container's
built-in healthcheck to reach `healthy`. Dumps container logs
on failure.
Co-authored-by: Cursor <cursoragent@cursor.com>
24 lines
1.2 KiB
JSON
24 lines
1.2 KiB
JSON
{
|
|
"name": "appspace-webex-alerts",
|
|
"version": "1.0.0",
|
|
"main": "index.js",
|
|
"engines": {
|
|
"node": ">=20"
|
|
},
|
|
"scripts": {
|
|
"start": "node index.js",
|
|
"dev": "node index.js",
|
|
"docker:dev": "docker compose --profile dev up app-dev",
|
|
"docker:prod": "docker compose up -d",
|
|
"docker:smoke": "echo '🚀 Running Docker smoke test (build + health check)...' && docker compose --profile smoke build smoke-test && docker compose --profile smoke up -d smoke-test && (for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30; do status=$(docker inspect --format='{{.State.Health.Status}}' appspace-smoke-test 2>/dev/null || echo 'none'); if [ \"$status\" = 'healthy' ]; then echo '✅ Smoke test PASSED: container healthcheck is healthy'; success=1; break; fi; sleep 1; done; if [ -z \"$success\" ]; then echo \"❌ Smoke test FAILED: final health status was $status\"; docker compose --profile smoke logs --tail=100 smoke-test; false; fi) ; docker compose --profile smoke down --remove-orphans smoke-test 2>/dev/null || true"
|
|
},
|
|
"dependencies": {
|
|
"axios": "^1.7.2",
|
|
"dotenv": "^16.4.5",
|
|
"express": "^4.19.2",
|
|
"webex-node-bot-framework": "^2.5.1"
|
|
},
|
|
"devDependencies": {
|
|
"nodemon": "^3.1.14"
|
|
}
|
|
}
|