refactor: update sleep session logic, models, and agent protocols
This commit is contained in:
@@ -56,6 +56,12 @@ Baby monitor - self-hosted web app for tracking infant sleep. Dual-stack monorep
|
||||
- **Frontend JS Slop**: NEVER create `.js` or `.jsx` files for the frontend. Use only TypeScript (`.ts`, `.tsx`). Write clean, type-safe code.
|
||||
- **Assumption Error**: NEVER assume the content of ANY files. ALWAYS read the target file to confirm its structure and implementation before modifying or referencing it.
|
||||
|
||||
## MANDATORY EXECUTION PROTOCOLS (INJECTABLE)
|
||||
|
||||
The following protocols must be strictly adhered to upon injection:
|
||||
- **Read Before Edit**: ALWAYS read the entire target file before performing any `edit` operation.
|
||||
- **Post-Edit Verification**: Immediately after an edit, verify that no lines have been duplicated.
|
||||
- **Stability Check**: Following any code change, run both backend and frontend services AND the full test suite to ensure system stability.
|
||||
## COMMANDS
|
||||
|
||||
### Backend Development
|
||||
|
||||
@@ -9,6 +9,5 @@ class SleepSession(SQLModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
start_time: datetime = Field(nullable=False)
|
||||
end_time: Optional[datetime] = Field(default=None, nullable=True)
|
||||
notes: Optional[str] = Field(default=None)
|
||||
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
|
||||
@@ -6,22 +6,17 @@ from pydantic import BaseModel
|
||||
class SleepSessionCreate(BaseModel):
|
||||
start_time: datetime
|
||||
|
||||
|
||||
class SleepSessionUpdate(BaseModel):
|
||||
start_time: Optional[datetime] = None
|
||||
end_time: Optional[datetime] = None
|
||||
notes: Optional[str] = None
|
||||
|
||||
|
||||
class SleepSessionRead(BaseModel):
|
||||
id: int
|
||||
start_time: datetime
|
||||
end_time: Optional[datetime]
|
||||
notes: Optional[str]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class SessionListResponse(BaseModel):
|
||||
sessions: List[SleepSessionRead]
|
||||
total: int
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useSettings } from '../../hooks/useSettings';
|
||||
import { Pagination } from './Pagination';
|
||||
import { Edit2, Check, X, Trash2 } from 'lucide-react';
|
||||
import type { SleepSessionRead } from '../../types';
|
||||
import { formatDateTime, toLocalDatetimeInputValue, getDurationMinutes, formatMinutes } from '../../utils/time';
|
||||
import { formatDateTime, toLocalDatetimeInputValue, getDurationMinutes, formatMinutes, toUTCFromLocalInput } from '../../utils/time';
|
||||
|
||||
export function SessionList() {
|
||||
const { sessions, isLoading, updateSession, deleteSession, isDeleting } = useSessions();
|
||||
@@ -29,13 +29,13 @@ export function SessionList() {
|
||||
|
||||
const handleSave = async (id: number) => {
|
||||
try {
|
||||
await updateSession({
|
||||
sessionId: id,
|
||||
payload: {
|
||||
start_time: new Date(editStart).toISOString(),
|
||||
end_time: editEnd ? new Date(editEnd).toISOString() : undefined,
|
||||
}
|
||||
});
|
||||
await updateSession({
|
||||
sessionId: id,
|
||||
payload: {
|
||||
start_time: toUTCFromLocalInput(editStart),
|
||||
end_time: editEnd ? toUTCFromLocalInput(editEnd) : undefined,
|
||||
},
|
||||
});
|
||||
setEditingId(null);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@@ -38,9 +38,15 @@ export function adjustForTimezone(utcMinutes: number): number {
|
||||
* @returns string in "YYYY-MM-DDTHH:MM" format
|
||||
*/
|
||||
export function toLocalDatetimeInputValue(date: Date): string {
|
||||
const offset = date.getTimezoneOffset() * 60 * 1000;
|
||||
const localDate = new Date(date.getTime() - offset);
|
||||
return localDate.toISOString().slice(0, 16);
|
||||
const formatter = new Intl.DateTimeFormat('sv-SE', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
hour12: false,
|
||||
});
|
||||
return formatter.format(date).replace(' ', 'T');
|
||||
}
|
||||
|
||||
export function formatElapsedTime(utcTimestamp: string): string {
|
||||
|
||||
@@ -19,10 +19,10 @@ exitcode '1': failure
|
||||
```
|
||||
|
||||
- [ ] Editing a sleep session in "sleep sessions", when I click the edit button the times show up as UTC but should show as my local timezone
|
||||
- [/] We should drop the "notes" column from the sleep_session table
|
||||
- [x] We should drop the "notes" column from the sleep_session table
|
||||
- [x] Switch over to oh-my-opencode and try it out
|
||||
- [x] Adda footer at the bottom of the app that shows the version (aka git tag) of the app
|
||||
- [-] Fix race condition of gitea workflows
|
||||
- [x] Fix race condition of gitea workflows
|
||||
|
||||
If both workflows run at the same time, a race condition occurs:
|
||||
1. Collision: Both workflows will query the latest tag (e.g., v1.0.5) and calculate the same next version (v1.0.6).
|
||||
|
||||
Reference in New Issue
Block a user