# Changelog All notable changes to inBOXER will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [2026-04.4] - 2026-04-23 ### Fixed - **Settings page unusable**: Password field referenced nonexistent struct field (`IMAPPass` vs `IMAPPassEncrypted`), rendered blank on every page load - **Password wiped on save**: Leaving password field blank (because it showed empty) overwrote encrypted password with empty string; now only updates when user enters a new password - **"Test Connection" never worked**: `TestConnectionHandler` returned `"Not implemented yet"`; now performs actual IMAP connect+login using go-imap and returns success/failure JSON - **"Process Now" was a no-op**: `ProcessNowHandler` just redirected; now signals worker to run an immediate processing cycle via new `Worker.ProcessNow()` channel - **Dashboard showed 0 for emails processed**: Template referenced `{{ .Stats.TotalProcessed }}` but `TotalProcessed` is a separate struct field, not a map key; corrected to `{{ .TotalProcessed }}` - **No getting-started guidance**: Dashboard now shows an info banner on first visit directing users to configure their IMAP account in Settings - **Password field `required`**: Removed HTML5 `required` attribute so users can save other settings without re-entering their password ### Changed - `Handler` struct now holds a `*worker.Worker` reference for `ProcessNowHandler` - Worker initialization moved before handler creation in `main.go` to satisfy the dependency - `Handler.NewHandler()` signature extended with `bgWorker *worker.Worker` parameter - Settings POST handler re-reads decrypted settings after save so the form reflects the current state ### Added - `Worker.ProcessNow()` — sends signal to `processNow` channel (buffered, capacity 1) to trigger `processAllUsers()` outside the normal poll interval - `Worker.processNow` channel field (buffered, prevents goroutine block) - `encoding/json` import in handlers for `TestConnectionHandler` JSON responses ## [2026-04.3] - 2026-04-23 ### Added - AI classification package (`src/internal/ai/`): - DeepSeek API client with chat completion requests (chat.deepseek.com API) - Configurable model, temperature, max tokens via `config.yaml` - Prompt template engine: loads `bin/prompt.txt` at runtime, substitutes `{sender}`, `{subject}`, `{body}` placeholders - Response parser validates folder names (Important/eCommerce/Spam/Other) and confidence scores (1-100) - Graceful fallback to placeholder classifier if prompt file is missing or API key unset - Unit tests for JSON parsing, prompt loading, and API client creation - Email body text now fetched up to 4000 chars (from 200) for AI classification context ### Changed - Replaced `EmailSummary.Snippet` with `EmailSummary.Body` (4000 char limit) - Main orchestrator now initializes DeepSeek classifier and passes to worker - Worker uses real AI classifier when available; falls back to placeholder on init failure ## [2026-04.2] - 2026-04-23 ### Added - IMAP client package (`src/internal/imap/`): - Secure connection management (TLS & STARTTLS) with auto-reconnect - Fetch unseen messages with envelope and body snippet extraction - Batch fetching by UID range for catch-up processing - Message move/copy operations (RFC 6851 UID MOVE) - Ensure folder existence before operations - Unit tests covering error paths (connection failures, not-connected scenarios) - Background worker package (`src/internal/worker/`): - Steady-state mode: polls unseen emails at configurable interval - Catch-up mode: processes backlog in batches with cooldown - Per-user processing with isolated IMAP connections - Test mode support (logs without moving emails) - AI classifier interface (placeholder routes everything to "Other") - Graceful shutdown with signal handling - Unit tests for classifier and lifecycle - Database: `GetUsersWithAutoStart()` method for worker user discovery ### Changed - Replaced placeholder background worker with full IMAP-driven implementation - Worker now creates target folders automatically on connect - Email processing respects per-user poll interval and batch size ## [2026-04.1] - 2026-04-23 ### Added - Initial repository structure per `PROJECT_PLAN.md` - Go module initialization with core dependencies (go-imap, gorm, sqlite, slog, gorilla) - Git repository setup with remote configuration using `.env` credentials - Basic documentation files (README, CHANGELOG, LICENSE, AGENTS.md) - Directory hierarchy for modular packages: - `src/cmd/` - Main orchestrator - `src/internal/auth/` - OTP authentication package - `src/internal/imap/` - IMAP client (placeholder) - `src/internal/ai/` - DeepSeek AI integration (placeholder) - `src/internal/db/` - SQLite database with GORM models and encryption - `src/internal/worker/` - Background worker (placeholder) - `src/web/` - Web interface (templates + static) - `src/pkg/` - Shared utilities (config loader) - `bin/` - Compiled binary and configuration - Modular authentication package: - OTP generation & hashing (bcrypt) - SMTP sender with `.env` credentials - Session cookie management (gorilla/sessions) - Database-backed OTP store - Mobile-first frontend: - Responsive CSS with modern design system - Go HTML templates (login, verify, dashboard, settings) - Authentication flow (email + OTP) - Database schema: - User model with OTP storage - Mailbox settings with encrypted passwords - Processed email tracking - Configuration system: - YAML configuration file (`bin/config.yaml`) - Environment variable loading (`.env`) - Secret management for session encryption - Web server with routing: - Gorilla mux router with middleware - Authentication middleware for protected routes - Static file serving - Makefile with build, run, test targets - Unit tests for authentication package