events: document bin/events.js in CLAUDE.md, OPERATIONS.md, CHECKLIST.md

This commit is contained in:
Arlind Ukshini 2026-04-27 10:54:04 +02:00
parent 31bfd72b4c
commit 32c88041ec
3 changed files with 47 additions and 1 deletions

View file

@ -110,6 +110,19 @@ Isolation audit (run after any change to desktop CSS/JS to confirm no mobile reg
- [ ] `sudo -u fenja node /opt/fenja/bin/joins.js stats` totals match what you see in `list`
- [ ] Logged out: `curl -X POST https://project-bifrost.fenja.ai/api/bifrost-join` → 401 (auth gate holds)
## H1b. After changes to engagement event tracking (events)
- [ ] [browser, logged out] Log in fresh via the entrance form → entrance advances to the welcome step
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js list --type login --limit 5` shows a new row with your email, current timestamp, populated device/os/browser, and a session-ID prefix
- [ ] [browser, logged in] Visit `/timeline` → page loads
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js list --type timeline_view --limit 5` shows a new row with `view=desktop forced=false` (or `view=mobile forced=false` if you tested on a phone UA)
- [ ] [browser] Visit `/timeline?view=mobile` from a desktop UA → mobile page renders
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js list --type timeline_view --limit 5` shows the most recent row with `view=mobile forced=true`
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js summary` includes your email with correct `LOGINS` and `TIMELINE` counts
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js stats` totals match what `list` shows; device breakdown reflects the views you generated
- [ ] `sudo -u fenja node /opt/fenja/bin/events.js for <yourtestemail>` shows full per-user history
- [ ] No 500s in `journalctl -u fenja -n 100` from the test traffic
## H2. After changes to the hidden admin page (`/fenjaops`)
Covers `admin/`, the `/api/fenjaops/*` endpoints, and `requireAdmin`.

View file

@ -18,6 +18,8 @@ npm start # production start
node bin/invite.js add <email> # invite (also: remove, list)
node bin/joins.js list # read join-CTA click log
# (also: summary, for <email>, stats)
node bin/events.js list # read engagement event log
# (also: summary, for <email>, stats)
```
There is no test suite, linter, or build step. Verification is the checklist in `CHECKLIST.md`, primarily by walking the entrance → code → timeline flow in a browser.
@ -67,4 +69,4 @@ These are from `PROJECT.md`. A change that breaks any of them is a security regr
- ESM imports only, Node 20+.
- File headers use the `// ─── ... ───` comment banner style. Match it when editing existing files.
- `bin/invite.js` and `bin/joins.js` are the admin CLIs — there is no web UI for either by design. `invite.js` manages the invite list; `joins.js` reads the CTA click log.
- `bin/invite.js`, `bin/joins.js`, and `bin/events.js` are the admin CLIs — there is no web UI for them by design. `invite.js` manages the invite list; `joins.js` reads the final-CTA click log; `events.js` reads the engagement event log (logins, timeline views).

View file

@ -87,6 +87,37 @@ sudo -u fenja sqlite3 /opt/fenja/data/fenja.sqlite \
"SELECT email, datetime(clicked_at/1000,'unixepoch') FROM bifrost_joins ORDER BY clicked_at DESC;"
```
## Reading engagement events
Logins and timeline page views are logged to the `events` table. Each row carries the user's email, a timestamp, the session ID, and device fields parsed from the User-Agent (`device_type`, `os`, `browser`). Use `bin/events.js` to read it:
```bash
# Every event, newest first (filter with --type, page with --limit)
sudo -u fenja node /opt/fenja/bin/events.js list
sudo -u fenja node /opt/fenja/bin/events.js list --type login --limit 50
# One row per user — login count, timeline-view count, last seen
sudo -u fenja node /opt/fenja/bin/events.js summary
# Full event history for a single user
sudo -u fenja node /opt/fenja/bin/events.js for someone@example.com
# Totals per event type + device-type breakdown
sudo -u fenja node /opt/fenja/bin/events.js stats
```
Events recorded:
- `login` — written on `POST /auth/login` success. One row per fresh login (cookie-loss re-logins included). The `meta` column is empty.
- `timeline_view` — written on every `GET /timeline`. `meta` is `{view: "mobile"|"desktop", forced: true|false}`; `forced=true` means the user passed `?view=mobile` or `?view=desktop` to override the UA guess.
For ad-hoc SQL:
```bash
sudo -u fenja sqlite3 /opt/fenja/data/fenja.sqlite \
"SELECT event_type, email, datetime(occurred_at/1000,'unixepoch'), device_type, os, browser FROM events ORDER BY occurred_at DESC LIMIT 50;"
```
## Service control
```bash