Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 0 additions & 192 deletions time-tracker/2025-11-20-backend-strategy.md

This file was deleted.

199 changes: 199 additions & 0 deletions time-tracker/backend-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Time Tracker Backend Contract

## Entities

### 1. tracked_entries

Events:
- Task
- Away (unpaid)
- Away (paid)
- Late
- Unwell
- Make-up time
- Make-up time for day-off
- Overtime
- Time-off

All-day events:
- Lunch
- Sick leave
- Vacation
- Day-off to make up for
- Personal day-off
- Unpaid day-off

#### sql notes

```sql
SELECT *
FROM tracked_entries
WHERE startTime > @startTime
AND endTime < @endTime
AND tenantId = @tenantId
AND employeeId = @employeeId

CREATE INDEX a ON tracked_entries
```

## Endpoints

#### entries

1. **GET** /api/time/tracking/entries?startDate={startDate}&endDate={endDate} - get list by period

**Response body:**
```ts
{
workEntries: [
{
id: long,
title: string,
taskId: string,
projectId: long,
description: string,
startTime: DateTime,
endTime: DateTime,
type: int,
},
]
unwellEntries: [
{
id: long,
startTime: DateTime,
endTime: DateTime,
type: int,
},
]
}
```

2. **DELETE** /api/time/tracking/entries/{entryId}/soft-delete - soft delete
**Request body:**
```ts
{
deletionReason: string,
}
```

## task-entries

1. **POST** /api/time/tracking/task-entries - add task entry

**Request body:**
```ts
{
title: string,
taskId: string,
projectId: long,
description: string,
startTime: DateTime,
endTime: DateTime,
timeZoneId: string
type: int,
}
```

**Response body:**
```ts
{
newTaskEntryId: long
}
```

3. **POST** /api/time/tracking/task-entries/{id} - update task entry

**Request body:**
```ts
{
title: string,
taskId: string,
projectId: long,
description: string,
startTime: DateTime,
endTime: DateTime,
timeZoneId: string
}
```

**Response body:** 200 OK

4. **GET** /api/time/tracking/task-entries/projects?date={date} - get employee's projects

**Response body:**

```ts
{
projects: [
{
id: long,
name: string;
},
]
}
```

#### unwell-entries

1. **POST** /api/time/tracking/unwell-entries - add unwell entries

**Request body:**
```ts
{
startTime: DateTime,
endTime: DateTime,
timeZoneId: string
type: int,
}
```

**Response body:**
```ts
{
newUnwellEntryId: long
}
```

2. **POST** /api/time/tracking/unwell-entries/{id} - update unwell entry

**Request body:**
```ts
{
startTime: DateTime,
endTime: DateTime,
timeZoneId: string
}
```

## db diagram

```mermaid
erDiagram
tracked_entries ||--|| projects : "1-to-1"
tracked_entries {
id long PK
tenant_id long FK
employee_id long FK
project_id long FK "Nullable. Internal request projects list"
parent_id long FK "Nullable. A self-reference to the original card from the same table"
start_time timestamp
end_time timestamp
time_zone_id text
duration interval "(calculated), positive for overtime, negative for time off"
amount interval "Nullable. To think about whether time is deducted from working hours or not"
type int
title text "Nullable."
task_id text "Nullable."
description text "Nullable."
deleted_at_utc timestamp with timezone "Nullable."
deletion_reason string "Nullable."
sick_leave_reason int "Nullable."
is_paid boolean "Nullable."
is_full_day boolean "Nullable."
}
projects {
id long PK
tenant_id long FK
name text
}
```