Skip to content

Commit 43c596d

Browse files
cpcloudclaude
andcommitted
refactor(config): replace hand-written validation with struct tags
Use go-playground/validator/v10 for config validation instead of ~100 lines of manual checks. Custom validators handle provider names, positive durations, and non-negative durations. Error messages preserve the existing dotted-path format users expect. Also removes the deprecated `documents.cache_ttl_days` field -- it was only kept for backward compatibility and `cache_ttl` has been the canonical setting since its introduction. closes #737 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 102f15a commit 43c596d

9 files changed

Lines changed: 164 additions & 216 deletions

File tree

docs/content/docs/reference/configuration.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ You can always infer the env var name from the config key.
126126
| `MICASA_EXTRACTION_OCR_TSV_CONFIDENCE_THRESHOLD` | `70` | `extraction.ocr.tsv.confidence_threshold` | OCR confidence threshold (0-100) |
127127
| `MICASA_DOCUMENTS_MAX_FILE_SIZE` | `50 MiB` | `documents.max_file_size` | Max document import size |
128128
| `MICASA_DOCUMENTS_CACHE_TTL` | `30d` | `documents.cache_ttl` | Document cache lifetime |
129-
| `MICASA_DOCUMENTS_CACHE_TTL_DAYS` | -- | `documents.cache_ttl_days` | Deprecated; use `MICASA_DOCUMENTS_CACHE_TTL` |
130129
| `MICASA_DOCUMENTS_FILE_PICKER_DIR` | (Downloads) | `documents.file_picker_dir` | Starting directory for the file picker |
131130
| `MICASA_LOCALE_CURRENCY` | (auto-detect) | `locale.currency` | ISO 4217 currency code (e.g. `USD`, `EUR`, `GBP`) |
132131

@@ -318,7 +317,6 @@ Document attachment limits and caching.
318317
|-----|------|---------|-------------|
319318
| `max_file_size` | string or integer | `"50 MiB"` | Maximum file size for document imports. Accepts unitized strings (`"50 MiB"`, `"1.5 GiB"`) or bare integers (bytes). Must be positive. |
320319
| `cache_ttl` | string or integer | `"30d"` | Cache lifetime for extracted documents. Accepts `"30d"`, `"720h"`, or bare integers (seconds). Set to `"0s"` to disable eviction. |
321-
| `cache_ttl_days` | integer | -- | Deprecated. Use `cache_ttl` instead. Bare integer interpreted as days. Cannot be set alongside `cache_ttl`. |
322320

