- Improve web interface layout for better user-friendliness and mobile responsiveness * Update CSS variables for consistent spacing and component sizing * Enhance card layouts with improved padding, borders, and shadows * Optimize button and form element dimensions for better touch targets * Add hover effects and animations for improved user interaction * Implement responsive grid system with mobile-first approach - Refactor mobile JavaScript to prevent duplicate initialization * Consolidate mobile enhancements into dedicated utility classes * Add initialization guards to prevent double loading * Implement MobileUtils and MobileNavigation classes * Remove duplicate event listeners and mobile enhancements - Fix circular import issue in logo handling * Replace problematic 'from app import app' with Flask's current_app * Add error handling for cases where current_app is unavailable * Improve logo path resolution with fallback mechanisms * Fix settings model to use proper Flask context - Clean up template code and remove duplication * Remove duplicate mobile enhancements from base template * Clean up dashboard template JavaScript * Centralize all mobile functionality in mobile.js * Add proper error handling and debugging - Update CSS variables and spacing system * Introduce --section-spacing and --card-spacing variables * Add mobile-specific spacing variables * Improve border-radius and shadow consistency * Enhance typography and visual hierarchy This commit resolves the double loading issue and logo import errors while significantly improving the overall user experience and mobile responsiveness of the web interface.
14 KiB
Raspberry Pi Time Tracker — Software Requirements Document (SRD)
Version: 1.0 Date: 2025-08-15 Owner: (to be assigned)
1. Purpose & Scope
This SRD defines requirements for a Python application that primarily runs on a Raspberry Pi (RPI) using Docker, with a web-based frontend. The application tracks time across multiple projects with two tracking modes: manual entry and automatic timers that persist even if the browser is closed. The system supports per-user tracking with simple username-only login (no passwords) and provides project overviews, reporting, and per-entry annotations. No external REST API is required.
In Scope
- Project management (name, client, brief description, billing information)
- Per-user time tracking
- Manual time entry (start/end date & time + project)
- Automatic timers that continue running server-side after browser close
- Project-level overviews of time spent
- Ability to add extra information (notes/metadata) per time entry
- Web-based UI (sleek, modern, and user-friendly)
- Execution on Raspberry Pi via Docker
- Local data storage and backups
Out of Scope (for v1)
- Public internet exposure (LAN only)
- External integrations (e.g., third-party invoicing, calendars)
- Advanced permissions/roles beyond simple user identification
- Mobile apps (web frontend should be responsive)
- External REST API endpoints
2. Stakeholders & Users
- End Users: Team members who log time per project.
- Project Managers / Admins: Configure projects, view summaries, export reports.
- IT/Ops: Deploy and maintain the Dockerized application on RPI.
3. Definitions & Glossary
- Automatic Timer: A server-side, long-lived timer associated with a user and project that continues running even if the browser is closed.
- Entry Notes/Metadata: Additional text fields or tags recorded with each time entry.
- Billing Information: Basic fields such as billing rate, billable flag, PO/Cost center, or invoicing reference stored on the project.
4. System Overview
A Python backend (Flask recommended) runs inside Docker on a Raspberry Pi. The frontend is a server-rendered web UI with light interactive components and optional WebSocket events for live timers. Data persists locally (SQLite by default) with optional scheduled backups.
5. Functional Requirements
5.1 Authentication & User Identity
-
Username-only Login:
- Users enter a username to start a session; no password.
- If username does not exist, offer to create it (admin-configurable setting).
- Persist session via secure cookies.
-
Access Model:
- All logged-in users can create and edit their own time entries.
- Admin users can manage projects, view all reports, and edit any entry.
- Admin assignment via config or first user bootstrap.
5.2 Project Management
-
Create/Read/Update/Archive Projects with fields:
- Project Name (required)
- Client (required)
- Brief Description (optional)
- Billing Information (see 5.2.2)
- Status: Active/Archived
-
Billing Information Fields (configurable subset):
- Billable (Yes/No)
- Hourly Rate (currency-aware)
- Billing Reference (e.g., PO number)
- Default Time Rounding (e.g., 1/5/15 minutes) (optional)
5.3 Manual Time Entry
-
Create Manual Entry:
- Required: Project, Start DateTime, End DateTime
- Optional: Notes/Description (free text), Tags
- Validation: End must be after Start; no overlaps check (configurable) with warning.
-
Edit/Delete Entry: Users can edit or delete their own entries; Admins can edit any.
-
Bulk Operations: Optional bulk edit for tags or project reassignment.
5.4 Automatic Timer Tracking
- Start Timer: User selects project and clicks Start.
- Server-Side Persistence: Timer continues running on the server even if the browser closes, device sleeps, or network drops.
- Stop Timer: User clicks Stop from any browser session or device; server finalizes entry (start->stop).
- Resilience: If the RPI restarts, active timers are restored using last known start time and a flag indicating “active”.
- Single Active Timer per User: Enforced; starting a new timer stops the previous one (configurable).
- Idle/AFK (optional v1.1): After N minutes of inactivity, prompt on next visit to confirm whether to subtract idle time.
5.5 Time Entry Annotations & Metadata
- Notes Field: Rich text (plain text in v1, markdown in v1.1) per entry.
- Tags: Freeform comma-separated tags; auto-suggest from existing tags.
- Edit History (optional): Keep non-destructive audit trail for edits.
5.6 Reporting & Overview
-
Project Overview:
- Total time spent, grouped by user and by time period (day/week/month).
- Filters: date range, user, tags, billable/non-billable.
- Summaries: total hours, billable hours, estimated cost (rate × hours).
-
User Overview:
- Personal dashboard of own entries and totals.
-
Entry List & Detail:
- Paginated list with search, sort by date/project/duration.
-
Exports:
- CSV export for entries and summaries.
5.7 Notifications & Feedback
- Inline validations, toasts for success/errors.
- Live timer display (mm:ss) with WebSocket/SSE updates.
5.8 Administration
- User list (usernames), role assignment (User/Admin).
- Project archival/unarchive.
- Configuration page (see 6.4) with authentication mode, rounding rules, timezone, currency.
6. Non-Functional Requirements
6.1 Platform & Runtime
- Target Hardware: Raspberry Pi 4 (2GB+) recommended.
- OS: Raspberry Pi OS (64-bit) or compatible Linux.
- Containerization: Docker + docker-compose.
- Python: 3.11+.
6.2 Performance
- Support 10–25 concurrent users on LAN with sub-200 ms page actions.
- Timer accuracy within ±1 second over 24 hours.
6.3 Reliability & Resilience
- Automatic restart with
restart: unless-stoppedin Compose. - Graceful shutdown; in-flight timers persisted.
- Periodic health checks and liveness endpoints (internal only).
6.4 Configurability
.env/config UI for: timezone (default Europe/Rome), currency, default rounding, allow self-register, single-active-timer, idle timeout, export delimiter.
6.5 Security
- LAN-only by default; bind to private IP.
- Reverse proxy optional (Caddy/nginx) for TLS on LAN.
- Username-only login; display clear banner that this is an internal tool.
- CSRF protection disabled for simplified development; secure cookies; session timeout.
- Role-based checks server-side.
6.6 Privacy & Data Retention
- Store minimal PII (username only).
- Retain entries indefinitely unless purged. Admin-configurable retention and backup.
6.7 Localization & Timezones
- System default timezone configurable; all storage in UTC; UI displays local time.
- Handle DST transitions; prevent overlapping/invalid times via UI validation.
6.8 Accessibility
- WCAG 2.1 AA-aligned basics: keyboard navigation, color-contrast, focus states.
7. Architecture & Design
7.1 High-Level Components
- Web App (Flask): Server-rendered templates (Jinja2) + HTMX/Alpine.js for interactivity.
- Background Scheduler: APScheduler (or asyncio task) for periodic jobs (backups, health checks).
- Real-Time Layer: WebSocket or Server-Sent Events for live timer updates.
- Storage: SQLite with WAL mode; upgrade path to PostgreSQL.
- Reverse Proxy (optional): Caddy/nginx container for TLS and static asset caching.
7.2 Data Model (Initial Schema)
users
- id (PK)
- username (unique, required)
- role (enum: user, admin)
- created_at
projects
- id (PK)
- name (required)
- client (required)
- description (text)
- billable (bool)
- hourly_rate (decimal, nullable)
- billing_ref (text, nullable)
- status (enum: active, archived)
- created_at, updated_at
time_entries
- id (PK)
- user_id (FK → users)
- project_id (FK → projects)
- start_utc (datetime)
- end_utc (datetime, nullable when active)
- duration_seconds (int, computed on finalize)
- notes (text)
- tags (text)
- source (enum: manual, auto)
- edited_at
settings
- id (singleton)
- timezone, currency, rounding_minutes, single_active_timer, allow_self_register, idle_timeout_minutes
Indexes on (user_id, start_utc), (project_id, start_utc), and active entries (end_utc IS NULL).
7.3 Timer Persistence Logic
- On Start: create
time_entriesrow withend_utc=NULLandsource=auto. - Heartbeat optional; not required for persistence.
- On Stop: set
end_utc, computeduration_secondsapplying rounding rules. - On Server Restart: query all
end_utc IS NULLand treat as still running sincestart_utc.
7.4 UI/UX Guidelines
-
Clean, modern layout with responsive design.
-
Primary views:
- Dashboard: Active timer status, quick Start/Stop, recent entries.
- Projects: List, filter, create/edit, archive.
- Log Time: Manual entry form.
- Reports: Project and user overviews with filters and CSV export.
- Admin: Users, settings.
-
Components: sticky header timer, toasts, modal dialogs, date/time picker, tag chips.
8. Deployment & Operations
8.1 Docker Compose (concept)
app(Flask + Gunicorn)db(optional Postgres; otherwise SQLite volume inapp)proxy(optional Caddy/nginx)- Volumes for
/data(DB, exports, backups).
8.2 Environment Variables
TZ,CURRENCY,ROUNDING_MINUTES,ALLOW_SELF_REGISTER,SINGLE_ACTIVE_TIMER,IDLE_TIMEOUT_MINUTES,ADMIN_USERNAMES.
8.3 Backup & Restore
- Nightly SQLite copy to
/backups/YYYY-MM-DD/with retention policy. - Manual on-demand export (zip: DB + CSVs of key tables).
8.4 Monitoring
- Health endpoint
/_health(no auth) for local check. - Logs to stdout; optional file rotation.
9. Security Considerations
- Username-only login is weak; mitigate by LAN isolation, optional reverse proxy auth, and kiosk usage.
- CSRF protection disabled; use SameSite cookies; disable framing.
- Rate-limit login attempts by IP to prevent session abuse.
10. Compliance & Legal
- Internal tool; ensure local employment/time-tracking rules if used formally (outside v1 scope).
11. Acceptance Criteria (Sample)
- Users can create projects with client and billing fields.
- Users can log manual entries with start & end times and notes.
- Users can start a timer, close the browser, reopen, and see the timer still running.
- Only one active timer per user (by default).
- Project overview shows total hours per user for a chosen date range.
- CSV export contains correct rows and computed durations.
- System restarts do not lose active timers or historical entries.
- Admin can archive a project; archived projects cannot be chosen for new entries.
- UI renders well on desktop and mobile and passes basic keyboard navigation.
12. Test Cases (Illustrative)
- TC-01: Create project with required fields → Project listed as Active.
- TC-02: Manual entry with end before start → Validation error displayed.
- TC-03: Start timer, close browser, wait 2 minutes, reopen, stop → Duration ≥ 120s.
- TC-04: Start timer A, then start timer B → Timer A auto-stops (if configured).
- TC-05: Edit entry notes and tags → Changes persist and appear in reports.
- TC-06: Archive project, attempt to log time → Not selectable in new entry form.
- TC-07: CSV export for project/date range → Matches on-screen totals.
- TC-08: RPI reboot → Active timers restored, dashboard reflects running state.
- TC-09: CSRF protection disabled - no CSRF validation required.
13. UI Wireframe Descriptions (Textual)
- Login: Username input, “Continue” button, disclaimer about internal use.
- Dashboard: Header with current user + active timer (project name, elapsed). Large Start/Stop button, quick project selector, recent entries table with inline edit.
- Projects: Card list with name, client, billable badge, actions (Edit, Archive).
- Log Time: Form with project dropdown, start/end pickers, notes, tags.
- Reports: Filters row (date range, user, project, tags), totals cards, table, export button.
- Admin: Users list with role toggles, settings form.
14. Future Enhancements (Backlog)
- Idle detection and retroactive adjustments.
- Mobile PWA installability and offline caching for UI.
- Calendar and Kanban views; week grid editor.
- Rate cards by client; multi-currency.
- LDAP/SSO or reverse-proxy auth (e.g., Authelia) for stronger security.
- REST API (if needed) or WebDAV/ICS export.
- PDF report templates and invoice drafts.
15. Constraints & Assumptions
- LAN-only deployment; minimal threat model.
- No external REST API required.
- SQLite is sufficient for initial scale; PostgreSQL available if needed.
16. Appendix: Example docker-compose.yml (Skeleton)
services:
app:
image: timetracker:latest
build: .
environment:
- TZ=Europe/Rome
- ROUNDING_MINUTES=1
- SINGLE_ACTIVE_TIMER=true
- ALLOW_SELF_REGISTER=true
- ADMIN_USERNAMES=admin
ports:
- "8080:8080"
volumes:
- app_data:/data
restart: unless-stopped
# Optional reverse proxy (TLS on LAN)
proxy:
image: caddy:latest
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
ports:
- "80:80"
- "443:443"
depends_on:
- app
restart: unless-stopped
volumes:
app_data:
caddy_data:
caddy_config:
17. Appendix: Data Dictionary (Selected Fields)
- projects.hourly_rate: Decimal(9,2), nullable; interpreted in
settings.currency. - time_entries.tags: CSV string; UI presents chips; stored raw for simplicity.
- time_entries.duration_seconds: Calculated as
round_to(duration, rounding_minutes)when finalized.
End of Document