Skip to content

Commit 3d28046

Browse files
committed
feat(absence): add absence crud commands
extend the absence command group with read/add/update/delete\noperations backed by /abcenses endpoints.\n\nadd e2e coverage for the new absence commands and update\nrepository docs to reflect the expanded workflow.
1 parent 351ac5c commit 3d28046

11 files changed

Lines changed: 857 additions & 14 deletions

File tree

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ It is intended for Finnish time tracking use cases.
1111
- worktime commands (`list/browse/report/options/add/update/delete`)
1212
- calendar commands (`overview/detailed`)
1313
- holidays retrieval command
14-
- absence commands (`options/browse/comment`)
14+
- absence commands (`options/browse/read/add/update/delete/comment`)
1515
- configurable local config path
1616
- separate cache file for API-derived user metadata
1717
- environment variable credential overrides (Docker/CI friendly)
@@ -74,7 +74,11 @@ otta saldo --format json
7474
otta holidays --from 2026-02-20 --to 2026-02-20 --worktimegroup <id> --format json
7575
otta absence browse --from 2026-02-01 --to 2026-02-28 --format json
7676
otta absence options --format json
77-
otta absence comment --type sick --from 2026-02-20 --to 2026-02-20
77+
otta absence add --type <absence-type-id> --from 2026-02-20 --to 2026-02-20 --description "sick leave" --format json
78+
otta absence read --id <absence-id> --format json
79+
otta absence update --id <absence-id> --description "sick leave" --format json
80+
otta absence delete --id <absence-id> --format json
81+
otta absence comment --type sick --from 2026-02-20 --to 2026-02-20 --format json
7882
```
7983

8084
Important: `worktimes list/browse/report` return only worktime rows and do not include absences.
@@ -133,7 +137,7 @@ Credential env vars:
133137
- `OTTA_CLI_TOKEN_TYPE`
134138
- `OTTA_CLI_REFRESH_TOKEN`
135139
- `OTTA_CLI_TOKEN_SCOPE`
136-
- `OTTA_CLI_USER_ID` (optional convenience for `worktimes add` and `saldo`)
140+
- `OTTA_CLI_USER_ID` (optional convenience for `worktimes add`, `absence add`, and `saldo`)
137141
- `OTTA_CLI_WORKTIMEGROUP_ID` (optional convenience for `holidays`, `calendar overview`, and `calendar detailed`)
138142

139143
## Test and Lint

docs-site/src/pages/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const quickCommands = [
1515
'otta calendar overview --from 2026-02-01 --to 2026-02-28 --format json',
1616
'otta absence browse --from 2026-02-01 --to 2026-02-28 --format json',
1717
'otta absence options --format json',
18+
'otta absence add --type <absence-type-id> --from 2026-02-20 --to 2026-02-20 --description "sick leave" --format json',
19+
'otta absence read --id <absence-id> --format json',
20+
'otta absence update --id <absence-id> --description "sick leave" --format json',
21+
'otta absence delete --id <absence-id> --format json',
1822
'otta absence comment --type sick --from 2026-02-20 --to 2026-02-20 --format json',
1923
'otta holidays --from 2026-02-20 --to 2026-02-20 --worktimegroup <id> --format json',
2024
];
@@ -38,7 +42,7 @@ const highlights = [
3842
{
3943
title: 'Timesheet Operations',
4044
description:
41-
'List, browse, report, inspect selectable options, add, update, and delete worktime entries plus run unified calendar overview with deterministic --format output.',
45+
'List, browse, report, inspect selectable options, and manage full worktime + absence CRUD flows with deterministic --format output.',
4246
},
4347
{
4448
title: 'Automation Friendly',
@@ -50,7 +54,7 @@ const highlights = [
5054
const docLinks = [
5155
{to: '/docs/cli-installation', label: 'Installation', summary: 'Build and run locally, set paths, and bootstrap env vars.'},
5256
{to: '/docs/cli-auth', label: 'Authentication', summary: 'Credential flow, token handling, and security notes.'},
53-
{to: '/docs/cli-timesheets', label: 'Time Tracking', summary: 'Worktime list/browse/report/CRUD, absence browse, holidays retrieval, and calendar overview.'},
57+
{to: '/docs/cli-timesheets', label: 'Time Tracking', summary: 'Worktime list/browse/report/CRUD, absence browse/read/add/update/delete, holidays retrieval, and calendar overview.'},
5458
{to: '/docs/cli-output-contract', label: 'Output Contract', summary: 'JSON envelope shape and scriptability guarantees.'},
5559
];
5660

docs/cli-installation.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ $OTTA_BIN --help
5757
$OTTA_BIN config path
5858
$OTTA_BIN config cache-path
5959
$OTTA_BIN absence browse --from 2026-02-01 --to 2026-02-28 --format json
60+
$OTTA_BIN absence options --format json
61+
$OTTA_BIN absence add --type <absence-type-id> --from 2026-02-20 --to 2026-02-20 --description "sick leave" --format json
62+
$OTTA_BIN absence read --id <absence-id> --format json
6063
$OTTA_BIN calendar overview --from 2026-02-01 --to 2026-02-28 --format json
6164
$OTTA_BIN calendar detailed --from 2026-02-01 --to 2026-02-28 --format json --duration-format hours
6265
```

docs/cli-output-contract.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ For scriptability, command output is deterministic.
1717
- `calendar overview`
1818
- `calendar detailed`
1919
- `holidays`
20-
- `absence options`
21-
- `absence browse`
22-
- `absence comment`
20+
- all `absence` subcommands (`options`, `browse`, `read`, `add`, `update`, `delete`, `comment`)
2321
- CSV mode is available only for `worktimes report --format csv`
2422
- `--json` exists as a deprecated alias for `--format json`
2523

