cutover

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const SmartAccountsSnapshotAdapterVersion = "smartaccounts-snapshot-v1"

Variables

View Source
var ErrMigrationExecutionRunNotFound = errors.New("migration execution run not found")

ErrMigrationExecutionRunNotFound is returned when a saved run does not belong to the tenant.

Functions

func ApplyMigrationExecutionResume

func ApplyMigrationExecutionResume(run *MigrationExecutionRun, resumeFrom *MigrationExecutionRun)

func CompleteMigrationExecutionStep

func CompleteMigrationExecutionStep(run *MigrationExecutionRun, index int, status MigrationExecutionResultStatus, message, errorText string, response interface{}, now time.Time)

func MarkMigrationExecutionStepRunning

func MarkMigrationExecutionStepRunning(run *MigrationExecutionRun, index int, now time.Time)

func MergeSavedMigrationExecutionRequest

func MergeSavedMigrationExecutionRequest(req *ExecuteMigrationRequest, saved *ExecuteMigrationRequest)

MergeSavedMigrationExecutionRequest fills a resume request from the saved run payload when fields are omitted.

func RefreshMigrationExecutionRunProgress

func RefreshMigrationExecutionRunProgress(run *MigrationExecutionRun)

Types

type BundleFile

type BundleFile struct {
	Kind       FileKind `json:"kind"`
	FileName   string   `json:"file_name"`
	CSVContent string   `json:"csv_content,omitempty"`
	XMLContent string   `json:"xml_content,omitempty"`
}

func CanonicalizeBundleFileCSV

func CanonicalizeBundleFileCSV(file BundleFile, providerPreset MigrationProviderPreset) (BundleFile, error)

CanonicalizeBundleFileCSV rewrites provider-specific CSV headers to the same canonical headers used by migration preflight validation.

type BundleValidationReport

type BundleValidationReport struct {
	Summary            BundleValidationSummary      `json:"summary"`
	Files              []FileValidation             `json:"files"`
	Issues             []ValidationIssue            `json:"issues,omitempty"`
	RemediationActions []MigrationRemediationAction `json:"remediation_actions,omitempty"`
}

type BundleValidationSummary

type BundleValidationSummary struct {
	FilesValidated int  `json:"files_validated"`
	RowsValidated  int  `json:"rows_validated"`
	ErrorCount     int  `json:"error_count"`
	WarningCount   int  `json:"warning_count"`
	Ready          bool `json:"ready"`
}

type EInvoiceContactMode

type EInvoiceContactMode string
const (
	EInvoiceContactModeSupplier EInvoiceContactMode = "supplier"
	EInvoiceContactModeCustomer EInvoiceContactMode = "customer"
	EInvoiceContactModeBoth     EInvoiceContactMode = "both"
)

type ExecuteMigrationRequest

type ExecuteMigrationRequest struct {
	Files                    []BundleFile            `json:"files"`
	EInvoiceContactMode      EInvoiceContactMode     `json:"e_invoice_contact_mode,omitempty"`
	EInvoiceInvoiceType      string                  `json:"e_invoice_invoice_type,omitempty"`
	ProviderPreset           MigrationProviderPreset `json:"provider_preset,omitempty"`
	BankTransactionAccountID string                  `json:"bank_transaction_account_id,omitempty"`
	BankTransactionFormat    string                  `json:"bank_transaction_format,omitempty"`
	OpeningBalanceEntryDate  string                  `json:"opening_balance_entry_date,omitempty"`
	PostJournalEntries       bool                    `json:"post_journal_entries,omitempty"`
	Confirm                  bool                    `json:"confirm,omitempty"`
	ResumeFromRun            *MigrationExecutionRun  `json:"resume_from_run,omitempty"`
	ResumeFromRunID          string                  `json:"resume_from_run_id,omitempty"`
}

func NewStoredMigrationExecutionRequest

func NewStoredMigrationExecutionRequest(req *ExecuteMigrationRequest) *ExecuteMigrationRequest

NewStoredMigrationExecutionRequest returns the replay-safe subset of an execution request.

func (ExecuteMigrationRequest) PlanRequest

type FileKind

type FileKind string
const (
	KindAccounts          FileKind = "accounts"
	KindContacts          FileKind = "contacts"
	KindEmployees         FileKind = "employees"
	KindExpenses          FileKind = "expenses"
	KindInvoices          FileKind = "invoices"
	KindEInvoices         FileKind = "e_invoices"
	KindPayments          FileKind = "payments"
	KindBankAccounts      FileKind = "bank_accounts"
	KindBankTransactions  FileKind = "bank_transactions"
	KindPayrollHistory    FileKind = "payroll_history"
	KindLeaveBalances     FileKind = "leave_balances"
	KindTSDHistory        FileKind = "tsd_history"
	KindKMDHistory        FileKind = "kmd_history"
	KindQuotes            FileKind = "quotes"
	KindOrders            FileKind = "orders"
	KindRecurringInvoices FileKind = "recurring_invoices"
	KindCostCenters       FileKind = "cost_centers"
	KindCostAllocations   FileKind = "cost_allocations"
	KindProductCategories FileKind = "product_categories"
	KindWarehouses        FileKind = "warehouses"
	KindProducts          FileKind = "products"
	KindStockAdjustments  FileKind = "stock_adjustments"
	KindFixedAssets       FileKind = "fixed_assets"
	KindOpeningBalances   FileKind = "opening_balances"
	KindJournalEntries    FileKind = "journal_entries"
)

type FileValidation

type FileValidation struct {
	Kind           FileKind `json:"kind"`
	FileName       string   `json:"file_name"`
	Rows           int      `json:"rows"`
	Headers        []string `json:"headers,omitempty"`
	MissingColumns []string `json:"missing_columns,omitempty"`
}

type GORMMigrationExecutionRunRepository

type GORMMigrationExecutionRunRepository struct {
	// contains filtered or unexported fields
}

GORMMigrationExecutionRunRepository implements MigrationExecutionRunStore using tenant-scoped tables.

func NewGORMMigrationExecutionRunRepository

func NewGORMMigrationExecutionRunRepository(db *gorm.DB) *GORMMigrationExecutionRunRepository

NewGORMMigrationExecutionRunRepository creates a repository from a GORM connection.

func NewMigrationExecutionRunRepository

func NewMigrationExecutionRunRepository(pool *pgxpool.Pool) *GORMMigrationExecutionRunRepository

NewMigrationExecutionRunRepository creates a migration execution run repository from the shared pgx pool.

func (*GORMMigrationExecutionRunRepository) GetExecutionRun

func (r *GORMMigrationExecutionRunRepository) GetExecutionRun(ctx context.Context, schemaName, tenantID, runID string) (*MigrationExecutionRun, error)

GetExecutionRun returns one saved run snapshot.

func (*GORMMigrationExecutionRunRepository) ListExecutionRuns

func (r *GORMMigrationExecutionRunRepository) ListExecutionRuns(ctx context.Context, schemaName, tenantID string, filter MigrationExecutionRunFilter) ([]MigrationExecutionRun, error)

ListExecutionRuns returns recent saved run snapshots.

func (*GORMMigrationExecutionRunRepository) SaveExecutionRun

func (r *GORMMigrationExecutionRunRepository) SaveExecutionRun(ctx context.Context, schemaName, tenantID, createdBy string, run *MigrationExecutionRun) (*MigrationExecutionRun, error)

SaveExecutionRun creates or updates a run snapshot.

type IssueSeverity

type IssueSeverity string
const (
	SeverityError   IssueSeverity = "ERROR"
	SeverityWarning IssueSeverity = "WARNING"
)

type MigrationExecutionPlan

type MigrationExecutionPlan struct {
	Summary            MigrationExecutionPlanSummary `json:"summary"`
	Validation         BundleValidationReport        `json:"validation"`
	Steps              []MigrationExecutionStep      `json:"steps,omitempty"`
	RemediationActions []MigrationRemediationAction  `json:"remediation_actions,omitempty"`
}

type MigrationExecutionPlanSummary

type MigrationExecutionPlanSummary struct {
	ValidationReady   bool `json:"validation_ready"`
	Ready             bool `json:"ready"`
	StepCount         int  `json:"step_count"`
	ReadyStepCount    int  `json:"ready_step_count"`
	NeedsContextCount int  `json:"needs_context_count"`
	BlockedStepCount  int  `json:"blocked_step_count"`
}

type MigrationExecutionResultStatus

type MigrationExecutionResultStatus string
const (
	MigrationExecutionResultPlanned   MigrationExecutionResultStatus = "PLANNED"
	MigrationExecutionResultRunning   MigrationExecutionResultStatus = "RUNNING"
	MigrationExecutionResultSkipped   MigrationExecutionResultStatus = "SKIPPED"
	MigrationExecutionResultSucceeded MigrationExecutionResultStatus = "SUCCEEDED"
	MigrationExecutionResultFailed    MigrationExecutionResultStatus = "FAILED"
)

type MigrationExecutionRun

type MigrationExecutionRun struct {
	ID                 string                       `json:"id,omitempty"`
	TenantID           string                       `json:"tenant_id,omitempty"`
	CreatedBy          string                       `json:"created_by,omitempty"`
	CreatedAt          *time.Time                   `json:"created_at,omitempty"`
	UpdatedAt          *time.Time                   `json:"updated_at,omitempty"`
	Summary            MigrationExecutionRunSummary `json:"summary"`
	Plan               *MigrationExecutionPlan      `json:"plan,omitempty"`
	Steps              []MigrationExecutionStepRun  `json:"steps,omitempty"`
	RemediationActions []MigrationRemediationAction `json:"remediation_actions,omitempty"`
	ExecutionRequest   *ExecuteMigrationRequest     `json:"-"`
}

func NewMigrationExecutionRun

func NewMigrationExecutionRun(plan *MigrationExecutionPlan, confirmed bool) *MigrationExecutionRun

func NewResumableMigrationExecutionRun

func NewResumableMigrationExecutionRun(plan *MigrationExecutionPlan, confirmed bool, resumeFrom *MigrationExecutionRun) *MigrationExecutionRun

type MigrationExecutionRunEvent

type MigrationExecutionRunEvent struct {
	Type     string                 `json:"type"`
	Sequence int                    `json:"sequence"`
	Run      *MigrationExecutionRun `json:"run,omitempty"`
}

type MigrationExecutionRunFilter

type MigrationExecutionRunFilter struct {
	Status string
	Limit  int
}

MigrationExecutionRunFilter controls saved execution-run listing.

type MigrationExecutionRunStore

type MigrationExecutionRunStore interface {
	SaveExecutionRun(ctx context.Context, schemaName, tenantID, createdBy string, run *MigrationExecutionRun) (*MigrationExecutionRun, error)
	ListExecutionRuns(ctx context.Context, schemaName, tenantID string, filter MigrationExecutionRunFilter) ([]MigrationExecutionRun, error)
	GetExecutionRun(ctx context.Context, schemaName, tenantID, runID string) (*MigrationExecutionRun, error)
}

MigrationExecutionRunStore persists migration execution runs for dashboard and operator resume workflows.

type MigrationExecutionRunSummary

type MigrationExecutionRunSummary struct {
	Status                string                         `json:"status"`
	Confirmed             bool                           `json:"confirmed"`
	Resumed               bool                           `json:"resumed"`
	PlanReady             bool                           `json:"plan_ready"`
	ValidationReady       bool                           `json:"validation_ready"`
	StepCount             int                            `json:"step_count"`
	RunningStepCount      int                            `json:"running_step_count"`
	SucceededStepCount    int                            `json:"succeeded_step_count"`
	FailedStepCount       int                            `json:"failed_step_count"`
	SkippedStepCount      int                            `json:"skipped_step_count"`
	PlannedStepCount      int                            `json:"planned_step_count"`
	ResumedStepCount      int                            `json:"resumed_step_count"`
	CompletedStepCount    int                            `json:"completed_step_count"`
	RemainingStepCount    int                            `json:"remaining_step_count"`
	ProgressPercent       int                            `json:"progress_percent"`
	DurationMS            int64                          `json:"duration_ms,omitempty"`
	NeedsContextCount     int                            `json:"needs_context_count"`
	BlockedStepCount      int                            `json:"blocked_step_count"`
	ActiveStepNumber      int                            `json:"active_step_number,omitempty"`
	ActiveStepKind        FileKind                       `json:"active_step_kind,omitempty"`
	ActiveStepFileName    string                         `json:"active_step_file_name,omitempty"`
	ActiveStepStatus      MigrationExecutionResultStatus `json:"active_step_status,omitempty"`
	ActiveStepStartedAt   *time.Time                     `json:"active_step_started_at,omitempty"`
	ActiveStepCompletedAt *time.Time                     `json:"active_step_completed_at,omitempty"`
	ActiveStepDurationMS  int64                          `json:"active_step_duration_ms,omitempty"`
}

type MigrationExecutionStep

type MigrationExecutionStep struct {
	StepNumber    int                          `json:"step_number"`
	Kind          FileKind                     `json:"kind"`
	FileName      string                       `json:"file_name"`
	Status        MigrationExecutionStepStatus `json:"status"`
	Message       string                       `json:"message"`
	Action        string                       `json:"action"`
	APIMethod     string                       `json:"api_method,omitempty"`
	APIPath       string                       `json:"api_path,omitempty"`
	CLICommand    string                       `json:"cli_command,omitempty"`
	DependsOn     []FileKind                   `json:"depends_on,omitempty"`
	ContextFields []string                     `json:"context_fields,omitempty"`
}

type MigrationExecutionStepRun

type MigrationExecutionStepRun struct {
	StepNumber  int                            `json:"step_number"`
	Kind        FileKind                       `json:"kind"`
	FileName    string                         `json:"file_name"`
	Status      MigrationExecutionResultStatus `json:"status"`
	Message     string                         `json:"message,omitempty"`
	Error       string                         `json:"error,omitempty"`
	APIPath     string                         `json:"api_path,omitempty"`
	CLICommand  string                         `json:"cli_command,omitempty"`
	Response    interface{}                    `json:"response,omitempty"`
	StartedAt   *time.Time                     `json:"started_at,omitempty"`
	CompletedAt *time.Time                     `json:"completed_at,omitempty"`
	DurationMS  int64                          `json:"duration_ms,omitempty"`
}

type MigrationExecutionStepStatus

type MigrationExecutionStepStatus string
const (
	MigrationExecutionStepReady        MigrationExecutionStepStatus = "READY"
	MigrationExecutionStepNeedsContext MigrationExecutionStepStatus = "NEEDS_CONTEXT"
	MigrationExecutionStepBlocked      MigrationExecutionStepStatus = "BLOCKED"
)

type MigrationProviderPreset

type MigrationProviderPreset string
const (
	MigrationProviderPresetGeneric       MigrationProviderPreset = "generic"
	MigrationProviderPresetMerit         MigrationProviderPreset = "merit"
	MigrationProviderPresetSmartAccounts MigrationProviderPreset = "smartaccounts"
	MigrationProviderPresetDirecto       MigrationProviderPreset = "directo"
)

type MigrationProviderPresetAlias

type MigrationProviderPresetAlias struct {
	SourceHeader    string `json:"source_header"`
	CanonicalHeader string `json:"canonical_header"`
}

type MigrationProviderPresetInfo

type MigrationProviderPresetInfo struct {
	Preset           MigrationProviderPreset           `json:"preset"`
	Label            string                            `json:"label"`
	Description      string                            `json:"description"`
	FileKindCount    int                               `json:"file_kind_count"`
	PresetAliasCount int                               `json:"preset_alias_count"`
	FileKinds        []MigrationProviderPresetKindInfo `json:"file_kinds,omitempty"`
}

func ListMigrationProviderPresets

func ListMigrationProviderPresets() []MigrationProviderPresetInfo

type MigrationProviderPresetKindInfo

type MigrationProviderPresetKindInfo struct {
	Kind                 FileKind                       `json:"kind"`
	RequiredColumnGroups [][]string                     `json:"required_column_groups,omitempty"`
	PresetAliasCount     int                            `json:"preset_alias_count"`
	SampleAliases        []MigrationProviderPresetAlias `json:"sample_aliases,omitempty"`
}

type MigrationRemediationAction

type MigrationRemediationAction struct {
	Code           string   `json:"code"`
	Severity       string   `json:"severity"`
	Scope          string   `json:"scope"`
	OwnerRole      string   `json:"owner_role"`
	WorkspaceQueue string   `json:"workspace_queue,omitempty"`
	AssignmentKey  string   `json:"assignment_key,omitempty"`
	Priority       string   `json:"priority,omitempty"`
	DueInDays      int      `json:"due_in_days,omitempty"`
	Message        string   `json:"message"`
	Action         string   `json:"action"`
	Kind           FileKind `json:"kind,omitempty"`
	FileName       string   `json:"file_name,omitempty"`
	Field          string   `json:"field,omitempty"`
	TargetKind     FileKind `json:"target_kind,omitempty"`
	IssueCount     int      `json:"issue_count"`
	UIPath         string   `json:"ui_path,omitempty"`
	CLICommand     string   `json:"cli_command,omitempty"`
}

func BuildMigrationRemediationActions

func BuildMigrationRemediationActions(report *BundleValidationReport) []MigrationRemediationAction

type PlanMigrationExecutionRequest

type PlanMigrationExecutionRequest struct {
	Files                    []BundleFile            `json:"files"`
	EInvoiceContactMode      EInvoiceContactMode     `json:"e_invoice_contact_mode,omitempty"`
	EInvoiceInvoiceType      string                  `json:"e_invoice_invoice_type,omitempty"`
	ProviderPreset           MigrationProviderPreset `json:"provider_preset,omitempty"`
	BankTransactionAccountID string                  `json:"bank_transaction_account_id,omitempty"`
	BankTransactionFormat    string                  `json:"bank_transaction_format,omitempty"`
	OpeningBalanceEntryDate  string                  `json:"opening_balance_entry_date,omitempty"`
	PostJournalEntries       bool                    `json:"post_journal_entries,omitempty"`
}

type SmartAccountsSnapshotOptions

type SmartAccountsSnapshotOptions struct {
	SourceDir         string
	OutputDir         string
	SourceCompanyID   string
	SourceCompanyName string
	CutoverDate       string
	GeneratedAt       time.Time
}

type SmartAccountsSnapshotPreparedFile

type SmartAccountsSnapshotPreparedFile struct {
	Kind              FileKind `json:"kind"`
	SourcePath        string   `json:"source_path"`
	OutputPath        string   `json:"output_path"`
	SourceSHA256      string   `json:"source_sha256"`
	OutputSHA256      string   `json:"output_sha256"`
	Rows              int      `json:"rows"`
	OutputRowStart    int      `json:"output_row_start,omitempty"`
	OutputRowEnd      int      `json:"output_row_end,omitempty"`
	Transformations   []string `json:"transformations,omitempty"`
	Classification    string   `json:"classification"`
	ValidationCLIFlag string   `json:"validation_cli_flag,omitempty"`
}

type SmartAccountsSnapshotReport

type SmartAccountsSnapshotReport struct {
	Provider          MigrationProviderPreset             `json:"provider"`
	AdapterVersion    string                              `json:"adapter_version"`
	GeneratedAt       string                              `json:"generated_at"`
	SourceDir         string                              `json:"source_dir"`
	OutputDir         string                              `json:"output_dir"`
	SourceCompanyID   string                              `json:"source_company_id,omitempty"`
	SourceCompanyName string                              `json:"source_company_name,omitempty"`
	CutoverDate       string                              `json:"cutover_date,omitempty"`
	SnapshotHash      string                              `json:"snapshot_hash"`
	ManifestPath      string                              `json:"manifest_path"`
	ValidationCommand string                              `json:"validation_command,omitempty"`
	PreparedFiles     []SmartAccountsSnapshotPreparedFile `json:"prepared_files,omitempty"`
	UnsupportedFiles  []SmartAccountsSnapshotUnsupported  `json:"unsupported_files,omitempty"`
	Warnings          []string                            `json:"warnings,omitempty"`
	// contains filtered or unexported fields
}

func (*SmartAccountsSnapshotReport) BundleFiles

func (r *SmartAccountsSnapshotReport) BundleFiles() []BundleFile

type SmartAccountsSnapshotUnsupported

type SmartAccountsSnapshotUnsupported struct {
	SourcePath   string `json:"source_path"`
	Reason       string `json:"reason"`
	SourceSHA256 string `json:"source_sha256"`
	SizeBytes    int64  `json:"size_bytes"`
}

type ValidateBundleRequest

type ValidateBundleRequest struct {
	Files               []BundleFile            `json:"files"`
	EInvoiceContactMode EInvoiceContactMode     `json:"e_invoice_contact_mode,omitempty"`
	EInvoiceInvoiceType string                  `json:"e_invoice_invoice_type,omitempty"`
	ProviderPreset      MigrationProviderPreset `json:"provider_preset,omitempty"`
}

type ValidationIssue

type ValidationIssue struct {
	Severity   IssueSeverity `json:"severity"`
	Kind       FileKind      `json:"kind"`
	FileName   string        `json:"file_name"`
	Row        int           `json:"row,omitempty"`
	Field      string        `json:"field,omitempty"`
	Value      string        `json:"value,omitempty"`
	TargetKind FileKind      `json:"target_kind,omitempty"`
	Message    string        `json:"message"`
}

Jump to

Keyboard shortcuts

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