Add four skills for Tempo/KSeF timesheet and invoice workflows: - check-my-timesheet: show/log the current user's Tempo time entries - timesheet-checker: audit timesheet completion across all reporters - invoice-checker: pull KSeF invoices, check contractors + MF white list - invoice-prep: summarize Tempo hours per Jira project for invoicing Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
209 lines
8.2 KiB
Markdown
209 lines
8.2 KiB
Markdown
# Timesheet Checker
|
||
|
||
Checks whether employees have completed their timesheets for a given period by pulling Tempo worklogs. Compares against each employee's country calendar (public holidays fetched from date.nager.at) and a configurable minimum of hours per day. Produces a completion report ranked by missing hours.
|
||
|
||
---
|
||
|
||
## Prerequisites
|
||
|
||
The skill needs four credentials. The easiest setup is a `.env` file — copy the template and fill it in once:
|
||
|
||
macOS / Linux:
|
||
```bash
|
||
cp .claude/skills/timesheet-checker/.env.example .claude/skills/timesheet-checker/.env
|
||
```
|
||
Windows (PowerShell):
|
||
```powershell
|
||
Copy-Item .claude\skills\timesheet-checker\.env.example .claude\skills\timesheet-checker\.env
|
||
```
|
||
Or copy the file manually in Explorer / Finder — rename `.env.example` to `.env` in the skill folder.
|
||
|
||
Then open `.env` and fill in your values:
|
||
|
||
```
|
||
TEMPO_API_TOKEN=your_tempo_token
|
||
JIRA_BASE_URL=https://your-company.atlassian.net
|
||
JIRA_EMAIL=your.email@company.com
|
||
JIRA_API_TOKEN=your_jira_token
|
||
```
|
||
|
||
The script looks for `.env` in the **working directory first**, then the skill folder as a fallback. This means you can also place a `.env` in your project root if you prefer one file for all skills.
|
||
|
||
Environment variables set via `export` always take priority over `.env` values, so both approaches work side-by-side.
|
||
|
||
The `.env` file is gitignored — credentials are never committed.
|
||
|
||
| Variable | What it is | Where to get it |
|
||
|---|---|---|
|
||
| `TEMPO_API_TOKEN` | Tempo read token | Tempo → Settings → API Integration |
|
||
| `JIRA_BASE_URL` | Your Atlassian URL | The URL you use to open Jira |
|
||
| `JIRA_EMAIL` | Your Jira login email | Your Atlassian account email |
|
||
| `JIRA_API_TOKEN` | Jira personal API token | [id.atlassian.com](https://id.atlassian.com) → Security → API tokens |
|
||
|
||
If any credential is missing from both `.env` and the environment, the script stops with a clear error listing exactly what is needed.
|
||
|
||
---
|
||
|
||
## How to use in Claude Code
|
||
|
||
Claude Code runs as a CLI, desktop app, web app (claude.ai/code), or IDE extension. **Claude Code runs the full pipeline automatically — no manual script steps.**
|
||
|
||
**Install** — copy the skill folder into your project's Claude skills directory:
|
||
|
||
macOS / Linux:
|
||
```bash
|
||
cp -r src/timesheet-checker .claude/skills/
|
||
```
|
||
Windows (PowerShell):
|
||
```powershell
|
||
Copy-Item -Recurse -Path src\timesheet-checker -Destination .claude\skills\
|
||
```
|
||
|
||
**Use:**
|
||
Just describe what you want — Claude will pick up the skill automatically:
|
||
```
|
||
Check if timesheets are complete for last week
|
||
```
|
||
```
|
||
Timesheet completion for last month
|
||
```
|
||
```
|
||
Check logged hours for 2026-06-01 to 2026-06-30
|
||
```
|
||
|
||
Claude fetches Polish public holidays, pulls Tempo worklogs, computes completion per employee, generates the report, and shows you the results. Output files land in `./timesheet-output/`.
|
||
|
||
---
|
||
|
||
## How to use in the Claude.ai app
|
||
|
||
> Full automation (no manual script running) requires Claude Code. In the Claude.ai app, the Python steps must be run locally.
|
||
|
||
**Set up once (Project approach):**
|
||
1. Create a new Project in Claude.ai.
|
||
2. In **Project Instructions**, paste the full contents of `SKILL.md`.
|
||
3. Upload `references/employees.md` and `references/output-format.md` to the Project knowledge.
|
||
|
||
**Each time you run:**
|
||
1. Set all four credentials in your shell, then run the pre-processor locally:
|
||
```bash
|
||
python3 $SKILL_DIR/scripts/preprocess.py \
|
||
--period last-week \
|
||
--output-dir ./timesheet-output
|
||
```
|
||
The script will use `./employees.md` if it exists, otherwise `$SKILL_DIR/references/employees.md`.
|
||
2. Upload `timesheet_data.json` to the Project conversation.
|
||
3. Ask Claude to summarise and present the results.
|
||
4. Run the post-processor locally to generate the formatted report:
|
||
```bash
|
||
python3 $SKILL_DIR/scripts/postprocess.py \
|
||
--data ./timesheet-output/timesheet_data.json \
|
||
--output-dir ./timesheet-output
|
||
```
|
||
|
||
**Without Projects:** Paste the contents of `SKILL.md` at the start of a new conversation, attach the two reference files, then follow the same steps.
|
||
|
||
---
|
||
|
||
## What is included
|
||
|
||
| File | Description |
|
||
|---|---|
|
||
| `SKILL.md` | Orchestrating skill — instructions for Claude |
|
||
| `references/employees.md` | Editable list of employees and their Tempo account IDs |
|
||
| `references/output-format.md` | Structure of `timesheet_data.json` and the final report |
|
||
| `scripts/preprocess.py` | Fetches Tempo worklogs + Polish holidays, computes completion |
|
||
| `scripts/postprocess.py` | Formats `timesheet_data.json` into the markdown report |
|
||
| `sample/employees_sample.md` | Sample employees file with placeholder account IDs |
|
||
|
||
## Outputs (in `./timesheet-output/`)
|
||
|
||
| File | Description |
|
||
|---|---|
|
||
| `timesheet_data.json` | Computed stats per employee + period + summary |
|
||
| `timesheet_report.md` | Manager-readable report ranked by missing hours |
|
||
|
||
---
|
||
|
||
## Configuring employees
|
||
|
||
The script looks for the employees file in this order:
|
||
|
||
1. `employees.md` in the **current working directory** — place it here for a project-specific list
|
||
2. `references/employees.md` in the **skill folder** — the default shipped with the skill
|
||
|
||
To use a project-specific list, copy the sample and edit it:
|
||
```bash
|
||
cp .claude/skills/timesheet-checker/sample/employees_sample.md ./employees.md
|
||
```
|
||
|
||
The file has two tables:
|
||
|
||
**Defaults** — applies to every employee unless overridden:
|
||
|
||
| setting | value |
|
||
|---|---|
|
||
| `country` | ISO 3166-1 alpha-2 country code (e.g. `PL`, `GB`, `DE`). Used for public holiday lookup. |
|
||
| `expected_hours_per_day` | Minimum hours per working day |
|
||
|
||
**Employees** — one row per person. Leave any column blank to inherit the default.
|
||
|
||
| Column | What it controls |
|
||
|---|---|
|
||
| `name` | Display name in the report |
|
||
| `email` | Work email address (used to look up the Jira account ID automatically) |
|
||
| `country` | Override the default country for this employee |
|
||
| `expected_hours_per_day` | Override the default hours for this employee |
|
||
| `start_date` | First working day — leave blank if employed for the full period |
|
||
|
||
---
|
||
|
||
## Period formats
|
||
|
||
| Input | Meaning | End date |
|
||
|---|---|---|
|
||
| `last-week` | Previous Monday–Friday | Last Friday |
|
||
| `last-month` | Previous calendar month | Last day of that month |
|
||
| `last-year` | Previous calendar year | 31 December |
|
||
| `yesterday` | Yesterday only | Yesterday |
|
||
| `current-week` | Monday of this week to yesterday | Yesterday |
|
||
| `current-month` | 1st of this month to yesterday | Yesterday |
|
||
| `current-year` | 1st January of this year to yesterday | Yesterday |
|
||
| `YYYY-MM-DD:YYYY-MM-DD` | Explicit date range | As specified |
|
||
|
||
For `current-*` periods the current in-progress day is always excluded — end date is yesterday. If today is the first day of the period (e.g. `current-week` on a Monday), the period contains no past working days and the report will show 0 expected hours.
|
||
|
||
In Claude Code, you can also use natural language ("last week", "this month", "yesterday", "June 2026") and Claude converts it automatically.
|
||
|
||
---
|
||
|
||
## How working days are calculated
|
||
|
||
The script fetches Polish public holidays from the [date.nager.at](https://date.nager.at) public API (no authentication needed). It then excludes weekends and those holidays from the period. This runs live each time — holiday data is never hardcoded.
|
||
|
||
---
|
||
|
||
## Integration
|
||
|
||
This skill connects to **Tempo Cloud** (`api.tempo.io/4`) by default. For self-hosted Tempo (Jira Data Center), pass the correct base URL:
|
||
|
||
```bash
|
||
python3 $SKILL_DIR/scripts/preprocess.py \
|
||
--tempo-base-url https://your-jira.company.com/rest/tempo-timesheets/4 \
|
||
...
|
||
```
|
||
|
||
Or in Claude Code:
|
||
```
|
||
Check timesheets for last week, Tempo is at https://jira.company.com/rest/tempo-timesheets/4
|
||
```
|
||
|
||
---
|
||
|
||
## Limits
|
||
|
||
- Requires `TEMPO_API_TOKEN` — the script stops immediately with a clear error if it is missing.
|
||
- Employees with 0 hours may be on leave; the tool does not distinguish between missing logs and approved absence. Review these manually.
|
||
- If the period end date is today or in the future, the period is still open and data will be partial.
|
||
- Polish holidays only. If your team uses a different country calendar, the `get_polish_holidays` function in `preprocess.py` needs updating.
|
||
- Tempo Cloud API v4 only. Tempo Server / Data Center may require a different base URL and authentication method.
|