Implement comprehensive analytics and monitoring system with PostHog integration, complete observability stack (Prometheus, Grafana, Loki, Promtail), and CI/CD workflows for automated builds. Features: - Add PostHog telemetry integration with privacy-focused event tracking - Implement installation flow for opt-in telemetry configuration - Add telemetry management UI in admin panel with detailed transparency - Track key user events across all major features (projects, tasks, timer, etc.) Infrastructure: - Set up Prometheus for metrics collection - Configure Grafana for visualization dashboards - Integrate Loki and Promtail for log aggregation - Add separate analytics docker-compose configuration CI/CD: - Add GitHub Actions workflows for building and publishing Docker images - Implement separate dev and production build pipelines - Configure automated image publishing to registry Documentation: - Restructure documentation into organized docs/ directory - Add comprehensive guides for telemetry, analytics, and local development - Create transparency documentation for tracked events - Add CI/CD and build configuration guides Code improvements: - Integrate telemetry hooks across all route handlers - Add feature flags and configuration management - Refactor test suite for analytics functionality - Clean up root directory by moving docs and removing test artifacts Breaking changes: - Requires new environment variables for PostHog configuration - Docker compose setup now supports analytics stack Changes: 73 files changed, 955 insertions(+), 14126 deletions(-)
10 KiB
Event Schema
This document lists all analytics events tracked by TimeTracker, including their properties and when they are triggered.
Event Naming Convention
Events follow the pattern resource.action:
resource: The entity being acted upon (project, timer, task, etc.)action: The action being performed (created, started, updated, etc.)
Authentication Events
auth.login
User successfully logs in
Properties:
user_id(string): User IDauth_method(string): Authentication method used ("local" or "oidc")timestamp(datetime): When the login occurred
Triggered: On successful login via local or OIDC authentication
auth.logout
User logs out
Properties:
user_id(string): User IDtimestamp(datetime): When the logout occurred
Triggered: When user explicitly logs out
auth.login_failed
Failed login attempt
Properties:
username(string): Attempted usernameauth_method(string): Authentication method attemptedreason(string): Failure reasontimestamp(datetime): When the attempt occurred
Triggered: On failed login attempt
Project Events
project.created
New project is created
Properties:
user_id(string): User who created the projectproject_id(string): Created project IDproject_name(string): Project namehas_client(boolean): Whether project is associated with a clienttimestamp(datetime): Creation timestamp
Triggered: When a new project is created via the projects interface
project.updated
Project is updated
Properties:
user_id(string): User who updated the projectproject_id(string): Updated project IDfields_changed(array): List of field names that changedtimestamp(datetime): Update timestamp
Triggered: When project details are modified
project.deleted
Project is deleted
Properties:
user_id(string): User who deleted the projectproject_id(string): Deleted project IDhad_time_entries(boolean): Whether project had time entriestimestamp(datetime): Deletion timestamp
Triggered: When a project is deleted
project.archived
Project is archived
Properties:
user_id(string): User who archived the projectproject_id(string): Archived project IDtimestamp(datetime): Archive timestamp
Triggered: When a project is archived
Timer Events
timer.started
Time tracking timer is started
Properties:
user_id(string): User who started the timerproject_id(string): Project being trackedtask_id(string|null): Associated task ID (if any)description(string): Timer descriptiontimestamp(datetime): Start timestamp
Triggered: When user starts a new timer
timer.stopped
Time tracking timer is stopped
Properties:
user_id(string): User who stopped the timertime_entry_id(string): Created time entry IDproject_id(string): Project trackedtask_id(string|null): Associated task ID (if any)duration_seconds(number): Duration in secondstimestamp(datetime): Stop timestamp
Triggered: When user stops an active timer
timer.idle_detected
Timer is automatically stopped due to idle detection
Properties:
user_id(string): User whose timer was stoppedtime_entry_id(string): Created time entry IDidle_minutes(number): Minutes of idle time detectedduration_seconds(number): Total durationtimestamp(datetime): Detection timestamp
Triggered: When idle timeout expires and timer is auto-stopped
Task Events
task.created
New task is created
Properties:
user_id(string): User who created the tasktask_id(string): Created task IDproject_id(string): Associated project IDpriority(string): Task priorityhas_due_date(boolean): Whether task has a due datetimestamp(datetime): Creation timestamp
Triggered: When a new task is created
task.updated
Task is updated
Properties:
user_id(string): User who updated the tasktask_id(string): Updated task IDstatus_changed(boolean): Whether status changedassignee_changed(boolean): Whether assignee changedtimestamp(datetime): Update timestamp
Triggered: When task details are modified
task.status_changed
Task status is changed (e.g., todo → in_progress → done)
Properties:
user_id(string): User who changed the statustask_id(string): Task IDold_status(string): Previous statusnew_status(string): New statustimestamp(datetime): Change timestamp
Triggered: When task is moved between statuses/columns
Report Events
report.generated
Report is generated
Properties:
user_id(string): User who generated the reportreport_type(string): Type of report ("summary", "detailed", "project")date_range_days(number): Number of days in reportformat(string): Export format ("html", "pdf", "csv")num_entries(number): Number of time entries in reporttimestamp(datetime): Generation timestamp
Triggered: When user generates any report
export.csv
Data is exported to CSV
Properties:
user_id(string): User who performed exportexport_type(string): Type of export ("time_entries", "projects", "tasks")num_rows(number): Number of rows exportedtimestamp(datetime): Export timestamp
Triggered: When user exports data to CSV format
export.pdf
Report is exported to PDF
Properties:
user_id(string): User who performed exportreport_type(string): Type of reportnum_pages(number): Number of pages in PDFtimestamp(datetime): Export timestamp
Triggered: When user exports a report to PDF
Invoice Events
invoice.created
Invoice is created
Properties:
user_id(string): User who created the invoiceinvoice_id(string): Created invoice IDclient_id(string): Associated client IDtotal_amount(number): Invoice totalnum_line_items(number): Number of line itemstimestamp(datetime): Creation timestamp
Triggered: When a new invoice is created
invoice.sent
Invoice is marked as sent
Properties:
user_id(string): User who marked invoice as sentinvoice_id(string): Invoice IDtimestamp(datetime): Send timestamp
Triggered: When invoice status is changed to "sent"
invoice.paid
Invoice is marked as paid
Properties:
user_id(string): User who marked invoice as paidinvoice_id(string): Invoice IDamount(number): Payment amounttimestamp(datetime): Payment timestamp
Triggered: When invoice status is changed to "paid"
Client Events
client.created
New client is created
Properties:
user_id(string): User who created the clientclient_id(string): Created client IDhas_billing_info(boolean): Whether billing info was providedtimestamp(datetime): Creation timestamp
Triggered: When a new client is created
client.updated
Client information is updated
Properties:
user_id(string): User who updated the clientclient_id(string): Updated client IDtimestamp(datetime): Update timestamp
Triggered: When client details are modified
Admin Events
admin.user_created
Admin creates a new user
Properties:
admin_user_id(string): Admin who created the usernew_user_id(string): Created user IDrole(string): Assigned roletimestamp(datetime): Creation timestamp
Triggered: When admin creates a new user
admin.user_role_changed
User role is changed by admin
Properties:
admin_user_id(string): Admin who changed the roleuser_id(string): Affected user IDold_role(string): Previous rolenew_role(string): New roletimestamp(datetime): Change timestamp
Triggered: When admin changes a user's role
admin.settings_updated
Application settings are updated
Properties:
admin_user_id(string): Admin who updated settingssettings_changed(array): List of setting keys changedtimestamp(datetime): Update timestamp
Triggered: When admin modifies application settings
System Events
system.backup_created
System backup is created
Properties:
backup_type(string): Type of backup ("manual", "scheduled")size_bytes(number): Backup file sizetimestamp(datetime): Backup timestamp
Triggered: When automated or manual backup is performed
system.error
System error occurred
Properties:
error_type(string): Error type/classendpoint(string): Endpoint where error occurreduser_id(string|null): User ID if authenticatederror_message(string): Error messagetimestamp(datetime): Error timestamp
Triggered: When an unhandled error occurs (also sent to Sentry)
Usage Guidelines
Adding New Events
When adding new events:
- Follow the
resource.actionnaming convention - Document all properties with types
- Include a clear description of when the event is triggered
- Update this document before implementing the event
- Ensure no PII (personally identifiable information) is included unless necessary
Event Properties
Required properties (automatically added):
timestamp: When the event occurredrequest_id: Request ID for tracing
Common optional properties:
user_id: Acting user (when authenticated)duration_seconds: For timed operationssuccess: Boolean for operation outcomes
Privacy Considerations
Do NOT include:
- Passwords or authentication tokens
- Email addresses (unless explicitly required)
- IP addresses
- Personal notes or descriptions (unless aggregated)
OK to include:
- User IDs (internal references)
- Counts and aggregates
- Feature usage flags
- Technical metadata
Event Lifecycle
- Definition: Event is defined in this document
- Implementation: Code is instrumented with
log_event()ortrack_event() - Testing: Event is verified in development/staging
- Monitoring: Event appears in PostHog, logs, and dashboards
- Review: Periodic review of event usefulness
- Deprecation: Unused events are removed and documented
Changelog
Maintain a changelog of event schema changes:
2025-10-20
- Initial event schema documentation
- Defined core events for authentication, projects, timers, tasks, reports, invoices, clients, and admin operations
Document Owner: Product & Engineering Team
Last Updated: 2025-10-20
Review Cycle: Quarterly