diff --git a/src/models/LASTOPENEDAT.md b/src/models/LASTOPENEDAT.md new file mode 100644 index 00000000..44867988 --- /dev/null +++ b/src/models/LASTOPENEDAT.md @@ -0,0 +1,116 @@ +# `lastOpenedAt` — operating notes + +## What it is + +A Date field on the `User` schema that tracks **real app-open events** — when an +authenticated user genuinely opens or re-opens the AXS Map app. + +Distinct from existing fields: + +| Field | When set | Semantics | +|---|---|---| +| `lastLogin` | Sign-in flows | Last successful password / social sign-in | +| `lastActivityTime` | ⚠️ **Every authenticated API call** (`helpers/index.js:isAuthenticated`) | Way too noisy — every background poll updates this. Source of the May 2026 user-status bug. | +| **`lastOpenedAt`** | **Sign-in flows + token refresh** | Real app-open signal. Used by future Salesforce User Status logic. | + +## Where it IS set (only these places) + +| File | When | +|---|---| +| `routes/auth/sign-in.js` | Successful email+password sign-in | +| `routes/auth/apple-sign-in.js` | Successful Apple sign-in (new or existing user) | +| `routes/auth/google-sign-in.js` | Successful Google sign-in (new or existing user) | +| `routes/auth/facebook-sign-in.js` | Successful Facebook sign-in (new or existing user) | +| `routes/auth/generate-token.js` | Successful refresh-token → new JWT (the AXS Map app was re-opened after the previous JWT expired) | + +Every update logs to stdout: +``` +[app-open] sign-in: userId= lastOpenedAt=2026-05-23T18:00:00.000Z +[app-open] google-sign-in (existing): userId= lastOpenedAt=... +[app-open] token-refresh: userId= lastOpenedAt=... +``` + +This is the audit trail — easy to grep for in CloudWatch / log aggregators. + +## Where it is NOT set (and must NEVER be set) + +- ❌ `helpers/index.js:isAuthenticated` middleware — this was the trap with + `lastActivityTime`. Setting any "user activity" field on every API request + means even silent background polling counts as activity. **Do not extend this.** +- ❌ Any of the AWS Lambda sync functions (`axs-map-sync-users` etc.) — they + don't read or write this field. Confirmed by code grep. +- ❌ Admin bulk scripts in `src/scripts/db/*` — `import-users.js`, + `update-users-avatars.js`, `migrate-scores.js` — none touch this field. +- ❌ MongoDB Atlas Triggers — they fire change events to AWS EventBridge but + don't update the source doc. +- ❌ Salesforce → MongoDB direction — there is no sync in that direction today. + +## How to verify before/after a deploy + +```bash +cd "/Users/saffiullah/AXS Map API" + +# Snapshot — read schema definition and population counts +node src/scripts/verify-last-opened-at.js + +# Watch a specific user in real time (do this BEFORE signing in via the app): +node src/scripts/verify-last-opened-at.js --watch --user me@example.com + +# Then sign in via the app or POST /auth/sign-in. You should see a single line: +# [