feat: implement per-account databases and native CouchDB attachments

- Create separate CouchDB database for each mail source (account)
- Store email attachments as native CouchDB attachments
- Add GenerateAccountDBName() for CouchDB-compatible database naming
- Update MailDocument structure to support _attachments field
- Implement StoreAttachment() for CouchDB attachment API
- Add placeholder attachment testing for every 3rd message

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-08-01 16:12:17 +02:00
commit 79f19a8877
3 changed files with 161 additions and 53 deletions

View file

@ -23,25 +23,30 @@ func main() {
log.Fatalf("Failed to create CouchDB client: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err = couchClient.EnsureDB(ctx, cfg.CouchDb.Database)
if err != nil {
log.Printf("Could not ensure CouchDB database exists (is it running?): %v", err)
} else {
fmt.Printf("CouchDB database '%s' is ready.\n", cfg.CouchDb.Database)
}
fmt.Printf("Found %d mail source(s) to process.\n", len(cfg.MailSources))
for _, source := range cfg.MailSources {
if !source.Enabled {
continue
}
// Generate per-account database name
dbName := couch.GenerateAccountDBName(source.Name, source.User)
// Ensure the account-specific database exists
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
err = couchClient.EnsureDB(ctx, dbName)
cancel()
if err != nil {
log.Printf("Could not ensure CouchDB database '%s' exists (is it running?): %v", dbName, err)
continue
} else {
fmt.Printf("CouchDB database '%s' is ready for account: %s\n", dbName, source.Name)
}
fmt.Printf(" - Processing source: %s\n", source.Name)
if source.Protocol == "imap" {
err := processImapSource(&source, couchClient, cfg.CouchDb.Database)
err := processImapSource(&source, couchClient, dbName)
if err != nil {
log.Printf(" ERROR: Failed to process IMAP source %s: %v", source.Name, err)
}
@ -112,11 +117,11 @@ func processImapSource(source *config.MailSource, couchClient *couch.Client, dbN
docs = append(docs, doc)
}
// Store messages in CouchDB
// Store messages in CouchDB with attachments
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
stored := 0
for _, doc := range docs {
err := couchClient.StoreMessage(ctx, dbName, doc)
for i, doc := range docs {
err := couchClient.StoreMessage(ctx, dbName, doc, messages[i])
if err != nil {
log.Printf(" ERROR: Failed to store message %s: %v", doc.ID, err)
} else {