chore: keep host/client specifics out of the tree (env & config)
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 4s
Tests / Test (Go 1.25) (pull_request) Successful in 59s
Tests / Test (Go stable) (pull_request) Successful in 1m7s

Showroom-safe: the tree no longer carries internal hosts, IPs, ports,
personal names, client domains or client file names. Behaviour is
unchanged and now supplied per deployment.

- catalog: hardcoded mail-org / project classifiers become a YAML-driven
  Classifier (OO_CATALOG_CONFIG or --config); neutral default classifies
  nothing as work. New catalog/classify.go + example + tests.
- storage_fallback: drop the baked-in MinIO endpoint IP; require
  MINIO_ENDPOINT (+ keys) from the env.
- kontolink: build DocEditor links from $ONLYOFFICE_URL instead of a
  hardcoded portal host; kontoblatt: no client file id in the output name.
- oo: load .env CLI-wide (bootstrap.LoadEnv in execute) so
  non-authenticating commands (catalog scans) also see config.
- genericize comments/docs/fixtures (AGENTS, README, .env.example,
  crm-associations, catalog tests, ES/pdfattach tests, mails).
This commit is contained in:
2026-09-22 22:03:36 +01:00
parent b493472f2e
commit afb93feae5
24 changed files with 377 additions and 110 deletions
+11 -5
View File
@@ -16,6 +16,8 @@ type ScanOptions struct {
MboxHeaders bool
// MboxMaxBytes skips individual mbox files larger than this (0 = 256 MiB default).
MboxMaxBytes int64
// Classifier supplies deployment classification rules; nil → neutral default.
Classifier *Classifier
}
// ScanThunderbirdRoot finds Thunderbird profiles under root and emits person rows
@@ -37,6 +39,10 @@ func ScanThunderbirdRootOpts(root string, opts ScanOptions) (*Document, error) {
if opts.MboxMaxBytes <= 0 {
opts.MboxMaxBytes = 256 << 20
}
cl := opts.Classifier
if cl == nil {
cl = DefaultClassifier()
}
var entries []Entry
seenDB := map[string]struct{}{}
@@ -64,7 +70,7 @@ func ScanThunderbirdRootOpts(root string, opts ScanOptions) (*Document, error) {
return nil
}
seenDB[path] = struct{}{}
parsed, perr := parseGlodaContacts(path)
parsed, perr := parseGlodaContacts(path, cl)
if perr != nil {
entries = append(entries, Entry{
ID: EntryID("person", "", filepath.Base(path)),
@@ -84,7 +90,7 @@ func ScanThunderbirdRootOpts(root string, opts ScanOptions) (*Document, error) {
return nil
}
seenMAB[path] = struct{}{}
parsed, perr := parseMABEmails(path)
parsed, perr := parseMABEmails(path, cl)
if perr != nil {
return nil
}
@@ -101,7 +107,7 @@ func ScanThunderbirdRootOpts(root string, opts ScanOptions) (*Document, error) {
if info.Size() > opts.MboxMaxBytes {
return nil
}
parsed, perr := parseMboxHeaderEmails(path)
parsed, perr := parseMboxHeaderEmails(path, cl)
if perr != nil {
return nil
}
@@ -150,7 +156,7 @@ func isLikelyMboxFile(name, path string) bool {
}
// parseMboxHeaderEmails extracts addresses from From/To/Cc/Reply-To headers only.
func parseMboxHeaderEmails(path string) ([]Entry, error) {
func parseMboxHeaderEmails(path string, cl *Classifier) ([]Entry, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
@@ -220,7 +226,7 @@ func parseMboxHeaderEmails(path string) ([]Entry, error) {
var out []Entry
for em := range emails {
org, zone, role := classifyMailIdentity("", em)
org, zone, role := cl.ClassifyMail("", em)
out = append(out, Entry{
ID: EntryID("person", em, ""),
Kind: "person",