323321
### `[extraction]` section
324322

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
inherit version;
3434
src = ./.;
3535
subPackages = [ "cmd/micasa" ];
36-
vendorHash = "sha256-x1Ar5Dnbpey4eRknnTvZkkRnSt9yz1/Crx1ksVHtPfs=";
36+
vendorHash = "sha256-qvThE9Ri2El41LZC4GRHJ17aIdkEhtzjTDDgv57t5z8=";
3737
env.CGO_ENABLED = 0;
3838
preCheck = ''
3939
export HOME="$(mktemp -d)"

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834
1818
github.com/charmbracelet/x/ansi v0.11.6
1919
github.com/dustin/go-humanize v1.0.1
20+
github.com/go-playground/validator/v10 v10.20.0
2021
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
2122
github.com/iancoleman/strcase v0.3.0
2223
github.com/itchyny/gojq v0.12.18
@@ -57,8 +58,11 @@ require (
5758
github.com/dlclark/regexp2 v1.11.5 // indirect
5859
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
5960
github.com/felixge/httpsnoop v1.0.4 // indirect
61+
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
6062
github.com/go-logr/logr v1.4.3 // indirect
6163
github.com/go-logr/stdr v1.2.2 // indirect
64+
github.com/go-playground/locales v0.14.1 // indirect
65+
github.com/go-playground/universal-translator v0.18.1 // indirect
6266
github.com/google/go-cmp v0.7.0 // indirect
6367
github.com/google/s2a-go v0.1.9 // indirect
6468
github.com/google/uuid v1.6.0 // indirect
@@ -69,6 +73,7 @@ require (
6973
github.com/itchyny/timefmt-go v0.1.7 // indirect
7074
github.com/jinzhu/inflection v1.0.0 // indirect
7175
github.com/jinzhu/now v1.1.5 // indirect
76+
github.com/leodido/go-urn v1.4.0 // indirect
7277
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
7378
github.com/mailru/easyjson v0.9.1 // indirect
7479
github.com/mattn/go-isatty v0.0.20 // indirect

go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,21 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6
9191
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
9292
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
9393
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
94+
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
95+
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
9496
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
9597
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
9698
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9799
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
98100
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
101+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
102+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
103+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
104+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
105+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
106+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
107+
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
108+
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
99109
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
100110
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
101111
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
@@ -134,6 +144,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
134144
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
135145
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
136146
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
147+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
148+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
137149
github.com/lrstanley/bubblezone v1.0.0 h1:bIpUaBilD42rAQwlg/4u5aTqVAt6DSRKYZuSdmkr8UA=
138150
github.com/lrstanley/bubblezone v1.0.0/go.mod h1:kcTekA8HE/0Ll2bWzqHlhA2c513KDNLW7uDfDP4Mly8=
139151
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=

internal/config/config.go

Lines changed: 15 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type ChatLLM struct {
6666
// ollama, anthropic, openai, openrouter, deepseek, gemini, groq,
6767
// mistral, llamacpp, llamafile. Auto-detected from base_url and
6868
// api_key when empty.
69-
Provider string `toml:"provider"`
69+
Provider string `toml:"provider" validate:"provider"`
7070

7171
// BaseURL is the base URL for the provider's API.
7272
// No /v1 suffix needed -- the provider handles path construction.
@@ -81,11 +81,11 @@ type ChatLLM struct {
8181

8282
// Timeout is the inference timeout for LLM responses (including
8383
// streaming). Go duration string, e.g. "5m", "10m". Default: "5m".
84-
Timeout string `toml:"timeout" default:"5m"`
84+
Timeout string `toml:"timeout" default:"5m" validate:"omitempty,positive_duration"`
8585

8686
// Thinking controls the model's reasoning effort level.
8787
// Supported: none, low, medium, high, auto. Empty = server default.
88-
Thinking string `toml:"thinking,omitempty"`
88+
Thinking string `toml:"thinking,omitempty" validate:"omitempty,oneof=none low medium high auto"`
8989

9090
// ExtraContext is custom text appended to chat system prompts.
9191
// Useful for domain-specific details: house style, location, etc.
@@ -102,7 +102,7 @@ func (l ChatLLM) TimeoutDuration() time.Duration {
102102
type Extraction struct {
103103
// MaxPages is the maximum number of pages for async extraction of
104104
// scanned documents. 0 means no limit. Default: 0.
105-
MaxPages int `toml:"max_pages"`
105+
MaxPages int `toml:"max_pages" validate:"min=0"`
106106

107107
// LLM holds the LLM connection settings for the extraction pipeline.
108108
LLM ExtractionLLM `toml:"llm" doc:"LLM connection settings for extraction."`
@@ -121,7 +121,7 @@ type ExtractionLLM struct {
121121

122122
// Provider selects which LLM provider to use. See ChatLLM.Provider
123123
// for supported values. Auto-detected when empty.
124-
Provider string `toml:"provider"`
124+
Provider string `toml:"provider" validate:"provider"`
125125

126126
// BaseURL is the base URL for the provider's API.
127127
BaseURL string `toml:"base_url" default:"http://localhost:11434"`
@@ -134,11 +134,11 @@ type ExtractionLLM struct {
134134
APIKey string `toml:"api_key"` //nolint:gosec // config field, not a hardcoded credential
135135

136136
// Timeout is the inference timeout for extraction LLM responses.
137-
Timeout string `toml:"timeout" default:"5m"`
137+
Timeout string `toml:"timeout" default:"5m" validate:"omitempty,positive_duration"`
138138

139139
// Thinking controls the model's reasoning effort level.
140140
// Supported: none, low, medium, high, auto. Empty = server default.
141-
Thinking string `toml:"thinking,omitempty"`
141+
Thinking string `toml:"thinking,omitempty" validate:"omitempty,oneof=none low medium high auto"`
142142
}
143143

144144
// IsEnabled returns whether LLM extraction is enabled. Defaults to true.
@@ -186,7 +186,7 @@ type OCRTSV struct {
186186
// OCR confidence annotations are included in spatial layout output.
187187
// Lines with min confidence >= this value omit the score to save
188188
// tokens. Set to 0 to never show confidence. Default: 70.
189-
ConfidenceThreshold *int `toml:"confidence_threshold,omitempty"`
189+
ConfidenceThreshold *int `toml:"confidence_threshold,omitempty" validate:"omitempty,min=0,max=100"`
190190
}
191191

192192
// IsEnabled returns whether TSV spatial annotations are enabled.
@@ -230,15 +230,12 @@ type Documents struct {
230230
// MaxFileSize is the largest file that can be imported as a document
231231
// attachment. Accepts unitized strings ("50 MiB") or bare integers
232232
// (bytes). Default: 50 MiB.
233-
MaxFileSize ByteSize `toml:"max_file_size" default:"52428800"`
233+
MaxFileSize ByteSize `toml:"max_file_size" default:"52428800" validate:"required"`
234234

235-
// CacheTTL is the preferred cache lifetime setting. Accepts unitized
236-
// strings ("30d", "720h") or bare integers (seconds). Default: 30d.
237-
CacheTTL *Duration `toml:"cache_ttl,omitempty"`
238-
239-
// CacheTTLDays is deprecated; use CacheTTL instead. Kept for backward
240-
// compatibility. Bare integer interpreted as days.
241-
CacheTTLDays *int `toml:"cache_ttl_days,omitempty"`
235+
// CacheTTL is the cache lifetime for extracted documents. Accepts
236+
// unitized strings ("30d", "720h") or bare integers (seconds).
237+
// Set to "0s" to disable eviction. Default: 30d.
238+
CacheTTL *Duration `toml:"cache_ttl,omitempty" validate:"omitempty,nonneg_duration"`
242239

243240
// FilePickerDir is the starting directory for the document file picker.
244241
// Default: the system Downloads folder (e.g. ~/Downloads).
@@ -266,14 +263,11 @@ func (d Documents) ResolvedFilePickerDir() string {
266263
}
267264

268265
// CacheTTLDuration returns the resolved cache TTL as a time.Duration.
269-
// CacheTTL takes precedence over CacheTTLDays. Returns 0 to disable.
266+
// Returns 0 to disable eviction.
270267
func (d Documents) CacheTTLDuration() time.Duration {
271268
if d.CacheTTL != nil {
272269
return d.CacheTTL.Duration
273270
}
274-
if d.CacheTTLDays != nil {
275-
return time.Duration(*d.CacheTTLDays) * 24 * time.Hour
276-
}
277271
return DefaultCacheTTL
278272
}
279273

@@ -332,107 +326,7 @@ func LoadFromPath(path string) (Config, error) {
332326
)
333327
}
334328

335-
// Validate providers.
336-
if !validProvider(cfg.Chat.LLM.Provider) {
337-
return cfg, fmt.Errorf(
338-
"chat.llm.provider: unknown provider %q -- supported: %s",
339-
cfg.Chat.LLM.Provider, strings.Join(providerNames(), ", "),
340-
)
341-
}
342-
if !validProvider(cfg.Extraction.LLM.Provider) {
343-
return cfg, fmt.Errorf(
344-
"extraction.llm.provider: unknown provider %q -- supported: %s",
345-
cfg.Extraction.LLM.Provider, strings.Join(providerNames(), ", "),
346-
)
347-
}
348-
349-
// Validate thinking levels.
350-
if cfg.Chat.LLM.Thinking != "" && !validThinkingLevel(cfg.Chat.LLM.Thinking) {
351-
return cfg, fmt.Errorf(
352-
"chat.llm.thinking: invalid level %q -- supported: none, low, medium, high, auto",
353-
cfg.Chat.LLM.Thinking,
354-
)
355-
}
356-
if cfg.Extraction.LLM.Thinking != "" && !validThinkingLevel(cfg.Extraction.LLM.Thinking) {
357-
return cfg, fmt.Errorf(
358-
"extraction.llm.thinking: invalid level %q -- supported: none, low, medium, high, auto",
359-
cfg.Extraction.LLM.Thinking,
360-
)
361-
}
362-
363-
// Validate timeouts.
364-
if err := validateTimeout(cfg.Chat.LLM.Timeout, "chat.llm"); err != nil {
365-
return cfg, err
366-
}
367-
if err := validateTimeout(cfg.Extraction.LLM.Timeout, "extraction.llm"); err != nil {
368-
return cfg, err
369-
}
370-
371-
if cfg.Documents.MaxFileSize == 0 {
372-
return cfg, fmt.Errorf("documents.max_file_size must be positive")
373-
}
374-
375-
if cfg.Documents.CacheTTL != nil && cfg.Documents.CacheTTLDays != nil {
376-
return cfg, fmt.Errorf(
377-
"documents.cache_ttl and documents.cache_ttl_days cannot both be set -- " +
378-
"remove cache_ttl_days (deprecated) and use cache_ttl instead",
379-
)
380-
}
381-
382-
if cfg.Documents.CacheTTLDays != nil {
383-
cfg.Warnings = append(
384-
cfg.Warnings,
385-
"documents.cache_ttl_days is deprecated -- use documents.cache_ttl (e.g. \"30d\") instead",
386-
)
387-
if *cfg.Documents.CacheTTLDays < 0 {
388-
return cfg, fmt.Errorf(
389-
"documents.cache_ttl_days must be non-negative, got %d",
390-
*cfg.Documents.CacheTTLDays,
391-
)
392-
}
393-
}
394-
395-
if cfg.Documents.CacheTTL != nil && cfg.Documents.CacheTTL.Duration < 0 {
396-
return cfg, fmt.Errorf(
397-
"documents.cache_ttl must be non-negative, got %s",
398-
cfg.Documents.CacheTTL.Duration,
399-
)
400-
}
401-
402-
if cfg.Extraction.MaxPages < 0 {
403-
return cfg, fmt.Errorf(
404-
"extraction.max_pages must be non-negative, got %d",
405-
cfg.Extraction.MaxPages,
406-
)
407-
}
408-
409-
if t := cfg.Extraction.OCR.TSV.Threshold(); t < 0 || t > 100 {
410-
return cfg, fmt.Errorf(
411-
"extraction.ocr.tsv.confidence_threshold must be 0-100, got %d", t,
412-
)
413-
}
414-
415-
checkFilePermissions(&cfg, path)
416-
417-
return cfg, nil
418-
}
419-
420-
// validateTimeout validates a pipeline timeout string.
421-
func validateTimeout(timeout, prefix string) error {
422-
if timeout == "" {
423-
return nil
424-
}
425-
d, err := time.ParseDuration(timeout)
426-
if err != nil {
427-
return fmt.Errorf(
428-
"%s.timeout: invalid duration %q -- use Go syntax like \"5m\" or \"10m\"",
429-
prefix, timeout,
430-
)
431-
}
432-
if d <= 0 {
433-
return fmt.Errorf("%s.timeout must be positive, got %s", prefix, timeout)
434-
}
435-
return nil
329+
return cfg, cfg.validate(path)
436330
}
437331

438332
// applyEnvOverrides walks the Config struct and applies environment variable
@@ -794,14 +688,6 @@ func validProvider(name string) bool {
794688
return false
795689
}
796690

797-
var thinkingLevels = map[string]bool{
798-
"none": true, "low": true, "medium": true, "high": true, "auto": true,
799-
}
800-
801-
func validThinkingLevel(level string) bool {
802-
return thinkingLevels[level]
803-
}
804-
805691
// detectProvider infers the provider from the base URL and API key.
806692
func detectProvider(baseURL, apiKey string) string {
807693
if apiKey != "" {

internal/config/config_test.go

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -311,55 +311,6 @@ func TestCacheTTLRejectsNegative(t *testing.T) {
311311
assert.Contains(t, err.Error(), "must be non-negative")
312312
}
313313

314-
// --- CacheTTLDays (deprecated) ---
315-
316-
func TestCacheTTLDaysStillWorks(t *testing.T) {
317-
path := writeConfig(t, "[documents]\ncache_ttl_days = 7\n")
318-
cfg, err := LoadFromPath(path)
319-
require.NoError(t, err)
320-
assert.Equal(t, 7*24*time.Hour, cfg.Documents.CacheTTLDuration())
321-
require.Len(t, cfg.Warnings, 1)
322-
assert.Contains(t, cfg.Warnings[0], "documents.cache_ttl_days")
323-
}
324-
325-
func TestCacheTTLDaysZeroDisables(t *testing.T) {
326-
path := writeConfig(t, "[documents]\ncache_ttl_days = 0\n")
327-
cfg, err := LoadFromPath(path)
328-
require.NoError(t, err)
329-
assert.Equal(t, time.Duration(0), cfg.Documents.CacheTTLDuration())
330-
}
331-
332-
func TestCacheTTLDaysEnvOverride(t *testing.T) {
333-
t.Setenv("MICASA_DOCUMENTS_CACHE_TTL_DAYS", "14")
334-
cfg, err := LoadFromPath(noConfig(t))
335-
require.NoError(t, err)
336-
assert.Equal(t, 14*24*time.Hour, cfg.Documents.CacheTTLDuration())
337-
require.Len(t, cfg.Warnings, 1)
338-
assert.Contains(t, cfg.Warnings[0], "documents.cache_ttl_days")
339-
}
340-
341-
func TestCacheTTLDaysRejectsNegative(t *testing.T) {
342-
path := writeConfig(t, "[documents]\ncache_ttl_days = -1\n")
343-
_, err := LoadFromPath(path)
344-
require.Error(t, err)
345-
assert.Contains(t, err.Error(), "must be non-negative")
346-
}
347-
348-
func TestCacheTTLAndCacheTTLDaysBothSetFails(t *testing.T) {
349-
path := writeConfig(t, "[documents]\ncache_ttl = \"30d\"\ncache_ttl_days = 30\n")
350-
_, err := LoadFromPath(path)
351-
require.Error(t, err)
352-
assert.Contains(t, err.Error(), "cannot both be set")
353-
}
354-
355-
func TestCacheTTLAndCacheTTLDaysEnvBothSetFails(t *testing.T) {
356-
t.Setenv("MICASA_DOCUMENTS_CACHE_TTL", "30d")
357-
t.Setenv("MICASA_DOCUMENTS_CACHE_TTL_DAYS", "30")
358-
_, err := LoadFromPath(noConfig(t))
359-
require.Error(t, err)
360-
assert.Contains(t, err.Error(), "cannot both be set")
361-
}
362-
363314
// --- API Keys ---
364315

365316
func TestAPIKeyFromFile(t *testing.T) {
@@ -565,7 +516,6 @@ func TestInvalidEnvVarReturnsError(t *testing.T) {
565516
{"MICASA_EXTRACTION_LLM_ENABLE", "maybe", "expected true or false"},
566517
{"MICASA_DOCUMENTS_MAX_FILE_SIZE", "lots", "expected byte size"},
567518
{"MICASA_DOCUMENTS_CACHE_TTL", "forever", "expected duration"},
568-
{"MICASA_DOCUMENTS_CACHE_TTL_DAYS", "many", "expected integer"},
569519
}
570520
for _, tt := range tests {
571521
t.Run(tt.envVar, func(t *testing.T) {
@@ -736,7 +686,6 @@ func TestEnvVars(t *testing.T) {
736686

737687
"MICASA_DOCUMENTS_MAX_FILE_SIZE": "documents.max_file_size",
738688
"MICASA_DOCUMENTS_CACHE_TTL": "documents.cache_ttl",
739-
"MICASA_DOCUMENTS_CACHE_TTL_DAYS": "documents.cache_ttl_days",
740689
"MICASA_DOCUMENTS_FILE_PICKER_DIR": "documents.file_picker_dir",
741690

742691
"MICASA_LOCALE_CURRENCY": "locale.currency",

internal/config/show.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ var hiddenPaths = map[string]bool{
2424

2525
// deprecatedPaths maps deprecated TOML key paths to a human-readable
2626
// replacement hint shown in ShowConfig output.
27-
var deprecatedPaths = map[string]string{
28-
"documents.cache_ttl_days": "documents.cache_ttl",
29-
}
27+
var deprecatedPaths = map[string]string{}
3028

3129
// ShowConfig writes the fully resolved configuration as valid TOML to w,
3230
// annotating each field with its env var name and marking active overrides.

0 commit comments

Comments
 (0)