Timezone is now sent from the client on each request that needs it,
instead of storing it in the database. This simplifies the model and
allows timezone to be dynamic (useful for traveling users).
Changes:
- Remove timezone field from User entity
- Remove timezone from user registration
- GET /habits/today now requires ?timezone= query param
- Add migration to drop timezone column from database
- Update related tests
Implemented email service infrastructure with SMTP support and optional email verification for self-hosted deployments. Registration flow now supports open/closed modes and hardcoded Apocapoc branding.
Key features:
- Email service with SMTP and template rendering
- Optional email verification (auto-verified without SMTP config)
- Registration modes: open/closed for access control
- Hardcoded Apocapoc branding (AppName, AppURL, DefaultFrom)
- Separate registration and login flows (registration no longer returns tokens)
- Create PasswordHasher interface in domain layer
- Implement BcryptHasher in infrastructure layer
- Update RegisterUserHandler and LoginUserHandler to use interface
- Remove bcrypt dependency from application layer
- Update main.go and integration tests with dependency injection
- Enhance CI/CD workflow with test and lint jobs
- Add code coverage check (minimum 50%)
- Add go vet and gofmt validation
- Configure build job to depend on test and lint passing
- Update GitHub Actions to latest versions (v4→v5)
This achieves 100% SOLID compliance (DIP) and ensures Clean Architecture
by removing external library dependencies from application/domain layers.
Update module name and all imports from habit-tracker-api to apocapoc-api.
This reflects the project's new branding as part of the apocapoc ecosystem
(apocapoc-api, apocapoc-web, apocapoc-android).
- Create register and login use cases
- Implement JWT service for token generation and validation
- Add authentication middleware to protect habit endpoints
- Create auth HTTP handlers (register, login)
- Update habit handlers to extract userID from JWT token
- Register/login endpoints: POST /auth/register, POST /auth/login
- Habit endpoints now require Bearer token in Authorization header
- Tested: register -> create habit -> list habits works correctly