Profpatsch/users/Profpatsch/timetrack/timetrack.1
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
.Dd December 2, 2025
.Dt TIMETRACK 1
.Os
.Sh NAME
.Nm timetrack
.Nd freelancing time tracker with TUI interface
.Sh SYNOPSIS
.Nm
.Op Ar database
.Nm
.Cm migrate
.Ar database
.Nm
.Cm import-client
.Ar database
.Ar client-name
.Ar json-file
.Op Ar shortcode
.Nm
.Cm create-invoice
.Ar database
.Ar client-name
.Sh DESCRIPTION
.Nm
is a terminal-based time tracking application designed for freelancers managing
multiple clients. It provides a TUI (Terminal User Interface) for interactive
time tracking and a CLI import command for bulk data import.
.Pp
When invoked without arguments,
.Nm
starts in TUI mode using the default database at
.Pa ~/.local/share/timetrack/timetrack.db .
An optional
.Ar database
path can be specified to use a different SQLite database.
.Pp
The
.Cm migrate
command applies any pending database migrations to the specified database and
displays the results. This is useful for upgrading database schemas after
software updates or inspecting which migrations have been applied. All
migrations run atomically within transactions.
.Pp
The
.Cm import-client
command imports time entries from a JSON file into the specified database,
either creating a new client or appending to an existing one. An optional
.Ar shortcode
can be provided when creating a new client for invoice numbering.
.Pp
The
.Cm create-invoice
command creates a new invoice for all uninvoiced time entries for the specified
client. Invoices are immutable once created and use a unique numbering scheme
based on the client's shortcode.
.Sh TUI MODE
The TUI displays time entries in a tabular format with columns for Date, Start,
End, Duration, and Comment. Multiple clients are shown as tabs at the top.
.Pp
Milestone markers can be inserted into the entry list to track project phases.
Milestones display as a flag (🏁) in the Date column and show cumulative hours
in the Start column, representing the total time worked from that milestone until
the next milestone (or end of list). This helps visualize time spent across
different project stages.
.Pp
The TUI automatically reloads data when the terminal gains focus, allowing you to
see changes made by external processes or other instances of timetrack.
.Ss Keyboard Shortcuts
.Bl -tag -width Ds
.It Ic q No or Ic Ctrl-c
Quit the application
.It Ic t
Toggle time tracking for the current client. If a completed entry ended less
than 15 minutes ago, it will be restarted (extending the previous entry).
Otherwise, a new entry is started. If an entry is running, it will be stopped.
.It Ic Ctrl-t
Force start a new entry (bypass the 15-minute restart logic)
.It Ic Tab
Switch to the next client
.It Ic Shift-Tab
Switch to the previous client
.It Ic up No or Ic k
Move selection up
.It Ic down No or Ic j
Move selection down
.It Ic PgUp
Move selection up one page
.It Ic PgDown
Move selection down one page
.It Ic home No or Ic g
Jump to first entry
.It Ic end No or Ic G
Jump to last entry
.It Ic e
Edit the comment for the selected entry
.It Ic m
Create a new milestone at the selected entry's timestamp, or edit the selected
milestone. Milestones are markers that show project phases and display cumulative
hours worked between milestones.
.It Ic Ctrl-d
Delete the selected entry or milestone (cannot delete invoiced entries)
.It Ic Ctrl-Left
For entries: adjust end time backward by 15 minutes. For milestones: move milestone
up to the previous item's timestamp (cannot adjust running or invoiced entries).
.It Ic Ctrl-Right
For entries: adjust end time forward by 15 minutes. For milestones: move milestone
down to the next item's timestamp (cannot adjust running or invoiced entries).
.It Ic Ctrl-Shift-Left
Adjust start time backward by 15 minutes (cannot adjust invoiced entries)
.It Ic Ctrl-Shift-Right
Adjust start time forward by 15 minutes (cannot adjust invoiced entries)
.It Ic i
Preview and create an invoice for all uninvoiced entries of the current client
.It Ic Ctrl-n
Create a new client (prompts for name and shortcode)
.It Ic Ctrl-a
Archive the current client
.It Ic Ctrl-u
Toggle archived clients view
.El
.Ss Input Mode Keys
When creating a client, editing a comment, or creating/editing a milestone:
.Bl -tag -width Ds
.It Ic Enter
Confirm input and save
.It Ic Escape No or Ic Ctrl-c
Cancel input and discard changes
.It Ic Left No / Ic Right
Move cursor
.It Ic Home No or Ic Ctrl-a
Move cursor to start
.It Ic End No or Ic Ctrl-e
Move cursor to end
.It Ic Ctrl-Left No / Ic Ctrl-Right
Jump to previous/next word boundary
.It Ic Backspace
Delete character before cursor
.It Ic Ctrl-Backspace No or Ic Ctrl-w
Delete word before cursor
.El
.Sh IMPORT MODE
The
.Cm import-client
command reads time entries from a JSON file and imports them into the specified
database. Entries are checked for overlaps with existing entries, and the import
is performed atomically (all or nothing).
.Ss Arguments
.Bl -tag -width Ds
.It Ar database
Path to the SQLite database file (e.g.,
.Pa ~/kot/work/timetracking.db )
.It Ar client-name
Name of the client. If the client doesn't exist, it will be created with a
default target of 40 hours.
.It Ar json-file
Path to the JSON file containing time entries
.It Ar shortcode Pq required for new clients
Invoice shortcode for new clients (e.g., "NP" for NewPipe). This shortcode is
used to generate unique invoice numbers in the format SHORTCODE-YYYY-NNN.
Required when creating a new client; ignored if the client already exists.
.El
.Ss JSON Format
The JSON file must contain an array of time entry objects with the following fields:
.Bl -tag -width Ds
.It Ic date Pq required
Date in YYYY-MM-DD format (e.g., "2025-10-18")
.It Ic start Pq required
Start time in HH:MM format (e.g., "10:00")
.It Ic end Pq optional
End time in HH:MM format. If omitted, creates an open (in-progress) entry.
If the end time is earlier than the start time, it's assumed to cross midnight.
.It Ic timezone Pq optional
Timezone name (e.g., "UTC", "Europe/Berlin", "America/New_York"). Defaults to
local time if not specified.
.It Ic comment Pq optional
Description or comment for the time entry
.El
.Ss Import Behavior
.Bl -bullet -compact
.It
Entries that overlap with existing entries are skipped
.It
Only one open (in-progress) entry is allowed per client
.It
Invalid entries (missing required fields, parse errors) are skipped
.It
All successful imports happen atomically within a database transaction
.It
A detailed summary is printed showing imported, skipped, and failed entries
.El
.Sh INVOICING
.Nm
provides built-in invoicing functionality to create immutable snapshots of
completed time entries. Each client must have a unique shortcode that is used to
generate invoice numbers.
.Ss Invoice Numbering
Invoice numbers follow the format SHORTCODE-YYYY-NNN, where:
.Bl -bullet -compact
.It
SHORTCODE is the client's invoice prefix (e.g., "NP" for NewPipe)
.It
YYYY is the current year
.It
NNN is a sequential number starting from 001 for each client+year combination
.El
.Pp
Examples: NP-2025-001, NP-2025-002, ACME-2025-001
.Ss Creating Invoices
Invoices can be created in two ways:
.Bl -enum -compact
.It
In TUI mode, press
.Ic i
on a client to preview and create an invoice for all uninvoiced entries
.It
From the command line using
.Cm create-invoice
.El
.Pp
When an invoice is created:
.Bl -bullet -compact
.It
All uninvoiced completed time entries are included
.It
Each entry is snapshot as an immutable line item
.It
The original time entries are marked as invoiced (preventing duplicate invoicing)
.It
Invoice status starts as "draft"
.El
.Ss Invoice Immutability
Once created, invoice line items are immutable snapshots that preserve the exact
state of time entries at invoice creation time. This ensures legal compliance and
prevents accidental modification of billed work. The original time entries remain
in the database for reference and can be navigated from invoice line items via
their source_entry_id.
.Ss Client Shortcodes
Every client must have a shortcode before invoices can be created. Shortcodes are
assigned when creating a client (either via
.Ic Ctrl-n
in TUI mode or via the
.Ar shortcode
parameter in
.Cm import-client
). Shortcodes must be unique across all clients and are typically 2-4 uppercase
letters.
.Sh EXAMPLES
.Ss Run Database Migrations
.Dl $ timetrack migrate ~/kot/work/timetracking.db
.Ss Start TUI with Production Database
.Dl $ timetrack ~/kot/work/timetracking.db
.Ss Import Time Entries
Create a JSON file
.Pq Pa entries.json
with the following content:
.Bd -literal -offset indent
[
  {"date": "2025-10-18", "start": "10:00", "end": "18:00",
   "timezone": "UTC", "comment": "Feature development"},
  {"date": "2025-10-17", "start": "09:00", "end": "17:00",
   "comment": "Bug fixes"}
]
.Ed
.Pp
Then import:
.Dl $ timetrack import-client ~/kot/work/timetracking.db ClientName entries.json
.Ss Import with Open Entry
To create an in-progress entry:
.Bd -literal -offset indent
[
  {"date": "2025-10-20", "start": "10:00"}
]
.Ed
.Ss Import Client with Shortcode
When importing a new client, specify the shortcode for invoice numbering:
.Dl $ timetrack import-client ~/kot/work/timetracking.db NewPipe entries.json NP
.Pp
This creates a client with shortcode "NP" that will generate invoices like
NP-2025-001, NP-2025-002, etc.
.Ss Create Invoice
To create an invoice for all uninvoiced entries:
.Dl $ timetrack create-invoice ~/kot/work/timetracking.db NewPipe
.Pp
This will create an invoice (e.g., NP-2025-001) containing all completed,
uninvoiced time entries for the client.
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.local/share/timetrack/timetrack.db
Default database path
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr sqlite3 1
.Sh AUTHORS
.An Profpatsch
.Sh CAVEATS
The import functionality uses the database path from
.Pa users/Profpatsch/timetrack/CLAUDE.md
which specifies
.Pa ~/kot/work/timetracking.db
as the production database. Always verify the database path before importing to
production.