api

package
v0.0.0-...-2bd5d0f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package api defines the core interfaces and data structures for expensor.

Index

Constants

View Source
const (
	// FailureAmountZero indicates extraction produced a zero amount.
	FailureAmountZero = "amount_zero"
	// FailureMerchantEmpty indicates extraction produced no merchant text.
	FailureMerchantEmpty = "merchant_empty"
)

Variables

This section is empty.

Functions

func ExtractionFailureReasons

func ExtractionFailureReasons(transaction *TransactionDetails) []string

ExtractionFailureReasons returns diagnostic reason codes for missing required transaction fields.

Types

type CategoryResolver

type CategoryResolver func(merchantInfo string) (category, bucket string)

CategoryResolver returns the category and bucket for a merchant string. Implementations perform substring matching against a community-maintained fragment list. Returns ("", "") when no fragment matches; callers treat this as "Uncategorized".

type DiagnosticSink

type DiagnosticSink interface {
	RecordExtractionDiagnostic(ctx context.Context, diagnostic ExtractionDiagnostic) error
}

DiagnosticSink persists extraction diagnostics for later inspection.

type EmailSearchQuery

type EmailSearchQuery struct {
	// SubjectQuery is a case-insensitive subject substring to search for.
	SubjectQuery string
	// Limit is validated by the caller. HTTP allows 1..50 and defaults omitted values to 10.
	Limit int
}

EmailSearchQuery describes an email search request.

type EmailSearchResult

type EmailSearchResult struct {
	// ID is provider-local and only meaningful within the provider that returned it.
	ID          string
	SenderEmail string
	Subject     string
	Body        string
	ReceivedAt  *time.Time
}

EmailSearchResult is a full email search result suitable for rule authoring.

type EmailSearcher

type EmailSearcher interface {
	Search(ctx context.Context, query EmailSearchQuery) ([]EmailSearchResult, error)
}

EmailSearcher searches emails for rule authoring samples.

type ExtractionDiagnostic

type ExtractionDiagnostic struct {
	Reader         string
	MessageID      string
	Source         string
	Sender         string
	SenderEmail    string
	Subject        string
	EmailBody      string
	ReceivedAt     *time.Time
	Snippet        string
	RuleID         string
	RuleName       string
	AmountRegex    string
	MerchantRegex  string
	CurrencyRegex  string
	FailureReasons []string
}

ExtractionDiagnostic records context for an extraction attempt that did not produce a usable transaction.

type Reader

type Reader interface {
	Read(ctx context.Context, out chan<- *TransactionDetails, ackChan <-chan string) error
}

Reader reads transactions from a source and sends them to the provided channel. Implementations should close the channel when done or on error. The ackChan is used to receive acknowledgments of successfully written transactions.

type Rule

type Rule struct {
	ID              string
	Name            string
	SenderEmail     string         // Email sender to match (e.g., "alerts@icicibank.com")
	SenderEmails    []string       // Exact sender email addresses to match.
	SubjectContains string         // Subject substring to match
	Amount          *regexp.Regexp // Regex to extract amount (group 1 = numeric amount, commas stripped)
	MerchantInfo    *regexp.Regexp // Regex to extract merchant; first non-empty capture group is used
	Currency        *regexp.Regexp // Regex to extract ISO currency code (group 1 = code, e.g. "INR", "USD")
	Source          Source         // Transaction source metadata.
}

Rule defines an email matching rule for transaction extraction. Rules are reader-agnostic: each reader uses the fields appropriate to its context.

func (Rule) DiagnosticSnapshot

func (r Rule) DiagnosticSnapshot() RuleDiagnosticSnapshot

DiagnosticSnapshot returns a diagnostic-safe copy of a rule's identity and regex strings.

func (*Rule) MatchesEmail

func (r *Rule) MatchesEmail(fromHeader, subject string) bool

MatchesEmail checks if an email matches this rule based on sender and subject. Used by readers that don't have query-based filtering (e.g., Thunderbird). The fromHeader parameter can be the full From header (e.g., "Bank <bank@example.com>").

type RuleDiagnosticSnapshot

type RuleDiagnosticSnapshot struct {
	RuleID        string
	RuleName      string
	AmountRegex   string
	MerchantRegex string
	CurrencyRegex string
}

RuleDiagnosticSnapshot captures the diagnostic fields from a rule at extraction time.

type Source

type Source struct {
	Type  string `json:"type"`
	Label string `json:"label"`
	Bank  string `json:"bank"`
}

Source describes where a transaction originated.

func (Source) Display

func (s Source) Display() string

Display returns a compact fallback label for places that still need a string.

type TransactionDetails

type TransactionDetails struct {
	Amount       float64 `json:"amount"`
	Timestamp    string  `json:"timestamp"`
	MerchantInfo string  `json:"merchant_info"`
	Category     string  `json:"category"`
	// Bucket classifies the expense as Need/Want/Investment.
	Bucket string `json:"bucket"`
	Source Source `json:"source"`
	// MessageID is the email message ID (used for marking as read after successful write).
	MessageID string `json:"-"`

	// Multi-currency support
	Currency         string   `json:"currency,omitempty"`          // e.g., "INR", "USD", "EUR"
	OriginalAmount   *float64 `json:"original_amount,omitempty"`   // If converted
	OriginalCurrency *string  `json:"original_currency,omitempty"` // Original currency if converted
	ExchangeRate     *float64 `json:"exchange_rate,omitempty"`     // Conversion rate if applicable

	// User-added fields
	Description string   `json:"description,omitempty"` // User-added description
	Labels      []string `json:"labels,omitempty"`      // User-added labels
}

TransactionDetails holds extracted transaction information.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL