@zykeco/sync-server 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +4 -0
- package/dist/app.js +56 -0
- package/dist/app.js.map +1 -0
- package/dist/db/schema.d.ts +1009 -0
- package/dist/db/schema.js +80 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/env.d.ts +6 -0
- package/dist/env.js +9 -1
- package/dist/env.js.map +1 -1
- package/dist/index.js +2 -23
- package/dist/index.js.map +1 -1
- package/dist/mcp/metric-types.d.ts +2 -0
- package/dist/mcp/metric-types.js +42 -0
- package/dist/mcp/metric-types.js.map +1 -0
- package/dist/mcp/oauth.d.ts +41 -0
- package/dist/mcp/oauth.js +90 -0
- package/dist/mcp/oauth.js.map +1 -0
- package/dist/mcp/server.d.ts +35 -0
- package/dist/mcp/server.js +94 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/timezones.d.ts +17 -0
- package/dist/mcp/timezones.js +32 -0
- package/dist/mcp/timezones.js.map +1 -0
- package/dist/mcp/tools.d.ts +4 -0
- package/dist/mcp/tools.js +236 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/transforms.d.ts +14 -0
- package/dist/mcp/transforms.js +45 -0
- package/dist/mcp/transforms.js.map +1 -0
- package/dist/routes/daily-stress-burden.d.ts +3 -0
- package/dist/routes/daily-stress-burden.js +24 -0
- package/dist/routes/daily-stress-burden.js.map +1 -0
- package/dist/routes/heart-rate-minute.d.ts +3 -0
- package/dist/routes/heart-rate-minute.js +24 -0
- package/dist/routes/heart-rate-minute.js.map +1 -0
- package/dist/routes/hr-zone-history.d.ts +3 -0
- package/dist/routes/hr-zone-history.js +24 -0
- package/dist/routes/hr-zone-history.js.map +1 -0
- package/dist/routes/mcp.d.ts +9 -0
- package/dist/routes/mcp.js +96 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/user-profile.d.ts +3 -0
- package/dist/routes/user-profile.js +24 -0
- package/dist/routes/user-profile.js.map +1 -0
- package/dist/routes/user-timezones.d.ts +3 -0
- package/dist/routes/user-timezones.js +24 -0
- package/dist/routes/user-timezones.js.map +1 -0
- package/dist/routes/wipe.d.ts +6 -1
- package/dist/routes/wipe.js +16 -2
- package/dist/routes/wipe.js.map +1 -1
- package/dist/stores/daily-stress-burden.d.ts +3 -0
- package/dist/stores/daily-stress-burden.js +58 -0
- package/dist/stores/daily-stress-burden.js.map +1 -0
- package/dist/stores/heart-rate-minute.d.ts +3 -0
- package/dist/stores/heart-rate-minute.js +48 -0
- package/dist/stores/heart-rate-minute.js.map +1 -0
- package/dist/stores/hr-zone-history.d.ts +3 -0
- package/dist/stores/hr-zone-history.js +49 -0
- package/dist/stores/hr-zone-history.js.map +1 -0
- package/dist/stores/user-profile.d.ts +3 -0
- package/dist/stores/user-profile.js +76 -0
- package/dist/stores/user-profile.js.map +1 -0
- package/dist/stores/user-timezones.d.ts +3 -0
- package/dist/stores/user-timezones.js +43 -0
- package/dist/stores/user-timezones.js.map +1 -0
- package/drizzle/0001_sweet_firebird.sql +78 -0
- package/drizzle/meta/0001_snapshot.json +733 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +4 -4
package/dist/routes/wipe.js
CHANGED
|
@@ -8,13 +8,27 @@ export function wipeRoutes(stores, auth) {
|
|
|
8
8
|
const body = await parseJsonBody(c, WipeRequest);
|
|
9
9
|
if (body instanceof Response)
|
|
10
10
|
return body;
|
|
11
|
-
const [dailyMetrics, weeklyMetrics, sleepSessions] = await Promise.all([
|
|
11
|
+
const [dailyMetrics, weeklyMetrics, sleepSessions, userTimezones, userProfile, dailyStressBurden, heartRateMinute, hrZoneHistory,] = await Promise.all([
|
|
12
12
|
stores.dailyMetrics.wipeAll(),
|
|
13
13
|
stores.weeklyMetrics.wipeAll(),
|
|
14
14
|
stores.sleepSessions.wipeAll(),
|
|
15
|
+
stores.userTimezones.wipeAll(),
|
|
16
|
+
stores.userProfile.wipeAll(),
|
|
17
|
+
stores.dailyStressBurden.wipeAll(),
|
|
18
|
+
stores.heartRateMinute.wipeAll(),
|
|
19
|
+
stores.hrZoneHistory.wipeAll(),
|
|
15
20
|
]);
|
|
16
21
|
return c.json({
|
|
17
|
-
wiped: {
|
|
22
|
+
wiped: {
|
|
23
|
+
dailyMetrics,
|
|
24
|
+
weeklyMetrics,
|
|
25
|
+
sleepSessions,
|
|
26
|
+
userTimezones,
|
|
27
|
+
userProfile,
|
|
28
|
+
dailyStressBurden,
|
|
29
|
+
heartRateMinute,
|
|
30
|
+
hrZoneHistory,
|
|
31
|
+
},
|
|
18
32
|
serverNowMs: Date.now(),
|
|
19
33
|
});
|
|
20
34
|
});
|
package/dist/routes/wipe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wipe.js","sourceRoot":"","sources":["../../src/routes/wipe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wipe.js","sourceRoot":"","sources":["../../src/routes/wipe.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,UAAU,UAAU,CACxB,MASC,EACD,IAAgB;IAEhB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QACjD,IAAI,IAAI,YAAY,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE1C,MAAM,CACJ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,aAAa,EACd,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACpB,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;YAC7B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;YAC9B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;YAC9B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;YAC9B,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE;YAC5B,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE;YAClC,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE;YAChC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE;gBACL,YAAY;gBACZ,aAAa;gBACb,aAAa;gBACb,aAAa;gBACb,WAAW;gBACX,iBAAiB;gBACjB,eAAe;gBACf,aAAa;aACd;YACD,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { dailyStressBurden } from '../db/schema.js';
|
|
3
|
+
export function createDailyStressBurdenStore(db) {
|
|
4
|
+
return {
|
|
5
|
+
async upsertBatch(rows, _serverNowMs) {
|
|
6
|
+
if (rows.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const values = rows.map((r) => ({
|
|
9
|
+
id: r.id,
|
|
10
|
+
isoDate: r.isoDate,
|
|
11
|
+
timezone: r.timezone,
|
|
12
|
+
intervalsRelaxed: r.intervalsRelaxed,
|
|
13
|
+
intervalsBalanced: r.intervalsBalanced,
|
|
14
|
+
intervalsElevated: r.intervalsElevated,
|
|
15
|
+
intervalsHigh: r.intervalsHigh,
|
|
16
|
+
intervalsScored: r.intervalsScored,
|
|
17
|
+
meanScore: r.meanScore,
|
|
18
|
+
peakScore: r.peakScore,
|
|
19
|
+
peakScoreUtc: r.peakScoreUtc,
|
|
20
|
+
stressBurden: r.stressBurden,
|
|
21
|
+
updatedAt: r.updatedAt,
|
|
22
|
+
}));
|
|
23
|
+
await db
|
|
24
|
+
.insert(dailyStressBurden)
|
|
25
|
+
.values(values)
|
|
26
|
+
.onConflictDoUpdate({
|
|
27
|
+
target: dailyStressBurden.id,
|
|
28
|
+
set: {
|
|
29
|
+
isoDate: sql `excluded.iso_date`,
|
|
30
|
+
timezone: sql `excluded.timezone`,
|
|
31
|
+
intervalsRelaxed: sql `excluded.intervals_relaxed`,
|
|
32
|
+
intervalsBalanced: sql `excluded.intervals_balanced`,
|
|
33
|
+
intervalsElevated: sql `excluded.intervals_elevated`,
|
|
34
|
+
intervalsHigh: sql `excluded.intervals_high`,
|
|
35
|
+
intervalsScored: sql `excluded.intervals_scored`,
|
|
36
|
+
meanScore: sql `excluded.mean_score`,
|
|
37
|
+
peakScore: sql `excluded.peak_score`,
|
|
38
|
+
peakScoreUtc: sql `excluded.peak_score_utc`,
|
|
39
|
+
stressBurden: sql `excluded.stress_burden`,
|
|
40
|
+
updatedAt: sql `excluded.updated_at`,
|
|
41
|
+
},
|
|
42
|
+
where: sql `excluded.updated_at > ${dailyStressBurden.updatedAt}`,
|
|
43
|
+
});
|
|
44
|
+
return rows.map((r) => r.id);
|
|
45
|
+
},
|
|
46
|
+
async deleteBatch(ids) {
|
|
47
|
+
if (ids.length === 0)
|
|
48
|
+
return [];
|
|
49
|
+
await db.delete(dailyStressBurden).where(inArray(dailyStressBurden.id, [...ids]));
|
|
50
|
+
return [...ids];
|
|
51
|
+
},
|
|
52
|
+
async wipeAll() {
|
|
53
|
+
const result = await db.delete(dailyStressBurden);
|
|
54
|
+
return result.rowsAffected;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=daily-stress-burden.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daily-stress-burden.js","sourceRoot":"","sources":["../../src/stores/daily-stress-burden.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,UAAU,4BAA4B,CAAC,EAAM;IACjD,OAAO;QACL,KAAK,CAAC,WAAW,CACf,IAAuC,EACvC,YAAoB;YAEpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;gBACtC,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;gBACtC,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,eAAe,EAAE,CAAC,CAAC,eAAe;gBAClC,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC,CAAC,CAAC;YACJ,MAAM,EAAE;iBACL,MAAM,CAAC,iBAAiB,CAAC;iBACzB,MAAM,CAAC,MAAM,CAAC;iBACd,kBAAkB,CAAC;gBAClB,MAAM,EAAE,iBAAiB,CAAC,EAAE;gBAC5B,GAAG,EAAE;oBACH,OAAO,EAAE,GAAG,CAAA,mBAAmB;oBAC/B,QAAQ,EAAE,GAAG,CAAA,mBAAmB;oBAChC,gBAAgB,EAAE,GAAG,CAAA,4BAA4B;oBACjD,iBAAiB,EAAE,GAAG,CAAA,6BAA6B;oBACnD,iBAAiB,EAAE,GAAG,CAAA,6BAA6B;oBACnD,aAAa,EAAE,GAAG,CAAA,yBAAyB;oBAC3C,eAAe,EAAE,GAAG,CAAA,2BAA2B;oBAC/C,SAAS,EAAE,GAAG,CAAA,qBAAqB;oBACnC,SAAS,EAAE,GAAG,CAAA,qBAAqB;oBACnC,YAAY,EAAE,GAAG,CAAA,yBAAyB;oBAC1C,YAAY,EAAE,GAAG,CAAA,wBAAwB;oBACzC,SAAS,EAAE,GAAG,CAAA,qBAAqB;iBACpC;gBACD,KAAK,EAAE,GAAG,CAAA,yBAAyB,iBAAiB,CAAC,SAAS,EAAE;aACjE,CAAC,CAAC;YACL,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAsB;YACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAClF,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { heartRateMinute } from '../db/schema.js';
|
|
3
|
+
export function createHeartRateMinuteStore(db) {
|
|
4
|
+
return {
|
|
5
|
+
async upsertBatch(rows, _serverNowMs) {
|
|
6
|
+
if (rows.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const values = rows.map((r) => ({
|
|
9
|
+
id: r.id,
|
|
10
|
+
minuteStartUtc: r.minuteStartUtc,
|
|
11
|
+
bpmMean: r.bpmMean,
|
|
12
|
+
bpmMin: r.bpmMin,
|
|
13
|
+
bpmMax: r.bpmMax,
|
|
14
|
+
sampleCount: r.sampleCount,
|
|
15
|
+
deviceId: r.deviceId,
|
|
16
|
+
updatedAt: r.updatedAt,
|
|
17
|
+
}));
|
|
18
|
+
await db
|
|
19
|
+
.insert(heartRateMinute)
|
|
20
|
+
.values(values)
|
|
21
|
+
.onConflictDoUpdate({
|
|
22
|
+
target: heartRateMinute.id,
|
|
23
|
+
set: {
|
|
24
|
+
minuteStartUtc: sql `excluded.minute_start_utc`,
|
|
25
|
+
bpmMean: sql `excluded.bpm_mean`,
|
|
26
|
+
bpmMin: sql `excluded.bpm_min`,
|
|
27
|
+
bpmMax: sql `excluded.bpm_max`,
|
|
28
|
+
sampleCount: sql `excluded.sample_count`,
|
|
29
|
+
deviceId: sql `excluded.device_id`,
|
|
30
|
+
updatedAt: sql `excluded.updated_at`,
|
|
31
|
+
},
|
|
32
|
+
where: sql `excluded.updated_at > ${heartRateMinute.updatedAt}`,
|
|
33
|
+
});
|
|
34
|
+
return rows.map((r) => r.id);
|
|
35
|
+
},
|
|
36
|
+
async deleteBatch(ids) {
|
|
37
|
+
if (ids.length === 0)
|
|
38
|
+
return [];
|
|
39
|
+
await db.delete(heartRateMinute).where(inArray(heartRateMinute.id, [...ids]));
|
|
40
|
+
return [...ids];
|
|
41
|
+
},
|
|
42
|
+
async wipeAll() {
|
|
43
|
+
const result = await db.delete(heartRateMinute);
|
|
44
|
+
return result.rowsAffected;
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=heart-rate-minute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heart-rate-minute.js","sourceRoot":"","sources":["../../src/stores/heart-rate-minute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,UAAU,0BAA0B,CAAC,EAAM;IAC/C,OAAO;QACL,KAAK,CAAC,WAAW,CACf,IAAqC,EACrC,YAAoB;YAEpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,cAAc,EAAE,CAAC,CAAC,cAAc;gBAChC,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC,CAAC,CAAC;YACJ,MAAM,EAAE;iBACL,MAAM,CAAC,eAAe,CAAC;iBACvB,MAAM,CAAC,MAAM,CAAC;iBACd,kBAAkB,CAAC;gBAClB,MAAM,EAAE,eAAe,CAAC,EAAE;gBAC1B,GAAG,EAAE;oBACH,cAAc,EAAE,GAAG,CAAA,2BAA2B;oBAC9C,OAAO,EAAE,GAAG,CAAA,mBAAmB;oBAC/B,MAAM,EAAE,GAAG,CAAA,kBAAkB;oBAC7B,MAAM,EAAE,GAAG,CAAA,kBAAkB;oBAC7B,WAAW,EAAE,GAAG,CAAA,uBAAuB;oBACvC,QAAQ,EAAE,GAAG,CAAA,oBAAoB;oBACjC,SAAS,EAAE,GAAG,CAAA,qBAAqB;iBACpC;gBACD,KAAK,EAAE,GAAG,CAAA,yBAAyB,eAAe,CAAC,SAAS,EAAE;aAC/D,CAAC,CAAC;YACL,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAsB;YACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9E,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YAChD,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { hrZoneHistory } from '../db/schema.js';
|
|
3
|
+
export function createHrZoneHistoryStore(db) {
|
|
4
|
+
return {
|
|
5
|
+
async upsertBatch(rows, _serverNowMs) {
|
|
6
|
+
if (rows.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const values = rows.map((r) => ({
|
|
9
|
+
id: r.id,
|
|
10
|
+
effectiveFromIsoDate: r.effectiveFromIsoDate,
|
|
11
|
+
zone1: r.zone1,
|
|
12
|
+
zone2: r.zone2,
|
|
13
|
+
zone3: r.zone3,
|
|
14
|
+
zone4: r.zone4,
|
|
15
|
+
zone5: r.zone5,
|
|
16
|
+
createdAt: r.createdAt,
|
|
17
|
+
}));
|
|
18
|
+
await db
|
|
19
|
+
.insert(hrZoneHistory)
|
|
20
|
+
.values(values)
|
|
21
|
+
.onConflictDoUpdate({
|
|
22
|
+
target: hrZoneHistory.id,
|
|
23
|
+
set: {
|
|
24
|
+
effectiveFromIsoDate: sql `excluded.effective_from_iso_date`,
|
|
25
|
+
zone1: sql `excluded.zone1`,
|
|
26
|
+
zone2: sql `excluded.zone2`,
|
|
27
|
+
zone3: sql `excluded.zone3`,
|
|
28
|
+
zone4: sql `excluded.zone4`,
|
|
29
|
+
zone5: sql `excluded.zone5`,
|
|
30
|
+
createdAt: sql `excluded.created_at`,
|
|
31
|
+
},
|
|
32
|
+
// LWW on createdAt (table is append-only; no updatedAt)
|
|
33
|
+
where: sql `excluded.created_at > ${hrZoneHistory.createdAt}`,
|
|
34
|
+
});
|
|
35
|
+
return rows.map((r) => r.id);
|
|
36
|
+
},
|
|
37
|
+
async deleteBatch(ids) {
|
|
38
|
+
if (ids.length === 0)
|
|
39
|
+
return [];
|
|
40
|
+
await db.delete(hrZoneHistory).where(inArray(hrZoneHistory.id, [...ids]));
|
|
41
|
+
return [...ids];
|
|
42
|
+
},
|
|
43
|
+
async wipeAll() {
|
|
44
|
+
const result = await db.delete(hrZoneHistory);
|
|
45
|
+
return result.rowsAffected;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=hr-zone-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hr-zone-history.js","sourceRoot":"","sources":["../../src/stores/hr-zone-history.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,wBAAwB,CAAC,EAAM;IAC7C,OAAO;QACL,KAAK,CAAC,WAAW,CACf,IAAmC,EACnC,YAAoB;YAEpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,oBAAoB,EAAE,CAAC,CAAC,oBAAoB;gBAC5C,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,SAAS,EAAE,CAAC,CAAC,SAAS;aACvB,CAAC,CAAC,CAAC;YACJ,MAAM,EAAE;iBACL,MAAM,CAAC,aAAa,CAAC;iBACrB,MAAM,CAAC,MAAM,CAAC;iBACd,kBAAkB,CAAC;gBAClB,MAAM,EAAE,aAAa,CAAC,EAAE;gBACxB,GAAG,EAAE;oBACH,oBAAoB,EAAE,GAAG,CAAA,kCAAkC;oBAC3D,KAAK,EAAE,GAAG,CAAA,gBAAgB;oBAC1B,KAAK,EAAE,GAAG,CAAA,gBAAgB;oBAC1B,KAAK,EAAE,GAAG,CAAA,gBAAgB;oBAC1B,KAAK,EAAE,GAAG,CAAA,gBAAgB;oBAC1B,KAAK,EAAE,GAAG,CAAA,gBAAgB;oBAC1B,SAAS,EAAE,GAAG,CAAA,qBAAqB;iBACpC;gBACD,wDAAwD;gBACxD,KAAK,EAAE,GAAG,CAAA,yBAAyB,aAAa,CAAC,SAAS,EAAE;aAC7D,CAAC,CAAC;YACL,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAsB;YACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { userProfile } from '../db/schema.js';
|
|
3
|
+
export function createUserProfileStore(db) {
|
|
4
|
+
return {
|
|
5
|
+
async upsertBatch(rows, _serverNowMs) {
|
|
6
|
+
if (rows.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const values = rows.map((r) => ({
|
|
9
|
+
id: r.id,
|
|
10
|
+
name: r.name,
|
|
11
|
+
birthDate: r.birthDate,
|
|
12
|
+
height: r.height,
|
|
13
|
+
weight: r.weight,
|
|
14
|
+
biologicalGender: r.biologicalGender,
|
|
15
|
+
maxHeartRate: r.maxHeartRate,
|
|
16
|
+
maxHeartRateManually: r.maxHeartRateManually,
|
|
17
|
+
restingHeartRate: r.restingHeartRate,
|
|
18
|
+
vo2Max: r.vo2Max,
|
|
19
|
+
heartRateZonesManually: r.heartRateZonesManually,
|
|
20
|
+
hrZone1: r.hrZone1,
|
|
21
|
+
hrZone2: r.hrZone2,
|
|
22
|
+
hrZone3: r.hrZone3,
|
|
23
|
+
hrZone4: r.hrZone4,
|
|
24
|
+
hrZone5: r.hrZone5,
|
|
25
|
+
trainingBackground: r.trainingBackground,
|
|
26
|
+
typicalDay: r.typicalDay,
|
|
27
|
+
sleepGoalMinutes: r.sleepGoalMinutes,
|
|
28
|
+
dataRetentionLevel: r.dataRetentionLevel,
|
|
29
|
+
createdAt: r.createdAt,
|
|
30
|
+
updatedAt: r.updatedAt,
|
|
31
|
+
}));
|
|
32
|
+
await db
|
|
33
|
+
.insert(userProfile)
|
|
34
|
+
.values(values)
|
|
35
|
+
.onConflictDoUpdate({
|
|
36
|
+
target: userProfile.id,
|
|
37
|
+
set: {
|
|
38
|
+
name: sql `excluded.name`,
|
|
39
|
+
birthDate: sql `excluded.birth_date`,
|
|
40
|
+
height: sql `excluded.height`,
|
|
41
|
+
weight: sql `excluded.weight`,
|
|
42
|
+
biologicalGender: sql `excluded.biological_gender`,
|
|
43
|
+
maxHeartRate: sql `excluded.max_heart_rate`,
|
|
44
|
+
maxHeartRateManually: sql `excluded.max_heart_rate_manually`,
|
|
45
|
+
restingHeartRate: sql `excluded.resting_heart_rate`,
|
|
46
|
+
vo2Max: sql `excluded.vo2_max`,
|
|
47
|
+
heartRateZonesManually: sql `excluded.heart_rate_zones_manually`,
|
|
48
|
+
hrZone1: sql `excluded.hr_zone_1`,
|
|
49
|
+
hrZone2: sql `excluded.hr_zone_2`,
|
|
50
|
+
hrZone3: sql `excluded.hr_zone_3`,
|
|
51
|
+
hrZone4: sql `excluded.hr_zone_4`,
|
|
52
|
+
hrZone5: sql `excluded.hr_zone_5`,
|
|
53
|
+
trainingBackground: sql `excluded.training_background`,
|
|
54
|
+
typicalDay: sql `excluded.typical_day`,
|
|
55
|
+
sleepGoalMinutes: sql `excluded.sleep_goal_minutes`,
|
|
56
|
+
dataRetentionLevel: sql `excluded.data_retention_level`,
|
|
57
|
+
createdAt: sql `excluded.created_at`,
|
|
58
|
+
updatedAt: sql `excluded.updated_at`,
|
|
59
|
+
},
|
|
60
|
+
where: sql `excluded.updated_at > ${userProfile.updatedAt}`,
|
|
61
|
+
});
|
|
62
|
+
return rows.map((r) => r.id);
|
|
63
|
+
},
|
|
64
|
+
async deleteBatch(ids) {
|
|
65
|
+
if (ids.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
await db.delete(userProfile).where(inArray(userProfile.id, [...ids]));
|
|
68
|
+
return [...ids];
|
|
69
|
+
},
|
|
70
|
+
async wipeAll() {
|
|
71
|
+
const result = await db.delete(userProfile);
|
|
72
|
+
return result.rowsAffected;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=user-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-profile.js","sourceRoot":"","sources":["../../src/stores/user-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { inArray, sql } from 'drizzle-orm';
|
|
2
|
+
import { userTimezones } from '../db/schema.js';
|
|
3
|
+
export function createUserTimezonesStore(db) {
|
|
4
|
+
return {
|
|
5
|
+
async upsertBatch(rows, _serverNowMs) {
|
|
6
|
+
if (rows.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const values = rows.map((r) => ({
|
|
9
|
+
id: r.id,
|
|
10
|
+
timezone: r.timezone,
|
|
11
|
+
type: r.type,
|
|
12
|
+
utcOffsetMinutes: r.utcOffsetMinutes,
|
|
13
|
+
effectiveFrom: r.effectiveFrom,
|
|
14
|
+
}));
|
|
15
|
+
await db
|
|
16
|
+
.insert(userTimezones)
|
|
17
|
+
.values(values)
|
|
18
|
+
.onConflictDoUpdate({
|
|
19
|
+
target: userTimezones.id,
|
|
20
|
+
set: {
|
|
21
|
+
timezone: sql `excluded.timezone`,
|
|
22
|
+
type: sql `excluded.type`,
|
|
23
|
+
utcOffsetMinutes: sql `excluded.utc_offset_minutes`,
|
|
24
|
+
effectiveFrom: sql `excluded.effective_from`,
|
|
25
|
+
},
|
|
26
|
+
// LWW on effectiveFrom (table is append-only; no updatedAt)
|
|
27
|
+
where: sql `excluded.effective_from > ${userTimezones.effectiveFrom}`,
|
|
28
|
+
});
|
|
29
|
+
return rows.map((r) => r.id);
|
|
30
|
+
},
|
|
31
|
+
async deleteBatch(ids) {
|
|
32
|
+
if (ids.length === 0)
|
|
33
|
+
return [];
|
|
34
|
+
await db.delete(userTimezones).where(inArray(userTimezones.id, [...ids]));
|
|
35
|
+
return [...ids];
|
|
36
|
+
},
|
|
37
|
+
async wipeAll() {
|
|
38
|
+
const result = await db.delete(userTimezones);
|
|
39
|
+
return result.rowsAffected;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=user-timezones.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-timezones.js","sourceRoot":"","sources":["../../src/stores/user-timezones.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,wBAAwB,CAAC,EAAM;IAC7C,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,IAAkC,EAAE,YAAoB;YACxE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,aAAa,EAAE,CAAC,CAAC,aAAa;aAC/B,CAAC,CAAC,CAAC;YACJ,MAAM,EAAE;iBACL,MAAM,CAAC,aAAa,CAAC;iBACrB,MAAM,CAAC,MAAM,CAAC;iBACd,kBAAkB,CAAC;gBAClB,MAAM,EAAE,aAAa,CAAC,EAAE;gBACxB,GAAG,EAAE;oBACH,QAAQ,EAAE,GAAG,CAAA,mBAAmB;oBAChC,IAAI,EAAE,GAAG,CAAA,eAAe;oBACxB,gBAAgB,EAAE,GAAG,CAAA,6BAA6B;oBAClD,aAAa,EAAE,GAAG,CAAA,yBAAyB;iBAC5C;gBACD,4DAA4D;gBAC5D,KAAK,EAAE,GAAG,CAAA,6BAA6B,aAAa,CAAC,aAAa,EAAE;aACrE,CAAC,CAAC;YACL,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,GAAsB;YACtC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAChC,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,KAAK,CAAC,OAAO;YACX,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC,YAAY,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
CREATE TABLE `daily_stress_burden` (
|
|
2
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
3
|
+
`iso_date` text NOT NULL,
|
|
4
|
+
`timezone` text NOT NULL,
|
|
5
|
+
`intervals_relaxed` integer NOT NULL,
|
|
6
|
+
`intervals_balanced` integer NOT NULL,
|
|
7
|
+
`intervals_elevated` integer NOT NULL,
|
|
8
|
+
`intervals_high` integer NOT NULL,
|
|
9
|
+
`intervals_scored` integer NOT NULL,
|
|
10
|
+
`mean_score` real NOT NULL,
|
|
11
|
+
`peak_score` real NOT NULL,
|
|
12
|
+
`peak_score_utc` integer NOT NULL,
|
|
13
|
+
`stress_burden` real NOT NULL,
|
|
14
|
+
`updated_at` integer NOT NULL
|
|
15
|
+
);
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
CREATE UNIQUE INDEX `dsb_unique_date_idx` ON `daily_stress_burden` (`iso_date`);--> statement-breakpoint
|
|
18
|
+
CREATE TABLE `heart_rate_minute` (
|
|
19
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
20
|
+
`minute_start_utc` integer NOT NULL,
|
|
21
|
+
`bpm_mean` real NOT NULL,
|
|
22
|
+
`bpm_min` integer NOT NULL,
|
|
23
|
+
`bpm_max` integer NOT NULL,
|
|
24
|
+
`sample_count` integer NOT NULL,
|
|
25
|
+
`device_id` integer NOT NULL,
|
|
26
|
+
`updated_at` integer NOT NULL
|
|
27
|
+
);
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
CREATE INDEX `hrm_minute_idx` ON `heart_rate_minute` (`minute_start_utc`);--> statement-breakpoint
|
|
30
|
+
CREATE UNIQUE INDEX `hrm_unique_minute_per_device_idx` ON `heart_rate_minute` (`minute_start_utc`,`device_id`);--> statement-breakpoint
|
|
31
|
+
CREATE INDEX `hrm_device_updated_idx` ON `heart_rate_minute` (`device_id`,`updated_at`);--> statement-breakpoint
|
|
32
|
+
CREATE TABLE `hr_zone_history` (
|
|
33
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
34
|
+
`effective_from_iso_date` text NOT NULL,
|
|
35
|
+
`zone1` integer NOT NULL,
|
|
36
|
+
`zone2` integer NOT NULL,
|
|
37
|
+
`zone3` integer NOT NULL,
|
|
38
|
+
`zone4` integer NOT NULL,
|
|
39
|
+
`zone5` integer NOT NULL,
|
|
40
|
+
`created_at` integer NOT NULL
|
|
41
|
+
);
|
|
42
|
+
--> statement-breakpoint
|
|
43
|
+
CREATE UNIQUE INDEX `hrzh_unique_effective_idx` ON `hr_zone_history` (`effective_from_iso_date`);--> statement-breakpoint
|
|
44
|
+
CREATE TABLE `user_profile` (
|
|
45
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
46
|
+
`name` text NOT NULL,
|
|
47
|
+
`birth_date` text NOT NULL,
|
|
48
|
+
`height` real NOT NULL,
|
|
49
|
+
`weight` real NOT NULL,
|
|
50
|
+
`biological_gender` text NOT NULL,
|
|
51
|
+
`max_heart_rate` integer,
|
|
52
|
+
`max_heart_rate_manually` integer,
|
|
53
|
+
`resting_heart_rate` integer,
|
|
54
|
+
`vo2_max` real,
|
|
55
|
+
`heart_rate_zones_manually` integer,
|
|
56
|
+
`hr_zone_1` integer,
|
|
57
|
+
`hr_zone_2` integer,
|
|
58
|
+
`hr_zone_3` integer,
|
|
59
|
+
`hr_zone_4` integer,
|
|
60
|
+
`hr_zone_5` integer,
|
|
61
|
+
`training_background` text,
|
|
62
|
+
`typical_day` text,
|
|
63
|
+
`sleep_goal_minutes` integer,
|
|
64
|
+
`data_retention_level` text,
|
|
65
|
+
`created_at` integer NOT NULL,
|
|
66
|
+
`updated_at` integer NOT NULL,
|
|
67
|
+
CONSTRAINT "user_profile_singleton" CHECK("user_profile"."id" = 1)
|
|
68
|
+
);
|
|
69
|
+
--> statement-breakpoint
|
|
70
|
+
CREATE TABLE `user_timezones` (
|
|
71
|
+
`id` integer PRIMARY KEY NOT NULL,
|
|
72
|
+
`timezone` text NOT NULL,
|
|
73
|
+
`type` text NOT NULL,
|
|
74
|
+
`utc_offset_minutes` integer NOT NULL,
|
|
75
|
+
`effective_from` integer NOT NULL
|
|
76
|
+
);
|
|
77
|
+
--> statement-breakpoint
|
|
78
|
+
CREATE INDEX `user_tz_effective_from_idx` ON `user_timezones` (`effective_from`);
|