Last Updated: 2026-04-02 Current Version: 1.2.1 (Build 44)
This is the canonical TODO file for ActaLog. All task tracking should be done here.
- Only track TODOs here - Do not create TODO sections in other documentation files
- Active Tasks - Items currently being worked on (move here when starting)
- Backlog - Planned features, known bugs, and improvements not yet started
- Completed Releases - Keep only the last 5 releases here; older releases are in CHANGELOG.md
- Periodic Cleanup - When starting a new session, clean up completed items and archive old releases
- Technical Details - Include file paths and implementation notes for completed work
- Priority Markers - Use
[HIGH],[MEDIUM],[LOW]for backlog items - Bug Format -
[BUG]prefix for bug reports - Code TODOs - Periodically scan codebase for TODO/FIXME comments:
grep -rn "TODO\|FIXME" --include="*.go" --include="*.vue" --include="*.js" .
TODO.md- Active task tracking (this file)CHANGELOG.md- Release history and change documentationROADMAP.md- High-level version planning and feature roadmap- Do NOT duplicate TODO content in ROADMAP.md or CHANGELOG.md
Items currently being worked on. Move items here from Backlog when starting.
Status: Phase 1-4 Complete
Phase 1-3 (v0.26.0 migration):
- Gym locations, class templates, schedule slots
- Class sessions with capacity management
- Coach assignments (per-gym role)
- Reservations with check-in flow
Phase 4 (v0.27.0 migration):
- Documents - Required documents (waivers, liability forms) per gym
- User Documents - Track document completion status per user
- Class Packages - Credit packages (e.g., "10-Class Pack")
- User Credits - Credit balances with expiration tracking
- Waitlist - Queue management when classes are full
- Class Notifications - Reminders and waitlist promotions
Frontend Views:
-
ScheduleView.vue- Browse sessions, reserve, join/leave waitlist -
MyCreditsView.vue- User's credits, documents, waitlist entries -
MyReservationsView.vue- User's upcoming reservations -
AdminPackagesView.vue- Admin management for packages, documents, user credits -
AdminSchedulingView.vue- Admin session/template management
API Endpoints (Phase 4):
- Documents:
GET/POST/PUT/DELETE /api/admin/gyms/{id}/documents - Packages:
GET/POST/PUT/DELETE /api/admin/gyms/{id}/packages - Credits:
POST /api/admin/gyms/{id}/users/{id}/credits,GET /api/gyms/{id}/users/me/credits - Waitlist:
POST/DELETE /api/sessions/{id}/waitlist,GET /api/users/me/waitlist - User documents:
GET /api/gyms/{id}/users/me/documents
Database Tables (6 new in v0.27.0):
documents,user_documents,class_packages,user_class_credits,waitlist_entries,class_notifications
Bug Fix: PurchaseCredits now correctly uses package credits when package_id is provided without explicit credits value.
Tested on: SQLite, MariaDB (192.168.1.234), PostgreSQL (192.168.1.143)
Status: Complete (Build 31)
- Three delete modes for class templates:
template_only- Delete template only, sessions orphanedwith_future_sessions- Delete template + future sessions, keep pastwith_all_sessions- Delete template + all sessions
- Cascade deletion (coaches, reservations, waitlist, notifications)
- Credit refunds for unconfirmed reservations
- User notifications for cancelled sessions
- New UI dialog with mode selection and session counts
- API:
DELETE /api/admin/scheduling/templates/{id}?mode=<mode>
Files Modified:
internal/domain/scheduling.go,internal/domain/phase4.go- Interface methodsinternal/repository/class_session_repository.go- Bulk delete methodsinternal/repository/session_coach_repository.go- DeleteBySessionIDsinternal/repository/reservation_repository.go- GetBySessionIDs, DeleteBySessionIDsinternal/repository/waitlist_repository.go- DeleteBySessionIDsinternal/repository/credits_repository.go- RefundCreditinternal/service/scheduling_service.go- DeleteTemplateWithModeinternal/handler/scheduling_handler.go- Mode parameter handlingweb/src/views/AdminSchedulingView.vue- Delete dialog UI
Tested on: SQLite, MariaDB, PostgreSQL
Status: Phase 1 Complete, Phase 2 Complete
Tracking: See docs/TEST_CLEANUP.md for detailed summary
Phase 1 - Removed ~31 low-value tests:
- Struct field assignment tests (19)
- Language feature tests (10)
- Trivial helper tests (2)
Phase 2 - Removed ~267 panic-expectation tests:
- All handler test files cleaned (24 files total)
- Panic tests that created nil dependencies removed
- Validation tests and mock-based tests preserved
- All tests pass with proper coverage
Status: golangci-lint set to continue-on-error in .github/workflows/ci.yml:37
The following lint issues need to be resolved to re-enable strict linting:
-
goconst warnings - Repeated strings in SQL queries (LIMIT, OFFSET, ORDER BY)
- Files:
internal/repository/movement_repository.go, others - Decision: Either make constants or add exclusion
- Files:
-
Remaining gofmt issues - Some files may still have formatting issues
- Run:
gofmt -w ./...and review changes
- Run:
-
Other minor issues - Review full golangci-lint output for any remaining items
To re-enable strict linting:
- Fix or exclude remaining issues
- Remove
continue-on-error: truefrom.github/workflows/ci.yml:37
-
[HIGH]Create/api/benchmarkendpoint for system-wide performance testing- Exercises database, serialization, business logic, and concurrency through synthetic operations
- Uses isolated
benchmark_datatable (never touches real user data) - Auto-cleanup after runs, user-scoped data isolation
- JWT authentication required
- Backend implementation:
- Domain model (
internal/domain/benchmark.go) - BenchmarkData entity, result structs, repository interface - Migration 0.22.0 (
internal/repository/migrations.go) - benchmark_data table with indexes - Migration 0.23.0 - Extended fields for stress testing (large_text, json_blob, uuid)
- Repository (
internal/repository/benchmark_repository.go) - CRUD + batch operations - Service (
internal/service/benchmark_service.go) - 18+ benchmark operations - Handler (
internal/handler/benchmark_handler.go) - POST /benchmark, GET /benchmark/status - Route registration (
cmd/actalog/main.go) - wire up handler
- Domain model (
- Benchmark operations:
- Database: Insert, BulkInsert(100), SelectByID, SelectByKey, SelectList, SelectFiltered, Update, Delete
- Serialization: Marshal/Unmarshal small & large JSON
- Business Logic: 1RM calculations (1000x), validation, string/date operations
- Concurrent (optional): 10 parallel reads, 5 writes, mixed operations
- Configurable record count:
-
?records=Nquery parameter (default: 1000, max: 500000) - Complex benchmark data (5-10KB text, nested JSON blobs)
- Server timeout configuration for large record counts
-
- Benchmark tool integration (
actalog-benchmarkv0.7.0):- Add
/api/benchmarkcaller (internal/metrics/benchmark_api.go) - Add BenchmarkAPIResult to types.go
- Update reporters to include benchmark API results
- Add
--benchmark-recordsflag for configurable record count - Comparison reports include server-side benchmark results
- Add
-
[HIGH]Frontend Subscription Status Display- Add subscription status badge to user profile/settings (SubscriptionStatusBadge.vue in SettingsView)
- Show expiration date for paid subscriptions
- Display "Permanent Free" badge for permanent users
- Show organization subscriptions the user benefits from
-
[HIGH]Admin Subscription Management UI- Admin panel for viewing all user subscriptions (AdminSubscriptionsView.vue)
- Admin panel for viewing all organization subscriptions
- Create subscription form (CreateSubscriptionDialog.vue)
- Mark subscription as paid button/action (MarkAsPaidDialog.vue)
- Cancel subscription with reason input (CancelSubscriptionDialog.vue)
- View subscription history (SubscriptionDetailDialog.vue)
- List expiring subscriptions API (backend complete v0.19.0)
- List overdue/expired subscriptions API (backend complete v0.19.0)
- Frontend UI for expiring/expired subscription lists (AdminSubscriptionsView.vue tabs)
-
[HIGH]Read-Only Mode UI Feedback- Graceful handling of HTTP 402 Payment Required responses (subscription.js store)
- Show "Subscription Expired" banner when in read-only mode (SubscriptionExpiredBanner.vue in App.vue)
- Disable/hide create/edit buttons when subscription expired
- "Renew Subscription" call-to-action in banner
- Toast notifications explaining why operations are blocked
-
[HIGH]PWA- Icon saved to home screen is fuzzy - regenerated all icons from SVG with full RGBA color
-
[HIGH]Overall- Find more attractive icons for the navigation bar - replaced with Font Awesome icons (fa-house-chimney, fa-arrow-trend-up, fa-person-running, fa-circle-user)
- Allow notifications to be marked as read/unread (implemented in NotificationsView.vue)
- Develop a theme called "Sunrise" based on colors from sunset image (added to vuetify.js and theme.js)
- Remove the View all link on the Dashboard (removed from DashboardView.vue)
- Add more helper text to form controls throughout the app - Added markdown hints to textarea fields in WODCreateView, WODEditView, MovementCreateView, MovementEditView, WorkoutTemplateEditView, AdminAnnouncementsView (v0.22.0)
-
[HIGH]User-Customizable Fonts (Completed v0.19.0)- Self-hosted web fonts with 10 options (including accessibility fonts)
- Backend sync via user_settings table + localStorage cache
- All fonts use SIL OFL 1.1 or Apache 2.0 (free for commercial use, self-hosting allowed)
- Font options:
- System Default, Inter, Roboto, Lato, Fira Sans, Lexend
- OpenDyslexic (A11y), Atkinson Hyperlegible (A11y)
- Source Serif Pro, JetBrains Mono
- Backend changes:
- Add
font_familyfield tointernal/domain/user_settings.go - Add migration 0.21.0 in
internal/repository/migrations.go - Update SQL queries in
internal/repository/user_settings_repository.go - Add default + audit logging in
internal/service/user_settings_service.go
- Add
- Frontend changes:
- Download fonts to
web/public/fonts/(woff2 format) - Create
web/src/assets/fonts.csswith @font-face declarations - Create
web/src/stores/font.js(font store) - Update
web/src/stores/settings.js(add fontFamily sync) - Update
web/src/App.vue(use CSS variable--app-font-family) - Add font selector UI in
web/src/views/SettingsView.vue
- Download fonts to
- Performance:
font-display: swap, service worker caching, only selected font loads
-
[HIGH]Security Response Headers Middleware (Completed v1.2.4) — Addedpkg/middleware/security_headers.gosetting X-Frame-Options, X-Content-Type-Options, Referrer-Policy, HSTS, and a project-tuned CSP. Wired after CORS incmd/actalog/main.go. Tests insecurity_headers_test.goassert per-header values and that script-src stays free of'unsafe-inline'/'unsafe-eval'. -
[HIGH]Avatar Upload Magic-Byte Validation (Completed v1.2.4) — Replaced trust-the-header check withhttp.DetectContentType()over the first 512 bytes plus a.jpg/.jpeg/.png/.gif/.webpextension allowlist. Negative tests cover spoofed-Content-Type and disallowed-extension cases.
-
[HIGH]Backup and Restore make sure the backup functions keep up with the database schema changes (tested backup and restore round trips on SQLite, PostgreSQL, and MariaDB).- Added schema metadata to backup format for type-aware restoration
- Implemented three restore modes:
replace,merge,skip - Natural key matching (users by email, movements by name, etc.)
- ID remapping for foreign key references during merge/skip
-
[HIGH]Duplicate Record Protection- All imports now protect against duplicate records:
- WOD Import:
skip_duplicatesandupdate_duplicatesoptions - Movement Import:
skip_duplicatesandupdate_duplicatesoptions - User Workout Import: Added
update_duplicatesoption (v0.17.0) - Wodify Import: Added
skip_duplicatesandupdate_duplicatesoptions (v0.17.0)
- WOD Import:
- System restore supports merge/skip modes with natural key matching
- API returns detailed results (records created, updated, skipped)
- All imports now protect against duplicate records:
-
[HIGH]Check for missing indexes - 83 indexes defined in migrations (foreign keys and commonly queried fields covered) -
[HIGH]Audit Log Enhancements - Added 17+ helper methods for comprehensive audit coverage (logout, token refresh, profile updates, user deletion, organization CRUD, subscription lifecycle) -
[HIGH]Database Query Optimization - Added audit_logs indexes (migration 0.17.0), optimized GetUsageStats (3→1 query), GetActiveUsersThisMonth (3→2 queries), ListByUserWithDetails N+1 fix (6N+1→5 queries) -
[HIGH]Error Handling Consistency - Centralized error handling in internal/handler/errors.go with HTTPError type and 30+ service error mappings -
[HIGH]Structured Logging - Added JSON format support to pkg/logger with InfoWithFields, ErrorWithFields, and FieldLogger chaining -
[HIGH]Comprehensive API Documentation - OpenAPI/Swagger documentation at/docs/swagger.json(v0.22.0) -
[HIGH]Implement Rate Limiting - pkg/middleware/rate_limit.go with sliding window algorithm
- Documentation Website
- Build a dedicated user and admin guide website from Markdown documents
- Use a static site generator (e.g., MkDocs, Docusaurus, VitePress, Hugo) to convert existing Markdown docs into an attractive HTML site with navigation, search, and theming
- Separate user guide (workout logging, schedules, PRs, leaderboards) and admin guide (user management, scheduling config, backups, subscriptions)
- Host alongside the app or as a standalone site
These features can be added after the core frontend is complete:
-
Stripe Integration (v0.15.0+)
- Replace manual admin control with automated billing webhooks
- Credit card payment processing
- Automatic subscription renewal
-
Email Notifications (v0.15.0+)
- Notify users 7/3/1 days before expiration
- Notify users when subscription expires
- Notify admins of failed payments
-
Self-Service Portal (v0.16.0+)
- Users can upgrade/downgrade themselves
- View payment history
- Update payment method
-
Usage Limits (v0.16.0+)
- Track API usage for free tier
- Enforce limits on free subscriptions
- Display usage metrics
-
Bulk Operations (v0.17.0+)
- Admin can bulk-update subscriptions
- Bulk extend expiration dates
- Bulk cancel subscriptions
-
Grace Period Configuration (v0.17.0+)
- Make grace period configurable per organization
- Different grace periods for different subscription tiers
-
[HIGH]Subscription Service Tests - Comprehensive test suite (internal/service/subscription_service_test.go) -
[HIGH]Backup Service Tests - 10 test functions with full restore mode coverage (internal/service/backup_service_test.go) -
[HIGH]User Workout Service Tests - Complete coverage with PR detection -
[HIGH]Wodify Import Service Tests - Duplicate handling and error recovery -
[HIGH]Most Service Tests Complete - 13 services at 100% coverage -
[HIGH]Add handler unit tests - Handler coverage at 72.6%- benchmark_handler_test.go (17 tests, 53-100% coverage per method)
- auth_handler_test.go (63-100% coverage, comprehensive with mock service)
- user_workout_handler_test.go (32-100% coverage)
- movement_handler_test.go (59-100% coverage)
- wod_handler_test.go (84-100% coverage)
- subscription_handler_test.go (28-69% coverage)
- All other handlers have tests: settings, admin, performance, data_change_log, organization, etc.
-
[MEDIUM]Improve user_service coverage - Currently 61.9%, target 80%+ -
[MEDIUM]Improve import_service coverage - Currently 60.8%, target 80%+ -
[LOW]Add repository unit tests - All repository implementations
-
Comprehensive User Edit Screen — Profile tab + framework (v1.3.0)
- Shipped: Profile tab, four-layer defense-in-depth, recovery tooling, full documentation
- Plan:
docs/superpowers/plans/2026-04-28-admin-user-edit-v1.3.0-plan.md
-
[HIGH]Admin: Create User flow on User Management screen (v1.3.2) —POST /api/admin/users+ "Create User" dialog. Tracked: #217 (Completed v1.3.2) -
[HIGH]Admin: edit full user details on Profile tab (v1.3.2) — Profile tab Password Management card with admin-set password (separate from force-password-reset) (Completed v1.3.2) -
[HIGH]Admin: break-glass CLI for protected users (v1.3.2) (Completed v1.3.2) —actalog admin force-edit-protected --email=X --field=<password|email|name|role|account_disabled> [--value=...] --confirm. Per-field audit events; identity-field changes drop+UPDATE+reinstall L3 triggers and re-run the boot invariant. Documented indocs/security/PROTECTED_USERS.md§"Break-glass CLI" -
[HIGH]User Edit Screen — Affiliations tab (v1.3.1) — gym memberships, coach assignments per gym; add/remove org membership; manageCoachAssignmentperGymLocation(assign/revoke coach role per gym); viewTemplateCoachandSessionCoachrows that reference this user -
[HIGH]User Edit Screen — Subscriptions / Credits / Preferences / Activity tabs (v1.3.2) — complete the remaining tabs deferred from v1.3.0: Subscriptions, Class Credits & Documents, Preferences (UserSettings), and read-only Activity & Audit summary -
[HIGH]User Import/Export System (Admin only) (Completed v0.23.0)- Export users to CSV format (email, name)
- Import users from CSV (email, name, password) with preview/confirm workflow
- Preview workflow with validation
- Duplicate detection by email
- Batch password reset emails - select users from filterable list
- Backend files:
internal/service/user_import_service.go,internal/handler/user_import_handler.go - Frontend:
web/src/views/AdminUserImportExportView.vuewith 3 tabs (Import, Export, Password Reset) - API endpoints:
POST /api/admin/users/import/preview- Preview CSV importPOST /api/admin/users/import/confirm- Execute importGET /api/admin/users/export- Download CSVGET /api/admin/users/filter- List users with search/date filtersPOST /api/admin/users/batch-password-reset- Send reset emails to selected users
-
[HIGH]Improved Duplicate Record Detection During Imports (v0.17.0)- Trap duplicate movements during import (check by name)
- Trap duplicate WODs during import (check by name)
- Trap duplicate user workouts during import (check by date/user/name)
- Trap duplicate Wodify workouts during import (check by date)
- Import options for handling duplicates:
- Skip duplicates (keep existing) -
skip_duplicates=true - Update duplicates (overwrite existing) -
update_duplicates=true
- Skip duplicates (keep existing) -
- Detailed import result with created/updated/skipped counts
- Frontend UI to review and select action for each duplicate
- Batch duplicate resolution UI (apply same action to all)
-
[HIGH]Database Duplicate Detection and Cleaning Procedure (Completed v0.24.0)- Create admin tool to scan for existing duplicates in database
- Detect duplicate movements (case-insensitive name matching)
- Detect duplicate WODs (case-insensitive name matching)
- Detect duplicate user workouts (same user, same date, same name)
- Detect duplicate users (case-insensitive email matching)
- Detect duplicate workout templates (same name, same user)
- Generate duplicate report with:
- Count of duplicates per entity type
- List of duplicate groups with record IDs
- FK reference counts for each record
- Safe merge/cleanup procedure:
- Preview which records will be kept vs deleted
- Automatically update foreign key references
- Delete child records from duplicates (movements/WODs)
- Preserve data integrity with transaction support
- Admin UI to review and approve cleanup (AdminDataQualityView.vue)
- Preview mode shows FK impact before confirming
- Audit log of all merge operations (duplicate_merge event type)
- Data Quality Issue Detection - 4 quality checks:
- Orphaned FK references (error severity)
- Empty required fields (error/warning severity)
- Future workout dates (warning severity)
- Invalid email formats (warning severity)
- Backend files:
internal/service/data_quality_service.go,internal/handler/data_quality_handler.go - Frontend:
web/src/views/AdminDataQualityView.vuewith 3 tabs (Overview, Duplicates, Data Issues) - API endpoints:
GET /api/admin/data-quality/duplicates- Scan all entitiesGET /api/admin/data-quality/duplicates/summary- Quick summaryGET /api/admin/data-quality/duplicates/{entity}- Scan specific entityPOST /api/admin/data-quality/duplicates/merge/preview- Preview mergePOST /api/admin/data-quality/duplicates/merge/confirm- Execute mergeGET /api/admin/data-quality/issues- Scan for data quality issues
-
[High]Enhance App Documentation with Screenshots -
[High]Static site deployed to GitHub Pages (https://johnzastrow.github.io/actalog/)- Home page with feature highlights and theme gallery
- For Admins page with subscription and announcement features
- For Developers page with tech stack, architecture, and deployment guide
- Performance & Benchmarks section added (v0.22.0) - minimum resources, load test results
- FAQ page
- Auto-deploy via GitHub Actions on push to main
- All 7 themes documented with screenshots (Myst added v0.24.0)
- Responsive design & PWA benefits explained in "Works Everywhere" section
- User flow guide added ("Your Workout Journey" 3-step visual guide)
-
[MEDIUM]Calendar View - WorkoutCalendarView.vue with workout dots and month navigation -
[MEDIUM]Timeline View - WorkoutTimelineView.vue with chronological history -
[MEDIUM]Progress Charts - WeightProgressChart.vue and WorkoutFrequencyChart.vue components (not yet integrated into views) -
[MEDIUM]Admin Metrics Dashboard - User stats, workout counts, system health (v0.22.0) -
[MEDIUM]1RM Percentage Display - Performance page 1RM percentage tops out at 95%; needs to also show 100% of the maximum weight lifted -
[MEDIUM]PR Leaderboards - Opt-in community leaderboards (migration 0.33.0, leaderboard_opt_in setting, movement/WOD leaderboard API endpoints, LeaderboardView.vue)
-
[MEDIUM]Add backup_service tests - backup_service_test.go with 10 test functions covering create/restore/export -
[MEDIUM]Add wodify_import_service tests - wodify_import_service_test.go with duplicate handling -
[MEDIUM]Add export/import_service tests - Currently at 60-83% coverage -
[MEDIUM]Add admin_handler tests
-
[MEDIUM]Lighthouse PWA audit completed (Jan 2026)- Performance: 56/100 (throttled network), Best Practices: 100/100, SEO: 92/100
- PWA features verified: service worker, offline caching, installable manifest
- Issues found: color contrast, meta viewport user-scalable, touch target sizes
-
[MEDIUM]Service worker cache analysis completed- Total precache: 6.9MB (150+ entries)
- Material Design Icons: 3.5MB (4 formats) → Optimization: remove ttf/eot, keep woff2 only (394KB)
- Self-hosted accessibility fonts: 848KB (9 families, 22 files)
- JavaScript: 1.5MB (properly chunked), CSS: 848KB
- Runtime caching: API responses (NetworkFirst), fonts (CacheFirst), uploads (StaleWhileRevalidate)
-
[MEDIUM]Offline sync implementation reviewed- IndexedDB storage for workouts, movements, pending sync queue
- Axios interceptor saves POST/PUT /api/workouts offline when network unavailable
- syncWithServer() replays pending operations when back online
- User-controlled updates via UpdatePrompt.vue and pwa.js store
- Status: Fully implemented, works for workout logging
Remaining PWA optimizations (deferred):
-
[LOW]Remove unused MDI font formats - Custom Vite pluginmdiWoff2Only()strips ttf/eot/woff- Dist size: 6.9MB → 3.8MB (45% reduction)
- Precache: 6.9MB → 3.4MB (50% reduction)
- Only woff2 (394KB) shipped to production
-
[LOW]Lazy-load accessibility fonts - Fonts loaded on-demand when user selects them- Split fonts.css into 9 separate font family CSS files
- Font store dynamically imports CSS via Vite's dynamic import
- Fonts excluded from precache via globIgnores
- Runtime caching (CacheFirst) caches fonts on first use
- Precache: 3.4MB → 2.6MB (additional 24% reduction)
-
[LOW]Fix accessibility issues (color contrast, touch targets) - Fixed label contrast (#666666 for 5.74:1 ratio), touch target sizes (24x24px min)
-
[HIGH]Coach Role (Completed Build 36) - Added dedicatedcoachrole (migration 0.32.0). Renamed"user"to"athlete". Three-tier role system: athlete < coach < admin.CoachOrAdminmiddleware protects/api/coaches/routes. Coaches bypass subscription checks. Coach Dashboard uses dedicated/api/coaches/sessions/endpoints with org-level access verification. Bottom nav shows Coach button for coach/admin roles when scheduling enabled.- Admin all-sessions visibility: Admins see ALL upcoming sessions across all gyms on Coach Dashboard (not limited to coach assignments). Added
GetAllUpcomingrepo method andGetAllUpcomingSessionsservice method; handler branches on role. - Comprehensive role/access middleware tests: 14 new test functions in
pkg/middleware/auth_test.goandpkg/middleware/subscription_test.gocovering all role permutations forAdminOnly,CoachOrAdmin, andRequireActiveSubscriptionmiddleware. Includes full JWT→middleware integration tests. - Files modified:
internal/domain/scheduling.go,internal/repository/class_session_repository.go,internal/service/scheduling_service.go,internal/handler/scheduling_handler.go,pkg/middleware/auth_test.go,pkg/middleware/subscription_test.go - Docker images pushed:
ghcr.io/johnzastrow/actalog:dev,:latest,:1.1.0-beta(Build 36)
- Admin all-sessions visibility: Admins see ALL upcoming sessions across all gyms on Coach Dashboard (not limited to coach assignments). Added
-
[LOW]Add audit_log_service tests - 100% coverage achieved -
[LOW]Add wodify_import_service tests - 100% coverage achieved
-
[MEDIUM]Admin Screen Consolidation (Partial) - Grouped Profile screen's 16 admin links into 5 labeled categories (Users & Access, Scheduling, Communication, Data & System, Organizations) usingv-list-subheaderdividers. Removed disabled "System Reports" placeholder. Full tab consolidation of admin screens into complex tabbed views remains for future work. -
[MEDIUM]Consistency Achievement Notifications - Daily scheduler checks all users for milestones (50/100/200/300 workouts, 4+/week, day streaks 4/7/14/21/30, inactivity warnings). Migration 0.34.0 consistency_achievements table, dedup via UNIQUE constraint, notification icons in NotificationsView. -
[LOW]Push Notifications - Workout reminders -
[LOW]Data Visualization - Charts for PR progression -
[LOW]Social Features - Share workouts (opt-in) -
[MEDIUM]UI Styling Consistency Review (Partial) - Replaced hardcoded#2c3e50inline color styles with Vuetify theme classes (text-h6,text-subtitle-1) in AdminDataQualityView (4 occurrences), AdminDataCleanupView (3), and AdminView (1) for dark mode compatibility. Remaining screens (WorkoutCalendarView, WorkoutTimelineView fixed headers; PerformanceView Chart.js config) flagged for future review. -
[MEDIUM]Admin Breadcrumbs & Navigation Consistency (Partial) - Fixed AdminSchedulingView to use shared AdminHeader component instead of custom gradient header, adding breadcrumb navigation (Admin > Scheduling) consistent with all other 17 admin views. Full audit of remaining admin views for navigation consistency remains for future work.
-
[LOW]Multiple Save Issue - TemplateEditDialog save() is being called 3x instead of 1x; investigate root cause (possibly related to Vue reactivity with Schedule tab slots)
Report bugs here with reproduction steps.
(none currently)
TODOs found in source code comments. These should be addressed or promoted to Backlog.
| File | Line | Description |
|---|---|---|
internal/service/workout_service.go |
396 | Add proper authorization through workout template ownership |
internal/service/import_service.go |
||
internal/handler/movement_handler.go |
141 | Get user ID from context when auth middleware is added |
| File | Line | Description |
|---|---|---|
web/src/views/WorkoutsView.vue |
372 | Navigate to template detail page |
Last scanned: 2026-01-09
Note: Calendar view (WorkoutCalendarView.vue) and PR notification system are implemented.
Status: Released from security/headers-and-uploads-2026-04-28. Closes the two items deferred from v1.2.3.
Completed:
- Security — Security response headers middleware (
pkg/middleware/security_headers.go) sets X-Frame-Options, X-Content-Type-Options, Referrer-Policy, HSTS, and a project-tuned CSP on every response; wired after CORS incmd/actalog/main.go - Security — Avatar upload no longer trusts client
Content-Type; useshttp.DetectContentTypeover first 512 bytes plus extension allowlist (internal/handler/user_handler.go) - CI — CI Failure Notify workflow now deduplicates issues per (workflow, branch) and auto-closes when a subsequent run on the same branch succeeds (
.github/workflows/ci-failure-notify.yml) - Maintenance — 8 Dependabot bumps merged (deploy-pages, setup-buildx, lib/pq, x/crypto, pgx, vue-ecosystem, go-sqlite3, dev-dependencies group); 2 closed with policy comments (Vuetify 4.0.5 watch-and-wait, axios 1.14.0 supply-chain)
Status: Released from security/hardening-2026-04-03.
Completed:
- Security — Password policy raised to 12-char min + uppercase/lowercase/digit (
internal/service/user_service.go); UI hints and client-side validation updated in RegisterView, SettingsView, ResetPasswordView, AdminUserImportExportView - Security —
WriteError()no longer leaks raw internal error strings to HTTP responses - Security — DOMPurify 3.3.3 added to
MarkdownRenderer.vue; allv-htmloutput sanitized - Security —
serialize-javascriptpinned to 7.0.5 viapackage.jsonoverrides (RCE + DoS CVEs) - Security — Rate limiter IP extraction fixed: leftmost XFF IP taken, RemoteAddr port stripped
- Security —
rate_limit_exceededaudit events now emitted from auth and password-reset limiters - Security — CORS allowlist now actually enforced —
pkg/middleware/cors.gono longer echoes disallowed origins back asAccess-Control-Allow-Origin; test asserts header absence for disallowed origins - Feature — Admin organizations list shows member count and supports edit-from-list
- CI — golangci-lint upgraded to v2.11.4; config migrated to v2 format
- CI — Frontend unit tests added to CI pipeline; 11 new Vitest suites covering App shell, auth store, axios interceptor, and admin views
- Docs —
docs/OWASP_AUDIT_2026-04-03.md,docs/MATURITY_ASSESSMENT.md,docs/plans/SECURITY_HARDENING_PLAN.mdcapture the audit and remediation plan
Status: Patch release — security fixes, dependency maintenance, CI hardening.
Completed:
- Security — Pinned axios to 1.13.5 (supply chain attack mitigation, 2026-03-31 incident)
- Security —
npm audit fix: patched brace-expansion, picomatch, undici, yaml - Fix — Calendar view now fetches all workouts (was capped at 20, causing missing entries)
- Fix — Admin breadcrumb returning 404
- Fix — Avatar upload click target; removed stale debug logging
- Feature — Calendar header shows workout count for viewed month
- UI — Nav bar icons switched to heavier filled MDI variants
- CI —
setup-gousesgo-version-file: go.mod(auto-tracks toolchain version) - CI — Pinned
golangci-lint-actionto v6 (v9 dropped v1.x support) - CI — Fixed date-sensitive test failure on first day of each month
- Deps — Go: x/crypto 0.48→0.49, pgx/v5 5.8→5.9, go-sqlite3 1.14.34→1.14.38, lib/pq 1.11→1.12
- Deps — Frontend: Vue 3.5.28→3.5.31, vue-router 5.0.3→5.0.4, vitest 4.0→4.1, sass 1.97→1.98
- Deps — GH Actions: docker/login-action 3→4, docker/metadata-action 5→6, docker/build-push-action 6→7, actions/checkout 4→6, super-linter 4→7
Known issues:
vite-plugin-pwadependency chain (serialize-javascript CVE) — fix requires major downgrade to 0.19.8; deferred to next release
Status: PR Leaderboards, configurable beta logo, nav and UI polish.
Completed:
- PR leaderboards and consistency achievement notifications
- Configurable beta logo via
LOGO_VARIANTenv variable - Leaderboard search API response parsing fix and header nav icon
- Improved avatar upload UX
Status: Coach role, three-tier permissions, class deletion modes, scheduling UX.
Completed:
- Three-tier role system: athlete < coach < admin (migration 0.32.0)
-
CoachOrAdminmiddleware; dedicated/api/coaches/routes - Delete class template with configurable cascade (template only / future sessions / all sessions)
- Credit refunds and notifications on session cancellation
- Coach Dashboard — admins see all sessions across all gyms
Status: Data Quality & Duplicate Detection system with merge functionality.
Completed:
-
Data Quality Admin Dashboard
-
AdminDataQualityView.vuewith 3 tabs (Overview, Duplicates, Data Issues) - Full database scan with summary cards
- Duplicates by entity type breakdown
- Data quality checks with issue counts
-
-
Duplicate Detection & Merge
- Scan 5 entity types: movements, WODs, user_workouts, users, workouts
- Case-insensitive name/email matching
- Composite key matching for user_workouts (user_id + date + name)
- Preview merge with FK reference counts
- Safe merge with FK updates in transaction
- Audit logging of all merge operations
-
Data Quality Issue Detection
- Orphaned FK references (error severity)
- Empty required fields (error/warning severity)
- Future workout dates (warning severity)
- Invalid email formats (warning severity)
- Filter chips for issue type filtering
-
Frontend UI Improvements
- Quality check type cards with icons, descriptions, counts
- Zero-state display with success checkmarks
- Clickable cards to navigate to filtered views
- Data Quality link added to admin menu in ProfileView
-
Demo Mode Configuration
- Added DEMO MODE section to .env.example
- Documented implemented vs planned features
- Current workaround instructions for basic demo setup
Files Created: internal/service/data_quality_service.go, internal/handler/data_quality_handler.go, web/src/views/AdminDataQualityView.vue
Files Modified: cmd/actalog/main.go (routes), web/src/router/index.js (route), web/src/views/ProfileView.vue (admin menu link), .env.example (demo mode)
API Endpoints:
GET /api/admin/data-quality/duplicates- Scan all entities for duplicatesGET /api/admin/data-quality/duplicates/summary- Quick duplicate summaryGET /api/admin/data-quality/duplicates/{entity}- Scan specific entity typePOST /api/admin/data-quality/duplicates/merge/preview- Preview merge operationPOST /api/admin/data-quality/duplicates/merge/confirm- Execute mergeGET /api/admin/data-quality/issues- Scan for data quality issues
Status: Comprehensive benchmark endpoint with configurable stress testing.
Completed:
-
Benchmark API Endpoint
-
POST /api/benchmark- Full system benchmark with 18+ operations -
GET /api/benchmark/status- Quick status check -
DELETE /api/admin/benchmark/data- Admin cleanup - Isolated
benchmark_datatable (never touches production data) - Auto-cleanup after runs
-
-
Configurable Record Count
-
?records=Nquery parameter (default: 1000, max: 500000) - Complex benchmark data (5-10KB text, nested JSON, UUIDs)
- Migration 0.23.0 for extended benchmark fields
-
-
Server Timeout Configuration
- Fixed EOF errors on long-running benchmarks
- Updated default SERVER_WRITE_TIMEOUT to 60s
- Buffered JSON response with explicit Content-Length
-
Benchmark Tool Integration (actalog-benchmark v0.7.0)
-
--benchmark-recordsflag for configurable record count - Server-side benchmark comparison in reports
- Enhanced error display with word wrapping
-
-
Static Site Updates
- Performance & Benchmarks section on For Developers page
- Updated version to 0.22.0-beta
- Added Myst theme (7 total themes)
Files Created: internal/domain/benchmark.go, internal/repository/benchmark_repository.go, internal/service/benchmark_service.go, internal/handler/benchmark_handler.go
Files Modified: internal/repository/migrations.go (0.22.0, 0.23.0), configs/config.go, .env.example, site/tech.html, site/index.html
For releases prior to v0.24.0, see CHANGELOG.md
These are longer-term ideas that may or may not be implemented:
- Kubernetes manifests - For larger deployments
- Mobile native apps - React Native or Flutter wrappers
- API rate limiting - For multi-tenant deployments
- Webhook integrations - Connect to external services
- Multi-language support - i18n framework
Items to address when time permits:
- Refactor large view components (DashboardView, PerformanceView) into smaller sub-components
- Add comprehensive API documentation (OpenAPI/Swagger)
- Improve error handling consistency across handlers (centralized in internal/handler/errors.go)
- Add structured logging throughout the codebase (JSON format support in pkg/logger)
- Review and optimize database queries with EXPLAIN (audit_logs indexes, N+1 fixes)
Current: Vuetify ^3.12.1 (pinned after accidental bump to 4.0.0 in Dependabot commit 039084d)
Trigger conditions — upgrade when ANY of these are true:
- Vuetify 4.1.x or later is released (indicates post-launch stabilization)
- Vuetify 3.x enters security-only or end-of-life maintenance
- A feature we need is only available in Vuetify 4
Watch:
- Vuetify GitHub releases:
https://github.com/vuetifyjs/vuetify/releases - Vuetify 3 EOL announcement (none as of 2026-04-03)
Known breaking changes for this app (catalogued 2026-04-03):
| Area | Change | Fix Required |
|---|---|---|
| CSS cascade | All Vuetify 4 CSS is in @layer vuetify-components — unlayered app CSS wins |
Wrap main.css reset in @layer reset { } and remove p, span, div { font-size: 14px } from App.vue |
v-main padding |
CSS reset * { padding: 0 } kills layout top/bottom padding |
Keep existing paddingTop/paddingBottom in mainStyle (already fixed) |
fill-height |
No longer sets display: flex or align-items: center — only height: 100% |
Add d-flex align-center to 47 views using v-container class="fill-height" |
app prop |
Removed from v-app-bar, v-bottom-navigation — layout registration is now automatic |
Remove app prop from both (harmless but dead code) |
v-bottom-navigation |
v-model controls selected tab only; active prop controls visibility separately |
Audit any code that passed v-model expecting visibility control |
Full plan: See memory file vuetify4-upgrade-plan.md
This file is maintained by Claude Code. See CHANGELOG.md for complete release history.