SYMBOL INDEX (432 symbols across 45 files) FILE: cmd/mcp/main.go function main (line 20) | func main() { FILE: cmd/migrate-dates/main.go function main (line 17) | func main() { function compareAllSubscriptions (line 95) | func compareAllSubscriptions(db *gorm.DB) { function compareSubscription (line 136) | func compareSubscription(checker *models.DateMigrationSafetyCheck, id ui... function printStats (line 160) | func printStats(stats map[string]interface{}) { FILE: internal/config/config.go type Config (line 7) | type Config struct function Load (line 13) | func Load() *Config { function getEnv (line 21) | func getEnv(key, defaultValue string) string { FILE: internal/database/database.go function Initialize (line 9) | func Initialize(dbPath string) (*gorm.DB, error) { FILE: internal/database/migrations.go function RunMigrations (line 11) | func RunMigrations(db *gorm.DB) error { function migrateCategoriesToDynamic (line 44) | func migrateCategoriesToDynamic(db *gorm.DB) error { function migrateCurrencyFields (line 106) | func migrateCurrencyFields(db *gorm.DB) error { function migrateDateCalculationVersioning (line 134) | func migrateDateCalculationVersioning(db *gorm.DB) error { function migrateSubscriptionIcons (line 162) | func migrateSubscriptionIcons(db *gorm.DB) error { function migrateReminderTracking (line 190) | func migrateReminderTracking(db *gorm.DB) error { function migrateCancellationReminderTracking (line 217) | func migrateCancellationReminderTracking(db *gorm.DB) error { function migrateScheduleInterval (line 243) | func migrateScheduleInterval(db *gorm.DB) error { function migrateReminderEnabled (line 266) | func migrateReminderEnabled(db *gorm.DB) error { FILE: internal/handlers/auth.go type AuthHandler (line 14) | type AuthHandler struct method ShowLoginPage (line 44) | func (h *AuthHandler) ShowLoginPage(c *gin.Context) { method Login (line 63) | func (h *AuthHandler) Login(c *gin.Context) { method Logout (line 112) | func (h *AuthHandler) Logout(c *gin.Context) { method ShowForgotPasswordPage (line 122) | func (h *AuthHandler) ShowForgotPasswordPage(c *gin.Context) { method ForgotPassword (line 127) | func (h *AuthHandler) ForgotPassword(c *gin.Context) { method ShowResetPasswordPage (line 174) | func (h *AuthHandler) ShowResetPasswordPage(c *gin.Context) { method ResetPassword (line 197) | func (h *AuthHandler) ResetPassword(c *gin.Context) { function NewAuthHandler (line 20) | func NewAuthHandler(settingsService *service.SettingsService, sessionSer... function isValidRedirect (line 29) | func isValidRedirect(redirect string) bool { FILE: internal/handlers/category.go type CategoryHandler (line 12) | type CategoryHandler struct method ListCategories (line 21) | func (h *CategoryHandler) ListCategories(c *gin.Context) { method CreateCategory (line 31) | func (h *CategoryHandler) CreateCategory(c *gin.Context) { method UpdateCategory (line 46) | func (h *CategoryHandler) UpdateCategory(c *gin.Context) { method DeleteCategory (line 66) | func (h *CategoryHandler) DeleteCategory(c *gin.Context) { function NewCategoryHandler (line 16) | func NewCategoryHandler(service *service.CategoryService) *CategoryHandl... FILE: internal/handlers/settings.go function splitLines (line 20) | func splitLines(s string) []string { return strings.Split(s, "\n") } function trimSpace (line 21) | func trimSpace(s string) string { return strings.TrimSpace(s) } function splitN (line 22) | func splitN(s, sep string, n int) []string { return strings.SplitN(s, se... type SettingsHandler (line 24) | type SettingsHandler struct method SaveSMTPSettings (line 33) | func (h *SettingsHandler) SaveSMTPSettings(c *gin.Context) { method TestSMTPConnection (line 77) | func (h *SettingsHandler) TestSMTPConnection(c *gin.Context) { method UpdateNotificationSetting (line 182) | func (h *SettingsHandler) UpdateNotificationSetting(c *gin.Context) { method GetNotificationSettings (line 258) | func (h *SettingsHandler) GetNotificationSettings(c *gin.Context) { method GetSMTPConfig (line 272) | func (h *SettingsHandler) GetSMTPConfig(c *gin.Context) { method ListAPIKeys (line 288) | func (h *SettingsHandler) ListAPIKeys(c *gin.Context) { method CreateAPIKey (line 311) | func (h *SettingsHandler) CreateAPIKey(c *gin.Context) { method DeleteAPIKey (line 366) | func (h *SettingsHandler) DeleteAPIKey(c *gin.Context) { method UpdateCurrency (line 389) | func (h *SettingsHandler) UpdateCurrency(c *gin.Context) { method UpdateDateFormat (line 405) | func (h *SettingsHandler) UpdateDateFormat(c *gin.Context) { method ToggleDarkMode (line 418) | func (h *SettingsHandler) ToggleDarkMode(c *gin.Context) { method SetupAuth (line 433) | func (h *SettingsHandler) SetupAuth(c *gin.Context) { method DisableAuth (line 490) | func (h *SettingsHandler) DisableAuth(c *gin.Context) { method GetAuthStatus (line 507) | func (h *SettingsHandler) GetAuthStatus(c *gin.Context) { method GetTheme (line 518) | func (h *SettingsHandler) GetTheme(c *gin.Context) { method SavePushoverSettings (line 531) | func (h *SettingsHandler) SavePushoverSettings(c *gin.Context) { method TestPushoverConnection (line 564) | func (h *SettingsHandler) TestPushoverConnection(c *gin.Context) { method SaveWebhookSettings (line 627) | func (h *SettingsHandler) SaveWebhookSettings(c *gin.Context) { method TestWebhookConnection (line 679) | func (h *SettingsHandler) TestWebhookConnection(c *gin.Context) { method GetPushoverConfig (line 760) | func (h *SettingsHandler) GetPushoverConfig(c *gin.Context) { method ToggleICalSubscription (line 776) | func (h *SettingsHandler) ToggleICalSubscription(c *gin.Context) { method GetICalSubscriptionURL (line 802) | func (h *SettingsHandler) GetICalSubscriptionURL(c *gin.Context) { method RegenerateICalToken (line 819) | func (h *SettingsHandler) RegenerateICalToken(c *gin.Context) { method UpdateBaseURL (line 834) | func (h *SettingsHandler) UpdateBaseURL(c *gin.Context) { method SetTheme (line 848) | func (h *SettingsHandler) SetTheme(c *gin.Context) { function NewSettingsHandler (line 28) | func NewSettingsHandler(service *service.SettingsService) *SettingsHandl... FILE: internal/handlers/subscription.go type SubscriptionWithConversion (line 20) | type SubscriptionWithConversion struct type SubscriptionHandler (line 30) | type SubscriptionHandler struct method enrichWithCurrencyConversion (line 55) | func (h *SubscriptionHandler) enrichWithCurrencyConversion(subscriptio... method isHighCostWithCurrency (line 102) | func (h *SubscriptionHandler) isHighCostWithCurrency(subscription *mod... method fetchAndSetLogo (line 130) | func (h *SubscriptionHandler) fetchAndSetLogo(subscription *models.Sub... method Dashboard (line 171) | func (h *SubscriptionHandler) Dashboard(c *gin.Context) { method SubscriptionsList (line 198) | func (h *SubscriptionHandler) SubscriptionsList(c *gin.Context) { method Analytics (line 226) | func (h *SubscriptionHandler) Analytics(c *gin.Context) { method Calendar (line 243) | func (h *SubscriptionHandler) Calendar(c *gin.Context) { method generateICalContent (line 338) | func (h *SubscriptionHandler) generateICalContent(forSubscription bool... method ExportICal (line 410) | func (h *SubscriptionHandler) ExportICal(c *gin.Context) { method ServeICalSubscription (line 423) | func (h *SubscriptionHandler) ServeICalSubscription(c *gin.Context) { method Settings (line 447) | func (h *SubscriptionHandler) Settings(c *gin.Context) { method GetSubscriptions (line 523) | func (h *SubscriptionHandler) GetSubscriptions(c *gin.Context) { method GetSubscriptionsAPI (line 548) | func (h *SubscriptionHandler) GetSubscriptionsAPI(c *gin.Context) { method CreateSubscription (line 559) | func (h *SubscriptionHandler) CreateSubscription(c *gin.Context) { method GetSubscription (line 657) | func (h *SubscriptionHandler) GetSubscription(c *gin.Context) { method UpdateSubscription (line 674) | func (h *SubscriptionHandler) UpdateSubscription(c *gin.Context) { method DeleteSubscription (line 805) | func (h *SubscriptionHandler) DeleteSubscription(c *gin.Context) { method GetStats (line 824) | func (h *SubscriptionHandler) GetStats(c *gin.Context) { method GetSubscriptionForm (line 835) | func (h *SubscriptionHandler) GetSubscriptionForm(c *gin.Context) { method ExportCSV (line 866) | func (h *SubscriptionHandler) ExportCSV(c *gin.Context) { method ExportJSON (line 917) | func (h *SubscriptionHandler) ExportJSON(c *gin.Context) { method BackupData (line 935) | func (h *SubscriptionHandler) BackupData(c *gin.Context) { method RestoreData (line 962) | func (h *SubscriptionHandler) RestoreData(c *gin.Context) { method ClearAllData (line 1063) | func (h *SubscriptionHandler) ClearAllData(c *gin.Context) { function NewSubscriptionHandler (line 41) | func NewSubscriptionHandler(service *service.SubscriptionService, settin... function parseScheduleInterval (line 144) | func parseScheduleInterval(s string) int { function parseDatePtr (line 158) | func parseDatePtr(dateStr string) *time.Time { function formatCurrency (line 1086) | func formatCurrency(amount float64) string { function formatDate (line 1091) | func formatDate(date *time.Time) string { FILE: internal/handlers/subscription_test.go function TestParseDatePtr (line 10) | func TestParseDatePtr(t *testing.T) { function timePtr (line 105) | func timePtr(t time.Time) *time.Time { FILE: internal/handlers/url.go function buildBaseURL (line 11) | func buildBaseURL(c *gin.Context, configuredBaseURL string) string { FILE: internal/middleware/auth.go function AuthMiddleware (line 13) | func AuthMiddleware(settingsService *service.SettingsService, sessionSer... function isPublicRoute (line 48) | func isPublicRoute(path string) bool { function isHTMLRequest (line 78) | func isHTMLRequest(r *http.Request) bool { function APIKeyAuth (line 84) | func APIKeyAuth(settingsService *service.SettingsService) gin.HandlerFunc { FILE: internal/models/category.go type Category (line 6) | type Category struct FILE: internal/models/date_migration_audit.go type DateMigrationLog (line 10) | type DateMigrationLog struct type DateMigrationSafetyCheck (line 22) | type DateMigrationSafetyCheck struct method MigrateSubscriptionToV2 (line 32) | func (dmsc *DateMigrationSafetyCheck) MigrateSubscriptionToV2(subscrip... method CompareCalculationVersions (line 72) | func (dmsc *DateMigrationSafetyCheck) CompareCalculationVersions(subsc... method BatchMigrateToV2WithAudit (line 94) | func (dmsc *DateMigrationSafetyCheck) BatchMigrateToV2WithAudit(dryRun... method RollbackSubscriptionToV1 (line 133) | func (dmsc *DateMigrationSafetyCheck) RollbackSubscriptionToV1(subscri... method GetMigrationStats (line 183) | func (dmsc *DateMigrationSafetyCheck) GetMigrationStats() (map[string]... function NewDateMigrationSafetyCheck (line 27) | func NewDateMigrationSafetyCheck(db *gorm.DB) *DateMigrationSafetyCheck { FILE: internal/models/date_migration_audit_test.go function setupAuditTestDB (line 12) | func setupAuditTestDB(t *testing.T) *gorm.DB { function TestNewDateMigrationSafetyCheck (line 27) | func TestNewDateMigrationSafetyCheck(t *testing.T) { function TestCompareCalculationVersions (line 36) | func TestCompareCalculationVersions(t *testing.T) { function TestGetMigrationStats (line 66) | func TestGetMigrationStats(t *testing.T) { FILE: internal/models/exchange_rate.go type ExchangeRate (line 8) | type ExchangeRate struct method IsStale (line 19) | func (er *ExchangeRate) IsStale() bool { FILE: internal/models/exchange_rate_test.go function TestExchangeRate_IsStale (line 10) | func TestExchangeRate_IsStale(t *testing.T) { FILE: internal/models/settings.go type Settings (line 8) | type Settings struct type SMTPConfig (line 17) | type SMTPConfig struct type PushoverConfig (line 28) | type PushoverConfig struct type WebhookConfig (line 34) | type WebhookConfig struct type NotificationSettings (line 40) | type NotificationSettings struct type APIKey (line 50) | type APIKey struct FILE: internal/models/subscription.go type Subscription (line 11) | type Subscription struct method effectiveInterval (line 40) | func (s *Subscription) effectiveInterval() int { method DisplaySchedule (line 48) | func (s *Subscription) DisplaySchedule() string { method AnnualCost (line 64) | func (s *Subscription) AnnualCost() float64 { method MonthlyCost (line 83) | func (s *Subscription) MonthlyCost() float64 { method DailyCost (line 102) | func (s *Subscription) DailyCost() float64 { method IsHighCost (line 107) | func (s *Subscription) IsHighCost(threshold float64) bool { method BeforeCreate (line 112) | func (s *Subscription) BeforeCreate(tx *gorm.DB) error { method AfterFind (line 122) | func (s *Subscription) AfterFind(tx *gorm.DB) error { method BeforeUpdate (line 143) | func (s *Subscription) BeforeUpdate(tx *gorm.DB) error { method calculateNextRenewalDate (line 206) | func (s *Subscription) calculateNextRenewalDate() { method calculateNextRenewalDateV1 (line 218) | func (s *Subscription) calculateNextRenewalDateV1() { method calculateNextRenewalDateV2 (line 229) | func (s *Subscription) calculateNextRenewalDateV2() { method calculateNextRenewalDateFromStartDate (line 291) | func (s *Subscription) calculateNextRenewalDateFromStartDate() { method calculateNextRenewalDateFromNow (line 406) | func (s *Subscription) calculateNextRenewalDateFromNow() { method calculateNextRenewalDateFromNowV2 (line 429) | func (s *Subscription) calculateNextRenewalDateFromNowV2() { type Stats (line 456) | type Stats struct type CategoryStat (line 468) | type CategoryStat struct FILE: internal/models/subscription_test.go function setupTestDB (line 13) | func setupTestDB(t *testing.T) *gorm.DB { function TestSubscription_CalculateNextRenewalDate (line 28) | func TestSubscription_CalculateNextRenewalDate(t *testing.T) { function TestSubscription_CalculateNextRenewalDateFromNow (line 97) | func TestSubscription_CalculateNextRenewalDateFromNow(t *testing.T) { function TestSubscription_BeforeUpdate_ScheduleChange (line 135) | func TestSubscription_BeforeUpdate_ScheduleChange(t *testing.T) { function TestSubscription_BeforeUpdate_NoScheduleChange (line 175) | func TestSubscription_BeforeUpdate_NoScheduleChange(t *testing.T) { function TestSubscription_BeforeUpdate_NilRenewalDate (line 205) | func TestSubscription_BeforeUpdate_NilRenewalDate(t *testing.T) { function TestSubscription_MonthlyCost (line 231) | func TestSubscription_MonthlyCost(t *testing.T) { function TestSubscription_BeforeCreate_WithStartDate (line 277) | func TestSubscription_BeforeCreate_WithStartDate(t *testing.T) { function TestSubscription_AnnualCost (line 355) | func TestSubscription_AnnualCost(t *testing.T) { function TestSubscription_DailyCost (line 402) | func TestSubscription_DailyCost(t *testing.T) { function TestSubscription_IsHighCost (line 449) | func TestSubscription_IsHighCost(t *testing.T) { function TestSubscription_DateEdgeCases (line 510) | func TestSubscription_DateEdgeCases(t *testing.T) { function TestSubscription_ScheduleChangePreservation (line 627) | func TestSubscription_ScheduleChangePreservation(t *testing.T) { function TestSubscription_LeapYearHandling (line 715) | func TestSubscription_LeapYearHandling(t *testing.T) { function TestSubscription_TimezoneConsistency (line 773) | func TestSubscription_TimezoneConsistency(t *testing.T) { function TestSubscription_DateCalculationV2 (line 808) | func TestSubscription_DateCalculationV2(t *testing.T) { function TestSubscription_VersionedCalculation (line 899) | func TestSubscription_VersionedCalculation(t *testing.T) { function TestSubscription_CarbonLibraryFeatures (line 931) | func TestSubscription_CarbonLibraryFeatures(t *testing.T) { function TestSubscription_DisplaySchedule (line 984) | func TestSubscription_DisplaySchedule(t *testing.T) { function TestSubscription_CostWithInterval (line 1011) | func TestSubscription_CostWithInterval(t *testing.T) { function TestSubscription_RenewalDateWithInterval (line 1040) | func TestSubscription_RenewalDateWithInterval(t *testing.T) { function TestSubscription_RenewalDateV2WithInterval (line 1082) | func TestSubscription_RenewalDateV2WithInterval(t *testing.T) { FILE: internal/repository/category.go type CategoryRepository (line 9) | type CategoryRepository struct method Create (line 17) | func (r *CategoryRepository) Create(category *models.Category) (*model... method GetAll (line 24) | func (r *CategoryRepository) GetAll() ([]models.Category, error) { method GetByID (line 32) | func (r *CategoryRepository) GetByID(id uint) (*models.Category, error) { method Update (line 40) | func (r *CategoryRepository) Update(id uint, category *models.Category... method Delete (line 47) | func (r *CategoryRepository) Delete(id uint) error { method GetByName (line 51) | func (r *CategoryRepository) GetByName(name string) (*models.Category,... method HasSubscriptions (line 59) | func (r *CategoryRepository) HasSubscriptions(id uint) (bool, error) { function NewCategoryRepository (line 13) | func NewCategoryRepository(db *gorm.DB) *CategoryRepository { FILE: internal/repository/exchange_rate.go type ExchangeRateRepository (line 10) | type ExchangeRateRepository struct method GetRate (line 19) | func (r *ExchangeRateRepository) GetRate(baseCurrency, targetCurrency ... method SaveRates (line 43) | func (r *ExchangeRateRepository) SaveRates(rates []models.ExchangeRate... method GetLatestRates (line 48) | func (r *ExchangeRateRepository) GetLatestRates(baseCurrency string) (... method DeleteStaleRates (line 65) | func (r *ExchangeRateRepository) DeleteStaleRates(olderThan time.Durat... function NewExchangeRateRepository (line 14) | func NewExchangeRateRepository(db *gorm.DB) *ExchangeRateRepository { FILE: internal/repository/settings.go type SettingsRepository (line 10) | type SettingsRepository struct method Set (line 19) | func (r *SettingsRepository) Set(key, value string) error { method Get (line 41) | func (r *SettingsRepository) Get(key string) (string, error) { method Delete (line 51) | func (r *SettingsRepository) Delete(key string) error { method GetAll (line 56) | func (r *SettingsRepository) GetAll() ([]models.Settings, error) { method CreateAPIKey (line 63) | func (r *SettingsRepository) CreateAPIKey(apiKey *models.APIKey) (*mod... method GetAllAPIKeys (line 71) | func (r *SettingsRepository) GetAllAPIKeys() ([]models.APIKey, error) { method GetAPIKeyByKey (line 78) | func (r *SettingsRepository) GetAPIKeyByKey(key string) (*models.APIKe... method DeleteAPIKey (line 88) | func (r *SettingsRepository) DeleteAPIKey(id uint) error { method UpdateAPIKeyUsage (line 93) | func (r *SettingsRepository) UpdateAPIKeyUsage(id uint) error { function NewSettingsRepository (line 14) | func NewSettingsRepository(db *gorm.DB) *SettingsRepository { FILE: internal/repository/subscription.go type SubscriptionRepository (line 11) | type SubscriptionRepository struct method checkLegacyColumn (line 20) | func (r *SubscriptionRepository) checkLegacyColumn() bool { method Create (line 31) | func (r *SubscriptionRepository) Create(subscription *models.Subscript... method GetAll (line 85) | func (r *SubscriptionRepository) GetAll() ([]models.Subscription, erro... method GetAllSorted (line 96) | func (r *SubscriptionRepository) GetAllSorted(sortBy, order string) ([... method GetByID (line 135) | func (r *SubscriptionRepository) GetByID(id uint) (*models.Subscriptio... method Update (line 143) | func (r *SubscriptionRepository) Update(id uint, subscription *models.... method Delete (line 224) | func (r *SubscriptionRepository) Delete(id uint) error { method Count (line 228) | func (r *SubscriptionRepository) Count() int64 { method GetActiveSubscriptions (line 234) | func (r *SubscriptionRepository) GetActiveSubscriptions() ([]models.Su... method GetCancelledSubscriptions (line 242) | func (r *SubscriptionRepository) GetCancelledSubscriptions() ([]models... method GetUpcomingRenewals (line 250) | func (r *SubscriptionRepository) GetUpcomingRenewals(days int) ([]mode... method GetUpcomingCancellations (line 261) | func (r *SubscriptionRepository) GetUpcomingCancellations(days int) ([... method GetCategoryStats (line 272) | func (r *SubscriptionRepository) GetCategoryStats() ([]models.Category... function NewSubscriptionRepository (line 16) | func NewSubscriptionRepository(db *gorm.DB) *SubscriptionRepository { FILE: internal/service/category.go type CategoryService (line 10) | type CategoryService struct method Create (line 18) | func (s *CategoryService) Create(category *models.Category) (*models.C... method GetAll (line 22) | func (s *CategoryService) GetAll() ([]models.Category, error) { method GetByID (line 26) | func (s *CategoryService) GetByID(id uint) (*models.Category, error) { method Update (line 30) | func (s *CategoryService) Update(id uint, category *models.Category) (... method GetByName (line 34) | func (s *CategoryService) GetByName(name string) (*models.Category, er... method Delete (line 38) | func (s *CategoryService) Delete(id uint) error { function NewCategoryService (line 14) | func NewCategoryService(repo *repository.CategoryRepository) *CategorySe... FILE: internal/service/currency.go type CurrencyInfo (line 18) | type CurrencyInfo struct function init (line 69) | func init() { function GetCurrencyInfo (line 79) | func GetCurrencyInfo(code string) CurrencyInfo { function GetAvailableCurrencies (line 87) | func GetAvailableCurrencies() []CurrencyInfo { function supportedCurrencySymbols (line 92) | func supportedCurrencySymbols() string { type CurrencyService (line 96) | type CurrencyService struct method IsEnabled (line 123) | func (s *CurrencyService) IsEnabled() bool { method GetExchangeRate (line 128) | func (s *CurrencyService) GetExchangeRate(fromCurrency, toCurrency str... method ConvertAmount (line 149) | func (s *CurrencyService) ConvertAmount(amount float64, fromCurrency, ... method fetchAndCacheRates (line 160) | func (s *CurrencyService) fetchAndCacheRates(baseCurrency, targetCurre... method RefreshRates (line 262) | func (s *CurrencyService) RefreshRates() error { type FixerResponse (line 101) | type FixerResponse struct type FixerError (line 110) | type FixerError struct function NewCurrencyService (line 115) | func NewCurrencyService(repo *repository.ExchangeRateRepository) *Curren... FILE: internal/service/currency_integration_test.go function setupTestDB (line 15) | func setupTestDB(t *testing.T) *gorm.DB { function TestCurrencyService_Integration_IsEnabled (line 30) | func TestCurrencyService_Integration_IsEnabled(t *testing.T) { function TestCurrencyService_Integration_ConvertAmount_SameCurrency (line 69) | func TestCurrencyService_Integration_ConvertAmount_SameCurrency(t *testi... function TestCurrencyService_Integration_ConvertAmount_WithCachedRate (line 82) | func TestCurrencyService_Integration_ConvertAmount_WithCachedRate(t *tes... function TestCurrencyService_Integration_ConvertAmount_NoAPIKey (line 108) | func TestCurrencyService_Integration_ConvertAmount_NoAPIKey(t *testing.T) { function TestCurrencyService_Integration_ConvertAmount_InvalidAmount (line 123) | func TestCurrencyService_Integration_ConvertAmount_InvalidAmount(t *test... function TestCurrencyService_Integration_SupportedCurrencies (line 158) | func TestCurrencyService_Integration_SupportedCurrencies(t *testing.T) { function TestCurrencyService_Integration_BDTCurrency (line 179) | func TestCurrencyService_Integration_BDTCurrency(t *testing.T) { function TestSettingsService_GetCurrencySymbol_BDT (line 203) | func TestSettingsService_GetCurrencySymbol_BDT(t *testing.T) { function TestSettingsService_SetCurrency_BDT (line 230) | func TestSettingsService_SetCurrency_BDT(t *testing.T) { FILE: internal/service/currency_test.go function TestGetCurrencyInfo_KnownCurrencies (line 13) | func TestGetCurrencyInfo_KnownCurrencies(t *testing.T) { function TestGetCurrencyInfo_UnknownCurrency (line 41) | func TestGetCurrencyInfo_UnknownCurrency(t *testing.T) { function TestGetCurrencyInfo_EmptyCode (line 48) | func TestGetCurrencyInfo_EmptyCode(t *testing.T) { function TestGetAvailableCurrencies (line 55) | func TestGetAvailableCurrencies(t *testing.T) { function TestSupportedCurrencies_DerivedFromBuiltin (line 66) | func TestSupportedCurrencies_DerivedFromBuiltin(t *testing.T) { function TestCurrencyInfoMap_AllEntriesPresent (line 74) | func TestCurrencyInfoMap_AllEntriesPresent(t *testing.T) { function TestCurrencySymbolForCode (line 82) | func TestCurrencySymbolForCode(t *testing.T) { function TestCurrencySymbolForSubscription (line 101) | func TestCurrencySymbolForSubscription(t *testing.T) { FILE: internal/service/email.go function currencySymbolForSubscription (line 15) | func currencySymbolForSubscription(subscription *models.Subscription, se... type EmailService (line 24) | type EmailService struct method SendEmail (line 36) | func (e *EmailService) SendEmail(subject, body string) error { method SendHighCostAlert (line 176) | func (e *EmailService) SendHighCostAlert(subscription *models.Subscrip... method SendRenewalReminder (line 258) | func (e *EmailService) SendRenewalReminder(subscription *models.Subscr... method SendCancellationReminder (line 346) | func (e *EmailService) SendCancellationReminder(subscription *models.S... function NewEmailService (line 29) | func NewEmailService(settingsService *SettingsService) *EmailService { FILE: internal/service/logo.go type LogoService (line 13) | type LogoService struct method FetchLogoFromURL (line 28) | func (s *LogoService) FetchLogoFromURL(websiteURL string) (string, err... method GetLogoURL (line 69) | func (s *LogoService) GetLogoURL(iconURL, websiteURL string) string { method ValidateLogoURL (line 90) | func (s *LogoService) ValidateLogoURL(logoURL string) bool { method FetchAndValidateLogo (line 106) | func (s *LogoService) FetchAndValidateLogo(websiteURL string) (string,... method ExtractDomain (line 124) | func (s *LogoService) ExtractDomain(websiteURL string) string { method DownloadLogo (line 157) | func (s *LogoService) DownloadLogo(logoURL string) ([]byte, error) { function NewLogoService (line 18) | func NewLogoService() *LogoService { FILE: internal/service/pushover.go type PushoverService (line 15) | type PushoverService struct method SendNotification (line 34) | func (p *PushoverService) SendNotification(title, message string, prio... method SendHighCostAlert (line 91) | func (p *PushoverService) SendHighCostAlert(subscription *models.Subsc... method SendRenewalReminder (line 122) | func (p *PushoverService) SendRenewalReminder(subscription *models.Sub... method SendCancellationReminder (line 158) | func (p *PushoverService) SendCancellationReminder(subscription *model... function NewPushoverService (line 20) | func NewPushoverService(settingsService *SettingsService) *PushoverServi... type PushoverResponse (line 27) | type PushoverResponse struct FILE: internal/service/pushover_test.go function setupPushoverTestDB (line 27) | func setupPushoverTestDB(t *testing.T) *gorm.DB { function TestPushoverService_SendNotification_NoConfig (line 45) | func TestPushoverService_SendNotification_NoConfig(t *testing.T) { function TestPushoverService_SendNotification_EmptyUserKey (line 58) | func TestPushoverService_SendNotification_EmptyUserKey(t *testing.T) { function TestPushoverService_SendNotification_EmptyAppToken (line 76) | func TestPushoverService_SendNotification_EmptyAppToken(t *testing.T) { function TestPushoverService_SendHighCostAlert_Disabled (line 94) | func TestPushoverService_SendHighCostAlert_Disabled(t *testing.T) { function TestPushoverService_SendHighCostAlert_EnabledButNoConfig (line 116) | func TestPushoverService_SendHighCostAlert_EnabledButNoConfig(t *testing... function TestPushoverService_SendRenewalReminder_Disabled (line 139) | func TestPushoverService_SendRenewalReminder_Disabled(t *testing.T) { function TestPushoverService_SendRenewalReminder_EnabledButNoConfig (line 162) | func TestPushoverService_SendRenewalReminder_EnabledButNoConfig(t *testi... function TestPushoverService_SendHighCostAlert_MessageFormat (line 186) | func TestPushoverService_SendHighCostAlert_MessageFormat(t *testing.T) { function TestPushoverService_SendRenewalReminder_MessageFormat (line 219) | func TestPushoverService_SendRenewalReminder_MessageFormat(t *testing.T) { function TestPushoverService_SendRenewalReminder_DaysText (line 252) | func TestPushoverService_SendRenewalReminder_DaysText(t *testing.T) { function getPushoverTestCredentials (line 306) | func getPushoverTestCredentials() (userKey, appToken string) { function TestPushoverService_SendNotification_Integration (line 314) | func TestPushoverService_SendNotification_Integration(t *testing.T) { function TestPushoverService_SendHighCostAlert_Integration (line 339) | func TestPushoverService_SendHighCostAlert_Integration(t *testing.T) { function TestPushoverService_SendRenewalReminder_Integration (line 374) | func TestPushoverService_SendRenewalReminder_Integration(t *testing.T) { FILE: internal/service/renewal_reminder_test.go function setupRenewalReminderTestDB (line 14) | func setupRenewalReminderTestDB(t *testing.T) *gorm.DB { function TestSubscriptionService_GetSubscriptionsNeedingReminders (line 33) | func TestSubscriptionService_GetSubscriptionsNeedingReminders(t *testing... function TestEmailService_SendRenewalReminder_Disabled (line 212) | func TestEmailService_SendRenewalReminder_Disabled(t *testing.T) { function TestEmailService_SendRenewalReminder_EnabledButNoSMTP (line 234) | func TestEmailService_SendRenewalReminder_EnabledButNoSMTP(t *testing.T) { function TestEmailService_SendRenewalReminder_WithSMTPConfig (line 257) | func TestEmailService_SendRenewalReminder_WithSMTPConfig(t *testing.T) { function TestSubscriptionService_GetSubscriptionsNeedingReminders_DaysCalculation (line 294) | func TestSubscriptionService_GetSubscriptionsNeedingReminders_DaysCalcul... function TestSubscriptionService_GetSubscriptionsNeedingReminders_BoundaryCases (line 328) | func TestSubscriptionService_GetSubscriptionsNeedingReminders_BoundaryCa... function TestSubscriptionService_GetSubscriptionsNeedingReminders_DuplicatePrevention (line 401) | func TestSubscriptionService_GetSubscriptionsNeedingReminders_DuplicateP... function TestSubscriptionService_GetSubscriptionsNeedingReminders_ReminderDisabled (line 453) | func TestSubscriptionService_GetSubscriptionsNeedingReminders_ReminderDi... function timePtr (line 501) | func timePtr(t time.Time) *time.Time { FILE: internal/service/session.go constant SessionName (line 10) | SessionName = "subtrackr_session" constant SessionUserKey (line 11) | SessionUserKey = "user_authenticated" constant SessionMaxAge (line 12) | SessionMaxAge = 24 * 60 * 60 constant RememberMeMaxAge (line 13) | RememberMeMaxAge = 30 * 24 * 60 * 60 type SessionService (line 16) | type SessionService struct method CreateSession (line 37) | func (s *SessionService) CreateSession(w http.ResponseWriter, r *http.... method IsAuthenticated (line 56) | func (s *SessionService) IsAuthenticated(r *http.Request) bool { method DestroySession (line 67) | func (s *SessionService) DestroySession(w http.ResponseWriter, r *http... method RefreshSession (line 81) | func (s *SessionService) RefreshSession(w http.ResponseWriter, r *http... method UpdateSessionExpiry (line 101) | func (s *SessionService) UpdateSessionExpiry(maxAge int) { method GetSession (line 106) | func (s *SessionService) GetSession(r *http.Request) (*sessions.Sessio... function NewSessionService (line 21) | func NewSessionService(secretKey string) *SessionService { FILE: internal/service/settings.go type SettingsService (line 17) | type SettingsService struct method SaveSMTPConfig (line 26) | func (s *SettingsService) SaveSMTPConfig(config *models.SMTPConfig) er... method GetSMTPConfig (line 37) | func (s *SettingsService) GetSMTPConfig() (*models.SMTPConfig, error) { method SetBoolSetting (line 53) | func (s *SettingsService) SetBoolSetting(key string, value bool) error { method GetBoolSetting (line 58) | func (s *SettingsService) GetBoolSetting(key string, defaultValue bool... method GetBoolSettingWithDefault (line 68) | func (s *SettingsService) GetBoolSettingWithDefault(key string, defaul... method SetIntSetting (line 77) | func (s *SettingsService) SetIntSetting(key string, value int) error { method GetIntSetting (line 82) | func (s *SettingsService) GetIntSetting(key string, defaultValue int) ... method GetIntSettingWithDefault (line 97) | func (s *SettingsService) GetIntSettingWithDefault(key string, default... method SetFloatSetting (line 106) | func (s *SettingsService) SetFloatSetting(key string, value float64) e... method GetFloatSetting (line 111) | func (s *SettingsService) GetFloatSetting(key string, defaultValue flo... method GetTheme (line 126) | func (s *SettingsService) GetTheme() (string, error) { method SetTheme (line 135) | func (s *SettingsService) SetTheme(theme string) error { method GetFloatSettingWithDefault (line 140) | func (s *SettingsService) GetFloatSettingWithDefault(key string, defau... method CreateAPIKey (line 149) | func (s *SettingsService) CreateAPIKey(name, key string) (*models.APIK... method GetAllAPIKeys (line 158) | func (s *SettingsService) GetAllAPIKeys() ([]models.APIKey, error) { method DeleteAPIKey (line 163) | func (s *SettingsService) DeleteAPIKey(id uint) error { method ValidateAPIKey (line 168) | func (s *SettingsService) ValidateAPIKey(key string) (*models.APIKey, ... method SetCurrency (line 184) | func (s *SettingsService) SetCurrency(currency string) error { method GetCurrency (line 193) | func (s *SettingsService) GetCurrency() string { method GetCurrencySymbol (line 207) | func (s *SettingsService) GetCurrencySymbol() string { method SetDateFormat (line 212) | func (s *SettingsService) SetDateFormat(format string) error { method GetDateFormat (line 222) | func (s *SettingsService) GetDateFormat() string { method GetGoDateFormat (line 231) | func (s *SettingsService) GetGoDateFormat() string { method GetGoDateFormatLong (line 236) | func (s *SettingsService) GetGoDateFormatLong() string { method SetDarkMode (line 265) | func (s *SettingsService) SetDarkMode(enabled bool) error { method IsDarkModeEnabled (line 270) | func (s *SettingsService) IsDarkModeEnabled() bool { method IsAuthEnabled (line 277) | func (s *SettingsService) IsAuthEnabled() bool { method SetAuthEnabled (line 282) | func (s *SettingsService) SetAuthEnabled(enabled bool) error { method GetAuthUsername (line 287) | func (s *SettingsService) GetAuthUsername() (string, error) { method SetAuthUsername (line 292) | func (s *SettingsService) SetAuthUsername(username string) error { method HashPassword (line 297) | func (s *SettingsService) HashPassword(password string) (string, error) { method SetAuthPassword (line 306) | func (s *SettingsService) SetAuthPassword(password string) error { method ValidatePassword (line 315) | func (s *SettingsService) ValidatePassword(password string) error { method GetOrGenerateSessionSecret (line 324) | func (s *SettingsService) GetOrGenerateSessionSecret() (string, error) { method SetupAuth (line 346) | func (s *SettingsService) SetupAuth(username, password string) error { method DisableAuth (line 367) | func (s *SettingsService) DisableAuth() error { method GenerateResetToken (line 381) | func (s *SettingsService) GenerateResetToken() (string, error) { method ValidateResetToken (line 402) | func (s *SettingsService) ValidateResetToken(token string) error { method ClearResetToken (line 422) | func (s *SettingsService) ClearResetToken() error { method GetBaseURL (line 429) | func (s *SettingsService) GetBaseURL() string { method SetBaseURL (line 438) | func (s *SettingsService) SetBaseURL(baseURL string) error { method IsICalSubscriptionEnabled (line 445) | func (s *SettingsService) IsICalSubscriptionEnabled() bool { method SetICalSubscriptionEnabled (line 450) | func (s *SettingsService) SetICalSubscriptionEnabled(enabled bool) err... method GetOrGenerateICalToken (line 455) | func (s *SettingsService) GetOrGenerateICalToken() (string, error) { method RegenerateICalToken (line 476) | func (s *SettingsService) RegenerateICalToken() (string, error) { method ValidateICalToken (line 491) | func (s *SettingsService) ValidateICalToken(token string) bool { method SavePushoverConfig (line 500) | func (s *SettingsService) SavePushoverConfig(config *models.PushoverCo... method GetPushoverConfig (line 511) | func (s *SettingsService) GetPushoverConfig() (*models.PushoverConfig,... method SaveWebhookConfig (line 527) | func (s *SettingsService) SaveWebhookConfig(config *models.WebhookConf... method GetWebhookConfig (line 536) | func (s *SettingsService) GetWebhookConfig() (*models.WebhookConfig, e... function NewSettingsService (line 21) | func NewSettingsService(repo *repository.SettingsRepository) *SettingsSe... function CurrencySymbolForCode (line 202) | func CurrencySymbolForCode(currency string) string { function DateFormatToGo (line 241) | func DateFormatToGo(format string) string { function DateFormatToGoLong (line 253) | func DateFormatToGoLong(format string) string { FILE: internal/service/settings_test.go function setupSettingsTestDB (line 13) | func setupSettingsTestDB(t *testing.T) *SettingsService { function TestSetDateFormat_Valid (line 26) | func TestSetDateFormat_Valid(t *testing.T) { function TestSetDateFormat_Invalid (line 49) | func TestSetDateFormat_Invalid(t *testing.T) { function TestGetDateFormat_Default (line 71) | func TestGetDateFormat_Default(t *testing.T) { function TestDateFormatToGo (line 78) | func TestDateFormatToGo(t *testing.T) { function TestDateFormatToGoLong (line 97) | func TestDateFormatToGoLong(t *testing.T) { function TestGetGoDateFormat (line 116) | func TestGetGoDateFormat(t *testing.T) { function TestGetGoDateFormatLong (line 131) | func TestGetGoDateFormatLong(t *testing.T) { function TestWebhookConfig_SaveAndRetrieve (line 142) | func TestWebhookConfig_SaveAndRetrieve(t *testing.T) { function TestWebhookConfig_NotConfigured (line 162) | func TestWebhookConfig_NotConfigured(t *testing.T) { FILE: internal/service/subscription.go type SubscriptionService (line 9) | type SubscriptionService struct method Create (line 18) | func (s *SubscriptionService) Create(subscription *models.Subscription... method GetAll (line 22) | func (s *SubscriptionService) GetAll() ([]models.Subscription, error) { method GetAllSorted (line 26) | func (s *SubscriptionService) GetAllSorted(sortBy, order string) ([]mo... method GetByID (line 30) | func (s *SubscriptionService) GetByID(id uint) (*models.Subscription, ... method Update (line 34) | func (s *SubscriptionService) Update(id uint, subscription *models.Sub... method Delete (line 38) | func (s *SubscriptionService) Delete(id uint) error { method Count (line 42) | func (s *SubscriptionService) Count() int64 { method GetStats (line 46) | func (s *SubscriptionService) GetStats() (*models.Stats, error) { method GetAllCategories (line 94) | func (s *SubscriptionService) GetAllCategories() ([]models.Category, e... method GetSubscriptionsNeedingReminders (line 100) | func (s *SubscriptionService) GetSubscriptionsNeedingReminders(reminde... method GetSubscriptionsNeedingCancellationReminders (line 146) | func (s *SubscriptionService) GetSubscriptionsNeedingCancellationRemin... function NewSubscriptionService (line 14) | func NewSubscriptionService(repo *repository.SubscriptionRepository, cat... FILE: internal/service/webhook.go type WebhookService (line 13) | type WebhookService struct method SendWebhook (line 76) | func (w *WebhookService) SendWebhook(payload *WebhookPayload) error { method SendHighCostAlert (line 114) | func (w *WebhookService) SendHighCostAlert(subscription *models.Subscr... method SendRenewalReminder (line 133) | func (w *WebhookService) SendRenewalReminder(subscription *models.Subs... method SendCancellationReminder (line 155) | func (w *WebhookService) SendCancellationReminder(subscription *models... function NewWebhookService (line 18) | func NewWebhookService(settingsService *SettingsService) *WebhookService { type WebhookPayload (line 25) | type WebhookPayload struct type WebhookSubscription (line 34) | type WebhookSubscription struct function subscriptionToWebhook (line 48) | func subscriptionToWebhook(sub *models.Subscription, settings *SettingsS... FILE: internal/service/webhook_test.go function setupWebhookTestDB (line 14) | func setupWebhookTestDB(t *testing.T) (*SettingsService, *WebhookService) { function TestWebhookService_SendWebhook_NoConfig (line 30) | func TestWebhookService_SendWebhook_NoConfig(t *testing.T) { function TestWebhookService_SendWebhook_EmptyURL (line 43) | func TestWebhookService_SendWebhook_EmptyURL(t *testing.T) { function TestWebhookService_SendHighCostAlert_Disabled (line 61) | func TestWebhookService_SendHighCostAlert_Disabled(t *testing.T) { function TestWebhookService_SendHighCostAlert_EnabledNoConfig (line 77) | func TestWebhookService_SendHighCostAlert_EnabledNoConfig(t *testing.T) { function TestWebhookService_SendRenewalReminder_Disabled (line 94) | func TestWebhookService_SendRenewalReminder_Disabled(t *testing.T) { function TestWebhookService_SendRenewalReminder_EnabledNoConfig (line 111) | func TestWebhookService_SendRenewalReminder_EnabledNoConfig(t *testing.T) { function TestWebhookService_SendCancellationReminder_Disabled (line 129) | func TestWebhookService_SendCancellationReminder_Disabled(t *testing.T) { function TestWebhookService_SendCancellationReminder_EnabledNoConfig (line 146) | func TestWebhookService_SendCancellationReminder_EnabledNoConfig(t *test... function TestSubscriptionToWebhook (line 164) | func TestSubscriptionToWebhook(t *testing.T) { function TestSubscriptionToWebhook_MinimalFields (line 207) | func TestSubscriptionToWebhook_MinimalFields(t *testing.T) { function TestWebhookService_SendRenewalReminder_DaysText (line 237) | func TestWebhookService_SendRenewalReminder_DaysText(t *testing.T) { FILE: internal/version/version.go function GetVersion (line 12) | func GetVersion() string { FILE: web/static/category-management.js function startEditCategory (line 1) | function startEditCategory(id) { function cancelEditCategory (line 6) | function cancelEditCategory(id) { FILE: web/static/js/darkmode.js class DarkModeManager (line 2) | class DarkModeManager { method constructor (line 3) | constructor() { method init (line 7) | init() { method setDarkMode (line 17) | setDarkMode(enabled, save = true) { method toggle (line 31) | toggle() { method syncWithServer (line 36) | syncWithServer(enabled) { method setupSystemPreferenceListener (line 44) | setupSystemPreferenceListener() { function toggleDarkMode (line 59) | function toggleDarkMode() { FILE: web/static/js/mobile-menu.js function openMobileMenu (line 4) | function openMobileMenu() { function closeMobileMenu (line 12) | function closeMobileMenu() { function closeMobileMenuAndThen (line 22) | function closeMobileMenuAndThen(callback) { FILE: web/static/js/sorting.js constant SORT_STORAGE_KEY (line 4) | const SORT_STORAGE_KEY = 'subtrackr-sort'; constant VALID_SORT_FIELDS (line 5) | const VALID_SORT_FIELDS = ['name', 'cost', 'renewal_date', 'status', 'ca... constant VALID_SORT_ORDERS (line 6) | const VALID_SORT_ORDERS = ['asc', 'desc']; function isValidSortPreference (line 9) | function isValidSortPreference(sortBy, order) { function saveSortPreference (line 14) | function saveSortPreference(sortBy, order) { function getSortPreference (line 21) | function getSortPreference() { function extractSortParams (line 35) | function extractSortParams(url) { function applySavedSortPreference (line 50) | function applySavedSortPreference() { FILE: web/static/js/themes.js function applyTheme (line 121) | function applyTheme(themeName) { function saveThemePreference (line 159) | function saveThemePreference(themeName) { function getStoredTheme (line 171) | function getStoredTheme() { function loadSavedTheme (line 193) | function loadSavedTheme() { function enableSnowfall (line 200) | function enableSnowfall() { function createSnowflake (line 225) | function createSnowflake(container) { function disableSnowfall (line 250) | function disableSnowfall() {