mirror of
https://github.com/Oak-and-Sprout/sprout-track.git
synced 2026-05-07 23:49:52 -05:00
Update sleep type so end sleep type is not required and updated documentation and API tests for timezone and sleep updates
This commit is contained in:
@@ -323,12 +323,15 @@ async function handlePost(req: NextRequest, ctx: ApiKeyContext, routeContext: an
|
||||
|
||||
case 'sleep': {
|
||||
const { sleepType, action, duration: sleepDuration, location, quality } = body;
|
||||
if (!sleepType || !['NAP', 'NIGHT_SLEEP'].includes(sleepType)) {
|
||||
return hookError('INVALID_SLEEP_TYPE', 'sleepType must be NAP or NIGHT_SLEEP', 400, rl.headers);
|
||||
}
|
||||
if (!action || !['start', 'end', 'log'].includes(action)) {
|
||||
return hookError('INVALID_ACTION', 'action must be start, end, or log', 400, rl.headers);
|
||||
}
|
||||
if (sleepType && !['NAP', 'NIGHT_SLEEP'].includes(sleepType)) {
|
||||
return hookError('INVALID_SLEEP_TYPE', 'sleepType must be NAP or NIGHT_SLEEP', 400, rl.headers);
|
||||
}
|
||||
if (action !== 'end' && !sleepType) {
|
||||
return hookError('INVALID_SLEEP_TYPE', 'sleepType is required for start and log actions', 400, rl.headers);
|
||||
}
|
||||
|
||||
if (action === 'start') {
|
||||
result = await prisma.sleepLog.create({
|
||||
@@ -349,7 +352,7 @@ async function handlePost(req: NextRequest, ctx: ApiKeyContext, routeContext: an
|
||||
const dur = Math.round((time.getTime() - activeSleep.startTime.getTime()) / 60000);
|
||||
result = await prisma.sleepLog.update({
|
||||
where: { id: activeSleep.id },
|
||||
data: { endTime: time, duration: dur, quality: quality || activeSleep.quality },
|
||||
data: { endTime: time, duration: dur, quality: quality || activeSleep.quality, ...(sleepType && { type: sleepType }) },
|
||||
});
|
||||
return hookSuccess({ activityType: 'sleep', id: result.id, time: result.startTime.toISOString(), details: { type: result.type, action: 'end', duration: dur, isActive: false } }, { familyId, babyId }, rl.headers);
|
||||
}
|
||||
|
||||
@@ -339,7 +339,15 @@ Sleep supports three actions:
|
||||
```json
|
||||
{
|
||||
"type": "sleep",
|
||||
"sleepType": "NAP",
|
||||
"action": "end"
|
||||
}
|
||||
```
|
||||
|
||||
**End and change the sleep type (e.g., a nap that became a night sleep):**
|
||||
```json
|
||||
{
|
||||
"type": "sleep",
|
||||
"sleepType": "NIGHT_SLEEP",
|
||||
"action": "end"
|
||||
}
|
||||
```
|
||||
@@ -355,10 +363,12 @@ Sleep supports three actions:
|
||||
}
|
||||
```
|
||||
|
||||
**sleepType:** `NAP` or `NIGHT_SLEEP`
|
||||
**sleepType:** `NAP` or `NIGHT_SLEEP` -- required for `start` and `log`, optional for `end`
|
||||
**action:** `start`, `end`, or `log`
|
||||
Optional fields: `location`, `quality`, `duration` (minutes, required for `log`)
|
||||
|
||||
> **Note:** If `sleepType` is provided on `end`, the sleep record's type is updated. If omitted, the type from `start` is preserved.
|
||||
|
||||
#### Note
|
||||
|
||||
```json
|
||||
|
||||
@@ -106,6 +106,21 @@ async function runReadTests(babyId) {
|
||||
}
|
||||
});
|
||||
|
||||
await test(`GET /babies/${babyId}/status?timezone=America/New_York — timezone param`, async () => {
|
||||
const res = await request('GET', `/babies/${babyId}/status?timezone=America/New_York`);
|
||||
assert(res.success, `Expected success, got: ${JSON.stringify(res.error)}`);
|
||||
assert(res.data.dailyCounts.date, 'Expected date in dailyCounts');
|
||||
assert(/^\d{4}-\d{2}-\d{2}$/.test(res.data.dailyCounts.date), `Expected YYYY-MM-DD date, got: ${res.data.dailyCounts.date}`);
|
||||
log(' ', `Daily counts date with timezone: ${res.data.dailyCounts.date}`);
|
||||
});
|
||||
|
||||
await test(`GET /babies/${babyId}/status?timezone=Fake/Zone — invalid timezone returns 400`, async () => {
|
||||
const res = await request('GET', `/babies/${babyId}/status?timezone=Fake/Zone`);
|
||||
assert(!res.success, 'Expected failure');
|
||||
assert(res.status === 400, `Expected 400, got ${res.status}`);
|
||||
assert(res.error.code === 'INVALID_TIMEZONE', `Expected INVALID_TIMEZONE, got ${res.error.code}`);
|
||||
});
|
||||
|
||||
await test(`GET /babies/${babyId}/activities — recent activities`, async () => {
|
||||
const res = await request('GET', `/babies/${babyId}/activities?limit=5`);
|
||||
assert(res.success, `Expected success, got: ${JSON.stringify(res.error)}`);
|
||||
@@ -310,6 +325,47 @@ async function runWriteTests(babyId) {
|
||||
log(' ', `Ended sleep ${endRes.data.id}, duration: ${endRes.data.details.duration} min`);
|
||||
});
|
||||
|
||||
await test('POST sleep (end without sleepType — type unchanged)', async () => {
|
||||
const startRes = await request('POST', `/babies/${babyId}/activities`, {
|
||||
type: 'sleep',
|
||||
sleepType: 'NAP',
|
||||
action: 'start',
|
||||
});
|
||||
assert(startRes.success, `Start failed: ${JSON.stringify(startRes.error)}`);
|
||||
log(' ', `Started sleep ${startRes.data.id} as NAP`);
|
||||
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
|
||||
const endRes = await request('POST', `/babies/${babyId}/activities`, {
|
||||
type: 'sleep',
|
||||
action: 'end',
|
||||
});
|
||||
assert(endRes.success, `End failed: ${JSON.stringify(endRes.error)}`);
|
||||
assert(endRes.data.details.type === 'NAP', `Expected NAP, got ${endRes.data.details.type}`);
|
||||
log(' ', `Ended sleep ${endRes.data.id} — type stayed NAP`);
|
||||
});
|
||||
|
||||
await test('POST sleep (end with sleepType change — NAP to NIGHT_SLEEP)', async () => {
|
||||
const startRes = await request('POST', `/babies/${babyId}/activities`, {
|
||||
type: 'sleep',
|
||||
sleepType: 'NAP',
|
||||
action: 'start',
|
||||
});
|
||||
assert(startRes.success, `Start failed: ${JSON.stringify(startRes.error)}`);
|
||||
log(' ', `Started sleep ${startRes.data.id} as NAP`);
|
||||
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
|
||||
const endRes = await request('POST', `/babies/${babyId}/activities`, {
|
||||
type: 'sleep',
|
||||
sleepType: 'NIGHT_SLEEP',
|
||||
action: 'end',
|
||||
});
|
||||
assert(endRes.success, `End failed: ${JSON.stringify(endRes.error)}`);
|
||||
assert(endRes.data.details.type === 'NIGHT_SLEEP', `Expected NIGHT_SLEEP, got ${endRes.data.details.type}`);
|
||||
log(' ', `Ended sleep ${endRes.data.id} — type changed to NIGHT_SLEEP`);
|
||||
});
|
||||
|
||||
await test('POST sleep (log with duration)', async () => {
|
||||
const res = await request('POST', `/babies/${babyId}/activities`, {
|
||||
type: 'sleep',
|
||||
|
||||
Reference in New Issue
Block a user