@@ -106,6 +104,24 @@ Example (`absence browse`, excerpt):
106104
}
107105
```
108106

107+
Example (`absence add`, excerpt):
108+
109+
```json
110+
{
111+
"ok": true,
112+
"command": "absence add",
113+
"data": {
114+
"id": 51744722,
115+
"raw": {
116+
"abcense": {
117+
"id": 51744722,
118+
"status": "open"
119+
}
120+
}
121+
}
122+
}
123+
```
124+
109125
Example (`calendar overview`, excerpt):
110126

111127
```json

docs/cli-overview.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ otta status
4646
- `otta holidays`: fetch workday calendar/holiday rows.
4747
- `otta absence options`: fetch absence type/user options.
4848
- `otta absence browse`: aggregate absence entries across a date range.
49+
- `otta absence read`: fetch one absence row by id.
50+
- `otta absence add`: create an absence row.
51+
- `otta absence update`: update an existing absence row.
52+
- `otta absence delete`: delete an absence row.
4953
- `otta absence comment`: generate absence comment text.
5054

5155
Important: `worktimes list/browse/report` do not return absences.
@@ -75,7 +79,12 @@ otta status --format json
7579
otta worktimes options --date 2026-02-20 --format json
7680
otta saldo --format json
7781
otta worktimes list --date 2026-02-20 --format json
82+
otta absence options --format json
7883
otta absence browse --from 2026-02-01 --to 2026-02-28 --format json
84+
otta absence add --type <absence-type-id> --from 2026-02-20 --to 2026-02-20 --description "sick leave" --format json
85+
otta absence read --id <absence-id> --format json
86+
otta absence update --id <absence-id> --description "sick leave" --format json
87+
otta absence delete --id <absence-id> --format json
7988
otta calendar overview --from 2026-02-01 --to 2026-02-28 --format json
8089
otta calendar detailed --from 2026-02-01 --to 2026-02-28 --format json
8190
```
@@ -91,4 +100,4 @@ A real terminal E2E sweep was run on 2026-02-22 against the live API, covering:
91100
- calendar overview
92101
- calendar detailed
93102
- holidays
94-
- absence options/browse/comment
103+
- absence options/browse/read/add/update/delete/comment

docs/cli-roadmap.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ sidebar_position: 6
77
## Recently Completed
88

99
- Added `absence browse` range command (`/ttapi/absence/split`).
10+
- Added absence CRUD commands: `absence read/add/update/delete` (`/abcenses`).
1011
- Added `calendar overview` combined day-by-day report (worktimes + absences + holidays).
1112
- Added `calendar detailed` full day-by-day report with day-off reasons and celebrations.
1213

1314
## Next
1415

15-
1. Add absence create/update/delete API commands.
16-
2. Add report/export commands for weekly/monthly summaries.
17-
3. Add a scripted live E2E smoke gate for auth/worktimes/holidays flows.
18-
4. Expand integration tests with tenant-specific recorded API fixtures.
19-
5. Add browser-driven fallback flows via MCP automation.
16+
1. Add report/export commands for weekly/monthly summaries.
17+
2. Add a scripted live E2E smoke gate for auth/worktimes/holidays flows.
18+
3. Expand integration tests with tenant-specific recorded API fixtures.
19+
4. Add browser-driven fallback flows via MCP automation.

docs/cli-timesheets.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,57 @@ Optional API filter for absence type mode:
172172
otta absence options --type days --format json
173173
```
174174

175+
Add an absence row (required: `--type`, plus resolved user):
176+
177+
```bash
178+
otta absence add \
179+
--type <absence-type-id> \
180+
--from 2026-02-20 \
181+
--to 2026-02-20 \
182+
--description "sick leave" \
183+
--format json
184+
```
185+
186+
If `--user` is omitted in `absence add`, fallback order is:
187+
188+
- `OTTA_CLI_USER_ID`
189+
- cached user profile (`~/.otta-cli/cache.json` by default)
190+
191+
Read one absence row by id:
192+
193+
```bash
194+
otta absence read --id <absence-id> --format json
195+
```
196+
197+
Update an absence row:
198+
199+
```bash
200+
otta absence update --id <absence-id> --description "sick leave" --format json
201+
```
202+
203+
Delete an absence row:
204+
205+
```bash
206+
otta absence delete --id <absence-id> --format json
207+
```
208+
209+
Minimal absence CRUD smoke flow (date used in live validation):
210+
211+
```bash
212+
DATE=2026-02-20
213+
214+
# 1) Resolve type id
215+
otta absence options --format json
216+
217+
# 2) Create one row (fill <absence-type-id>)
218+
otta absence add --type <absence-type-id> --from "$DATE" --to "$DATE" --description "tmp-smoke" --format json
219+
220+
# 3) Read/update/delete (replace <absence-id>)
221+
otta absence read --id <absence-id> --format json
222+
otta absence update --id <absence-id> --description "sick leave" --format json
223+
otta absence delete --id <absence-id> --format json
224+
```
225+
175226
Generate unified calendar overview (worktimes + absences + holidays):
176227

177228
```bash

internal/cli/absence_command.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ func newAbsenceCommand() *cobra.Command {
1919

2020
absenceCmd.AddCommand(newAbsenceOptionsCommand())
2121
absenceCmd.AddCommand(newAbsenceBrowseCommand())
22+
absenceCmd.AddCommand(newAbsenceReadCommand())
23+
absenceCmd.AddCommand(newAbsenceAddCommand())
24+
absenceCmd.AddCommand(newAbsenceUpdateCommand())
25+
absenceCmd.AddCommand(newAbsenceDeleteCommand())
2226
absenceCmd.AddCommand(newAbsenceCommentCommand())
2327

2428
return absenceCmd

0 commit comments

Comments
 (0)