Files
eatme/docs/api/admin-routes.md
Michal Pemcak fffcb73ea4 Initial commit: EatMe attendance tracker
Google-SSO PWA for bistro employee clock-in/out, admin employee
management, and stats with CSV export. Express + SQLite backend,
React + Zustand frontend in the light-mono-tui design language.
Multi-stage Dockerfile, compose.yaml for image-based deploys, nginx
reverse-proxy template, and an OKF documentation bundle in docs/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 18:41:11 +02:00

72 lines
2.3 KiB
Markdown

---
type: API Endpoint
title: Admin routes
description: Employee CRUD (add/soft-delete), org-wide and per-employee stats, and CSV export — all requireAdmin.
resource: backend/src/routes/admin.ts
tags: [api, admin]
timestamp: 2026-08-12T00:00:00Z
---
# Admin routes
Mounted at `/api/admin`. Every route requires `requireAuth` + `requireAdmin`
(role resolved from `ADMIN_EMAILS`, see [Auth flow](/docs/architecture/auth-flow.md)).
# Examples
```
GET /api/admin/employees
200 -> { "employees": Employee[] } // includes inactive (soft-deleted) rows
```
```
POST /api/admin/employees
Body: { "email": string, "name"?: string }
201 -> { "employee": Employee }
```
Upserts by email — see [employees](/docs/data-model/employees.md) for the
reactivate-on-re-add behavior.
```
DELETE /api/admin/employees/:id
204 on success, 404 if not found.
```
Soft delete only (`active = 0`) — never removes the row or its attendance
history.
```
GET /api/admin/stats?month=YYYY-MM
200 -> {
"range": { "from": string, "to": string },
"totals": { "totalWorkedMs": number, "totalBreakMs": number, "shiftCount": number },
"employees": [{ "employee": Employee, "totalWorkedMs": number, "totalBreakMs": number, "shiftCount": number }]
}
```
Same calendar-month default as the employee's own stats endpoint.
```
GET /api/admin/stats/:id?month=YYYY-MM
200 -> { "employee": Employee, "range": {...}, "sessions": Session[], "totalWorkedMs": number, "totalBreakMs": number, "shiftCount": number }
404 -> employee not found
```
```
GET /api/admin/stats/:id/export?month=YYYY-MM
200, Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="<email>_<YYYY-MM>.csv"
```
Columns: `Datum, Příchod, Odchod, Pauza (h:mm), Odpracováno (h:mm)`, one row
per shift, sorted chronologically (`backend/src/util/csv.ts`). Prefixed with
a UTF-8 BOM so Excel renders the Czech diacritics correctly. Downloaded from
the frontend as a plain `<a href=... download>` — the session cookie rides
along automatically since it's a same-origin GET.
# Related
- [employees](/docs/data-model/employees.md)
- [attendance_events](/docs/data-model/attendance-events.md)
- [Attendance routes](./attendance-routes.md)
- [Frontend stores](/docs/frontend/stores.md) — `adminStore` owns the
selected month and drives both the summary table and the per-employee
chart off it