- Enforce task ownership on PATCH/DELETE /api/tasks (was: any signed-in user could edit or delete anyone's tasks) - Validate all API request bodies with zod; escape user content and restrict links to http(s) in the Drive export; block reverting a SUBMITTED report - Add @@unique([userId, date]) on Report with upsert to eliminate the duplicate-daily-report race; switch startup from `prisma db push --accept-data-loss` to `prisma migrate deploy` with automatic baselining of existing databases (dedup migration merges any pre-existing duplicates) - Autosave: re-queue and retry failed task saves with a visible saving/error indicator instead of silently dropping edits - Paginate and filter GET /api/reports (?date, ?mine, ?q, ?take, ?cursor); report form fetches only today's report, admin dashboard uses server-side search + Load more - Type the frontend and lib layer (DTOs in src/types/api.ts); zero eslint errors - Update README and Unraid guide for migrations, upgrade path, and API Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WFH Daily Report App
A sleek, modern, and dockerized web application for employees to track and submit their daily work-from-home reports. Features a stunning glassmorphic design and seamless integration with Google Workspace.
✨ Features
- Premium UI: Modern glassmorphism aesthetics with smooth animations and responsive design.
- Google OAuth 2.0: Secure authentication using your company's Google Workspace accounts.
- Multi-Step Reporting:
- Morning: Log planned tasks, time estimates, and initial notes.
- Evening: Review achievements, update statuses, and submit links to completed work.
- Reliable Autosave: Task edits are debounced and saved automatically; failed saves are retried and surfaced in the UI so no edit is ever silently lost.
- Smart Admin Logic:
- The first user to log in is automatically granted the ADMIN role.
- Exclusive Admin Panel with server-side search and paginated report browsing, user role management, and settings.
- Google Drive Integration:
- Automatically exports completed reports as Google Docs.
- Admins can designate a specific folder for all exports.
- Single-Container Architecture: Uses SQLite for persistent storage, making it ideal for "drop-in" deployments (e.g., Unraid, Synology).
🚀 Quick Start
1. Prerequisites
- Google Cloud Console Project with:
- OAuth 2.0 Credentials (Web Application)
- Google Drive API enabled
- Docker installed on your host.
2. Environment Setup
Copy .env.example to .env and provide your credentials:
cp .env.example .env
3. Run with Docker
# Build and run the container
docker build -t wfh-report .
docker run -p 3000:3000 \
--env-file .env \
-v $(pwd)/data:/app/data \
wfh-report
🗄️ Database & Migrations
The schema is managed with Prisma Migrate. On every container start, entrypoint.sh runs prisma migrate deploy, which applies any pending migrations from prisma/migrations/ — additive and safe, unlike the old db push --accept-data-loss approach.
- Fresh installs: all migrations are applied automatically to the new database.
- Upgrading an existing deployment (created before migrations were introduced): the first boot logs a one-time
P3005error, then automatically baselines the database (marks0_initas applied) and applies the remaining migrations. This is expected — no manual action needed. - Reports are unique per user per day (
@@unique([userId, date])); the migration merges any pre-existing duplicate reports, keeping the earliest and moving its tasks.
To add a schema change during development:
npx prisma migrate dev --name describe_your_change
🔌 API Overview
All endpoints require a session; admin endpoints require the ADMIN role. Request bodies are validated with zod (invalid input returns 400 with field details).
| Endpoint | Notes |
|---|---|
GET /api/reports |
Returns { reports, nextCursor }. Query params: date (YYYY-MM-DD), mine=1 (own reports only, matters for admins), q (search by employee/manager, admin), take (page size, max 100), cursor (pagination). |
POST /api/reports |
Creates or resumes the day's report (upsert — safe against double-submits). |
GET/PATCH /api/reports/[id] |
Owner (or admin for GET) only. A SUBMITTED report cannot be reverted. |
POST /api/reports/[id]/export |
Exports/re-exports the report to Google Drive. User content is HTML-escaped; only http(s) links are rendered. |
POST/PATCH/DELETE /api/tasks |
Scoped to tasks on the caller's own reports. |
GET/POST /api/admin/settings |
Admin only. Allowed keys: GOOGLE_DRIVE_FOLDER_ID. |
GET/PATCH /api/admin/users |
Admin only. Role management; self-demotion is blocked. |
🏡 Unraid Installation
For specific instructions on installing this on Unraid (including volume mapping and Unraid UI configuration), please refer to our Unraid Installation Guide.
🛠️ Tech Stack
- Framework: Next.js (App Router)
- Database: SQLite via Prisma ORM (Prisma Migrate for schema management)
- Auth: NextAuth.js
- Validation: Zod on all API request bodies
- Styles: Vanilla CSS & TailwindCSS (for utility)
- Icons: Lucide React