feat: interaction / event logging
New `events` table with (user_id, kind, created_at, data JSON). Instruments: Bot: - cmd.start, cmd.history, cmd.stats, cmd.delete, cmd.export, cmd.feedback - workout.save (source=text), workout.delete (source=bot) Server: - workout.save (source=webapp), workout.update, workout.delete (source=webapp) - POST /api/events for Mini App client-side events Mini App: - miniapp.open on init() - set.add on addSet(), with exercise name / reps / weight (per-set timestamps unlock the rest-timer feature later) log_event swallows failures so it can never break a caller. get_events supports user_id / kind filtering for inspection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1d3e7d5e80
commit
52277e99de
5 changed files with 187 additions and 2 deletions
|
|
@ -29,6 +29,24 @@ async function api(method, path, body = null) {
|
|||
return res.json();
|
||||
}
|
||||
|
||||
// ── Event logging (fire-and-forget) ─────────────────────────────
|
||||
function logEvent(kind, data) {
|
||||
if (!userId) return;
|
||||
try {
|
||||
fetch(API + "/events", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Telegram-Init-Data": tg.initData,
|
||||
},
|
||||
body: JSON.stringify({ kind, data: data || null }),
|
||||
keepalive: true,
|
||||
}).catch(() => {});
|
||||
} catch (e) {
|
||||
// Never let logging break anything
|
||||
}
|
||||
}
|
||||
|
||||
// ── Toast ───────────────────────────────────────────────────────
|
||||
function showToast(msg) {
|
||||
let toast = document.querySelector(".toast");
|
||||
|
|
@ -330,6 +348,12 @@ function addSet() {
|
|||
addSetToDOM(reps, weight);
|
||||
syncEditorUI();
|
||||
|
||||
logEvent("set.add", {
|
||||
exercise: currentExercise?.name || null,
|
||||
reps,
|
||||
weight_kg: weight,
|
||||
});
|
||||
|
||||
repsInput.value = "";
|
||||
weightInput.value = weight ? String(weight) : "";
|
||||
repsInput.focus();
|
||||
|
|
@ -784,6 +808,7 @@ async function loadVersion() {
|
|||
async function init() {
|
||||
loadVersion();
|
||||
if (!userId) return;
|
||||
logEvent("miniapp.open");
|
||||
try {
|
||||
const data = await api("GET", "/exercises");
|
||||
knownExercises = data.exercises || [];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue