first ruggedy draft
This commit is contained in:
782
apps/api/mousehold_api/schemas.py
Normal file
782
apps/api/mousehold_api/schemas.py
Normal file
@@ -0,0 +1,782 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import Any
|
||||
|
||||
from mousehold_domain import (
|
||||
AccountType,
|
||||
EventObservationRelation,
|
||||
FinancialEventStatus,
|
||||
FinancialEventType,
|
||||
ImportConnectionStatus,
|
||||
ImportConnectionType,
|
||||
ObservationStatus,
|
||||
PaymentLineStatus,
|
||||
PaymentStatus,
|
||||
PlanningStatus,
|
||||
ProjectStatus,
|
||||
ReconciliationStatus,
|
||||
RecurringCommitmentStatus,
|
||||
RecurringInterval,
|
||||
RelationType,
|
||||
SettlementStatus,
|
||||
SourceType,
|
||||
VisibilityMode,
|
||||
)
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class ApiModel(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class HouseholdCreate(ApiModel):
|
||||
name: str
|
||||
default_currency: str = "EUR"
|
||||
|
||||
|
||||
class HouseholdUpdate(ApiModel):
|
||||
name: str | None = None
|
||||
default_currency: str | None = None
|
||||
|
||||
|
||||
class HouseholdRead(ApiModel):
|
||||
id: str
|
||||
name: str
|
||||
default_currency: str
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class UserCreate(ApiModel):
|
||||
household_id: str
|
||||
display_name: str
|
||||
email: str | None = None
|
||||
|
||||
|
||||
class UserUpdate(ApiModel):
|
||||
display_name: str | None = None
|
||||
email: str | None = None
|
||||
|
||||
|
||||
class UserRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
display_name: str
|
||||
email: str | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class LoginIdentityCreate(ApiModel):
|
||||
user_id: str
|
||||
provider: str
|
||||
provider_subject: str
|
||||
email: str | None = None
|
||||
display_name: str | None = None
|
||||
|
||||
|
||||
class LoginIdentityRead(ApiModel):
|
||||
id: str
|
||||
user_id: str
|
||||
provider: str
|
||||
provider_subject: str
|
||||
email: str | None
|
||||
display_name: str | None
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class LocalLoginRequest(ApiModel):
|
||||
user_id: str
|
||||
|
||||
|
||||
class LocalSessionRead(ApiModel):
|
||||
id: str
|
||||
user_id: str
|
||||
household_id: str
|
||||
created_at: datetime
|
||||
last_seen_at: datetime
|
||||
expires_at: datetime
|
||||
|
||||
|
||||
class AuthSessionRead(ApiModel):
|
||||
session: LocalSessionRead
|
||||
user: UserRead
|
||||
household: HouseholdRead
|
||||
|
||||
|
||||
class AccountCreate(ApiModel):
|
||||
household_id: str
|
||||
owner_user_id: str | None = None
|
||||
name: str
|
||||
account_type: AccountType
|
||||
institution_name: str | None = None
|
||||
currency: str = "EUR"
|
||||
visibility_mode: VisibilityMode = VisibilityMode.PRIVATE
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class AccountUpdate(ApiModel):
|
||||
owner_user_id: str | None = None
|
||||
name: str | None = None
|
||||
account_type: AccountType | None = None
|
||||
institution_name: str | None = None
|
||||
currency: str | None = None
|
||||
visibility_mode: VisibilityMode | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class AccountRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
owner_user_id: str | None
|
||||
name: str
|
||||
account_type: AccountType
|
||||
institution_name: str | None
|
||||
currency: str
|
||||
visibility_mode: VisibilityMode
|
||||
is_active: bool
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class SplitLineCreate(ApiModel):
|
||||
user_id: str
|
||||
share_amount: Decimal
|
||||
share_percent: Decimal | None = None
|
||||
reason: str = "manual"
|
||||
|
||||
|
||||
class SplitLineRead(ApiModel):
|
||||
id: str
|
||||
event_id: str
|
||||
user_id: str
|
||||
share_amount: Decimal
|
||||
share_percent: Decimal | None
|
||||
reason: str
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class ManualObservationCreate(ApiModel):
|
||||
household_id: str
|
||||
source_type: SourceType = SourceType.MANUAL
|
||||
source_account_id: str | None = None
|
||||
owner_user_id: str | None = None
|
||||
observed_at: datetime | None = None
|
||||
source_reference: str | None = None
|
||||
provider_transaction_id: str | None = None
|
||||
message_id: str | None = None
|
||||
raw_text: str | None = None
|
||||
raw_payload_json: dict[str, Any] | None = None
|
||||
amount: Decimal
|
||||
currency: str = "EUR"
|
||||
event_date: date
|
||||
booking_date: date | None = None
|
||||
due_date: date | None = None
|
||||
merchant: str | None = None
|
||||
counterparty: str | None = None
|
||||
description: str | None = None
|
||||
event_type: FinancialEventType = FinancialEventType.EXPENSE
|
||||
status: FinancialEventStatus | None = None
|
||||
payer_user_id: str | None = None
|
||||
payment_account_id: str | None = None
|
||||
category_id: str | None = None
|
||||
project_id: str | None = None
|
||||
split_lines: list[SplitLineCreate] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ObservationImportCreate(ManualObservationCreate):
|
||||
source_type: SourceType
|
||||
|
||||
|
||||
class RawObservationRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
source_type: SourceType
|
||||
source_account_id: str | None
|
||||
owner_user_id: str | None
|
||||
observed_at: datetime | None
|
||||
received_at: datetime
|
||||
raw_hash: str
|
||||
source_reference: str | None
|
||||
provider_transaction_id: str | None
|
||||
message_id: str | None
|
||||
raw_text: str | None
|
||||
raw_file_path: str | None
|
||||
raw_payload_json: dict[str, Any] | None
|
||||
parsed_json: dict[str, Any] | None
|
||||
parser_name: str | None
|
||||
parser_version: str | None
|
||||
confidence: Decimal
|
||||
status: ObservationStatus
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class EventObservationLinkRead(ApiModel):
|
||||
id: str
|
||||
event_id: str
|
||||
observation_id: str
|
||||
relation: EventObservationRelation
|
||||
confidence: Decimal
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class EventCreate(ApiModel):
|
||||
household_id: str
|
||||
source_account_id: str | None = None
|
||||
payment_account_id: str | None = None
|
||||
payer_user_id: str | None = None
|
||||
event_type: FinancialEventType = FinancialEventType.EXPENSE
|
||||
status: FinancialEventStatus = FinancialEventStatus.CANDIDATE
|
||||
event_date: date
|
||||
booking_date: date | None = None
|
||||
due_date: date | None = None
|
||||
amount: Decimal
|
||||
currency: str = "EUR"
|
||||
merchant: str | None = None
|
||||
counterparty: str | None = None
|
||||
description: str | None = None
|
||||
category_id: str | None = None
|
||||
project_id: str | None = None
|
||||
created_by_user_id: str | None = None
|
||||
split_lines: list[SplitLineCreate] = Field(default_factory=list)
|
||||
|
||||
|
||||
class EventUpdate(ApiModel):
|
||||
source_account_id: str | None = None
|
||||
payment_account_id: str | None = None
|
||||
payer_user_id: str | None = None
|
||||
event_type: FinancialEventType | None = None
|
||||
status: FinancialEventStatus | None = None
|
||||
event_date: date | None = None
|
||||
booking_date: date | None = None
|
||||
due_date: date | None = None
|
||||
amount: Decimal | None = None
|
||||
currency: str | None = None
|
||||
merchant: str | None = None
|
||||
counterparty: str | None = None
|
||||
description: str | None = None
|
||||
category_id: str | None = None
|
||||
project_id: str | None = None
|
||||
|
||||
|
||||
class EventRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
source_account_id: str | None
|
||||
payment_account_id: str | None
|
||||
payer_user_id: str | None
|
||||
event_type: FinancialEventType
|
||||
status: FinancialEventStatus
|
||||
event_date: date
|
||||
booking_date: date | None
|
||||
due_date: date | None
|
||||
amount: Decimal
|
||||
currency: str
|
||||
merchant: str | None
|
||||
counterparty: str | None
|
||||
description: str | None
|
||||
category_id: str | None
|
||||
project_id: str | None
|
||||
created_by_user_id: str | None
|
||||
fingerprint: str | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
split_lines: list[SplitLineRead] = Field(default_factory=list)
|
||||
tag_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class EventRelationCreate(ApiModel):
|
||||
to_event_id: str
|
||||
relation_type: RelationType
|
||||
confidence: Decimal = Decimal("1.00")
|
||||
created_by: str = "user"
|
||||
|
||||
|
||||
class EventRelationRead(ApiModel):
|
||||
id: str
|
||||
from_event_id: str
|
||||
to_event_id: str
|
||||
relation_type: RelationType
|
||||
confidence: Decimal
|
||||
created_by: str
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class CategoryCreate(ApiModel):
|
||||
household_id: str
|
||||
name: str
|
||||
parent_id: str | None = None
|
||||
path: str | None = None
|
||||
is_active: bool = True
|
||||
|
||||
|
||||
class CategoryUpdate(ApiModel):
|
||||
name: str | None = None
|
||||
parent_id: str | None = None
|
||||
path: str | None = None
|
||||
is_active: bool | None = None
|
||||
|
||||
|
||||
class CategoryRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
parent_id: str | None
|
||||
name: str
|
||||
path: str
|
||||
is_active: bool
|
||||
|
||||
|
||||
class TagCreate(ApiModel):
|
||||
household_id: str
|
||||
name: str
|
||||
|
||||
|
||||
class TagUpdate(ApiModel):
|
||||
name: str | None = None
|
||||
|
||||
|
||||
class TagRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
name: str
|
||||
|
||||
|
||||
class EventTagsUpdate(ApiModel):
|
||||
tag_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class EventDetailRead(ApiModel):
|
||||
event: EventRead
|
||||
category: CategoryRead | None = None
|
||||
tags: list[TagRead] = Field(default_factory=list)
|
||||
observation_links: list[EventObservationLinkRead] = Field(default_factory=list)
|
||||
observations: list[RawObservationRead] = Field(default_factory=list)
|
||||
relations: list[EventRelationRead] = Field(default_factory=list)
|
||||
related_events: list[EventRead] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ObservationReviewItem(ApiModel):
|
||||
observation: RawObservationRead
|
||||
events: list[EventRead] = Field(default_factory=list)
|
||||
action_required: bool = True
|
||||
suggested_action: str = "review"
|
||||
|
||||
|
||||
class ObservationAcceptRequest(ApiModel):
|
||||
event_status: FinancialEventStatus | None = None
|
||||
create_event_if_missing: bool = True
|
||||
|
||||
|
||||
class ObservationUpdateRequest(ApiModel):
|
||||
source_account_id: str | None = None
|
||||
owner_user_id: str | None = None
|
||||
raw_text: str | None = None
|
||||
amount: Decimal | None = None
|
||||
currency: str | None = None
|
||||
event_date: date | None = None
|
||||
booking_date: date | None = None
|
||||
due_date: date | None = None
|
||||
merchant: str | None = None
|
||||
counterparty: str | None = None
|
||||
description: str | None = None
|
||||
event_type: FinancialEventType | None = None
|
||||
status: FinancialEventStatus | None = None
|
||||
sync_linked_events: bool = True
|
||||
|
||||
|
||||
class ObservationIgnoreRequest(ApiModel):
|
||||
ignore_linked_events: bool = False
|
||||
reason: str | None = None
|
||||
|
||||
|
||||
class ObservationLinkRequest(ApiModel):
|
||||
event_id: str
|
||||
relation: EventObservationRelation = EventObservationRelation.EVIDENCE_FOR
|
||||
|
||||
|
||||
class ObservationBatchRequest(ApiModel):
|
||||
observation_ids: list[str]
|
||||
action: str
|
||||
event_status: FinancialEventStatus | None = None
|
||||
ignore_linked_events: bool = False
|
||||
|
||||
|
||||
class ObservationBatchResponse(ApiModel):
|
||||
updated_count: int
|
||||
items: list[ObservationReviewItem]
|
||||
|
||||
|
||||
class SettlementTransfer(ApiModel):
|
||||
from_user_id: str
|
||||
to_user_id: str
|
||||
amount: Decimal
|
||||
currency: str
|
||||
|
||||
|
||||
class SettlementUserBalance(ApiModel):
|
||||
user_id: str
|
||||
paid: Decimal
|
||||
share: Decimal
|
||||
net: Decimal
|
||||
|
||||
|
||||
class SettlementSummary(ApiModel):
|
||||
household_id: str
|
||||
project_id: str | None
|
||||
currency: str
|
||||
included_event_ids: list[str]
|
||||
excluded_event_ids: list[str]
|
||||
balances: list[SettlementUserBalance]
|
||||
suggested_transfers: list[SettlementTransfer]
|
||||
explanation: list[str]
|
||||
|
||||
|
||||
class ProjectCreate(ApiModel):
|
||||
household_id: str
|
||||
name: str
|
||||
description: str | None = None
|
||||
start_date: date | None = None
|
||||
end_date: date | None = None
|
||||
default_split_rule_id: str | None = None
|
||||
status: ProjectStatus = ProjectStatus.PLANNING
|
||||
currency: str = "EUR"
|
||||
participant_user_ids: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ProjectRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
name: str
|
||||
description: str | None
|
||||
start_date: date | None
|
||||
end_date: date | None
|
||||
default_split_rule_id: str | None
|
||||
status: ProjectStatus
|
||||
currency: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ProjectParticipantCreate(ApiModel):
|
||||
user_id: str
|
||||
role: str = "participant"
|
||||
default_share_percent: Decimal | None = None
|
||||
|
||||
|
||||
class ProjectParticipantRead(ApiModel):
|
||||
id: str
|
||||
project_id: str
|
||||
user_id: str
|
||||
role: str
|
||||
default_share_percent: Decimal | None
|
||||
|
||||
|
||||
class ProjectBudgetLineCreate(ApiModel):
|
||||
category_id: str | None = None
|
||||
name: str
|
||||
budgeted_amount: Decimal = Decimal("0.00")
|
||||
sort_order: int = 0
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class ProjectBudgetLineRead(ApiModel):
|
||||
id: str
|
||||
project_id: str
|
||||
category_id: str | None
|
||||
name: str
|
||||
budgeted_amount: Decimal
|
||||
committed_amount_cached: Decimal | None
|
||||
paid_amount_cached: Decimal | None
|
||||
sort_order: int
|
||||
notes: str | None
|
||||
|
||||
|
||||
class ProjectPlannedItemCreate(ApiModel):
|
||||
budget_line_id: str | None = None
|
||||
description: str
|
||||
estimated_amount: Decimal = Decimal("0.00")
|
||||
committed_amount: Decimal | None = None
|
||||
expected_date: date | None = None
|
||||
due_date: date | None = None
|
||||
expected_payer_account_id: str | None = None
|
||||
split_rule_id: str | None = None
|
||||
planning_status: PlanningStatus = PlanningStatus.IDEA
|
||||
payment_status: PaymentStatus = PaymentStatus.UNPAID
|
||||
reconciliation_status: ReconciliationStatus = ReconciliationStatus.NO_EVIDENCE
|
||||
settlement_status: SettlementStatus = SettlementStatus.UNSETTLED
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class ProjectPlannedItemRead(ApiModel):
|
||||
id: str
|
||||
project_id: str
|
||||
budget_line_id: str | None
|
||||
description: str
|
||||
estimated_amount: Decimal
|
||||
committed_amount: Decimal | None
|
||||
expected_date: date | None
|
||||
due_date: date | None
|
||||
expected_payer_account_id: str | None
|
||||
split_rule_id: str | None
|
||||
planning_status: PlanningStatus
|
||||
payment_status: PaymentStatus
|
||||
reconciliation_status: ReconciliationStatus
|
||||
settlement_status: SettlementStatus
|
||||
notes: str | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class PaymentLineCreate(ApiModel):
|
||||
planned_item_id: str | None = None
|
||||
event_id: str | None = None
|
||||
amount: Decimal
|
||||
currency: str = "EUR"
|
||||
date: date
|
||||
paid_by_user_id: str | None = None
|
||||
payment_account_id: str | None = None
|
||||
source_observation_id: str | None = None
|
||||
status: PaymentLineStatus = PaymentLineStatus.EXPECTED
|
||||
|
||||
|
||||
class PaymentLineRead(ApiModel):
|
||||
id: str
|
||||
planned_item_id: str | None
|
||||
event_id: str | None
|
||||
amount: Decimal
|
||||
currency: str
|
||||
date: date
|
||||
paid_by_user_id: str | None
|
||||
payment_account_id: str | None
|
||||
source_observation_id: str | None
|
||||
status: PaymentLineStatus
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class ProjectSummary(ApiModel):
|
||||
project_id: str
|
||||
currency: str
|
||||
budgeted_total: Decimal
|
||||
committed_total: Decimal
|
||||
paid_total: Decimal
|
||||
reconciled_total: Decimal
|
||||
settled_total: Decimal
|
||||
due_later_total: Decimal
|
||||
remaining_uncommitted_budget: Decimal
|
||||
open_actions: list[str]
|
||||
|
||||
|
||||
class ImportConnectionCreate(ApiModel):
|
||||
household_id: str
|
||||
owner_user_id: str
|
||||
connection_type: ImportConnectionType
|
||||
display_name: str
|
||||
status: ImportConnectionStatus = ImportConnectionStatus.NEEDS_AUTH
|
||||
secret_storage_ref: str | None = None
|
||||
runs_locally: bool = True
|
||||
connector_config_json: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class ImportConnectionUpdate(ApiModel):
|
||||
owner_user_id: str | None = None
|
||||
connection_type: ImportConnectionType | None = None
|
||||
display_name: str | None = None
|
||||
status: ImportConnectionStatus | None = None
|
||||
secret_storage_ref: str | None = None
|
||||
runs_locally: bool | None = None
|
||||
connector_config_json: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class ImportConnectionRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
owner_user_id: str
|
||||
connection_type: ImportConnectionType
|
||||
display_name: str
|
||||
status: ImportConnectionStatus
|
||||
last_sync_at: datetime | None
|
||||
last_error: str | None
|
||||
secret_storage_ref: str | None
|
||||
runs_locally: bool
|
||||
connector_config_json: dict[str, Any] | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ImportRunRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
connection_id: str | None
|
||||
actor_user_id: str | None
|
||||
source_type: str | None
|
||||
status: str
|
||||
imported_count: int
|
||||
duplicate_count: int
|
||||
created_event_count: int
|
||||
skipped_count: int
|
||||
error: str | None
|
||||
summary_json: dict[str, Any] | None
|
||||
started_at: datetime
|
||||
finished_at: datetime | None
|
||||
|
||||
|
||||
class ImportRunDetailRead(ApiModel):
|
||||
run: ImportRunRead
|
||||
observations: list[RawObservationRead] = Field(default_factory=list)
|
||||
events: list[EventRead] = Field(default_factory=list)
|
||||
|
||||
|
||||
class LocalAgentRegister(ApiModel):
|
||||
household_id: str
|
||||
owner_user_id: str
|
||||
display_name: str = "Local connector agent"
|
||||
|
||||
|
||||
class LocalAgentHeartbeat(ApiModel):
|
||||
connection_id: str
|
||||
status: ImportConnectionStatus = ImportConnectionStatus.ACTIVE
|
||||
last_error: str | None = None
|
||||
|
||||
|
||||
class SyncObservationsRequest(ApiModel):
|
||||
connection_id: str
|
||||
observations: list[ObservationImportCreate]
|
||||
|
||||
|
||||
class SyncObservationsResponse(ApiModel):
|
||||
imported_observation_ids: list[str]
|
||||
created_event_ids: list[str]
|
||||
duplicate_observation_ids: list[str]
|
||||
connection_id: str | None = None
|
||||
imported_count: int = 0
|
||||
duplicate_count: int = 0
|
||||
created_event_count: int = 0
|
||||
run: ImportRunRead | None = None
|
||||
|
||||
|
||||
class BackupResult(ApiModel):
|
||||
file_path: str
|
||||
size_bytes: int
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class HouseholdExport(ApiModel):
|
||||
household: dict[str, Any]
|
||||
exported_at: datetime
|
||||
counts: dict[str, int]
|
||||
data: dict[str, list[dict[str, Any]]]
|
||||
|
||||
|
||||
class RecurringCommitmentCreate(ApiModel):
|
||||
household_id: str
|
||||
provider: str
|
||||
description: str | None = None
|
||||
amount_expected: Decimal
|
||||
amount_min: Decimal | None = None
|
||||
amount_max: Decimal | None = None
|
||||
currency: str = "EUR"
|
||||
interval: RecurringInterval
|
||||
next_due_date: date
|
||||
payer_account_id: str | None = None
|
||||
category_id: str | None = None
|
||||
project_id: str | None = None
|
||||
notice_period: str | None = None
|
||||
renewal_date: date | None = None
|
||||
status: RecurringCommitmentStatus = RecurringCommitmentStatus.ACTIVE
|
||||
matching_rule_json: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class RecurringCommitmentUpdate(ApiModel):
|
||||
provider: str | None = None
|
||||
description: str | None = None
|
||||
amount_expected: Decimal | None = None
|
||||
amount_min: Decimal | None = None
|
||||
amount_max: Decimal | None = None
|
||||
currency: str | None = None
|
||||
interval: RecurringInterval | None = None
|
||||
next_due_date: date | None = None
|
||||
payer_account_id: str | None = None
|
||||
category_id: str | None = None
|
||||
project_id: str | None = None
|
||||
notice_period: str | None = None
|
||||
renewal_date: date | None = None
|
||||
status: RecurringCommitmentStatus | None = None
|
||||
matching_rule_json: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class RecurringCommitmentRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
provider: str
|
||||
description: str | None
|
||||
amount_expected: Decimal
|
||||
amount_min: Decimal | None
|
||||
amount_max: Decimal | None
|
||||
currency: str
|
||||
interval: RecurringInterval
|
||||
next_due_date: date
|
||||
payer_account_id: str | None
|
||||
category_id: str | None
|
||||
project_id: str | None
|
||||
notice_period: str | None
|
||||
renewal_date: date | None
|
||||
status: RecurringCommitmentStatus
|
||||
matching_rule_json: dict[str, Any] | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ReconciliationEventSummary(ApiModel):
|
||||
id: str
|
||||
source_type: str | None
|
||||
event_type: str
|
||||
status: str
|
||||
event_date: date
|
||||
amount: Decimal
|
||||
currency: str
|
||||
merchant: str | None
|
||||
counterparty: str | None
|
||||
description: str | None
|
||||
source_reference: str | None
|
||||
provider_transaction_id: str | None
|
||||
observation_id: str | None
|
||||
|
||||
|
||||
class ReconciliationSuggestionRead(ApiModel):
|
||||
id: str
|
||||
kind: str
|
||||
relation_type: RelationType
|
||||
primary_event: ReconciliationEventSummary
|
||||
confirming_event: ReconciliationEventSummary
|
||||
confidence: Decimal
|
||||
reasons: list[str]
|
||||
action: str
|
||||
|
||||
|
||||
class ReconciliationAcceptResponse(ApiModel):
|
||||
accepted: ReconciliationSuggestionRead
|
||||
|
||||
|
||||
class ReconciliationIgnoreRequest(ApiModel):
|
||||
actor_user_id: str | None = None
|
||||
reason: str | None = None
|
||||
|
||||
|
||||
class ReconciliationDecisionRead(ApiModel):
|
||||
id: str
|
||||
household_id: str
|
||||
suggestion_id: str
|
||||
decision: str
|
||||
kind: str
|
||||
relation_type: RelationType
|
||||
primary_event_id: str
|
||||
confirming_event_id: str
|
||||
confidence: Decimal
|
||||
actor_user_id: str | None
|
||||
reason: str | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ReconciliationIgnoreResponse(ApiModel):
|
||||
ignored: ReconciliationSuggestionRead
|
||||
decision: ReconciliationDecisionRead
|
||||
Reference in New Issue
Block a user