From 023612ce0a341808439ba30ca8e867a24482914a Mon Sep 17 00:00:00 2001 From: k1nq Date: Thu, 24 Sep 2026 08:34:13 +0500 Subject: [PATCH] Update manifest.json with new file metadata and add pytest configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated timestamps and AST hashes for multiple files in the manifest.json. - Added new test file backend/tests/test_expected_income.py. - Added documentation files: перево́д_между_своими.md and 0002-fixes.md. - Introduced pytest.ini to configure pytest settings, including test paths and warning filters. --- backend/app/budgeting/router.py | 161 +- backend/app/budgeting/service.py | 213 +- backend/app/imports/adapters/ozon_pdf.py | 6 +- backend/tests/test_adapter_contracts.py | 15 +- backend/tests/test_budget.py | 12 +- backend/tests/test_expected_income.py | 346 + backend/tests/test_import_savings.py | 7 +- backend/tests/test_imports.py | 10 +- backend/tests/test_private_fixtures.py | 3 +- backend/tests/test_savings.py | 5 +- design.pen | 2187 +- docs/questions/перевод_между_своими.md | 3 + docs/tasks/0002-fixes.md | 9 + frontend/package.json | 1 + frontend/pnpm-lock.yaml | 8 + frontend/src/api/endpoints.ts | 8 + frontend/src/api/types.ts | 8 + .../budget/CategoryManagerModal.tsx | 26 +- frontend/src/components/layout/AppLayout.tsx | 4 +- frontend/src/components/ui/Modal.tsx | 13 + frontend/src/hooks/useBudget.ts | 25 +- frontend/src/i18n/locales/en.json | 11 +- frontend/src/i18n/locales/ru.json | 11 +- frontend/src/main.tsx | 8 + frontend/src/pages/BudgetPage.tsx | 59 +- frontend/src/pages/OverviewPage.tsx | 156 +- frontend/src/styles/global.css | 56 +- frontend/src/test/category-manager.test.tsx | 8 +- frontend/src/test/expected-income.test.tsx | 82 + graphify-out/.graphify_labels.json | 67 +- graphify-out/.graphify_labels.json.sig | 2 +- graphify-out/2026-09-23/.graphify_labels.json | 64 +- graphify-out/2026-09-23/GRAPH_REPORT.md | 336 +- graphify-out/2026-09-23/graph.json | 16702 +++++++------ graphify-out/2026-09-23/manifest.json | 126 +- graphify-out/GRAPH_REPORT.md | 339 +- graphify-out/graph.html | 8 +- graphify-out/graph.json | 19354 +++++++++------- graphify-out/manifest.json | 192 +- pytest.ini | 8 + 40 files changed, 23855 insertions(+), 16804 deletions(-) create mode 100644 backend/tests/test_expected_income.py create mode 100644 docs/questions/перевод_между_своими.md create mode 100644 docs/tasks/0002-fixes.md create mode 100644 frontend/src/test/expected-income.test.tsx create mode 100644 pytest.ini diff --git a/backend/app/budgeting/router.py b/backend/app/budgeting/router.py index 551ff1a..42177e8 100644 --- a/backend/app/budgeting/router.py +++ b/backend/app/budgeting/router.py @@ -3,8 +3,8 @@ from collections import defaultdict from datetime import date from typing import Annotated, Literal -from fastapi import APIRouter, Query -from pydantic import BaseModel, Field +from fastapi import APIRouter, Query, Response +from pydantic import BaseModel, ConfigDict, Field from app.budgeting import service from app.categorization import service as categorization @@ -37,10 +37,28 @@ class FundingBody(BaseModel): class ExpectedIncomeBody(BaseModel): - expected_on: date - amount_kopecks: int = Field(gt=0) - source_name: str | None = Field(default=None, max_length=200) - note: str | None = Field(default=None, max_length=500) + model_config = ConfigDict(populate_by_name=True) + + expected_on: date = Field(alias="expectedOn") + amount_kopecks: int = Field(gt=0, alias="amountKopecks") + source_name: str | None = Field(default=None, max_length=200, alias="sourceName") + note: str | None = Field(default=None, max_length=500, alias="note") + + +class ExpectedIncomePatchBody(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + expected_on: date | None = Field(default=None, alias="expectedOn") + amount_kopecks: int | None = Field(default=None, gt=0, alias="amountKopecks") + source_name: str | None = Field(default=None, max_length=200, alias="sourceName") + note: str | None = Field(default=None, max_length=500, alias="note") + + +class ExpectedIncomeMatchBody(BaseModel): + model_config = ConfigDict(populate_by_name=True) + + operation_id: uuid.UUID = Field(alias="operationId") + amount_kopecks: int | None = Field(default=None, gt=0, alias="amountKopecks") def period_for(db: Db, context: Context, year: int, month: int): @@ -71,6 +89,22 @@ def parse_month(value: str) -> tuple[int, int]: return year, month +def expected_income_json(item: dict) -> dict: + return { + "id": item["id"], + "expectedOn": item["expected_on"], + "amountKopecks": item["amount_kopecks"], + "sourceName": item["source_name"], + "note": item["note"], + "matchedKopecks": item["matched_kopecks"], + "status": "matched" + if item["matched_kopecks"] >= item["amount_kopecks"] + else "partially_matched" + if item["matched_kopecks"] + else "expected", + } + + def frontend_summary(state: dict) -> dict: monthly = state["monthly_categories"] envelopes = state["envelopes"] @@ -90,21 +124,7 @@ def frontend_summary(state: dict) -> dict: "availableKopecks": available, "warnings": [{"code": code} for code in state["warnings"]], "blockers": state["close_blockers"], - "expectedIncomes": [ - { - "id": item["id"], - "expectedOn": item["expected_on"], - "amountKopecks": item["amount_kopecks"], - "sourceName": item["source_name"], - "matchedKopecks": item["matched_kopecks"], - "status": "matched" - if item["matched_kopecks"] >= item["amount_kopecks"] - else "partially_matched" - if item["matched_kopecks"] - else "expected", - } - for item in state["expected_incomes"] - ], + "expectedIncomes": [expected_income_json(item) for item in state["expected_incomes"]], } @@ -308,8 +328,20 @@ def fund(year: int, month: int, body: FundingBody, db: Db, context: Context, _cs return {"id": movement.id} +def expected_income_item(db: Db, context: Context, period, income_id: uuid.UUID) -> dict: + items = service.expected_income_items(db, space_id=context.space.id, period=period) + return next(item for item in items if item["id"] == str(income_id)) + + +@router.get("/{year}/{month}/expected-incomes") +def expected_incomes(year: int, month: int, db: Db, context: Context) -> list[dict]: + period = period_for(db, context, year, month) + items = service.expected_income_items(db, space_id=context.space.id, period=period) + return [expected_income_json(item) for item in items] + + @router.post("/{year}/{month}/expected-incomes", status_code=201) -def expected_income( +def create_expected_income( year: int, month: int, body: ExpectedIncomeBody, @@ -325,7 +357,90 @@ def expected_income( period=period, **body.model_dump(), ) - return {"id": income.id} + return expected_income_json(expected_income_item(db, context, period, income.id)) + + +@router.patch("/{year}/{month}/expected-incomes/{income_id}") +def patch_expected_income( + year: int, + month: int, + income_id: uuid.UUID, + body: ExpectedIncomePatchBody, + db: Db, + context: Context, + _csrf: Csrf, +) -> dict: + period = period_for(db, context, year, month) + service.update_expected_income( + db, + space_id=context.space.id, + user=context.user, + period=period, + income_id=income_id, + changes=body.model_dump(exclude_unset=True), + ) + return expected_income_json(expected_income_item(db, context, period, income_id)) + + +@router.delete("/{year}/{month}/expected-incomes/{income_id}", status_code=204) +def delete_expected_income( + year: int, + month: int, + income_id: uuid.UUID, + db: Db, + context: Context, + _csrf: Csrf, +) -> Response: + period = period_for(db, context, year, month) + service.delete_expected_income( + db, space_id=context.space.id, user=context.user, period=period, income_id=income_id + ) + return Response(status_code=204) + + +@router.post("/{year}/{month}/expected-incomes/{income_id}/match", status_code=201) +def match_expected_income( + year: int, + month: int, + income_id: uuid.UUID, + body: ExpectedIncomeMatchBody, + db: Db, + context: Context, + _csrf: Csrf, +) -> dict: + period = period_for(db, context, year, month) + service.match_expected_income( + db, + space_id=context.space.id, + user=context.user, + period=period, + expected_income_id=income_id, + operation_id=body.operation_id, + amount_kopecks=body.amount_kopecks, + ) + return expected_income_json(expected_income_item(db, context, period, income_id)) + + +@router.delete("/{year}/{month}/expected-incomes/{income_id}/match/{operation_id}", status_code=204) +def unmatch_expected_income( + year: int, + month: int, + income_id: uuid.UUID, + operation_id: uuid.UUID, + db: Db, + context: Context, + _csrf: Csrf, +) -> Response: + period = period_for(db, context, year, month) + service.unmatch_expected_income( + db, + space_id=context.space.id, + user=context.user, + period=period, + expected_income_id=income_id, + operation_id=operation_id, + ) + return Response(status_code=204) @router.post("/{year}/{month}/close") diff --git a/backend/app/budgeting/service.py b/backend/app/budgeting/service.py index 11bb16f..1b98bb2 100644 --- a/backend/app/budgeting/service.py +++ b/backend/app/budgeting/service.py @@ -422,17 +422,8 @@ def compute_period_state(db: Session, *, space_id: uuid.UUID, period: BudgetPeri row["planned"] = planned_by_cat.get(cid, 0) planned_total = sum(planned_by_cat.values()) - expected = db.query(ExpectedIncome).filter_by(period_id=period.id).all() - expected_total = sum(e.amount_kopecks for e in expected) - matched_by_expected: dict[Any, int] = defaultdict(int) - for m in ( - db.query(ExpectedIncomeMatch) - .filter(ExpectedIncomeMatch.expected_income_id.in_([e.id for e in expected] or [None])) - .all() - if expected - else [] - ): - matched_by_expected[m.expected_income_id] += m.amount_kopecks + expected_items = expected_income_items(db, space_id=space_id, period=period) + expected_total = sum(item["amount_kopecks"] for item in expected_items) uncategorized_count = sum(1 for op in ops if op.type == "expense" and op.category_id is None) negative_envelopes = [ @@ -465,16 +456,7 @@ def compute_period_state(db: Session, *, space_id: uuid.UUID, period: BudgetPeri "income_total": income_total, "planned_total": planned_total, "expected_income_total": expected_total, - "expected_incomes": [ - { - "id": str(e.id), - "expected_on": e.expected_on.isoformat(), - "amount_kopecks": e.amount_kopecks, - "source_name": e.source_name, - "matched_kopecks": matched_by_expected.get(e.id, 0), - } - for e in expected - ], + "expected_incomes": expected_items, "monthly_categories": monthly_rows, "envelopes": envelope_rows, "credit_reserves": credit_reserves, @@ -717,6 +699,65 @@ def set_assignments( return result +def get_expected_income( + db: Session, *, space_id: uuid.UUID, income_id: uuid.UUID +) -> ExpectedIncome: + income = db.query(ExpectedIncome).filter_by(id=income_id, space_id=space_id).one_or_none() + if income is None: + raise not_found("BUDGET_EXPECTED_INCOME_NOT_FOUND", "Expected income not found") + return income + + +def get_period_expected_income( + db: Session, *, space_id: uuid.UUID, period: BudgetPeriod, income_id: uuid.UUID +) -> ExpectedIncome: + """Load an expected income scoped to the route's year/month period.""" + income = get_expected_income(db, space_id=space_id, income_id=income_id) + if income.period_id != period.id: + raise not_found("BUDGET_EXPECTED_INCOME_NOT_FOUND", "Expected income not found") + return income + + +def _ensure_expected_date_in_period(period: BudgetPeriod, expected_on: date) -> None: + start, end = period_bounds(period.year, period.month) + if not start <= expected_on < end: + raise bad_request( + "BUDGET_EXPECTED_INCOME_DATE_OUTSIDE", + "Expected income date must fall within the budget period month", + ) + + +def expected_income_items( + db: Session, *, space_id: uuid.UUID, period: BudgetPeriod +) -> list[dict[str, Any]]: + """Aggregate expected incomes of the period with matched totals.""" + expected = ( + db.query(ExpectedIncome) + .filter_by(period_id=period.id) + .order_by(ExpectedIncome.expected_on, ExpectedIncome.created_at) + .all() + ) + matched_by_expected: dict[Any, int] = defaultdict(int) + if expected: + for match in ( + db.query(ExpectedIncomeMatch) + .filter(ExpectedIncomeMatch.expected_income_id.in_([e.id for e in expected])) + .all() + ): + matched_by_expected[match.expected_income_id] += match.amount_kopecks + return [ + { + "id": str(e.id), + "expected_on": e.expected_on.isoformat(), + "amount_kopecks": e.amount_kopecks, + "source_name": e.source_name, + "note": e.note, + "matched_kopecks": matched_by_expected.get(e.id, 0), + } + for e in expected + ] + + def add_expected_income( db: Session, *, @@ -731,6 +772,7 @@ def add_expected_income( require_open(period) if amount_kopecks <= 0: raise bad_request("MONEY_AMOUNT_MUST_BE_POSITIVE", "Amount must be positive") + _ensure_expected_date_in_period(period, expected_on) income = ExpectedIncome( space_id=space_id, period_id=period.id, @@ -741,6 +783,13 @@ def add_expected_income( ) db.add(income) db.flush() + audit.record( + db, + event_type="budget.expected_income_created", + space_id=space_id, + user_id=user.id, + detail={"expected_income_id": str(income.id), "period_id": str(period.id)}, + ) return income @@ -749,15 +798,14 @@ def match_expected_income( *, space_id: uuid.UUID, user: User, + period: BudgetPeriod, expected_income_id: uuid.UUID, operation_id: uuid.UUID, amount_kopecks: int | None = None, ) -> ExpectedIncomeMatch: - expected = ( - db.query(ExpectedIncome).filter_by(id=expected_income_id, space_id=space_id).one_or_none() + expected = get_period_expected_income( + db, space_id=space_id, period=period, income_id=expected_income_id ) - if expected is None: - raise not_found("BUDGET_EXPECTED_INCOME_NOT_FOUND", "Expected income not found") operation = db.query(Operation).filter_by(id=operation_id, space_id=space_id).one_or_none() if operation is None or operation.type != "income" or operation.status != "confirmed": raise not_found("BUDGET_INCOME_OPERATION_NOT_FOUND", "Confirmed income operation not found") @@ -776,15 +824,128 @@ def match_expected_income( ) match = ExpectedIncomeMatch( space_id=space_id, - expected_income_id=expected.id, + expected_income_id=expected_income_id, operation_id=operation.id, amount_kopecks=amount, ) db.add(match) db.flush() + audit.record( + db, + event_type="budget.expected_income_matched", + space_id=space_id, + user_id=user.id, + detail={ + "expected_income_id": str(expected_income_id), + "operation_id": str(operation.id), + "amount_kopecks": amount, + }, + ) return match +def unmatch_expected_income( + db: Session, + *, + space_id: uuid.UUID, + user: User, + period: BudgetPeriod, + expected_income_id: uuid.UUID, + operation_id: uuid.UUID, +) -> None: + get_period_expected_income(db, space_id=space_id, period=period, income_id=expected_income_id) + match = ( + db.query(ExpectedIncomeMatch) + .filter_by( + space_id=space_id, expected_income_id=expected_income_id, operation_id=operation_id + ) + .one_or_none() + ) + if match is None: + raise not_found("BUDGET_MATCH_NOT_FOUND", "Expected income match not found") + db.delete(match) + db.flush() + audit.record( + db, + event_type="budget.expected_income_unmatched", + space_id=space_id, + user_id=user.id, + detail={ + "expected_income_id": str(expected_income_id), + "operation_id": str(operation_id), + }, + ) + + +def update_expected_income( + db: Session, + *, + space_id: uuid.UUID, + user: User, + period: BudgetPeriod, + income_id: uuid.UUID, + changes: dict[str, Any], +) -> ExpectedIncome: + """Partially update expected_on/amount_kopecks/source_name/note of one entry.""" + require_open(period) + income = get_period_expected_income(db, space_id=space_id, period=period, income_id=income_id) + if "expected_on" in changes: + expected_on = changes["expected_on"] + if expected_on is None: + raise bad_request( + "BUDGET_EXPECTED_INCOME_DATE_REQUIRED", "Expected date cannot be removed" + ) + _ensure_expected_date_in_period(period, expected_on) + income.expected_on = expected_on + if "amount_kopecks" in changes: + amount = changes["amount_kopecks"] + if amount is None or amount <= 0: + raise bad_request("MONEY_AMOUNT_MUST_BE_POSITIVE", "Amount must be positive") + income.amount_kopecks = amount + if "source_name" in changes: + income.source_name = changes["source_name"] + if "note" in changes: + income.note = changes["note"] + db.flush() + audit.record( + db, + event_type="budget.expected_income_updated", + space_id=space_id, + user_id=user.id, + detail={ + "expected_income_id": str(income.id), + "fields": sorted( + key + for key in changes + if key in ("expected_on", "amount_kopecks", "source_name", "note") + ), + }, + ) + return income + + +def delete_expected_income( + db: Session, + *, + space_id: uuid.UUID, + user: User, + period: BudgetPeriod, + income_id: uuid.UUID, +) -> None: + require_open(period) + income = get_period_expected_income(db, space_id=space_id, period=period, income_id=income_id) + detail = {"expected_income_id": str(income.id), "period_id": str(period.id)} + db.delete(income) + db.flush() + audit.record( + db, + event_type="budget.expected_income_deleted", + space_id=space_id, + user_id=user.id, + detail=detail, + ) + + def fund( db: Session, *, diff --git a/backend/app/imports/adapters/ozon_pdf.py b/backend/app/imports/adapters/ozon_pdf.py index 47220fc..b4a5019 100644 --- a/backend/app/imports/adapters/ozon_pdf.py +++ b/backend/app/imports/adapters/ozon_pdf.py @@ -170,7 +170,7 @@ class OzonDebitPdfAdapter: def parse(self, raw: bytes) -> StatementDraft: pages_text: list[str] = [] - pages_tables: list[list[list[list[object]]]] = [] + pages_tables: list[list[list[list[str | None]]]] = [] with open_pdf(raw) as pdf: if not pdf.pages: raise UnsupportedStatementLayout("PDF has no pages") @@ -186,7 +186,7 @@ class OzonDebitPdfAdapter: return self._draft_from_extracted(pages_text, pages_tables) def _draft_from_extracted( - self, pages_text: list[str], pages_tables: list[list[list[list[object]]]] + self, pages_text: list[str], pages_tables: list[list[list[list[str | None]]]] ) -> StatementDraft: page_zero = _ozon_normalize(pages_text[0]) if self.bank_marker not in page_zero or self.title_marker not in page_zero: @@ -240,7 +240,7 @@ class OzonDebitPdfAdapter: raise UnsupportedStatementLayout(f"Ozon {what} total line not found") return match.group(1) - def _table_row(self, cells: list[object], row_ref: str) -> SourceRow | None: + def _table_row(self, cells: list[str | None], row_ref: str) -> SourceRow | None: if cells is None: raise UnsupportedStatementLayout("unexpected Ozon table row shape") texts = [_ozon_cell(cell) for cell in cells] diff --git a/backend/tests/test_adapter_contracts.py b/backend/tests/test_adapter_contracts.py index d5c8700..b27ba54 100644 --- a/backend/tests/test_adapter_contracts.py +++ b/backend/tests/test_adapter_contracts.py @@ -7,6 +7,7 @@ suite (tests/test_private_fixtures.py, marker `private_fixtures`). import io from datetime import date +from typing import Any import pytest from openpyxl import Workbook @@ -39,7 +40,7 @@ NBSP = "\u00a0" def make_source_row(**overrides: object) -> SourceRow: - values: dict[str, object] = { + values: dict[str, Any] = { "external_id": None, "occurred_on": date(2026, 1, 1), "posted_on": date(2026, 1, 2), @@ -52,11 +53,11 @@ def make_source_row(**overrides: object) -> SourceRow: "row_ref": "row1", } values.update(overrides) - return SourceRow(**values) # type: ignore[arg-type] + return SourceRow(**values) def make_draft(**overrides: object) -> StatementDraft: - values: dict[str, object] = { + values: dict[str, Any] = { "adapter_id": "alfa_debit_xlsx", "parser_version": ALFA_DEBIT_XLSX_VERSION, "bank_code": "alfa", @@ -70,7 +71,7 @@ def make_draft(**overrides: object) -> StatementDraft: "rows": (), } values.update(overrides) - return StatementDraft(**values) # type: ignore[arg-type] + return StatementDraft(**values) class TestBaseContract: @@ -560,7 +561,7 @@ class TestAlfaSavingsRule: None, "416,90 RUR", ] - savings_row = [ + savings_row: list[object] = [ "03.09.2026", "03.09.2026", None, @@ -603,7 +604,7 @@ class TestAlfaSavingsRule: assert all(not row.savings_transfer for row in draft.rows) -def ozon_extracted() -> tuple[list[str], list[list[list[object]]]]: +def ozon_extracted() -> tuple[list[str], list[list[list[list[str | None]]]]]: pages_text = [ "\n".join( [ @@ -623,7 +624,7 @@ def ozon_extracted() -> tuple[list[str], list[list[list[object]]]]: ] ), ] - pages_tables = [ + pages_tables: list[list[list[list[str | None]]]] = [ [ [ [ diff --git a/backend/tests/test_budget.py b/backend/tests/test_budget.py index 7cfffd8..9c765f6 100644 --- a/backend/tests/test_budget.py +++ b/backend/tests/test_budget.py @@ -88,16 +88,22 @@ def test_default_mcc_categories_are_budgetable_and_editable_mapping(db: Session) occurred_on=date(2026, 5, 2), category_id=others.id, ) - assert categorization.category_for_mcc(db, space_id=space.id, code=5999).id == others.id + groceries_match = categorization.category_for_mcc(db, space_id=space.id, code=5999) + assert groceries_match is not None + assert groceries_match.id == others.id custom = create_category(db, space_id=space.id, user=user, kind="monthly", name="My shops") codes = categorization.set_category_mcc_codes( db, space_id=space.id, category_id=custom.id, codes=[5999, 5994] ) assert codes == [5994, 5999] - assert categorization.category_for_mcc(db, space_id=space.id, code=5999).id == custom.id + custom_match = categorization.category_for_mcc(db, space_id=space.id, code=5999) + assert custom_match is not None + assert custom_match.id == custom.id custom.archived = True - assert categorization.category_for_mcc(db, space_id=space.id, code=5999).id == others.id + fallback_match = categorization.category_for_mcc(db, space_id=space.id, code=5999) + assert fallback_match is not None + assert fallback_match.id == others.id custom.archived = False with pytest.raises(AppError) as exc: categorization.set_category_mcc_codes( diff --git a/backend/tests/test_expected_income.py b/backend/tests/test_expected_income.py new file mode 100644 index 0000000..0c86eb0 --- /dev/null +++ b/backend/tests/test_expected_income.py @@ -0,0 +1,346 @@ +from datetime import date + +import pytest +from fastapi.testclient import TestClient +from sqlalchemy.orm import Session + +from app.budgeting.service import ( + add_expected_income, + close_period, + delete_expected_income, + expected_income_items, + get_or_create_period, + match_expected_income, + unmatch_expected_income, + update_expected_income, +) +from app.errors import AppError +from app.identity.models import User +from app.ledger.service import create_account, create_income +from app.spaces.service import create_space + + +def seed(db: Session): + user = User(email="expected@example.test", password_hash="unused-in-domain-tests") + db.add(user) + db.flush() + return user, create_space(db, user=user, name="Expected") + + +def test_expected_income_crud_and_validation(db: Session) -> None: + user, space = seed(db) + period = get_or_create_period(db, space_id=space.id, year=2026, month=9) + with pytest.raises(AppError) as exc: + add_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_on=date(2026, 10, 1), + amount_kopecks=1_000, + source_name=None, + ) + assert exc.value.code == "BUDGET_EXPECTED_INCOME_DATE_OUTSIDE" + + income = add_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_on=date(2026, 9, 25), + amount_kopecks=120_000, + source_name="Salary", + note="net", + ) + assert expected_income_items(db, space_id=space.id, period=period) == [ + { + "id": str(income.id), + "expected_on": "2026-09-25", + "amount_kopecks": 120_000, + "source_name": "Salary", + "note": "net", + "matched_kopecks": 0, + } + ] + + update_expected_income( + db, + space_id=space.id, + user=user, + period=period, + income_id=income.id, + changes={"amount_kopecks": 130_000, "note": None, "expected_on": date(2026, 9, 30)}, + ) + refreshed = expected_income_items(db, space_id=space.id, period=period)[0] + assert refreshed["amount_kopecks"] == 130_000 + assert refreshed["expected_on"] == "2026-09-30" + assert refreshed["note"] is None + + with pytest.raises(AppError) as exc: + update_expected_income( + db, + space_id=space.id, + user=user, + period=period, + income_id=income.id, + changes={"expected_on": date(2026, 8, 31)}, + ) + assert exc.value.code == "BUDGET_EXPECTED_INCOME_DATE_OUTSIDE" + with pytest.raises(AppError) as exc: + update_expected_income( + db, + space_id=space.id, + user=user, + period=period, + income_id=income.id, + changes={"amount_kopecks": 0}, + ) + assert exc.value.code == "MONEY_AMOUNT_MUST_BE_POSITIVE" + + delete_expected_income(db, space_id=space.id, user=user, period=period, income_id=income.id) + assert expected_income_items(db, space_id=space.id, period=period) == [] + + +def test_expected_income_match_unmatch_and_delete_cascade(db: Session) -> None: + user, space = seed(db) + period = get_or_create_period(db, space_id=space.id, year=2026, month=9) + account = create_account( + db, + space_id=space.id, + user=user, + name="Wallet", + kind="cash", + opened_on=date(2026, 9, 1), + ) + income = add_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_on=date(2026, 9, 25), + amount_kopecks=100_000, + source_name="Salary", + ) + operation = create_income( + db, + space_id=space.id, + user=user, + account_id=account.id, + amount_kopecks=40_000, + occurred_on=date(2026, 9, 20), + ) + with pytest.raises(AppError) as exc: + match_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_income_id=income.id, + operation_id=operation.id, + amount_kopecks=50_000, + ) + assert exc.value.code == "BUDGET_MATCH_AMOUNT_INVALID" + + match_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_income_id=income.id, + operation_id=operation.id, + ) + assert ( + expected_income_items(db, space_id=space.id, period=period)[0]["matched_kopecks"] == 40_000 + ) + + other_period = get_or_create_period(db, space_id=space.id, year=2026, month=10) + with pytest.raises(AppError) as exc: + match_expected_income( + db, + space_id=space.id, + user=user, + period=other_period, + expected_income_id=income.id, + operation_id=operation.id, + ) + assert exc.value.code == "BUDGET_EXPECTED_INCOME_NOT_FOUND" + + unmatch_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_income_id=income.id, + operation_id=operation.id, + ) + assert expected_income_items(db, space_id=space.id, period=period)[0]["matched_kopecks"] == 0 + with pytest.raises(AppError) as exc: + unmatch_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_income_id=income.id, + operation_id=operation.id, + ) + assert exc.value.code == "BUDGET_MATCH_NOT_FOUND" + + match_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_income_id=income.id, + operation_id=operation.id, + ) + delete_expected_income(db, space_id=space.id, user=user, period=period, income_id=income.id) + from app.budgeting.models import ExpectedIncomeMatch + + assert db.query(ExpectedIncomeMatch).filter_by(space_id=space.id).count() == 0 + + +def test_expected_income_mutations_guard_closed_period(db: Session) -> None: + user, space = seed(db) + period = get_or_create_period(db, space_id=space.id, year=2026, month=9) + income = add_expected_income( + db, + space_id=space.id, + user=user, + period=period, + expected_on=date(2026, 9, 5), + amount_kopecks=5_000, + source_name=None, + ) + close_period(db, space_id=space.id, user=user, period=period) + with pytest.raises(AppError) as exc: + update_expected_income( + db, + space_id=space.id, + user=user, + period=period, + income_id=income.id, + changes={"amount_kopecks": 1}, + ) + assert exc.value.code == "BUDGET_PERIOD_CLOSED" + with pytest.raises(AppError) as exc: + delete_expected_income(db, space_id=space.id, user=user, period=period, income_id=income.id) + assert exc.value.code == "BUDGET_PERIOD_CLOSED" + + +def _login(client: TestClient) -> dict[str, str]: + invite = client.post( + "/api/v1/admin/invitations", + headers={"X-Admin-Token": "test-admin-token"}, + json={"email": "Expected@Example.com"}, + ) + assert invite.status_code == 201, invite.text + accepted = client.post( + "/api/v1/auth/invitations/accept", + json={ + "token": invite.json()["token"], + "password": "a-long-password-for-tests", + "fullName": "Test Person", + "locale": "en", + }, + ) + assert accepted.status_code == 201, accepted.text + return {"X-CSRF-Token": client.cookies["csrf_token"]} + + +def test_expected_income_month_api_crud_and_summary(client: TestClient) -> None: + headers = _login(client) + account = client.post( + "/api/v1/accounts", + headers=headers, + json={ + "name": "Wallet", + "type": "cash", + "openedOn": "2026-09-01", + "openingBalanceKopecks": 0, + }, + ) + assert account.status_code == 201, account.text + account_id = account.json()["id"] + + created = client.post( + "/api/v1/budget/2026/9/expected-incomes", + headers=headers, + json={"expectedOn": "2026-09-25", "amountKopecks": 120_000, "sourceName": "Salary"}, + ) + assert created.status_code == 201, created.text + income = created.json() + assert income["status"] == "expected" + assert income["amountKopecks"] == 120_000 + + legacy = client.post( + "/api/v1/budget/2026/9/expected-incomes", + headers=headers, + json={"expected_on": "2026-09-26", "amount_kopecks": 1_000, "source_name": "Gift"}, + ) + assert legacy.status_code == 201, legacy.text + assert legacy.json()["amountKopecks"] == 1_000 + legacy_removed = client.delete( + f"/api/v1/budget/2026/9/expected-incomes/{legacy.json()['id']}", headers=headers + ) + assert legacy_removed.status_code == 204, legacy_removed.text + + listed = client.get("/api/v1/budget/2026/9/expected-incomes") + assert listed.status_code == 200, listed.text + assert [item["id"] for item in listed.json()] == [income["id"]] + + patched = client.patch( + f"/api/v1/budget/2026/9/expected-incomes/{income['id']}", + headers=headers, + json={"amountKopecks": 130_000, "note": None}, + ) + assert patched.status_code == 200, patched.text + assert patched.json()["amountKopecks"] == 130_000 + assert patched.json()["note"] is None + + rejected = client.patch( + f"/api/v1/budget/2026/9/expected-incomes/{income['id']}", + headers=headers, + json={"expectedOn": "2026-10-01"}, + ) + assert rejected.status_code == 400, rejected.text + assert rejected.json()["error"]["code"] == "BUDGET_EXPECTED_INCOME_DATE_OUTSIDE" + + operation = client.post( + "/api/v1/operations", + headers=headers, + json={ + "kind": "income", + "amountKopecks": 80_000, + "accountId": account_id, + "occurredOn": "2026-09-20", + }, + ) + assert operation.status_code == 201, operation.text + operation_id = operation.json()["id"] + + matched = client.post( + f"/api/v1/budget/2026/9/expected-incomes/{income['id']}/match", + headers=headers, + json={"operationId": operation_id}, + ) + assert matched.status_code == 201, matched.text + assert matched.json()["matchedKopecks"] == 80_000 + assert matched.json()["status"] == "partially_matched" + + summary = client.get("/api/v1/budget/summary", params={"month": "2026-09"}) + assert summary.status_code == 200, summary.text + body = summary.json() + assert body["expectedIncomes"][0]["status"] == "partially_matched" + assert body["projectedPoolKopecks"] == 130_000 + + unmatched = client.delete( + f"/api/v1/budget/2026/9/expected-incomes/{income['id']}/match/{operation_id}", + headers=headers, + ) + assert unmatched.status_code == 204, unmatched.text + + deleted = client.delete( + f"/api/v1/budget/2026/9/expected-incomes/{income['id']}", headers=headers + ) + assert deleted.status_code == 204, deleted.text + assert client.get("/api/v1/budget/2026/9/expected-incomes").json() == [] diff --git a/backend/tests/test_import_savings.py b/backend/tests/test_import_savings.py index 1752233..f4e57f4 100644 --- a/backend/tests/test_import_savings.py +++ b/backend/tests/test_import_savings.py @@ -3,10 +3,12 @@ import uuid from datetime import date from types import SimpleNamespace +from typing import cast import pytest from sqlalchemy.orm import Session +from app.dependencies import RequestContext from app.errors import AppError from app.identity.models import User from app.imports import router as imports_router @@ -132,6 +134,7 @@ def test_confirm_creates_savings_transfer_with_system_category(db: Session) -> N db.flush() savings_account = get_savings_account(db, space_id=space.id) + assert savings_account is not None operations = db.query(Operation).filter_by(space_id=space.id).all() assert len(operations) == 1 transfer = operations[0] @@ -233,6 +236,7 @@ def test_statement_mapping_rejects_system_account(db: Session) -> None: user, space, account = seed(db) document, _run = make_document(db, space, account, user=user) savings_account = get_savings_account(db, space_id=space.id) + assert savings_account is not None with pytest.raises(AppError) as exc: service.set_review_confirmation( @@ -358,7 +362,7 @@ def test_unresolved_hold_counts_and_month_filter(db: Session) -> None: assert service.unresolved_hold_counts( db, space_id=space.id, document_ids=[document.id], month=may ) == {document.id: 1} - context = SimpleNamespace(space=space) + context = cast(RequestContext, SimpleNamespace(space=space)) july_items = imports_router.imports(db, context, month="2026-07") assert july_items[0]["id"] == document.id assert july_items[0]["unresolvedHoldCount"] == 0 @@ -376,6 +380,7 @@ def test_unresolved_hold_counts_and_month_filter(db: Session) -> None: def test_confirm_savings_transfer_rejects_savings_statement_account(db: Session) -> None: user, space, account = seed(db) savings_account = get_savings_account(db, space_id=space.id) + assert savings_account is not None document, run = make_document(db, space, savings_account, user=user) document.account_id = savings_account.id add_record(db, document, run, description=SAVINGS_PHRASE) diff --git a/backend/tests/test_imports.py b/backend/tests/test_imports.py index 41008a8..0f2c9e2 100644 --- a/backend/tests/test_imports.py +++ b/backend/tests/test_imports.py @@ -2,10 +2,12 @@ import uuid from contextlib import contextmanager from datetime import date from types import SimpleNamespace +from typing import cast import pytest from sqlalchemy.orm import Session +from app.dependencies import RequestContext from app.errors import AppError from app.identity.models import User from app.imports import router as imports_router @@ -129,7 +131,9 @@ def test_import_mcc_assigns_default_category_and_label( service.confirm_document(db, space_id=space.id, document_id=document.id, user=user) operation = db.query(Operation).filter_by(space_id=space.id).one() - assert db.get(Category, operation.category_id).system_key == system_key + category = db.get(Category, operation.category_id) + assert category is not None + assert category.system_key == system_key def test_confirm_rejects_arithmetic_mismatch(db: Session) -> None: @@ -467,7 +471,9 @@ def test_import_detail_exposes_pending_candidate_and_blocker(db: Session) -> Non db.add(candidate) db.flush() - response = imports_router.detail(document.id, db, SimpleNamespace(space=space)) + response = imports_router.detail( + document.id, db, cast(RequestContext, SimpleNamespace(space=space)) + ) assert response["rows"][0]["decision"] == "pending" assert response["rows"][0]["candidates"] == [ diff --git a/backend/tests/test_private_fixtures.py b/backend/tests/test_private_fixtures.py index 529df9a..857731b 100644 --- a/backend/tests/test_private_fixtures.py +++ b/backend/tests/test_private_fixtures.py @@ -20,6 +20,7 @@ Privacy contract (docs/parsers/private-fixture-gate.md): import json import os from pathlib import Path +from typing import NoReturn import pytest @@ -75,7 +76,7 @@ def _check(ok: bool, name: str, what: str) -> None: assert ok, f"{name}: {what} mismatch" -def _fail(name: str, message: str) -> None: +def _fail(name: str, message: str) -> NoReturn: pytest.fail(f"{name}: {message}", pytrace=False) diff --git a/backend/tests/test_savings.py b/backend/tests/test_savings.py index 2f31122..50fc44b 100644 --- a/backend/tests/test_savings.py +++ b/backend/tests/test_savings.py @@ -98,6 +98,7 @@ def test_adjust_balance_creates_single_signed_posting(db: Session) -> None: assert postings[0].amount_kopecks == -25_000 assert account_balance(db, account) == 475_000 event = db.query(AuditEvent).filter_by(event_type="account.balance_adjusted").one() + assert event.detail is not None assert event.detail["old_balance_kopecks"] == 500_000 assert event.detail["new_balance_kopecks"] == 475_000 assert event.detail["delta_kopecks"] == -25_000 @@ -295,12 +296,14 @@ def test_convert_rejects_income_refund_transfer_and_double_conversion( convert_expense_to_savings(db, space_id=space.id, user=user, operation_id=expense.id) assert exc.value.code == "LEDGER_SAVINGS_CONVERT_INVALID" + savings_account = get_savings_account(db, space_id=space.id) + assert savings_account is not None transfer = create_transfer( db, space_id=space.id, user=user, source_account_id=account.id, - target_account_id=get_savings_account(db, space_id=space.id).id, + target_account_id=savings_account.id, amount_kopecks=1_000, occurred_on=date(2026, 3, 6), ) diff --git a/design.pen b/design.pen index 716eed1..2a1f5dd 100644 --- a/design.pen +++ b/design.pen @@ -4093,895 +4093,859 @@ }, { "type": "frame", - "id": "f3aMV", - "name": "Overview Working Row", + "id": "ExJy8", + "name": "Month Categories and Expected Income", "width": "fill_container", - "height": 330, - "gap": 26, + "height": "fill_container", + "gap": 20, "children": [ { "type": "frame", - "id": "D2dCW", - "name": "Month Story", + "id": "fd4Xr", + "name": "Budget Categories", "width": "fill_container", "height": "fill_container", + "fill": "$white", + "stroke": "$line", + "strokeWidth": 1, "layout": "vertical", - "gap": 14, "children": [ { "type": "frame", - "id": "b9mjY5", - "name": "Month Story Header", + "id": "x5WgC", + "name": "Budget Categories Header", "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "end", - "children": [ - { - "type": "text", - "id": "BweUo", - "name": "Month Story Title", - "fill": "$ink", - "content": "How the month is moving", - "fontFamily": "$font-ui", - "fontSize": 20, - "fontWeight": "600" - }, - { - "type": "text", - "id": "KgB3h", - "name": "Month Story Meta", - "fill": "$blue", - "content": "LIVE STATE", - "fontFamily": "$font-data", - "fontSize": 9, - "fontWeight": "700", - "letterSpacing": 0.8 - } - ] - }, - { - "type": "frame", - "id": "DnPoy", - "name": "Month Story Flow", - "width": "fill_container", - "height": "fill_container", + "height": 48, + "fill": "#EFEEE9", "stroke": "$line", - "strokeWidth": { - "top": 1, - "right": 1, - "left": 1 - }, - "layout": "vertical", - "children": [ - { - "type": "frame", - "id": "Xffq6", - "name": "Story Step 01", - "width": "fill_container", - "height": "fill_container", - "stroke": "$line", - "strokeWidth": { - "bottom": 1 - }, - "gap": 16, - "padding": [ - 0, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "BjR6P", - "name": "Story Step Index 01", - "fill": "$blue", - "content": "01", - "fontFamily": "$font-data", - "fontSize": 10, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "S3Kokm", - "name": "Story Step Copy 01", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "mNmNP", - "name": "Story Step Title 01", - "fill": "$ink", - "content": "Carry + actual income", - "fontFamily": "$font-ui", - "fontSize": 13, - "fontWeight": "600" - }, - { - "type": "text", - "id": "pb3Zp", - "name": "Story Step Detail 01", - "fill": "$muted", - "content": "General pool", - "fontFamily": "$font-ui", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "ot2O3", - "name": "Story Step Value 01", - "fill": "$ink", - "content": "₽155 420", - "fontFamily": "$font-data", - "fontSize": 14, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "A6ySZ", - "name": "Story Step 02", - "width": "fill_container", - "height": "fill_container", - "stroke": "$line", - "strokeWidth": { - "bottom": 1 - }, - "gap": 16, - "padding": [ - 0, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "T6MKb", - "name": "Story Step Index 02", - "fill": "$blue", - "content": "02", - "fontFamily": "$font-data", - "fontSize": 10, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "F9O1cG", - "name": "Story Step Copy 02", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "xBdDW", - "name": "Story Step Title 02", - "fill": "$ink", - "content": "Funded to categories", - "fontFamily": "$font-ui", - "fontSize": 13, - "fontWeight": "600" - }, - { - "type": "text", - "id": "FT2c1", - "name": "Story Step Detail 02", - "fill": "$muted", - "content": "Planned ≠ funded", - "fontFamily": "$font-ui", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "s0Iai9", - "name": "Story Step Value 02", - "fill": "$ink", - "content": "−₽94 000", - "fontFamily": "$font-data", - "fontSize": 14, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "P7WCp", - "name": "Story Step 03", - "width": "fill_container", - "height": "fill_container", - "stroke": "$line", - "strokeWidth": { - "bottom": 1 - }, - "gap": 16, - "padding": [ - 0, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "GYv6O", - "name": "Story Step Index 03", - "fill": "$blue", - "content": "03", - "fontFamily": "$font-data", - "fontSize": 10, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "Qyk7X", - "name": "Story Step Copy 03", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "jm6nw", - "name": "Story Step Title 03", - "fill": "$ink", - "content": "Uncategorized expenses", - "fontFamily": "$font-ui", - "fontSize": 13, - "fontWeight": "600" - }, - { - "type": "text", - "id": "fmFjg", - "name": "Story Step Detail 03", - "fill": "$muted", - "content": "Needs attention", - "fontFamily": "$font-ui", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "hBU1b", - "name": "Story Step Value 03", - "fill": "$amber", - "content": "−₽4 260", - "fontFamily": "$font-data", - "fontSize": 14, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "nLV9G", - "name": "Story Step 04", - "width": "fill_container", - "height": "fill_container", - "stroke": "$line", - "strokeWidth": { - "bottom": 1 - }, - "gap": 16, - "padding": [ - 0, - 16 - ], - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ElrkF", - "name": "Story Step Index 04", - "fill": "$blue", - "content": "04", - "fontFamily": "$font-data", - "fontSize": 10, - "fontWeight": "700" - }, - { - "type": "frame", - "id": "i7eHm", - "name": "Story Step Copy 04", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "liykM", - "name": "Story Step Title 04", - "fill": "$ink", - "content": "Pool remaining", - "fontFamily": "$font-ui", - "fontSize": 13, - "fontWeight": "600" - }, - { - "type": "text", - "id": "Cheev", - "name": "Story Step Detail 04", - "fill": "$muted", - "content": "Before future income", - "fontFamily": "$font-ui", - "fontSize": 11, - "fontWeight": "normal" - } - ] - }, - { - "type": "text", - "id": "l4n4X", - "name": "Story Step Value 04", - "fill": "$ink", - "content": "₽57 160", - "fontFamily": "$font-data", - "fontSize": 14, - "fontWeight": "600" - } - ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "N7Bks", - "name": "Close Readiness", - "width": 360, - "height": "fill_container", - "fill": "$ink", - "layout": "vertical", - "gap": 13, - "padding": 20, - "children": [ - { - "type": "frame", - "id": "ZucZo", - "name": "Close Readiness Header", - "width": "fill_container", - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "ALWjl", - "name": "Close Readiness Title", - "fill": "$white", - "content": "Close readiness", - "fontFamily": "$font-ui", - "fontSize": 19, - "fontWeight": "600" - }, - { - "type": "text", - "id": "rgRrT", - "name": "Close Readiness Count", - "fill": "#FFCC7A", - "content": "2 BLOCKERS", - "fontFamily": "$font-data", - "fontSize": 9, - "fontWeight": "700", - "letterSpacing": 0.8 - } - ] - }, - { - "type": "frame", - "id": "N90A1", - "name": "Readiness · 3 uncategorized expenses", - "width": "fill_container", - "stroke": "#FFFFFF24", "strokeWidth": { "bottom": 1 }, - "gap": 12, - "padding": [ - 10, - 0 - ], - "children": [ - { - "type": "icon", - "id": "qaxZ6", - "name": "Readiness Icon · 3 uncategorized expenses", - "width": 16, - "height": 16, - "icon": "circle-alert", - "library": "lucide", - "fill": "$amber" - }, - { - "type": "frame", - "id": "E2cmG7", - "name": "Readiness Copy · 3 uncategorized expenses", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "V5MLK", - "name": "Readiness Title · 3 uncategorized expenses", - "fill": "$white", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "3 uncategorized expenses", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "600" - }, - { - "type": "text", - "id": "wGWIL", - "name": "Readiness Detail · 3 uncategorized expenses", - "fill": "#8D8D89", - "content": "Assign before closing", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "r9o69B", - "name": "Readiness · 2 unresolved statement holds", - "width": "fill_container", - "stroke": "#FFFFFF24", - "strokeWidth": { - "bottom": 1 - }, - "gap": 12, - "padding": [ - 10, - 0 - ], - "children": [ - { - "type": "icon", - "id": "SA7Wm", - "name": "Readiness Icon · 2 unresolved statement holds", - "width": 16, - "height": 16, - "icon": "clock-3", - "library": "lucide", - "fill": "$amber" - }, - { - "type": "frame", - "id": "i1u68O", - "name": "Readiness Copy · 2 unresolved statement holds", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "xCeDr", - "name": "Readiness Title · 2 unresolved statement holds", - "fill": "$white", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "2 unresolved statement holds", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "600" - }, - { - "type": "text", - "id": "d7X80", - "name": "Readiness Detail · 2 unresolved statement holds", - "fill": "#8D8D89", - "content": "Review September holds", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "y1Ygjc", - "name": "Readiness · Credit reserve underfunded", - "width": "fill_container", - "stroke": "#FFFFFF24", - "strokeWidth": { - "bottom": 1 - }, - "gap": 12, - "padding": [ - 10, - 0 - ], - "children": [ - { - "type": "icon", - "id": "kEGNA", - "name": "Readiness Icon · Credit reserve underfunded", - "width": 16, - "height": 16, - "icon": "triangle-alert", - "library": "lucide", - "fill": "#8FAEFF" - }, - { - "type": "frame", - "id": "BqawT", - "name": "Readiness Copy · Credit reserve underfunded", - "width": "fill_container", - "layout": "vertical", - "gap": 3, - "children": [ - { - "type": "text", - "id": "Gf2lr", - "name": "Readiness Title · Credit reserve underfunded", - "fill": "$white", - "textGrowth": "fixed-width", - "width": "fill_container", - "content": "Credit reserve underfunded", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "600" - }, - { - "type": "text", - "id": "T6Y2A", - "name": "Readiness Detail · Credit reserve underfunded", - "fill": "#8D8D89", - "content": "Warning only", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" - } - ] - } - ] - }, - { - "type": "frame", - "id": "TozId", - "name": "Close Month Disabled", - "width": "fill_container", - "height": 40, - "fill": "#30302E", "gap": 8, - "justifyContent": "center", + "padding": [ + 0, + 14 + ], "alignItems": "center", "children": [ { - "type": "icon", - "id": "go7ts", - "name": "Close Month Disabled Icon", - "width": 15, - "height": 15, - "icon": "lock-keyhole", - "library": "lucide", - "fill": "#777773" + "type": "text", + "id": "mr4U1", + "name": "Budget Column · CATEGORY", + "fill": "$muted", + "textGrowth": "fixed-width", + "width": "fill_container", + "content": "CATEGORY", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.7 }, { "type": "text", - "id": "hWvEi", - "name": "Close Month Disabled Label", - "fill": "#777773", - "content": "Resolve blockers to close", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "600" + "id": "XQxww", + "name": "Budget Column · PLAN", + "fill": "$muted", + "textGrowth": "fixed-width", + "width": 100, + "content": "PLAN", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.7 + }, + { + "type": "text", + "id": "Qa54S", + "name": "Budget Column · FUNDED", + "fill": "$muted", + "textGrowth": "fixed-width", + "width": 100, + "content": "FUNDED", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.7 + }, + { + "type": "text", + "id": "dDuVZ", + "name": "Budget Column · SPENT", + "fill": "$muted", + "textGrowth": "fixed-width", + "width": 100, + "content": "SPENT", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.7 + }, + { + "type": "text", + "id": "d3yL2D", + "name": "Budget Column · AVAILABLE", + "fill": "$muted", + "textGrowth": "fixed-width", + "width": 110, + "content": "AVAILABLE", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.7 } ] - } - ] - } - ] - }, - { - "type": "frame", - "id": "ZMqJR", - "name": "Overview Category Strip", - "width": "fill_container", - "layout": "vertical", - "gap": 10, - "children": [ - { - "type": "frame", - "id": "joOoK", - "name": "Overview Category Header", - "width": "fill_container", - "justifyContent": "space_between", - "children": [ - { - "type": "text", - "id": "EzYY8", - "name": "Overview Category Title", - "fill": "$ink", - "content": "Category pulse", - "fontFamily": "$font-ui", - "fontSize": 18, - "fontWeight": "600" }, - { - "type": "text", - "id": "DCAy3", - "name": "Overview Category Link", - "fill": "$blue", - "content": "Open full budget →", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "600" - } - ] - }, - { - "type": "frame", - "id": "J3lz3", - "name": "Overview Categories", - "width": "fill_container", - "height": 90, - "gap": 12, - "children": [ { "type": "frame", - "id": "ZlmIs", - "name": "Category Pulse · Groceries", + "id": "FJHqu", + "name": "Budget Category · Groceries", "width": "fill_container", - "height": "fill_container", + "height": 78, "stroke": "$line", - "strokeWidth": 1, - "layout": "vertical", - "gap": 6, - "padding": 12, + "strokeWidth": { + "bottom": 1 + }, + "gap": 8, + "padding": [ + 0, + 14 + ], + "alignItems": "center", "children": [ { "type": "frame", - "id": "UFV6I", - "name": "Category Pulse Header · Groceries", + "id": "I0NuLQ", + "name": "Budget Category Info · Groceries", "width": "fill_container", - "justifyContent": "space_between", + "layout": "vertical", + "gap": 5, "children": [ { "type": "text", - "id": "wTDhp", - "name": "Category Pulse Label · Groceries", + "id": "E3gDOD", + "name": "Budget Category Name · Groceries", "fill": "$ink", "content": "Groceries", "fontFamily": "$font-ui", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600" }, { - "type": "text", - "id": "O22Ay", - "name": "Category Pulse Value · Groceries", - "fill": "$ink", - "content": "₽8 240", - "fontFamily": "$font-data", - "fontSize": 11, - "fontWeight": "600" + "type": "frame", + "id": "K2BLK", + "name": "Budget Category Kind · Groceries", + "gap": 8, + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "uUrkh", + "name": "Budget Category Kind Label · Groceries", + "fill": "$muted", + "content": "MONTHLY", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + }, + { + "type": "frame", + "id": "UA7vg", + "name": "Budget Category Track · Groceries", + "width": 82, + "height": 3, + "fill": "#E4E1D9", + "children": [ + { + "type": "rectangle", + "id": "T9hpz0", + "name": "Budget Category Bar · Groceries", + "fill": "$blue", + "width": 48.379999999999995, + "height": 3 + } + ] + } + ] } ] }, { "type": "text", - "id": "gVAAU", - "name": "Category Pulse Detail · Groceries", - "fill": "$muted", - "content": "of ₽14 000", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" + "id": "tu6hL", + "name": "Budget PLAN · Groceries", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽14 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" }, { - "type": "frame", - "id": "IOA0x", - "name": "Category Pulse Track · Groceries", - "width": "fill_container", - "height": 4, - "fill": "#E4E1D9", - "children": [ - { - "type": "rectangle", - "id": "L0Uaet", - "name": "Category Pulse Bar · Groceries", - "fill": "$blue", - "width": 100.3, - "height": 4 - } - ] + "type": "text", + "id": "fp7Mb", + "name": "Budget FUNDED · Groceries", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽14 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "lHFI4", + "name": "Budget SPENT · Groceries", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽8 240", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "Z24js", + "name": "Budget AVAILABLE · Groceries", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 110, + "content": "₽5 760", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "700" } ] }, { "type": "frame", - "id": "TgpIX", - "name": "Category Pulse · Transport", + "id": "lDHO3", + "name": "Budget Category · Transport", "width": "fill_container", - "height": "fill_container", + "height": 78, "stroke": "$line", - "strokeWidth": 1, - "layout": "vertical", - "gap": 6, - "padding": 12, + "strokeWidth": { + "bottom": 1 + }, + "gap": 8, + "padding": [ + 0, + 14 + ], + "alignItems": "center", "children": [ { "type": "frame", - "id": "gq6DQ", - "name": "Category Pulse Header · Transport", + "id": "KSepZ", + "name": "Budget Category Info · Transport", "width": "fill_container", - "justifyContent": "space_between", + "layout": "vertical", + "gap": 5, "children": [ { "type": "text", - "id": "vWfs7", - "name": "Category Pulse Label · Transport", + "id": "G6ZmG", + "name": "Budget Category Name · Transport", "fill": "$ink", "content": "Transport", "fontFamily": "$font-ui", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600" }, { - "type": "text", - "id": "F8ljRG", - "name": "Category Pulse Value · Transport", - "fill": "$ink", - "content": "₽4 870", - "fontFamily": "$font-data", - "fontSize": 11, - "fontWeight": "600" + "type": "frame", + "id": "M1mK6v", + "name": "Budget Category Kind · Transport", + "gap": 8, + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "oaETQ", + "name": "Budget Category Kind Label · Transport", + "fill": "$muted", + "content": "MONTHLY", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + }, + { + "type": "frame", + "id": "E1vGH", + "name": "Budget Category Track · Transport", + "width": 82, + "height": 3, + "fill": "#E4E1D9", + "children": [ + { + "type": "rectangle", + "id": "JO1wO", + "name": "Budget Category Bar · Transport", + "fill": "$blue", + "width": 66.42, + "height": 3 + } + ] + } + ] } ] }, { "type": "text", - "id": "Bbeks", - "name": "Category Pulse Detail · Transport", - "fill": "$muted", - "content": "of ₽6 000", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" + "id": "m9qbJ", + "name": "Budget PLAN · Transport", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽6 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" }, { - "type": "frame", - "id": "Te9fW", - "name": "Category Pulse Track · Transport", - "width": "fill_container", - "height": 4, - "fill": "#E4E1D9", - "children": [ - { - "type": "rectangle", - "id": "LmWIU", - "name": "Category Pulse Bar · Transport", - "fill": "$amber", - "width": 137.7, - "height": 4 - } - ] + "type": "text", + "id": "wj7Qq", + "name": "Budget FUNDED · Transport", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽6 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "NRINa", + "name": "Budget SPENT · Transport", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽4 870", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "RjkYQ", + "name": "Budget AVAILABLE · Transport", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 110, + "content": "₽1 130", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "700" } ] }, { "type": "frame", - "id": "qBl8t", - "name": "Category Pulse · Travel envelope", + "id": "DaZBv", + "name": "Budget Category · Home", "width": "fill_container", - "height": "fill_container", + "height": 78, "stroke": "$line", - "strokeWidth": 1, - "layout": "vertical", - "gap": 6, - "padding": 12, + "strokeWidth": { + "bottom": 1 + }, + "gap": 8, + "padding": [ + 0, + 14 + ], + "alignItems": "center", "children": [ { "type": "frame", - "id": "p7Gd7", - "name": "Category Pulse Header · Travel envelope", + "id": "hDYs2", + "name": "Budget Category Info · Home", "width": "fill_container", - "justifyContent": "space_between", + "layout": "vertical", + "gap": 5, "children": [ { "type": "text", - "id": "M6zj4m", - "name": "Category Pulse Label · Travel envelope", + "id": "pGpH9", + "name": "Budget Category Name · Home", "fill": "$ink", - "content": "Travel envelope", + "content": "Home", "fontFamily": "$font-ui", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600" }, { - "type": "text", - "id": "s5Oh27", - "name": "Category Pulse Value · Travel envelope", - "fill": "$ink", - "content": "₽21 000", - "fontFamily": "$font-data", - "fontSize": 11, - "fontWeight": "600" + "type": "frame", + "id": "UVfqQ", + "name": "Budget Category Kind · Home", + "gap": 8, + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "W60r5", + "name": "Budget Category Kind Label · Home", + "fill": "$muted", + "content": "MONTHLY", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + }, + { + "type": "frame", + "id": "NX0Ih", + "name": "Budget Category Track · Home", + "width": 82, + "height": 3, + "fill": "#E4E1D9", + "children": [ + { + "type": "rectangle", + "id": "avGOs", + "name": "Budget Category Bar · Home", + "fill": "$amber", + "width": 74.61999999999999, + "height": 3 + } + ] + } + ] } ] }, { "type": "text", - "id": "F9GCox", - "name": "Category Pulse Detail · Travel envelope", - "fill": "$muted", - "content": "saved", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" + "id": "MpD9U", + "name": "Budget PLAN · Home", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽32 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" }, { - "type": "frame", - "id": "gjGD9", - "name": "Category Pulse Track · Travel envelope", - "width": "fill_container", - "height": 4, - "fill": "#E4E1D9", - "children": [ - { - "type": "rectangle", - "id": "X8Bx7", - "name": "Category Pulse Bar · Travel envelope", - "fill": "$blue", - "width": 119, - "height": 4 - } - ] + "type": "text", + "id": "O5PMLg", + "name": "Budget FUNDED · Home", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽32 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "EIUKj", + "name": "Budget SPENT · Home", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽29 100", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "ffy3l", + "name": "Budget AVAILABLE · Home", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 110, + "content": "₽2 900", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "700" } ] }, { "type": "frame", - "id": "pugy5", - "name": "Category Pulse · Credit reserve", + "id": "QnPuN", + "name": "Budget Category · Travel", "width": "fill_container", - "height": "fill_container", + "height": 78, "stroke": "$line", - "strokeWidth": 1, - "layout": "vertical", - "gap": 6, - "padding": 12, + "strokeWidth": { + "bottom": 1 + }, + "gap": 8, + "padding": [ + 0, + 14 + ], + "alignItems": "center", "children": [ { "type": "frame", - "id": "aTp0Z", - "name": "Category Pulse Header · Credit reserve", + "id": "j2qDB", + "name": "Budget Category Info · Travel", "width": "fill_container", - "justifyContent": "space_between", + "layout": "vertical", + "gap": 5, "children": [ { "type": "text", - "id": "P4zg67", - "name": "Category Pulse Label · Credit reserve", + "id": "ib5iA", + "name": "Budget Category Name · Travel", + "fill": "$ink", + "content": "Travel", + "fontFamily": "$font-ui", + "fontSize": 13, + "fontWeight": "600" + }, + { + "type": "frame", + "id": "kgb2m", + "name": "Budget Category Kind · Travel", + "gap": 8, + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "R6wRYT", + "name": "Budget Category Kind Label · Travel", + "fill": "$muted", + "content": "ENVELOPE", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + }, + { + "type": "frame", + "id": "J7XEg", + "name": "Budget Category Track · Travel", + "width": 82, + "height": 3, + "fill": "#E4E1D9", + "children": [ + { + "type": "rectangle", + "id": "BGPHS", + "name": "Budget Category Bar · Travel", + "fill": "$blue", + "width": 3, + "height": 3 + } + ] + } + ] + } + ] + }, + { + "type": "text", + "id": "VQ6iu", + "name": "Budget PLAN · Travel", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽20 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "M89uw5", + "name": "Budget FUNDED · Travel", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽12 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "uJNT3", + "name": "Budget SPENT · Travel", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽0", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "i1zNl", + "name": "Budget AVAILABLE · Travel", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 110, + "content": "₽21 000", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "700" + } + ] + }, + { + "type": "frame", + "id": "kIWka", + "name": "Budget Category · Credit reserve", + "width": "fill_container", + "height": 78, + "stroke": "$line", + "strokeWidth": { + "bottom": 1 + }, + "gap": 8, + "padding": [ + 0, + 14 + ], + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "FVCWK", + "name": "Budget Category Info · Credit reserve", + "width": "fill_container", + "layout": "vertical", + "gap": 5, + "children": [ + { + "type": "text", + "id": "w10WGG", + "name": "Budget Category Name · Credit reserve", "fill": "$ink", "content": "Credit reserve", "fontFamily": "$font-ui", - "fontSize": 12, + "fontSize": 13, "fontWeight": "600" }, + { + "type": "frame", + "id": "mTLfr", + "name": "Budget Category Kind · Credit reserve", + "gap": 8, + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "U1QIyy", + "name": "Budget Category Kind Label · Credit reserve", + "fill": "$muted", + "content": "SYSTEM · CREDIT", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + }, + { + "type": "frame", + "id": "q1D9a", + "name": "Budget Category Track · Credit reserve", + "width": 82, + "height": 3, + "fill": "#E4E1D9", + "children": [ + { + "type": "rectangle", + "id": "M6FfG", + "name": "Budget Category Bar · Credit reserve", + "fill": "$blue", + "width": 25.419999999999998, + "height": 3 + } + ] + } + ] + } + ] + }, + { + "type": "text", + "id": "tqi7L", + "name": "Budget PLAN · Credit reserve", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "—", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "t2PLPP", + "name": "Budget FUNDED · Credit reserve", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽18 100", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "W4tbhO", + "name": "Budget SPENT · Credit reserve", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 100, + "content": "₽5 620", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "500" + }, + { + "type": "text", + "id": "cP58i", + "name": "Budget AVAILABLE · Credit reserve", + "fill": "$ink", + "textGrowth": "fixed-width", + "width": 110, + "content": "₽112 480", + "textAlign": "right", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "700" + } + ] + } + ] + }, + { + "type": "frame", + "id": "Pe8CX", + "name": "Budget Aside", + "width": 350, + "height": "fill_container", + "layout": "vertical", + "gap": 16, + "children": [ + { + "type": "frame", + "id": "hvzYa", + "name": "Expected Incomes", + "width": "fill_container", + "fill": "$white", + "stroke": "$line", + "strokeWidth": 1, + "layout": "vertical", + "children": [ + { + "type": "frame", + "id": "bQH73", + "name": "Expected Incomes Header", + "width": "fill_container", + "fill": "#EFEEE9", + "padding": 14, + "justifyContent": "space_between", + "alignItems": "center", + "children": [ { "type": "text", - "id": "Mnnfr", - "name": "Category Pulse Value · Credit reserve", + "id": "AQNC2", + "name": "Expected Incomes Title", "fill": "$ink", - "content": "₽12 480", + "content": "Expected income", + "fontFamily": "$font-ui", + "fontSize": 14, + "fontWeight": "600" + }, + { + "type": "icon", + "id": "hpQUM", + "name": "Expected Incomes Add", + "width": 16, + "height": 16, + "icon": "plus", + "library": "lucide", + "fill": "$blue" + } + ] + }, + { + "type": "frame", + "id": "x5pBv", + "name": "Expected Income · Salary · Acme", + "width": "fill_container", + "stroke": "$line", + "strokeWidth": { + "top": 1 + }, + "padding": 14, + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "LDIZS", + "name": "Expected Income Copy · Salary · Acme", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "ja7YS", + "name": "Expected Income Source · Salary · Acme", + "fill": "$ink", + "content": "Salary · Acme", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "NgZIm", + "name": "Expected Income Meta · Salary · Acme", + "fill": "$green", + "content": "05 SEP · MATCHED", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + } + ] + }, + { + "type": "text", + "id": "SjULy", + "name": "Expected Income Amount · Salary · Acme", + "fill": "$ink", + "content": "₽95 000", "fontFamily": "$font-data", "fontSize": 11, "fontWeight": "600" @@ -4989,30 +4953,366 @@ ] }, { - "type": "text", - "id": "y3Ktjg", - "name": "Category Pulse Detail · Credit reserve", - "fill": "$muted", - "content": "of ₽18 100", - "fontFamily": "$font-ui", - "fontSize": 10, - "fontWeight": "normal" + "type": "frame", + "id": "s3NeVh", + "name": "Expected Income · Freelance", + "width": "fill_container", + "stroke": "$line", + "strokeWidth": { + "top": 1 + }, + "padding": 14, + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "frame", + "id": "wJi7E", + "name": "Expected Income Copy · Freelance", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "U3PJ9", + "name": "Expected Income Source · Freelance", + "fill": "$ink", + "content": "Freelance", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "T8mJx4", + "name": "Expected Income Meta · Freelance", + "fill": "$amber", + "content": "25 SEP · PARTIAL", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + } + ] + }, + { + "type": "text", + "id": "FfmEz", + "name": "Expected Income Amount · Freelance", + "fill": "$ink", + "content": "₽15 000", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "600" + } + ] }, { "type": "frame", - "id": "t3SMr", - "name": "Category Pulse Track · Credit reserve", + "id": "ITQ0J", + "name": "Expected Income · Tax return", "width": "fill_container", - "height": 4, - "fill": "#E4E1D9", + "stroke": "$line", + "strokeWidth": { + "top": 1 + }, + "padding": 14, + "justifyContent": "space_between", + "alignItems": "center", "children": [ { - "type": "rectangle", - "id": "aTKMM", - "name": "Category Pulse Bar · Credit reserve", - "fill": "$blue", - "width": 117.3, - "height": 4 + "type": "frame", + "id": "sxieS", + "name": "Expected Income Copy · Tax return", + "layout": "vertical", + "gap": 4, + "children": [ + { + "type": "text", + "id": "F0q8I", + "name": "Expected Income Source · Tax return", + "fill": "$ink", + "content": "Tax return", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "mjuiM", + "name": "Expected Income Meta · Tax return", + "fill": "$muted", + "content": "28 SEP · EXPECTED", + "fontFamily": "$font-data", + "fontSize": 8, + "fontWeight": "700", + "letterSpacing": 0.5 + } + ] + }, + { + "type": "text", + "id": "yOoLY", + "name": "Expected Income Amount · Tax return", + "fill": "$ink", + "content": "₽15 000", + "fontFamily": "$font-data", + "fontSize": 11, + "fontWeight": "600" + } + ] + } + ] + }, + { + "type": "frame", + "id": "Aztym", + "name": "Month Close Readiness", + "width": "fill_container", + "height": "fill_container", + "fill": "$ink", + "layout": "vertical", + "gap": 13, + "padding": 20, + "children": [ + { + "type": "frame", + "id": "dZov8", + "name": "Close Readiness Header", + "width": "fill_container", + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "nBxc7", + "name": "Close Readiness Title", + "fill": "$white", + "content": "Close readiness", + "fontFamily": "$font-ui", + "fontSize": 19, + "fontWeight": "600" + }, + { + "type": "text", + "id": "Q0mz9", + "name": "Close Readiness Count", + "fill": "#FFCC7A", + "content": "2 BLOCKERS", + "fontFamily": "$font-data", + "fontSize": 9, + "fontWeight": "700", + "letterSpacing": 0.8 + } + ] + }, + { + "type": "frame", + "id": "W4cJL", + "name": "Readiness · 3 uncategorized expenses", + "width": "fill_container", + "stroke": "#FFFFFF24", + "strokeWidth": { + "bottom": 1 + }, + "gap": 12, + "padding": [ + 10, + 0 + ], + "children": [ + { + "type": "icon", + "id": "akbJ3", + "name": "Readiness Icon · 3 uncategorized expenses", + "width": 16, + "height": 16, + "icon": "circle-alert", + "library": "lucide", + "fill": "$amber" + }, + { + "type": "frame", + "id": "V93EW", + "name": "Readiness Copy · 3 uncategorized expenses", + "width": "fill_container", + "layout": "vertical", + "gap": 3, + "children": [ + { + "type": "text", + "id": "Zisr4", + "name": "Readiness Title · 3 uncategorized expenses", + "fill": "$white", + "textGrowth": "fixed-width", + "width": "fill_container", + "content": "3 uncategorized expenses", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "u3zs4", + "name": "Readiness Detail · 3 uncategorized expenses", + "fill": "#8D8D89", + "content": "Assign before closing", + "fontFamily": "$font-ui", + "fontSize": 10, + "fontWeight": "normal" + } + ] + } + ] + }, + { + "type": "frame", + "id": "sAVg5", + "name": "Readiness · 2 unresolved statement holds", + "width": "fill_container", + "stroke": "#FFFFFF24", + "strokeWidth": { + "bottom": 1 + }, + "gap": 12, + "padding": [ + 10, + 0 + ], + "children": [ + { + "type": "icon", + "id": "Dhi3f", + "name": "Readiness Icon · 2 unresolved statement holds", + "width": 16, + "height": 16, + "icon": "clock-3", + "library": "lucide", + "fill": "$amber" + }, + { + "type": "frame", + "id": "M7v2x6", + "name": "Readiness Copy · 2 unresolved statement holds", + "width": "fill_container", + "layout": "vertical", + "gap": 3, + "children": [ + { + "type": "text", + "id": "IccS4", + "name": "Readiness Title · 2 unresolved statement holds", + "fill": "$white", + "textGrowth": "fixed-width", + "width": "fill_container", + "content": "2 unresolved statement holds", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "o5xe6c", + "name": "Readiness Detail · 2 unresolved statement holds", + "fill": "#8D8D89", + "content": "Review September holds", + "fontFamily": "$font-ui", + "fontSize": 10, + "fontWeight": "normal" + } + ] + } + ] + }, + { + "type": "frame", + "id": "l5ciE", + "name": "Readiness · Credit reserve underfunded", + "width": "fill_container", + "stroke": "#FFFFFF24", + "strokeWidth": { + "bottom": 1 + }, + "gap": 12, + "padding": [ + 10, + 0 + ], + "children": [ + { + "type": "icon", + "id": "nkoRb", + "name": "Readiness Icon · Credit reserve underfunded", + "width": 16, + "height": 16, + "icon": "triangle-alert", + "library": "lucide", + "fill": "#8FAEFF" + }, + { + "type": "frame", + "id": "uXJlx", + "name": "Readiness Copy · Credit reserve underfunded", + "width": "fill_container", + "layout": "vertical", + "gap": 3, + "children": [ + { + "type": "text", + "id": "K8QuF", + "name": "Readiness Title · Credit reserve underfunded", + "fill": "$white", + "textGrowth": "fixed-width", + "width": "fill_container", + "content": "Credit reserve underfunded", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "text", + "id": "ZUGmi", + "name": "Readiness Detail · Credit reserve underfunded", + "fill": "#8D8D89", + "content": "Warning only", + "fontFamily": "$font-ui", + "fontSize": 10, + "fontWeight": "normal" + } + ] + } + ] + }, + { + "type": "frame", + "id": "ugRcL", + "name": "Close Month Disabled", + "width": "fill_container", + "height": 40, + "fill": "#30302E", + "gap": 8, + "justifyContent": "center", + "alignItems": "center", + "children": [ + { + "type": "icon", + "id": "h6MioH", + "name": "Close Month Disabled Icon", + "width": 15, + "height": 15, + "icon": "lock-keyhole", + "library": "lucide", + "fill": "#777773" + }, + { + "type": "text", + "id": "HE2zy", + "name": "Close Month Disabled Label", + "fill": "#777773", + "content": "Resolve blockers to close", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" } ] } @@ -5030,7 +5330,7 @@ "type": "frame", "id": "DEToL", "x": 4560, - "y": 0, + "y": 1104, "name": "03 · Ledger / Operation Composer", "clip": true, "width": 1440, @@ -16224,8 +16524,8 @@ { "type": "frame", "id": "Sfejn", - "x": 3040, - "y": 1104, + "x": -2190, + "y": 0, "name": "08 · Mobile / Month", "clip": true, "width": 390, @@ -17175,8 +17475,8 @@ { "type": "frame", "id": "BUW9i", - "x": 3478, - "y": 1104, + "x": -1752, + "y": 0, "name": "09 · Mobile / New Operation", "clip": true, "width": 390, @@ -17806,8 +18106,8 @@ { "type": "frame", "id": "J7GUbZ", - "x": 3916, - "y": 1104, + "x": -1314, + "y": 0, "name": "10 · Mobile / Hold Resolution", "clip": true, "width": 390, @@ -20811,23 +21111,23 @@ "id": "JD5sH", "layoutPosition": "absolute", "x": 238, - "y": -50, + "y": 0, "name": "Category Drawer Scrim", - "fill": "#16161633", - "width": 682, - "height": 974 + "fill": "#16161688", + "width": 772, + "height": 1024 }, { "type": "frame", "id": "WnDLj", "layoutPosition": "absolute", - "x": 920, - "y": -50, + "x": 1010, + "y": 0, "name": "Category Manager Drawer", - "width": 520, - "height": 974, - "fill": "$white", - "stroke": "$line", + "width": 430, + "height": 1024, + "fill": "$ink", + "stroke": "#3D3D3A", "strokeWidth": { "left": 1 }, @@ -20842,10 +21142,10 @@ "blur": 24 }, "layout": "vertical", - "gap": 18, + "gap": 20, "padding": [ - 26, - 24 + 32, + 28 ], "children": [ { @@ -20859,7 +21159,7 @@ "type": "frame", "id": "Qt1Dj", "name": "Category Drawer Header Copy", - "width": 400, + "width": 290, "layout": "vertical", "gap": 5, "children": [ @@ -20867,23 +21167,25 @@ "type": "text", "id": "FvOdO", "name": "Category Drawer Title", - "fill": "$ink", + "fill": "$white", + "textGrowth": "fixed-width", + "width": "fill_container", "content": "Управление категориями", "fontFamily": "$font-ui", - "fontSize": 24, + "fontSize": 20, "fontWeight": "700" }, { "type": "text", "id": "A2zji", "name": "Category Drawer Subtitle", - "fill": "$muted", + "fill": "#AAA9A5", "textGrowth": "fixed-width", "width": "fill_container", "content": "Создавайте категории и управляйте доступностью, не теряя историю бюджета.", "lineHeight": 1.35, "fontFamily": "$font-ui", - "fontSize": 12, + "fontSize": 11, "fontWeight": "normal" } ] @@ -20894,7 +21196,7 @@ "name": "Close Category Drawer", "width": 34, "height": 34, - "stroke": "$line", + "stroke": "#FFFFFF55", "strokeWidth": 1, "justifyContent": "center", "alignItems": "center", @@ -20903,7 +21205,7 @@ "type": "text", "id": "a4HZF", "name": "Close Category Drawer Label", - "fill": "$ink", + "fill": "$white", "content": "×", "fontFamily": "$font-ui", "fontSize": 20, @@ -20918,18 +21220,25 @@ "id": "B1RyF", "name": "Create Category Form", "width": "fill_container", - "fill": "$paper", - "stroke": "$line", - "strokeWidth": 1, + "fill": "#00000000", + "stroke": "#FFFFFF2C", + "strokeWidth": { + "bottom": 1 + }, "layout": "vertical", "gap": 10, - "padding": 14, + "padding": [ + 0, + 0, + 20, + 0 + ], "children": [ { "type": "text", "id": "e9H7G", "name": "Create Category Label", - "fill": "$muted", + "fill": "#8D8D89", "content": "НОВАЯ КАТЕГОРИЯ", "fontFamily": "$font-data", "fontSize": 10, @@ -20941,71 +21250,120 @@ "id": "fagu2", "name": "Create Category Fields", "width": "fill_container", - "gap": 8, - "alignItems": "center", + "layout": "vertical", + "gap": 12, "children": [ { "type": "frame", - "id": "ft0LN", - "name": "Category Name Field", - "width": 210, - "height": 40, - "fill": "$white", - "stroke": "$line", - "strokeWidth": 1, - "padding": [ - 0, - 12 - ], - "alignItems": "center", + "id": "ce23V", + "name": "Name and type fields", + "width": "fill_container", + "gap": 8, "children": [ { - "type": "text", - "id": "YirAu", - "name": "Category Name Placeholder", - "fill": "$muted", - "content": "Например, Здоровье", - "fontFamily": "$font-ui", - "fontSize": 12, - "fontWeight": "normal" - } - ] - }, - { - "type": "frame", - "id": "PXcQQ", - "name": "Category Kind Field", - "width": 125, - "height": 40, - "fill": "$white", - "stroke": "$line", - "strokeWidth": 1, - "padding": [ - 0, - 10 - ], - "justifyContent": "space_between", - "alignItems": "center", - "children": [ - { - "type": "text", - "id": "k8UUOw", - "name": "Category Kind Value", - "fill": "$ink", - "content": "Ежемесячная", - "fontFamily": "$font-ui", - "fontSize": 11, - "fontWeight": "normal" + "type": "frame", + "id": "Ykigh", + "name": "Category name with label", + "width": 195, + "layout": "vertical", + "gap": 6, + "children": [ + { + "type": "text", + "id": "w41Ud", + "name": "Name field label", + "fill": "#AAA9A5", + "content": "Название", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "frame", + "id": "ft0LN", + "name": "Category Name Field", + "width": "fill_container", + "height": 40, + "fill": "#1D1D1D", + "stroke": "#3D3D3A", + "strokeWidth": 1, + "padding": [ + 0, + 12 + ], + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "YirAu", + "name": "Category Name Placeholder", + "fill": "#AAA9A5", + "content": "Например, Здоровье", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "normal" + } + ] + } + ] }, { - "type": "text", - "id": "dxAY4", - "name": "Category Kind Chevron", - "fill": "$muted", - "content": "⌄", - "fontFamily": "$font-ui", - "fontSize": 13, - "fontWeight": "normal" + "type": "frame", + "id": "sZjJH", + "name": "Category type with label", + "width": "fill_container", + "layout": "vertical", + "gap": 6, + "children": [ + { + "type": "text", + "id": "dkxT7", + "name": "Type field label", + "fill": "#AAA9A5", + "content": "Тип", + "fontFamily": "$font-ui", + "fontSize": 12, + "fontWeight": "600" + }, + { + "type": "frame", + "id": "PXcQQ", + "name": "Category Kind Field", + "width": "fill_container", + "height": 40, + "fill": "#1D1D1D", + "stroke": "#3D3D3A", + "strokeWidth": 1, + "padding": [ + 0, + 10 + ], + "justifyContent": "space_between", + "alignItems": "center", + "children": [ + { + "type": "text", + "id": "k8UUOw", + "name": "Category Kind Value", + "fill": "$white", + "content": "Ежемесячная", + "fontFamily": "$font-ui", + "fontSize": 11, + "fontWeight": "normal" + }, + { + "type": "text", + "id": "dxAY4", + "name": "Category Kind Chevron", + "fill": "#AAA9A5", + "content": "⌄", + "fontFamily": "$font-ui", + "fontSize": 13, + "fontWeight": "normal" + } + ] + } + ] } ] }, @@ -21013,8 +21371,8 @@ "type": "frame", "id": "Pmikk", "name": "Create Category Button", - "width": 100, - "height": 40, + "width": "fill_container", + "height": 42, "fill": "$blue", "justifyContent": "center", "alignItems": "center", @@ -21041,7 +21399,7 @@ "name": "Category Manager Tabs", "width": "fill_container", "height": 39, - "stroke": "$line", + "stroke": "#FFFFFF44", "strokeWidth": { "bottom": 1 }, @@ -21052,6 +21410,7 @@ "name": "Active Categories Tab", "width": 145, "height": 39, + "fill": "#FFFFFF", "stroke": "$blue", "strokeWidth": { "bottom": 2 @@ -21077,6 +21436,7 @@ "name": "Archived Categories Tab", "width": 145, "height": 39, + "fill": "#FFFFFF", "justifyContent": "center", "alignItems": "center", "children": [ @@ -21084,7 +21444,7 @@ "type": "text", "id": "JlhOV", "name": "Archived Categories Tab Label", - "fill": "$muted", + "fill": "#272725", "content": "Архив · 1", "fontFamily": "$font-ui", "fontSize": 12, @@ -21099,7 +21459,7 @@ "id": "TGcLs", "name": "Active Category Definitions", "width": "fill_container", - "stroke": "$line", + "stroke": "#FFFFFF2C", "strokeWidth": 1, "layout": "vertical", "children": [ @@ -21108,7 +21468,7 @@ "id": "vEIjl", "name": "Category Definition · Продукты", "width": "fill_container", - "stroke": "$line", + "stroke": "#3D3D3A", "strokeWidth": { "bottom": 1 }, @@ -21123,7 +21483,7 @@ "type": "frame", "id": "tWjCs", "name": "Category Definition Copy · Продукты", - "width": 250, + "width": 150, "layout": "vertical", "gap": 4, "children": [ @@ -21131,7 +21491,7 @@ "type": "text", "id": "rNVLR", "name": "Category Definition Name · Продукты", - "fill": "$ink", + "fill": "$white", "content": "Продукты", "fontFamily": "$font-ui", "fontSize": 13, @@ -21141,7 +21501,7 @@ "type": "text", "id": "J0DS1g", "name": "Category Definition Meta · Продукты", - "fill": "$muted", + "fill": "#AAA9A5", "content": "Ежемесячная", "fontFamily": "$font-data", "fontSize": 9.5, @@ -21156,7 +21516,7 @@ "name": "Category Definition Action · Продукты", "fill": "$blue", "textGrowth": "fixed-width", - "width": 165, + "width": 166, "content": "Переименовать · Архивировать", "lineHeight": 1.35, "textAlign": "right", @@ -21171,7 +21531,7 @@ "id": "uYh24", "name": "Category Definition · Накопления", "width": "fill_container", - "stroke": "$line", + "stroke": "#3D3D3A", "strokeWidth": { "bottom": 1 }, @@ -21186,7 +21546,7 @@ "type": "frame", "id": "UcBaV", "name": "Category Definition Copy · Накопления", - "width": 250, + "width": 150, "layout": "vertical", "gap": 4, "children": [ @@ -21194,7 +21554,7 @@ "type": "text", "id": "fSY0G", "name": "Category Definition Name · Накопления", - "fill": "$ink", + "fill": "$white", "content": "Накопления", "fontFamily": "$font-ui", "fontSize": 13, @@ -21204,7 +21564,9 @@ "type": "text", "id": "h9xvnS", "name": "Category Definition Meta · Накопления", - "fill": "$blue", + "fill": "#A9C4FF", + "textGrowth": "fixed-width", + "width": 150, "content": "Накопительная · Системная", "fontFamily": "$font-data", "fontSize": 9.5, @@ -21217,9 +21579,9 @@ "type": "text", "id": "Y7thn", "name": "Category Definition Action · Накопления", - "fill": "$muted", + "fill": "#AAA9A5", "textGrowth": "fixed-width", - "width": 165, + "width": 166, "content": "Защищена: связана со счётом", "lineHeight": 1.35, "textAlign": "right", @@ -21234,7 +21596,7 @@ "id": "si15V", "name": "Category Definition · Резерв · Alfa credit", "width": "fill_container", - "stroke": "$line", + "stroke": "#3D3D3A", "strokeWidth": { "bottom": 1 }, @@ -21249,7 +21611,7 @@ "type": "frame", "id": "jyMq6", "name": "Category Definition Copy · Резерв · Alfa credit", - "width": 250, + "width": 150, "layout": "vertical", "gap": 4, "children": [ @@ -21257,7 +21619,7 @@ "type": "text", "id": "R1VQ2b", "name": "Category Definition Name · Резерв · Alfa credit", - "fill": "$ink", + "fill": "$white", "content": "Резерв · Alfa credit", "fontFamily": "$font-ui", "fontSize": 13, @@ -21280,9 +21642,9 @@ "type": "text", "id": "EoOJz", "name": "Category Definition Action · Резерв · Alfa credit", - "fill": "$muted", + "fill": "#AAA9A5", "textGrowth": "fixed-width", - "width": 165, + "width": 166, "content": "Защищена: связана с кредиткой", "lineHeight": 1.35, "textAlign": "right", @@ -21299,8 +21661,8 @@ "id": "E77GOx", "name": "Archived Category Preview", "width": "fill_container", - "fill": "$paper", - "stroke": "$line", + "fill": "#1D1D1D", + "stroke": "#3D3D3A", "strokeWidth": 1, "layout": "vertical", "gap": 8, @@ -21310,7 +21672,7 @@ "type": "text", "id": "Q3HPG", "name": "Archived Category Preview Label", - "fill": "$muted", + "fill": "#AAA9A5", "content": "СОСТОЯНИЕ · АРХИВ", "fontFamily": "$font-data", "fontSize": 9.5, @@ -21336,7 +21698,7 @@ "type": "text", "id": "gcwym", "name": "Archived Category Name", - "fill": "$muted", + "fill": "$white", "content": "Путешествия", "fontFamily": "$font-ui", "fontSize": 12, @@ -21346,7 +21708,7 @@ "type": "text", "id": "BmoEs", "name": "Archived Category History Note", - "fill": "$muted", + "fill": "#AAA9A5", "content": "История и суммы сохранены", "fontFamily": "$font-ui", "fontSize": 10, @@ -21359,7 +21721,7 @@ "id": "NQhCs", "name": "Restore Category Button", "height": 32, - "stroke": "$blue", + "stroke": "#8FAEFF", "strokeWidth": 1, "padding": [ 0, @@ -21372,7 +21734,7 @@ "type": "text", "id": "DuFV2", "name": "Restore Category Button Label", - "fill": "$blue", + "fill": "#A9C4FF", "content": "Восстановить", "fontFamily": "$font-ui", "fontSize": 11, @@ -21387,8 +21749,11 @@ { "type": "frame", "id": "duWTj", + "x": 28, + "y": 649, "name": "Category Manager State Checklist", - "width": "fill_container", + "enabled": false, + "width": "fill_container(374)", "gap": 7, "children": [ { @@ -21508,8 +21873,8 @@ { "type": "frame", "id": "B1pE0", - "x": 12160, - "y": 0, + "x": 6080, + "y": 2208, "name": "12 · Savings & Resolution States", "clip": true, "width": 1440, @@ -23136,8 +23501,8 @@ { "type": "frame", "id": "bWcks", - "x": 4354, - "y": 1104, + "x": -876, + "y": 0, "name": "13 · Mobile / Category Manager", "clip": true, "width": 390, @@ -23560,8 +23925,8 @@ { "type": "frame", "id": "QZZ3p", - "x": 4792, - "y": 1104, + "x": -438, + "y": 0, "name": "14 · Mobile / Savings Adjustment", "clip": true, "width": 390, @@ -23942,7 +24307,7 @@ { "type": "frame", "id": "aZild", - "x": 13680, + "x": 4560, "y": 0, "name": "03a · Ledger / Default", "clip": true, @@ -26163,8 +26528,8 @@ { "type": "frame", "id": "zYL6A", - "x": 15200, - "y": 0, + "x": 7600, + "y": 1104, "name": "05a · Review Queue", "clip": true, "width": 1440, diff --git a/docs/questions/перевод_между_своими.md b/docs/questions/перевод_между_своими.md new file mode 100644 index 0000000..821a883 --- /dev/null +++ b/docs/questions/перевод_между_своими.md @@ -0,0 +1,3 @@ +Как создать перевод между двумя счетами через выписки. +Вот я выгружаю выписку из одного банка (но для того чтобы отметить транзакцию как перевод нужна вторая такая же на другом счете) +Я не могу применить одновременно две выписки, все равно сначала принимается одна потом вторая. Как сметчить их, чтобы задетектились переводы? diff --git a/docs/tasks/0002-fixes.md b/docs/tasks/0002-fixes.md new file mode 100644 index 0000000..de92ac4 --- /dev/null +++ b/docs/tasks/0002-fixes.md @@ -0,0 +1,9 @@ +Используй скиллы pen-dev и design-interface для работы с дизайном в @design.pen +Используй скиллы pen-dev, frontend-design и impeccable для верстки фронта + +1. На русском на фронте в меню навигации шрифт сильно отличается от английского. Мне нравится подобранный шрифт на английском. Надо сделать подобный и для русского. +2. Страница This month сильно отличается от дизайна, в дизайне идёт табличка категорий слева как основное меню, в дизайне есть Expected Income, также надо реализовать его и на бэке. В дизайне управление категориями почему-то в This month, хотя его там быть не должно. +3. Страница Бюджет вообще отсутствует в дизайн-доке, доделай. Большая проблема с "Управлять категориями" на странице Бюджет. Текст в кнопках вылезает из рамок (текст кнопки Создать) Поле Name шириной меньше одной буквы, а заголовок полей Name и Type наложились друг на друга. Сначала нарисовать дизайн для этого меню "Manage categories" - потом сверстать по нему +4. При клике вне выезжающего меню (категории или новая операция) оно должно закрываться +5. Расположи на дизайн листе @design.pen экраны таким образом слева направа - разные страницы. Одинаковые страницы в разных состояниях друг над другом в столбик. Мобильные экраны вообще где-нибудь слева сбоку +6. Прогони 'ty check .' и pytest в корне и исправь все выявленные проблемы. Там много чего по тайпчеку и один тест падает \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index f43ed1e..c32b6d6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ "dependencies": { "@fontsource/funnel-sans": "^5.3.0", "@fontsource/geist-mono": "^5.3.0", + "@fontsource/onest": "^5.3.1", "@hookform/resolvers": "^5.1.0", "@tanstack/react-query": "^5.80.0", "i18next": "^25.2.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 7d614fa..2168c55 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@fontsource/geist-mono': specifier: ^5.3.0 version: 5.3.0 + '@fontsource/onest': + specifier: ^5.3.1 + version: 5.3.1 '@hookform/resolvers': specifier: ^5.1.0 version: 5.9.1(react-hook-form@7.87.0(react@19.3.0))(zod@3.25.76) @@ -420,6 +423,9 @@ packages: '@fontsource/geist-mono@5.3.0': resolution: {integrity: sha512-UtJ1BBBCVpMYdIcW7nEB45UAoAw5M53ZXs2t0ciPW+IokuAAIc56M8+kW5tXbRJCTpDw4XTtU7proT6NdQAHTg==} + '@fontsource/onest@5.3.1': + resolution: {integrity: sha512-2uA9HUzQHBB8H7T2R6inmrnqPofB6+svATHM/huIG640duJr4rm+uanmAIheTTlbZvRC0ujMtf2T4U4RX51oEQ==} + '@hookform/resolvers@5.9.1': resolution: {integrity: sha512-7b7vsbraJxKgjVSA1Nur9tLwj539WGJUBLA7QNvXnFoT2pM5Z7G+6rlukk4B2/QrTZy6huRtH6wKeESPKuIr6w==} peerDependencies: @@ -2461,6 +2467,8 @@ snapshots: '@fontsource/geist-mono@5.3.0': {} + '@fontsource/onest@5.3.1': {} + '@hookform/resolvers@5.9.1(react-hook-form@7.87.0(react@19.3.0))(zod@3.25.76)': dependencies: '@standard-schema/utils': 0.3.0 diff --git a/frontend/src/api/endpoints.ts b/frontend/src/api/endpoints.ts index 67c1ae6..861cc14 100644 --- a/frontend/src/api/endpoints.ts +++ b/frontend/src/api/endpoints.ts @@ -17,6 +17,8 @@ import type { CreateCategoryPayload, CreateOperationPayload, ExportInfo, + ExpectedIncome, + ExpectedIncomePayload, ImportDetail, ImportSummary, LoginPayload, @@ -94,6 +96,12 @@ export const api = { apiClient.post('/budget/categories', { json: payload }), updateCategoryDefinition: (id: string, payload: PatchCategoryDefinitionPayload) => apiClient.patch(`/budget/category-definitions/${id}`, { json: payload }), + createExpectedIncome: (month: string, payload: ExpectedIncomePayload) => + apiClient.post(`/budget/${month.replace('-', '/')}/expected-incomes`, { json: payload }), + updateExpectedIncome: (month: string, id: string, payload: ExpectedIncomePayload) => + apiClient.patch(`/budget/${month.replace('-', '/')}/expected-incomes/${id}`, { json: payload }), + deleteExpectedIncome: (month: string, id: string) => + apiClient.delete(`/budget/${month.replace('-', '/')}/expected-incomes/${id}`), }, imports: { list: (month?: string) => diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index d64376c..1428baa 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -190,10 +190,18 @@ export interface ExpectedIncome { expectedOn: string amountKopecks: number sourceName: string | null + note?: string | null matchedKopecks: number status: ExpectedIncomeStatus } +export interface ExpectedIncomePayload { + expectedOn: string + amountKopecks: number + sourceName: string | null + note: string | null +} + export interface BudgetSummary { month: string status: BudgetStatus diff --git a/frontend/src/components/budget/CategoryManagerModal.tsx b/frontend/src/components/budget/CategoryManagerModal.tsx index 2e77432..393cd8f 100644 --- a/frontend/src/components/budget/CategoryManagerModal.tsx +++ b/frontend/src/components/budget/CategoryManagerModal.tsx @@ -59,18 +59,20 @@ function CreateCategoryForm() { return (
- - - {CREATE_KINDS.map((kind) => ( - - ))} - +
+ + + {CREATE_KINDS.map((kind) => ( + + ))} + +
{watch('kind') === 'monthly' ? ( MOBILE_NAV_ROUTES.includes(item.to)) export function AppLayout() { - const { t } = useTranslation() + const { t, i18n } = useTranslation() const me = useMe() const logout = useLogout() const navigate = useNavigate() @@ -124,7 +124,7 @@ export function AppLayout() { }) return ( -
+
{t('common.skipToContent')} diff --git a/frontend/src/components/ui/Modal.tsx b/frontend/src/components/ui/Modal.tsx index 24a28cc..10bd8e2 100644 --- a/frontend/src/components/ui/Modal.tsx +++ b/frontend/src/components/ui/Modal.tsx @@ -21,6 +21,19 @@ export function Modal({ open, onClose, title, children }: ModalProps) { if (!open && dialog.open) dialog.close() }, [open]) + useEffect(() => { + const dialog = dialogRef.current + if (!dialog) return + const closeOnBackdrop = (event: MouseEvent) => { + if (event.target !== dialog) return + const bounds = dialog.getBoundingClientRect() + if (event.clientX < bounds.left || event.clientX > bounds.right || + event.clientY < bounds.top || event.clientY > bounds.bottom) onClose() + } + dialog.addEventListener('click', closeOnBackdrop) + return () => dialog.removeEventListener('click', closeOnBackdrop) + }, [onClose]) + return ( void queryClient.invalidateQueries({ queryKey: queryKeys.budgetSummary(month) }) + const create = useMutation({ + mutationFn: (payload: ExpectedIncomePayload) => api.budget.createExpectedIncome(month, payload), + onSuccess: invalidate, + onError, + }) + const update = useMutation({ + mutationFn: ({ id, payload }: { id: string; payload: ExpectedIncomePayload }) => + api.budget.updateExpectedIncome(month, id, payload), + onSuccess: invalidate, + onError, + }) + const remove = useMutation({ + mutationFn: (id: string) => api.budget.deleteExpectedIncome(month, id), + onSuccess: invalidate, + onError, + }) + return { create, update, remove } +} + export function useCategoryDefinitions() { return useQuery({ queryKey: queryKeys.budgetCategoryDefinitions(), diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 981845e..ea21c6f 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -37,7 +37,14 @@ "readyToClose": "No blockers. This month is ready to close.", "importsNeedReview": "{{count}} statement needs review", "reviewBlockers": "Review blockers", - "categoryPulse": "Category pulse" + "categoryPulse": "Category pulse", + "noExpectedIncome": "No expected income yet. Add an estimate for this month.", + "addIncome": "Add income", + "editIncome": "Edit expected income", + "incomeNote": "Note (optional)", + "incomeInvalid": "Enter a positive amount and a date in this month.", + "deleteIncome": "Delete expected income", + "deleteIncomeConfirm": "Remove this expected income from the monthly forecast?" }, "authShell": { "statement": "Your household ledger, sealed by design.", @@ -65,6 +72,8 @@ "create": "Create", "dash": "—", "date": "Date", + "delete": "Delete", + "edit": "Edit", "empty": "Nothing here yet", "loading": "Loading…", "name": "Name", diff --git a/frontend/src/i18n/locales/ru.json b/frontend/src/i18n/locales/ru.json index 5c9fd10..d24c9bc 100644 --- a/frontend/src/i18n/locales/ru.json +++ b/frontend/src/i18n/locales/ru.json @@ -37,7 +37,14 @@ "readyToClose": "Блокировок нет. Месяц можно закрывать.", "importsNeedReview": "Выписок на проверке: {{count}}", "reviewBlockers": "Разобрать блокировки", - "categoryPulse": "Состояние категорий" + "categoryPulse": "Состояние категорий", + "noExpectedIncome": "Ожидаемых доходов пока нет. Добавьте прогноз на этот месяц.", + "addIncome": "Добавить доход", + "editIncome": "Изменить ожидаемый доход", + "incomeNote": "Примечание (необязательно)", + "incomeInvalid": "Укажите положительную сумму и дату в этом месяце.", + "deleteIncome": "Удалить ожидаемый доход", + "deleteIncomeConfirm": "Удалить этот доход из прогноза месяца?" }, "authShell": { "statement": "Семейный гроссбух, закрытый по замыслу.", @@ -65,6 +72,8 @@ "create": "Создать", "dash": "—", "date": "Дата", + "delete": "Удалить", + "edit": "Изменить", "empty": "Пока ничего нет", "loading": "Загрузка…", "name": "Название", diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index e4067f8..dd1912a 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -4,6 +4,14 @@ import '@fontsource/funnel-sans/400.css' import '@fontsource/funnel-sans/500.css' import '@fontsource/funnel-sans/600.css' import '@fontsource/funnel-sans/700.css' +import '@fontsource/onest/cyrillic-400.css' +import '@fontsource/onest/cyrillic-500.css' +import '@fontsource/onest/cyrillic-600.css' +import '@fontsource/onest/cyrillic-700.css' +import '@fontsource/onest/latin-400.css' +import '@fontsource/onest/latin-500.css' +import '@fontsource/onest/latin-600.css' +import '@fontsource/onest/latin-700.css' import '@fontsource/geist-mono/400.css' import '@fontsource/geist-mono/500.css' import '@fontsource/geist-mono/600.css' diff --git a/frontend/src/pages/BudgetPage.tsx b/frontend/src/pages/BudgetPage.tsx index 866e061..6c982c0 100644 --- a/frontend/src/pages/BudgetPage.tsx +++ b/frontend/src/pages/BudgetPage.tsx @@ -293,47 +293,8 @@ export function BudgetPage() { {() => ( - <> - {summary.data && summary.data.expectedIncomes.length > 0 ? ( -
-

{t('budget.expectedIncome')}

- - - - - - - - - - - - - {summary.data.expectedIncomes.map((income) => ( - - - - - - - - ))} - -
{t('budget.expectedIncome')}
{t('common.date')}{t('budget.incomeSource')}{t('common.amount')}{t('budget.matched')}{t('common.status')}
- {formatDate(income.expectedOn, locale)} - - {income.sourceName ?? t('budget.noSource')} - - {formatMoney(income.amountKopecks, locale)} - - {formatMoney(income.matchedKopecks, locale)} - - - {t(`budget.income.status.${income.status}`)} - -
-
- ) : null} +
+

{t('budget.categories')}

@@ -377,7 +338,21 @@ export function BudgetPage() {
) : null} - +
+ +
)}
{planTarget ? ( diff --git a/frontend/src/pages/OverviewPage.tsx b/frontend/src/pages/OverviewPage.tsx index b837e7f..f336aa1 100644 --- a/frontend/src/pages/OverviewPage.tsx +++ b/frontend/src/pages/OverviewPage.tsx @@ -1,14 +1,21 @@ +import { useState } from 'react' import { Link } from 'react-router-dom' import { useTranslation } from 'react-i18next' +import type { FormEvent } from 'react' +import type { ExpectedIncome } from '@/api/types' import { BudgetBlockers } from '@/components/budget/BudgetBlockers' +import { Button } from '@/components/ui/Button' +import { ConfirmDialog } from '@/components/ui/ConfirmDialog' +import { MoneyField, TextField } from '@/components/ui/fields' +import { Modal } from '@/components/ui/Modal' import { PageHeader } from '@/components/ui/PageHeader' import { QueryGate } from '@/components/ui/QueryGate' -import { useBudgetCategories, useBudgetSummary } from '@/hooks/useBudget' +import { useBudgetCategories, useBudgetSummary, useExpectedIncomeMutation } from '@/hooks/useBudget' import { useImports } from '@/hooks/useImports' import { categoryLabel } from '@/lib/categoryLabel' -import { currentMonth, formatMonth } from '@/lib/dates' +import { currentMonth, formatDate, formatMonth, monthBounds, todayISO } from '@/lib/dates' import { currentLocale } from '@/lib/locale' -import { formatMoney } from '@/lib/money' +import { formatMoney, kopecksToInput, parseAmountToKopecks } from '@/lib/money' export function OverviewPage() { const { t, i18n } = useTranslation() @@ -16,10 +23,40 @@ export function OverviewPage() { const month = currentMonth() const summary = useBudgetSummary(month) const categories = useBudgetCategories(month) + const incomeMutation = useExpectedIncomeMutation(month) const imports = useImports() + const [incomeEditor, setIncomeEditor] = useState(null) + const [deleteTarget, setDeleteTarget] = useState(null) + const [expectedOn, setExpectedOn] = useState(todayISO()) + const [sourceName, setSourceName] = useState('') + const [amount, setAmount] = useState('') + const [note, setNote] = useState('') + const [formError, setFormError] = useState('') const money = (value: number) => formatMoney(value, locale) const attentionImports = (imports.data ?? []).filter((item) => item.status === 'review_required') + const openIncomeEditor = (income?: ExpectedIncome) => { + setExpectedOn(income?.expectedOn ?? todayISO()) + setSourceName(income?.sourceName ?? '') + setAmount(income ? kopecksToInput(income.amountKopecks) : '') + setNote(income?.note ?? '') + setFormError('') + setIncomeEditor(income ?? 'new') + } + + const saveIncome = (event: FormEvent) => { + event.preventDefault() + const amountKopecks = parseAmountToKopecks(amount) + if (!amountKopecks || amountKopecks <= 0 || !expectedOn.startsWith(`${month}-`)) { + setFormError(t('overview.incomeInvalid')) + return + } + const payload = { expectedOn, amountKopecks, sourceName: sourceName.trim() || null, note: note.trim() || null } + const onSuccess = () => setIncomeEditor(null) + if (incomeEditor === 'new') incomeMutation.create.mutate(payload, { onSuccess }) + else if (incomeEditor) incomeMutation.update.mutate({ id: incomeEditor.id, payload }, { onSuccess }) + } + return (
{t('budget.spentTotal')}
{money(data.spentTotalKopecks)}
{t('overview.ofFunded')}
-
-
-

{t('overview.monthStory')}

- {t('overview.liveState')} -
-
    -
  1. {t('overview.poolAndIncome')}{money(data.actualPoolKopecks + data.fundedTotalKopecks)}
  2. -
  3. {t('overview.funded')}−{money(data.fundedTotalKopecks)}
  4. -
  5. {t('overview.spent')}−{money(data.spentTotalKopecks)}
  6. -
  7. {t('overview.poolRemaining')}{money(data.actualPoolKopecks)}
  8. -
+
+

{t('budget.categories')}

{t('overview.openBudget')}
+ + {(items) => items.filter((item) => !item.archived).length > 0 ? ( + + + + + + + + + + {items.filter((item) => !item.archived).map((item) => ( + + + + + + + + ))} +
{t('budget.categories')}
{t('common.name')}{t('budget.planned')}{t('budget.funded')}{t('budget.spent')}{t('budget.remaining')}
{categoryLabel(item, t)}{money(item.plannedKopecks)}{money(item.fundedKopecks)}{money(item.spentKopecks)}{money(item.availableKopecks)}
+ ) :

{t('budget.noCategories')}

} +
- +
+
+
+

{t('budget.expectedIncome')}

+ {data.status === 'open' ? : null} +
+ {data.expectedIncomes.length ? ( +
    + {data.expectedIncomes.map((income) => ( +
  • +
    {income.sourceName ?? t('budget.noSource')}{formatDate(income.expectedOn, locale)} · {t(`budget.income.status.${income.status}`)}
    + {money(income.amountKopecks)} + {data.status === 'open' ?
    + + +
    : null} +
  • + ))} +
+ ) :

{t('overview.noExpectedIncome')}

} +
+ +
)} -
-

{t('overview.categoryPulse')}

{t('overview.openBudget')}
- - {(items) => ( -
- {items.filter((item) => !item.archived).slice(0, 4).map((item) => { - const ratio = item.fundedKopecks > 0 ? Math.min(item.spentKopecks / item.fundedKopecks, 1) : 0 - return ( -
- {categoryLabel(item, t)} - {money(item.availableKopecks)} - {t('budget.available')} - -
- ) - })} -
- )} -
-
{t('overview.newOperation')}
+ setIncomeEditor(null)} title={t(incomeEditor === 'new' ? 'overview.addIncome' : 'overview.editIncome')}> + + setSourceName(event.target.value)} /> + setAmount(event.target.value)} required /> + setExpectedOn(event.target.value)} required /> + setNote(event.target.value)} /> + {formError ?

{formError}

: null} + + +
+ setDeleteTarget(null)} + onConfirm={() => { + if (deleteTarget) incomeMutation.remove.mutate(deleteTarget.id, { onSuccess: () => setDeleteTarget(null) }) + }} + />
) } diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css index c546865..2c35580 100644 --- a/frontend/src/styles/global.css +++ b/frontend/src/styles/global.css @@ -17,7 +17,7 @@ --amber-soft: #fff0c7; --red: #b42f25; --red-soft: #fbe2df; - --font-ui: 'Funnel Sans', 'Arial Narrow', Arial, sans-serif; + --font-ui: 'Funnel Sans', 'Onest', Arial, sans-serif; --font-data: 'Geist Mono', 'SFMono-Regular', Consolas, monospace; --sidebar: 238px; } @@ -206,6 +206,11 @@ a { text-decoration: none; } +.app-shell:lang(ru) .nav-pill, +.app-shell:lang(ru) .mobile-nav a { + font-family: 'Onest', sans-serif; +} + .nav-pill:hover { color: var(--white); background: #202020; } .nav-pill[aria-current='page'] { @@ -657,19 +662,29 @@ input[type='file']::file-selector-button { min-height: 30px; margin-right: 10px; .categories-heading { margin: 34px 0 14px; } .categories-heading .section-title { margin: 0; } +.budget-workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(275px, 350px); align-items: start; gap: 20px; } +.budget-category-column { min-width: 0; } +.budget-category-column .categories-heading { margin-top: 0; } +.budget-income-aside { min-width: 0; background: var(--white); border: 1px solid var(--line); } +.budget-income-aside .section-heading { margin: 0; padding: 14px; background: var(--paper-deep); } +.budget-income-aside > .muted { padding: 0 14px 14px; font-size: 12px; } -.manager-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(130px, auto) auto; gap: 10px; align-items: end; margin-bottom: 18px; } +.manager-form { display: grid; min-width: 0; gap: 14px; margin-bottom: 24px; padding-bottom: 24px; border-bottom: 1px solid #3d3d3a; } +.manager-form-fields { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 10px; } +.manager-form-fields .field { min-width: 0; } +.manager-form-fields .input { min-width: 0; } .manager-form .btn { min-height: 44px; } .manager-tabs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; margin-bottom: 14px; border: 1px solid #3d3d3a; } .manager-tabs .btn { min-width: 0; color: #858580; border: 0; border-right: 1px solid #3d3d3a; font-family: var(--font-data); font-size: 10px; } .manager-tabs .btn:last-child { border-right: 0; } .manager-tabs .btn-primary { color: var(--white); background: var(--blue); } .manager-list { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; border-top: 1px solid #3d3d3a; } -.manager-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 10px 0; border-bottom: 1px solid #3d3d3a; } +.manager-row { display: grid; gap: 10px; min-width: 0; padding: 13px 0; border-bottom: 1px solid #3d3d3a; } .manager-row-main { display: grid; gap: 3px; min-width: 0; } -.manager-row-name { font-weight: 500; } -.manager-row-meta { color: #858580; font-family: var(--font-data); font-size: 10px; } -.manager-row-actions .btn { min-height: 30px; padding: 5px 8px; font-size: 11px; } +.manager-row-name { overflow-wrap: anywhere; font-weight: 500; } +.manager-row-meta { color: #aaa9a5; font-family: var(--font-data); font-size: 10px; overflow-wrap: anywhere; } +.manager-row-actions { width: 100%; } +.manager-row-actions .btn { min-height: 32px; padding: 6px 9px; font-size: 11px; line-height: 1.25; white-space: normal; } .steps { display: grid; @@ -744,7 +759,26 @@ input[type='file']::file-selector-button { min-height: 30px; margin-right: 10px; .overview-page .page-header { margin-bottom: 20px; } .mobile-pool { display: none; } -.overview-workbench { display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(260px, 0.75fr); gap: 16px; margin-bottom: 28px; } +.overview-workbench { display: grid; grid-template-columns: minmax(0, 1fr) minmax(275px, 350px); align-items: start; gap: 20px; margin-bottom: 28px; } +.overview-categories { min-width: 0; } +.overview-categories .data-table { table-layout: fixed; } +.overview-categories .data-table th:first-child { width: 26%; } +.overview-categories .data-table td { white-space: nowrap; } +.overview-aside { display: grid; gap: 16px; min-width: 0; } +.expected-income { background: var(--white); border: 1px solid var(--line); } +.expected-income .section-heading { margin: 0; padding: 14px; background: var(--paper-deep); } +.expected-income-list { margin: 0; padding: 0; list-style: none; } +.expected-income-list li { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 14px; border-top: 1px solid var(--line); } +.expected-income-list li { flex-wrap: wrap; } +.expected-income-list li > div { display: grid; gap: 4px; min-width: 0; } +.expected-income-list .income-actions { display: flex; width: 100%; gap: 4px; } +.income-actions .btn { min-height: 28px; padding: 4px 8px; color: var(--blue-dark); font-size: 11px; } +.income-actions .btn:hover { color: var(--white); background: var(--blue-dark); } +.expected-income .section-heading .btn { min-height: 30px; padding: 5px 8px; color: var(--blue-dark); white-space: nowrap; } +.expected-income-list strong { overflow-wrap: anywhere; font-size: 13px; font-weight: 600; } +.expected-income-list small { color: var(--muted); font-size: 11px; } +.expected-income-list .num { flex-shrink: 0; font-size: 12px; } +.expected-income > .muted { padding: 0 14px 14px; font-size: 12px; } .month-story { padding: 18px 0 0; } .story-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); } .story-list li { display: flex; justify-content: space-between; gap: 20px; padding: 14px 4px; border-bottom: 1px solid var(--line); } @@ -852,9 +886,10 @@ input[type='file']::file-selector-button { min-height: 30px; margin-right: 10px; .mobile-pool strong { margin: 4px 0; font-size: 28px; } .overview-stats .stat:first-child { display: none; } .overview-stats .stat:nth-child(4) { display: block; } - .overview-workbench { display: block; margin-top: 20px; } + .overview-workbench { display: grid; grid-template-columns: minmax(0, 1fr); margin-top: 20px; } + .overview-categories .data-table { table-layout: auto; } .month-story { display: none; } - .decision-panel { margin-bottom: 24px; padding: 14px; color: var(--ink); background: var(--amber-soft); } + .decision-panel { padding: 14px; color: var(--ink); background: var(--amber-soft); } .decision-panel .section-heading { border-color: #d4ad52; } .decision-panel .section-heading h2, .decision-panel p, @@ -862,7 +897,8 @@ input[type='file']::file-selector-button { min-height: 30px; margin-right: 10px; .decision-panel li { border-color: #e0c57f; } .decision-panel .btn { color: var(--ink); background: transparent; border: 1px solid var(--ink); } .decision-panel .blocker-link { color: var(--blue); } - .manager-form { grid-template-columns: 1fr; } + .manager-form-fields { grid-template-columns: 1fr; } + .budget-workspace { grid-template-columns: minmax(0, 1fr); } .manager-row-actions { width: 100%; } .manager-row-actions .btn { flex: 1; } .pulse-grid { display: block; border: 0; } diff --git a/frontend/src/test/category-manager.test.tsx b/frontend/src/test/category-manager.test.tsx index cd9a75a..6354996 100644 --- a/frontend/src/test/category-manager.test.tsx +++ b/frontend/src/test/category-manager.test.tsx @@ -1,6 +1,6 @@ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest' import userEvent from '@testing-library/user-event' -import { within } from '@testing-library/react' +import { fireEvent, within } from '@testing-library/react' import { api } from '@/api/endpoints' import type { BudgetCategory, BudgetSummary, CategoryDefinition } from '@/api/types' import { BudgetPage } from '@/pages/BudgetPage' @@ -142,6 +142,12 @@ describe('BudgetPage category manager lifecycle', () => { expect(await screen.findByText('Category “Dining” created')).toBeInTheDocument() }) + it('closes the drawer when the backdrop is clicked', async () => { + const { screen, dialog } = await openManager() + fireEvent.click(dialog, { clientX: -10 }) + expect(screen.queryByRole('dialog', { name: 'Manage categories' })).not.toBeInTheDocument() + }) + it('creates a category with multiple MCC codes', async () => { createCategoryMock.mockResolvedValue(definition({ id: 'def-new', mccCodes: [5999, 5994] })) const { dialog } = await openManager() diff --git a/frontend/src/test/expected-income.test.tsx b/frontend/src/test/expected-income.test.tsx new file mode 100644 index 0000000..4164f21 --- /dev/null +++ b/frontend/src/test/expected-income.test.tsx @@ -0,0 +1,82 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import userEvent from '@testing-library/user-event' +import { within } from '@testing-library/react' +import { api } from '@/api/endpoints' +import type { BudgetSummary, ExpectedIncome } from '@/api/types' +import { OverviewPage } from '@/pages/OverviewPage' +import { currentMonth, todayISO } from '@/lib/dates' +import { renderWithProviders } from './helpers' + +vi.mock('@/api/endpoints', () => ({ + api: { + budget: { + summary: vi.fn(), categories: vi.fn(), + createExpectedIncome: vi.fn(), updateExpectedIncome: vi.fn(), deleteExpectedIncome: vi.fn(), + }, + imports: { list: vi.fn() }, + }, +})) + +const month = currentMonth() +const income: ExpectedIncome = { + id: 'income-1', expectedOn: todayISO(), amountKopecks: 250000, + sourceName: 'Salary', note: null, matchedKopecks: 0, status: 'expected', +} +const summary: BudgetSummary = { + month, status: 'open', projectedPoolKopecks: 250000, actualPoolKopecks: 0, + plannedTotalKopecks: 0, fundedTotalKopecks: 0, spentTotalKopecks: 0, + availableKopecks: 0, warnings: [], blockers: [], expectedIncomes: [income], +} + +describe('This month expected income', () => { + beforeEach(() => { + vi.mocked(api.budget.summary).mockResolvedValue(summary) + vi.mocked(api.budget.categories).mockResolvedValue([{ + id: 'groceries', name: 'Groceries', nameKey: null, kind: 'monthly', system: false, + archived: false, creditAccountId: null, plannedKopecks: 500000, + fundedKopecks: 300000, spentKopecks: 100000, availableKopecks: 200000, + }]) + vi.mocked(api.imports.list).mockResolvedValue([]) + }) + afterEach(() => vi.clearAllMocks()) + + it('shows income alongside the category table without category management', async () => { + const screen = renderWithProviders() + expect(await screen.findByText('Salary')).toBeInTheDocument() + expect(screen.getByRole('table', { name: 'Categories' })).toBeInTheDocument() + expect(screen.queryByRole('button', { name: 'Manage categories' })).not.toBeInTheDocument() + }) + + it('creates an expected income for the current month', async () => { + vi.mocked(api.budget.createExpectedIncome).mockResolvedValue(income) + const screen = renderWithProviders() + await screen.findByText('Salary') + await userEvent.click(screen.getByRole('button', { name: 'Add income' })) + const dialog = screen.getByRole('dialog', { name: 'Add income' }) + await userEvent.type(within(dialog).getByLabelText('Source'), 'Side job') + await userEvent.type(within(dialog).getByLabelText('Amount'), '1234.50') + await userEvent.click(within(dialog).getByRole('button', { name: 'Save' })) + expect(api.budget.createExpectedIncome).toHaveBeenCalledWith(month, { + expectedOn: todayISO(), amountKopecks: 123450, sourceName: 'Side job', note: null, + }) + }) + + it('edits and deletes an existing expected income', async () => { + vi.mocked(api.budget.updateExpectedIncome).mockResolvedValue(income) + vi.mocked(api.budget.deleteExpectedIncome).mockResolvedValue(undefined) + const screen = renderWithProviders() + await screen.findByText('Salary') + await userEvent.click(screen.getByRole('button', { name: 'Edit' })) + const editor = screen.getByRole('dialog', { name: 'Edit expected income' }) + await userEvent.clear(within(editor).getByLabelText('Amount')) + await userEvent.type(within(editor).getByLabelText('Amount'), '3500') + await userEvent.click(within(editor).getByRole('button', { name: 'Save' })) + expect(api.budget.updateExpectedIncome).toHaveBeenCalledWith(month, 'income-1', { + expectedOn: todayISO(), amountKopecks: 350000, sourceName: 'Salary', note: null, + }) + await userEvent.click(screen.getByRole('button', { name: 'Delete' })) + const confirm = screen.getByRole('dialog', { name: 'Delete expected income' }) + await userEvent.click(within(confirm).getByRole('button', { name: 'Delete' })) + expect(api.budget.deleteExpectedIncome).toHaveBeenCalledWith(month, 'income-1') + }) +}) diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index 6e20f5f..ab102f2 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -1,33 +1,33 @@ { - "0": "Category", + "0": "imports/router.py", "1": "budgeting/router.py", - "2": "db/models.py", - "3": "AppError", - "4": "imports/router.py", + "2": "Base", + "3": "main.py", + "4": "test_import_savings.py", "5": "alfa_xlsx.py", "6": "system-account-picker.test.tsx", "7": "types.ts", - "8": "router.tsx", + "8": "LoginPage.tsx", "9": "ledger/router.py", "10": "@testing-library/jest-dom", "11": "compilerOptions", - "12": "ReviewQueuePage.tsx", - "13": "@testing-library/user-event", + "12": "AnalyticsPage.tsx", + "13": "mcc.py", "14": "devDependencies", "15": "ledger/service.py", "16": "dependencies", - "17": "ImportDetailPage.tsx", + "17": "useOperations.ts", "18": "OperationsPage.tsx", - "19": "Base", + "19": "analytics/service.py", "20": "apiErrors.ts", - "21": "adapters/base.py", + "21": "test_adapter_contracts.py", "22": "BudgetPage.tsx", "23": "client.ts", - "24": "fields.tsx", + "24": "imports/service.py", "25": "Docker Compose Development Stack", "26": "Financial Space", "27": "scripts", - "28": "@types/react", + "28": "router.tsx", "29": "General Pool", "30": "TestBaseContract", "31": "Per-File Envelope Encryption", @@ -37,20 +37,20 @@ "35": "Closed Beta Launch Gates", "36": "package.json", "37": "Financial Tracker MVP", - "38": "test_adapter_contracts.py", + "38": "TestRocketbankDebitContract", "39": "generate-api.mjs", "40": "schema.d.ts", "41": "test_api.py", "42": "i18n-parity.test.ts", "43": "Expected Income", - "44": "helpers.tsx", - "45": "ledger/models.py", + "44": "api", + "45": "AccountsPage.tsx", "46": "category-manager.test.tsx", "47": "graphify", - "48": "@types/react-dom", + "48": "index.ts", "49": "typescript-eslint", "50": "Ближайший край: накопления, категории и блокировки бюджета", - "51": "vitest", + "51": "RocketbankDebitPdfAdapter", "52": "Favicon SVG (ledger lines icon)", "53": "init-app-role.sh", "54": "app/__init__.py", @@ -62,36 +62,43 @@ "60": "vite.config.ts", "61": "finance-backend", "62": "LocalDirectoryBlobStore", - "63": "OzonDebitPdfAdapter", + "63": "TestOzonDebitContract", "64": "Gitea CI and real statement imports", "65": "20260918_0002_hold_lifecycle.py", "66": "eslint-plugin-react-hooks", "67": "import-hold-resolution.test.tsx", "68": "budgeting/service.py", "69": "TestAlfaDebitContract", - "70": "vite", - "71": "mcc.py", - "72": "TestAlfaSavingsRule", + "70": "AppLayout.tsx", + "71": "20260922_0003_savings_system.py", + "72": "jsdom", "73": "savings-convert-revert.test.tsx", "74": "get_settings", "75": "ColumnChart.tsx", "76": "dependencies.py", "77": "AGENTS.md", "78": "graphify.js", - "79": "test_savings.py", + "79": "Session", "80": "test_category_definitions.py", "81": "budget-plan.test.tsx", - "82": "imports/service.py", + "82": "TestAlfaSavingsRule", "83": "exports/service.py", - "84": "test_imports.py", + "84": "@testing-library/react", "85": "identity/service.py", - "86": "Session", + "86": "test_import_holds.py", "87": "get_or_create_period", "88": "20260923_0005_optional_hold_reason.py", - "89": "test_import_savings.py", - "90": "conftest.py", + "89": "typescript", + "90": "useAuth.ts", "91": "test_review_queue_batch.py", - "92": "review-queue-save.test.tsx", - "94": "account-adjustment.test.tsx", - "99": "0001-fixes.md" + "92": "@vitejs/plugin-react", + "93": "useImports.ts", + "94": "describeApiError", + "95": "app_error_handler", + "96": "review-queue-save.test.tsx", + "97": "перевод_между_своими.md", + "98": "0002-fixes.md", + "99": "0001-fixes.md", + "100": "detect_adapter", + "101": "review-queue-month.test.tsx" } diff --git a/graphify-out/.graphify_labels.json.sig b/graphify-out/.graphify_labels.json.sig index d870adb..61eadef 100644 --- a/graphify-out/.graphify_labels.json.sig +++ b/graphify-out/.graphify_labels.json.sig @@ -1 +1 @@ -{"0": "6d1d9dee2594feb8", "1": "6ce69c6c91bfb10d", "2": "c2a9c6c75ef7b06e", "3": "07ad68ae268274e3", "4": "6e29ff77b331c271", "5": "753b54d66d56a181", "6": "fafcd7f26e85d11e", "7": "7196de2bd58ce7b6", "8": "a1304e2f6d040c08", "9": "12777a923784a450", "10": "0a5a0ba97778625e", "11": "f039d542469fefc7", "12": "68a6ed0d02f19f50", "13": "8744084aeb65fbd3", "14": "b3e752fefc98c002", "15": "2aa78b1e6532083d", "16": "8ef6cf9118db3195", "17": "8baf7195f33c896e", "18": "89eb4ee52c62e004", "19": "ba69db1a2f1f3a58", "20": "683cad078c7e0ed9", "21": "ca6369f4becd6192", "22": "f4a28fa280943a77", "23": "f3004ec80ca9f448", "24": "8965526f063eed24", "25": "f01c92b243645b4e", "26": "54c3380f579b6729", "27": "d8d767c824110809", "28": "8bc2e2fc5c336465", "29": "3147966ac3ee3b0f", "30": "7552b18e805318e1", "31": "099ee7edfccfb30f", "32": "0778a13a682f0cbb", "33": "6be20de557b963e9", "34": "da7b9f31790187c3", "35": "17bba31989deabe4", "36": "267c43d4a566a343", "37": "cff206ec60c41144", "38": "b6d52a30ac873a97", "39": "0e87c765d5713ad6", "40": "ce680f01cc87ac2b", "41": "24380e4087fb70d5", "42": "c58209407d4237e8", "43": "54905c779f6306ec", "44": "b6e6b302dfb2b4b7", "45": "c484c809d185e550", "46": "ab5b47947fe3bf98", "47": "2f8c667574e48967", "48": "08332675f638af21", "49": "4ed4ad08eaab7c1c", "50": "39e65f28c37e0e46", "51": "ba6724f5637cd5d9", "52": "fdf8b4d4bf2be849", "53": "66f8ffc9c3fbedf2", "54": "73723cec09ed2417", "55": "f9e8dac18e2e7bdf", "56": "86619fe91fc50452", "57": "8a3d1d863ddb4d2f", "58": "33678aa2c758e454", "59": "99c0fcbdc4f53a0e", "60": "cd42295e6b9fcac1", "61": "3712295d0a11267c", "62": "f787d08450bb4ac6", "63": "337e92dfeec532be", "64": "fa2cf116b4b9871b", "65": "f3a0edb87b006f25", "66": "a0aa708a9e56bca1", "67": "d58d1cd140a5fa40", "68": "3e5a785c54610ba0", "69": "0d74f7f6d933b4d1", "70": "e049e07b5afc08cf", "71": "c5240b928a15b0fa", "72": "2b92b704e5454347", "73": "e404eb8a5c1d93eb", "74": "ec0076e638dfa420", "75": "c11d4d615ce6b927", "76": "36f3b631daec8343", "77": "97ec841e4f367258", "78": "c9051bc3ad4170f1", "79": "0f585e9a81c4fb6c", "80": "f091cbed551517ed", "81": "30a50b463d66a82d", "82": "80551df1b95b31a0", "83": "9a369c70bcf0858b", "84": "9eb0c7e75d99ef54", "85": "ad0253a8a1e41307", "86": "98ecf4f0948d7a51", "87": "eeef008da0eeea12", "88": "f6b2e16972be0df8", "89": "bb20719f64caa678", "90": "491a658d3322d1ec", "91": "d520dd258c357f5d", "92": "48aeb4d25174096d", "94": "7f935939209226f1", "99": "719211c5f13f5583"} \ No newline at end of file +{"0": "a3eec3e115dd18ab", "1": "c27501115524f813", "2": "aebb6d2f52ce7e1c", "3": "4c33cf87d94fa437", "4": "6664a6bcf0c8fc35", "5": "755dc69bb9e66ed9", "6": "5f666b37102bd0e3", "7": "b5b13d699ed2bb2c", "8": "7401aeb7ceaeda0d", "9": "12777a923784a450", "10": "0a5a0ba97778625e", "11": "f039d542469fefc7", "12": "22ac35c4ca449ea9", "13": "c5240b928a15b0fa", "14": "6e988a39e737f2e4", "15": "19c9db4d67450852", "16": "9fe5c851ea02c082", "17": "784e36d3016ebecb", "18": "170db1e7ebfb683d", "19": "c21f2f279d69d652", "20": "85e49032e2cac2d3", "21": "ba54fd97c91a51d3", "22": "7a54822cd1958230", "23": "f3004ec80ca9f448", "24": "3ced84211744963d", "25": "f01c92b243645b4e", "26": "54c3380f579b6729", "27": "d8d767c824110809", "28": "b165fb5e39a272ef", "29": "3147966ac3ee3b0f", "30": "7552b18e805318e1", "31": "099ee7edfccfb30f", "32": "0778a13a682f0cbb", "33": "6be20de557b963e9", "34": "da7b9f31790187c3", "35": "17bba31989deabe4", "36": "267c43d4a566a343", "37": "cff206ec60c41144", "38": "c9cd0ce5f2cf7cba", "39": "0e87c765d5713ad6", "40": "ce680f01cc87ac2b", "41": "24380e4087fb70d5", "42": "c58209407d4237e8", "43": "54905c779f6306ec", "44": "edf6a7f7e4a244de", "45": "ad8dc3b0df5922f3", "46": "ab5b47947fe3bf98", "47": "2f8c667574e48967", "48": "14650a356e308605", "49": "4ed4ad08eaab7c1c", "50": "39e65f28c37e0e46", "51": "2fb44d8350e43e52", "52": "fdf8b4d4bf2be849", "53": "66f8ffc9c3fbedf2", "54": "73723cec09ed2417", "55": "f9e8dac18e2e7bdf", "56": "86619fe91fc50452", "57": "8a3d1d863ddb4d2f", "58": "015eb51e77115067", "59": "99c0fcbdc4f53a0e", "60": "cd42295e6b9fcac1", "61": "3712295d0a11267c", "62": "f787d08450bb4ac6", "63": "dd6c938c47e2c6c9", "64": "fa2cf116b4b9871b", "65": "f3a0edb87b006f25", "66": "a0aa708a9e56bca1", "67": "d58d1cd140a5fa40", "68": "cadc0543d2eb4318", "69": "0d74f7f6d933b4d1", "70": "c490dc676aca8db4", "71": "ea7c38b08bfb0f43", "72": "12858d9498b8f2dc", "73": "e404eb8a5c1d93eb", "74": "ef6090e1505912ff", "75": "c11d4d615ce6b927", "76": "8c9859706b3f23f9", "77": "97ec841e4f367258", "78": "c9051bc3ad4170f1", "79": "366cb4d699d4af5d", "80": "f091cbed551517ed", "81": "5bbe65ee1b43d1d4", "82": "cd194738a7a82be2", "83": "cf129a9b660744ef", "84": "2735bfc7a6304c2e", "85": "879153c4e9273e22", "86": "d50761d9712fa60c", "87": "33d576b3c0601a2a", "88": "f6b2e16972be0df8", "89": "c0b1e53d3ba8b2bf", "90": "f3e64dc4e14483ba", "91": "d520dd258c357f5d", "92": "40c7bb70cfb7a834", "93": "7bd0d5828fb0701d", "94": "de541478274e13ab", "95": "511e2b5f5a529368", "96": "48aeb4d25174096d", "97": "7134dc1a92d0f766", "98": "42502f5fa028f50d", "99": "719211c5f13f5583", "100": "06d1498c4a5206dd", "101": "3fc1e93cf13ab7a9"} \ No newline at end of file diff --git a/graphify-out/2026-09-23/.graphify_labels.json b/graphify-out/2026-09-23/.graphify_labels.json index 6e20f5f..05e0790 100644 --- a/graphify-out/2026-09-23/.graphify_labels.json +++ b/graphify-out/2026-09-23/.graphify_labels.json @@ -1,9 +1,9 @@ { - "0": "Category", + "0": "Settings", "1": "budgeting/router.py", - "2": "db/models.py", - "3": "AppError", - "4": "imports/router.py", + "2": "Base", + "3": "main.py", + "4": "imports/service.py", "5": "alfa_xlsx.py", "6": "system-account-picker.test.tsx", "7": "types.ts", @@ -11,25 +11,25 @@ "9": "ledger/router.py", "10": "@testing-library/jest-dom", "11": "compilerOptions", - "12": "ReviewQueuePage.tsx", - "13": "@testing-library/user-event", + "12": "BudgetPage.tsx", + "13": "mcc.py", "14": "devDependencies", "15": "ledger/service.py", "16": "dependencies", - "17": "ImportDetailPage.tsx", + "17": "useOperations.ts", "18": "OperationsPage.tsx", - "19": "Base", + "19": "Session", "20": "apiErrors.ts", - "21": "adapters/base.py", - "22": "BudgetPage.tsx", + "21": "UnsupportedStatementLayout", + "22": "ImportDetailPage.tsx", "23": "client.ts", - "24": "fields.tsx", + "24": "set_space_context", "25": "Docker Compose Development Stack", "26": "Financial Space", "27": "scripts", - "28": "@types/react", + "28": "ImportsPage.tsx", "29": "General Pool", - "30": "TestBaseContract", + "30": "test_adapter_contracts.py", "31": "Per-File Envelope Encryption", "32": "Operation", "33": "Versioned Statement Imports", @@ -37,20 +37,20 @@ "35": "Closed Beta Launch Gates", "36": "package.json", "37": "Financial Tracker MVP", - "38": "test_adapter_contracts.py", + "38": "TestRocketbankDebitContract", "39": "generate-api.mjs", "40": "schema.d.ts", "41": "test_api.py", "42": "i18n-parity.test.ts", "43": "Expected Income", - "44": "helpers.tsx", - "45": "ledger/models.py", + "44": "api", + "45": "fields.tsx", "46": "category-manager.test.tsx", "47": "graphify", - "48": "@types/react-dom", + "48": "BudgetBlockers.tsx", "49": "typescript-eslint", "50": "Ближайший край: накопления, категории и блокировки бюджета", - "51": "vitest", + "51": "UTCDateTime", "52": "Favicon SVG (ledger lines icon)", "53": "init-app-role.sh", "54": "app/__init__.py", @@ -62,36 +62,40 @@ "60": "vite.config.ts", "61": "finance-backend", "62": "LocalDirectoryBlobStore", - "63": "OzonDebitPdfAdapter", + "63": "TestOzonDebitContract", "64": "Gitea CI and real statement imports", "65": "20260918_0002_hold_lifecycle.py", "66": "eslint-plugin-react-hooks", "67": "import-hold-resolution.test.tsx", "68": "budgeting/service.py", "69": "TestAlfaDebitContract", - "70": "vite", - "71": "mcc.py", - "72": "TestAlfaSavingsRule", + "70": "celery_app.py", + "71": "20260922_0003_savings_system.py", + "72": "jsdom", "73": "savings-convert-revert.test.tsx", "74": "get_settings", "75": "ColumnChart.tsx", - "76": "dependencies.py", + "76": "spaces/router.py", "77": "AGENTS.md", "78": "graphify.js", - "79": "test_savings.py", + "79": "AppError", "80": "test_category_definitions.py", "81": "budget-plan.test.tsx", - "82": "imports/service.py", + "82": "spaces/service.py", "83": "exports/service.py", - "84": "test_imports.py", + "84": "@testing-library/react", "85": "identity/service.py", - "86": "Session", + "86": "test_import_holds.py", "87": "get_or_create_period", "88": "20260923_0005_optional_hold_reason.py", - "89": "test_import_savings.py", + "89": "typescript", "90": "conftest.py", "91": "test_review_queue_batch.py", - "92": "review-queue-save.test.tsx", - "94": "account-adjustment.test.tsx", + "92": "@vitejs/plugin-react", + "93": "useImports.ts", + "95": "dependencies.py", + "96": "_login", + "97": "перевод_между_своими.md", + "98": "0002-fixes.md", "99": "0001-fixes.md" } diff --git a/graphify-out/2026-09-23/GRAPH_REPORT.md b/graphify-out/2026-09-23/GRAPH_REPORT.md index 57d89e4..37df96d 100644 --- a/graphify-out/2026-09-23/GRAPH_REPORT.md +++ b/graphify-out/2026-09-23/GRAPH_REPORT.md @@ -1,25 +1,25 @@ # Graph Report - finance (2026-09-23) ## Corpus Check -- 187 files · ~90,160 words +- 190 files · ~91,840 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 1667 nodes · 5182 edges · 95 communities (72 shown, 16 thin omitted) -- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 91 edges (avg confidence: 0.93) +- 1702 nodes · 5362 edges · 99 communities (74 shown, 16 thin omitted) +- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 96 edges (avg confidence: 0.93) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `63d06501` +- Built from commit: `970fe9da` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). ## Community Hubs (Navigation) -- Category +- Settings - budgeting/router.py -- db/models.py -- AppError -- imports/router.py +- Base +- main.py +- imports/service.py - alfa_xlsx.py - system-account-picker.test.tsx - types.ts @@ -27,25 +27,25 @@ - ledger/router.py - @testing-library/jest-dom - compilerOptions -- ReviewQueuePage.tsx -- @testing-library/user-event +- BudgetPage.tsx +- mcc.py - devDependencies - ledger/service.py - dependencies -- ImportDetailPage.tsx +- useOperations.ts - OperationsPage.tsx -- Base +- Session - apiErrors.ts -- adapters/base.py -- BudgetPage.tsx +- UnsupportedStatementLayout +- ImportDetailPage.tsx - client.ts -- fields.tsx +- set_space_context - Docker Compose Development Stack - Financial Space - scripts -- @types/react +- ImportsPage.tsx - General Pool -- TestBaseContract +- test_adapter_contracts.py - Per-File Envelope Encryption - Operation - Versioned Statement Imports @@ -53,68 +53,70 @@ - Closed Beta Launch Gates - package.json - Financial Tracker MVP -- test_adapter_contracts.py +- TestRocketbankDebitContract - generate-api.mjs - schema.d.ts - test_api.py - i18n-parity.test.ts - Expected Income -- helpers.tsx -- ledger/models.py +- api +- fields.tsx - category-manager.test.tsx - graphify -- @types/react-dom +- BudgetBlockers.tsx - typescript-eslint - Ближайший край: накопления, категории и блокировки бюджета -- vitest +- UTCDateTime - Favicon SVG (ledger lines icon) - init-app-role.sh - Payee - test_private_fixtures.py - finance-backend - LocalDirectoryBlobStore -- OzonDebitPdfAdapter +- TestOzonDebitContract - Gitea CI and real statement imports - 20260918_0002_hold_lifecycle.py - eslint-plugin-react-hooks - import-hold-resolution.test.tsx - budgeting/service.py - TestAlfaDebitContract -- vite -- mcc.py -- TestAlfaSavingsRule +- celery_app.py +- 20260922_0003_savings_system.py +- jsdom - savings-convert-revert.test.tsx - get_settings - ColumnChart.tsx -- dependencies.py +- spaces/router.py - AGENTS.md -- test_savings.py +- AppError - test_category_definitions.py - budget-plan.test.tsx -- imports/service.py +- spaces/service.py - exports/service.py -- test_imports.py +- @testing-library/react - identity/service.py -- Session +- test_import_holds.py - get_or_create_period - 20260923_0005_optional_hold_reason.py -- test_import_savings.py +- typescript - conftest.py - test_review_queue_batch.py -- review-queue-save.test.tsx -- account-adjustment.test.tsx +- @vitejs/plugin-react +- useImports.ts +- dependencies.py +- _login ## God Nodes (most connected - your core abstractions) -1. `Session` - 211 edges -2. `AppError` - 72 edges +1. `Session` - 221 edges +2. `AppError` - 76 edges 3. `Base` - 48 edges -4. `conflict()` - 43 edges -5. `get_settings()` - 40 edges -6. `PkMixin` - 40 edges -7. `record()` - 39 edges -8. `TimestampMixin` - 38 edges -9. `StatementDocument` - 36 edges -10. `create_expense()` - 36 edges +4. `record()` - 44 edges +5. `conflict()` - 43 edges +6. `get_settings()` - 40 edges +7. `PkMixin` - 40 edges +8. `get_or_create_period()` - 39 edges +9. `TimestampMixin` - 38 edges +10. `bad_request()` - 36 edges ## Surprising Connections (you probably didn't know these) - `Typed Same-Origin API Client` --conceptually_related_to--> `Same-Origin Reverse Proxy` [INFERRED] @@ -136,43 +138,39 @@ - **Financial Space Tenancy Boundary** — context_financial_space, context_membership, docs_adr_0001_financial_space_ownership_and_rls_defense_in_depth_authorization, docs_adr_0001_financial_space_ownership_and_rls_transaction_local_rls, docs_adr_0001_financial_space_ownership_and_rls_cross_space_integrity [EXTRACTED 1.00] - **Safe Statement Import Flow** — context_statement_import, context_parse_run, context_source_record, docs_adr_0003_versioned_statement_imports_immutable_statement_document, docs_adr_0003_versioned_statement_imports_conservative_deduplication, docs_adr_0003_versioned_statement_imports_atomic_confirm_revert [EXTRACTED 1.00] -## Communities (95 total, 16 thin omitted) - -### Community 0 - "Category" -Cohesion: 0.20 -Nodes (15): balances(), cash_flow(), category_spend(), plan_fact(), date, UUID, category_for_mcc(), Category owning the MCC code, else the system «Остальное» fallback. (+7 more) +## Communities (99 total, 16 thin omitted) ### Community 1 - "budgeting/router.py" Cohesion: 0.11 -Nodes (52): balances(), cash_flow(), category_spend(), plan_fact(), Context, date, Db, get (+44 more) +Nodes (59): balances(), cash_flow(), category_spend(), plan_fact(), Context, date, Db, get (+51 more) -### Community 2 - "db/models.py" +### Community 2 - "Base" +Cohesion: 0.15 +Nodes (34): downgrade(), upgrade(), AuditEvent, Append-only domain/security event. Never stores raw financial payloads., ExpectedIncome, ExpectedIncomeMatch, FundingMovement, PeriodClosure (+26 more) + +### Community 3 - "main.py" Cohesion: 0.17 -Nodes (23): AuditEvent, Append-only domain/security event. Never stores raw financial payloads., ExpectedIncome, ExpectedIncomeMatch, FundingMovement, PeriodClosure, PlanAssignment, Links one actual income operation to one expected income (1:1 per operation). (+15 more) +Nodes (17): get_db(), get_engine(), get_session_factory(), sessionmaker, app_error_handler(), health(), healthz(), get (+9 more) -### Community 3 - "AppError" -Cohesion: 0.19 -Nodes (11): AppError, Any, Domain error rendered as a machine-readable JSON error payload., unprocessable(), decrypt_file(), encrypt_file(), EncryptedFile, Per-file random DEK; DEK wrapped with the KEK from the secret manager. (+3 more) - -### Community 4 - "imports/router.py" -Cohesion: 0.05 -Nodes (79): _check_constraints(), downgrade(), _has_column(), _has_row(), _has_unique_constraint(), _normalized_sqltext(), Savings system resources, adjustments and reversible conversions., Swap a check constraint for a new value list, dialect-safely. Fresh databases… (+71 more) +### Community 4 - "imports/service.py" +Cohesion: 0.06 +Nodes (105): datetime, utcnow(), RequestContext, magic_kind(), ParseRun, Immutable extracted bank fact with document origin coordinates., SourceRecord, StatementDocument (+97 more) ### Community 5 - "alfa_xlsx.py" -Cohesion: 0.12 -Nodes (32): AlfaCreditXlsxAdapter, AlfaDebitXlsxAdapter, _AlfaHeaderMeta, AlfaXlsxAdapterBase, _cell_str(), _debit_find_header(), _debit_header_metadata(), _debit_header_value() (+24 more) +Cohesion: 0.15 +Nodes (23): _AlfaHeaderMeta, AlfaXlsxAdapterBase, _cell_str(), _debit_find_header(), _debit_header_metadata(), _debit_header_value(), _debit_norm(), _debit_operation_rows() (+15 more) ### Community 6 - "system-account-picker.test.tsx" Cohesion: 0.11 -Nodes (15): AdjustBalanceResult, BudgetCategory, Operation, Page, budgetCategoriesMock, listAccountsMock, listOperationsMock, categoriesMock (+7 more) +Nodes (13): BudgetCategory, Page, budgetCategoriesMock, listAccountsMock, listOperationsMock, categoriesMock, importsListMock, importSummary (+5 more) ### Community 7 - "types.ts" -Cohesion: 0.08 -Nodes (35): AccountStatus, AccountType, AdjustBalancePayload, BalanceItem, BalancesReport, BudgetStatus, BudgetWarning, CashFlowMonth (+27 more) +Cohesion: 0.07 +Nodes (38): AcceptInvitePayload, AccountStatus, AccountType, AdjustBalancePayload, BalanceItem, BalancesReport, BudgetStatus, BudgetWarning (+30 more) ### Community 8 - "router.tsx" -Cohesion: 0.07 -Nodes (43): AcceptInvitePayload, LoginPayload, PasswordResetPayload, AcceptInvitePage, AccountsPage, AnalyticsPage, BudgetPage, ImportDetailPage (+35 more) +Cohesion: 0.08 +Nodes (45): AcceptInvitePage, AccountsPage, AnalyticsPage, BudgetPage, LoginPage, OperationsPage, OverviewPage, RequireAuth() (+37 more) ### Community 9 - "ledger/router.py" Cohesion: 0.15 @@ -182,53 +180,57 @@ Nodes (38): account_json(), AccountBody, accounts(), adjust_balance(), AdjustBal Cohesion: 0.07 Nodes (28): compilerOptions, baseUrl, esModuleInterop, forceConsistentCasingInFileNames, isolatedModules, jsx, lib, module (+20 more) -### Community 12 - "ReviewQueuePage.tsx" -Cohesion: 0.09 -Nodes (43): NotFoundPage, PlanFactBars(), PlanFactBarsProps, PlanFactRow, EmptyState(), EmptyStateProps, MonthSwitcher(), MonthSwitcherProps (+35 more) +### Community 12 - "BudgetPage.tsx" +Cohesion: 0.11 +Nodes (40): NotFoundPage, PlanFactBars(), PlanFactBarsProps, PlanFactRow, MonthSwitcher(), MonthSwitcherProps, PageHeader(), PageHeaderProps (+32 more) + +### Community 13 - "mcc.py" +Cohesion: 0.14 +Nodes (23): _create_tenant_policy(), _default_keys(), downgrade(), _has_table(), _space_ids(), upgrade(), _default_categories(), default_category_system_keys() (+15 more) ### Community 14 - "devDependencies" -Cohesion: 0.10 -Nodes (21): eslint, @eslint/js, eslint-plugin-jsx-a11y, devDependencies, eslint, @eslint/js, eslint-plugin-jsx-a11y, globals (+13 more) +Cohesion: 0.09 +Nodes (23): eslint, @eslint/js, eslint-plugin-jsx-a11y, devDependencies, eslint, @eslint/js, eslint-plugin-jsx-a11y, globals (+15 more) ### Community 15 - "ledger/service.py" -Cohesion: 0.13 -Nodes (48): ensure_others_category(), The system «Остальное» fallback category, created on first use., Operation, Posting, Signed balance change of one account within one operation. Sign convention…, User financial fact. amount_kopecks is always positive; direction lives in…, account_balance(), _apply_suggestion() (+40 more) +Cohesion: 0.15 +Nodes (45): Operation, Posting, Signed balance change of one account within one operation. Sign convention…, User financial fact. amount_kopecks is always positive; direction lives in…, account_balance(), _apply_suggestion(), archive_account(), categorize_batch() (+37 more) ### Community 16 - "dependencies" -Cohesion: 0.09 -Nodes (23): @fontsource/funnel-sans, @fontsource/geist-mono, dependencies, @fontsource/funnel-sans, @fontsource/geist-mono, @hookform/resolvers, i18next, react (+15 more) - -### Community 17 - "ImportDetailPage.tsx" Cohesion: 0.08 -Nodes (45): api, invalidationRoots, queryKeys, SESSION_ROOT, sessionInvalidationRoot, SPACE_ROOT, spaceInvalidationRoot, HoldResolutionAction (+37 more) +Nodes (25): @fontsource/funnel-sans, @fontsource/geist-mono, @fontsource/onest, dependencies, @fontsource/funnel-sans, @fontsource/geist-mono, @fontsource/onest, @hookform/resolvers (+17 more) + +### Community 17 - "useOperations.ts" +Cohesion: 0.15 +Nodes (17): invalidationRoots, queryKeys, SESSION_ROOT, sessionInvalidationRoot, SPACE_ROOT, spaceInvalidationRoot, CategorizeBatchPayload, CreateOperationPayload (+9 more) ### Community 18 - "OperationsPage.tsx" -Cohesion: 0.11 -Nodes (46): CategorizeBatchPayload, CreateOperationPayload, isSystemAccount(), Locale, useAccounts(), useActiveAccounts(), useUserAccounts(), useCategorizeBatch() (+38 more) +Cohesion: 0.12 +Nodes (40): Account, isSystemAccount(), Operation, useAccounts(), useActiveAccounts(), useAdjustBalance(), useArchiveAccount(), useCreateAccount() (+32 more) -### Community 19 - "Base" -Cohesion: 0.15 -Nodes (22): downgrade(), upgrade(), BankCategoryMapping, CategorizationRule, CategoryMcc, IncomeSource, MccCode, Payee (+14 more) +### Community 19 - "Session" +Cohesion: 0.12 +Nodes (33): balances(), cash_flow(), category_spend(), plan_fact(), date, UUID, _balance_until(), ensure_credit_reserve_category() (+25 more) ### Community 20 - "apiErrors.ts" -Cohesion: 0.09 -Nodes (24): isApiError(), BudgetBlocker, App(), queryClient, AppRoutes(), blockerCta(), blockerText(), BudgetBlockers() (+16 more) +Cohesion: 0.11 +Nodes (19): isApiError(), Locale, App(), queryClient, AppRoutes(), LangSwitcher(), ToastApi, ToastContext (+11 more) -### Community 21 - "adapters/base.py" -Cohesion: 0.12 -Nodes (20): account_fingerprint(), _mask_digits(), money_to_kopecks(), normalize_description(), date, Parse statement money strings like '-1 234,56 RUR', '+ 500.00 ₽', '12 345'.…, record_fingerprint(), StatementDraft (+12 more) - -### Community 22 - "BudgetPage.tsx" +### Community 21 - "UnsupportedStatementLayout" Cohesion: 0.14 -Nodes (27): CreatableCategoryKind, CategoryManagerModal(), CREATE_KINDS, CreateCategoryForm(), MccCodesModal(), parseMccCodes(), RenameModal(), Badge() (+19 more) +Nodes (22): account_fingerprint(), amount_to_kopecks(), _mask_digits(), money_to_kopecks(), Parse statement money strings like '-1 234,56 RUR', '+ 500.00 ₽', '12 345'.…, Stable diagnostic for unknown bank layouts; never guesses., SourceRow, StatementDraft (+14 more) + +### Community 22 - "ImportDetailPage.tsx" +Cohesion: 0.09 +Nodes (40): CreatableCategoryKind, CreateCategoryPayload, PatchCategoryDefinitionPayload, ImportDetailPage, CategoryManagerModal(), CREATE_KINDS, CreateCategoryForm(), MccCodesModal() (+32 more) ### Community 23 - "client.ts" Cohesion: 0.26 Nodes (10): apiClient, ApiError, buildUrl(), ErrorEnvelope, parseErrorEnvelope(), QueryValue, readCsrfToken(), request() (+2 more) -### Community 24 - "fields.tsx" -Cohesion: 0.21 -Nodes (11): FieldChrome, InputProps, MoneyField(), MoneyFieldProps, SelectField(), SelectFieldProps, SelectProps, TextareaField() (+3 more) +### Community 24 - "set_space_context" +Cohesion: 0.15 +Nodes (20): Any, Transaction-local RLS context. No-op on SQLite (tests); fail-closed on…, Transactional scope for workers/endpoints that own the transaction lifecycle., session_scope(), set_space_context(), download(), export_status(), Context (+12 more) ### Community 25 - "Docker Compose Development Stack" Cohesion: 0.29 @@ -242,13 +244,17 @@ Nodes (12): Credit Reserve, Financial Account, Financial Space, Membership, User Cohesion: 0.22 Nodes (9): scripts, api:generate, build, dev, lint, preview, test, test:watch (+1 more) +### Community 28 - "ImportsPage.tsx" +Cohesion: 0.20 +Nodes (11): ImportsPage, EmptyState(), EmptyStateProps, ErrorState(), QueryGate(), QueryGateProps, Spinner(), useImports() (+3 more) + ### Community 29 - "General Pool" Cohesion: 0.29 Nodes (8): Budget Period, Funding, General Pool, Monthly Category, Plan Assignment, Savings Envelope, Immutable Closure Snapshots, Plan and Funding Separation -### Community 30 - "TestBaseContract" -Cohesion: 0.21 -Nodes (3): make_draft(), make_source_row(), TestBaseContract +### Community 30 - "test_adapter_contracts.py" +Cohesion: 0.11 +Nodes (11): AlfaCreditXlsxAdapter, Protocol, StatementAdapter, detect_adapter(), OzonCreditPdfAdapter, make_draft(), make_source_row(), Sanitized synthetic contract tests for the evidenced statement adapters. These… (+3 more) ### Community 31 - "Per-File Envelope Encryption" Cohesion: 0.29 @@ -278,9 +284,9 @@ Nodes (4): name, private, type, version Cohesion: 0.18 Nodes (11): Audited Break-Glass Access, Cross-Space Referential Integrity, Defense-in-Depth Authorization, Financial Space Ownership, Transaction-Local RLS Context, Budget Invariants, Critical User Path, Financial Tracker MVP (+3 more) -### Community 38 - "test_adapter_contracts.py" -Cohesion: 0.13 -Nodes (8): minimal_pdf(), _QuotaSettings, Sanitized synthetic contract tests for the evidenced statement adapters. These…, Build a small valid single-font PDF with empty or ASCII-only pages., same_page_rocket_lines(), synthetic_rocket_lines(), TestRocketbankDebitContract, MonkeyPatch +### Community 38 - "TestRocketbankDebitContract" +Cohesion: 0.18 +Nodes (5): Rocketbank debit statement contract, evidenced against the real document.…, RocketbankDebitPdfAdapter, same_page_rocket_lines(), synthetic_rocket_lines(), TestRocketbankDebitContract ### Community 39 - "generate-api.mjs" Cohesion: 0.40 @@ -294,13 +300,13 @@ Nodes (5): components, $defs, operations, paths, webhooks Cohesion: 0.67 Nodes (3): TestClient, test_invite_login_and_authenticated_space(), test_openapi_contains_critical_paths() -### Community 44 - "helpers.tsx" -Cohesion: 0.18 -Nodes (11): User, DESKTOP_NAV, meMock, MOBILE_NAV, user, createTestQueryClient(), renderWithProviders(), loginMock (+3 more) +### Community 44 - "api" +Cohesion: 0.08 +Nodes (23): api, AdjustBalanceResult, User, adjustBalanceMock, listMock, createMock, listMock, DESKTOP_NAV (+15 more) -### Community 45 - "ledger/models.py" -Cohesion: 0.26 -Nodes (11): HoldResolution, Append-only, tenant-scoped settlement of one HOLD source record. The extracted…, Account, Financial account. Balance is always derived: opening + confirmed postings., FinancialSpace, Membership, test_postgres_rls_requires_matching_transaction_context(), test_s3_blob_round_trip() (+3 more) +### Community 45 - "fields.tsx" +Cohesion: 0.21 +Nodes (11): FieldChrome, InputProps, MoneyField(), MoneyFieldProps, SelectField(), SelectFieldProps, SelectProps, TextareaField() (+3 more) ### Community 46 - "category-manager.test.tsx" Cohesion: 0.14 @@ -310,21 +316,29 @@ Nodes (12): CategoryDefinition, categoriesMock, createCategoryMock, definitions, Cohesion: 0.17 Nodes (11): command, enabled, timeout, type, mcp, graphify, plugin, $schema (+3 more) +### Community 48 - "BudgetBlockers.tsx" +Cohesion: 0.43 +Nodes (6): BudgetBlocker, blockerCta(), blockerText(), BudgetBlockers(), BudgetBlockersProps, Cta + ### Community 50 - "Ближайший край: накопления, категории и блокировки бюджета" Cohesion: 0.10 Nodes (20): 1. Доменная основа накоплений, 2. Альфа debit: «Копилка для сдачи», 3. Управление категориями, 4. Понятные и устранимые блокировки, Backend-контракт, Frontend, Ближайший край: накопления, категории и блокировки бюджета, Бюджетная семантика (+12 more) +### Community 51 - "UTCDateTime" +Cohesion: 0.40 +Nodes (4): Any, Datetimes stored as naive UTC in the DB and exposed tz-aware (UTC) in Python., UTCDateTime, TypeDecorator + ### Community 58 - "test_private_fixtures.py" -Cohesion: 0.10 -Nodes (24): Protocol, StatementAdapter, detect_adapter(), Any, Reconcile parsed rows against declared bank controls with stable diagnostics.…, _reconciliation_summary(), _check(), _fail() (+16 more) +Cohesion: 0.13 +Nodes (21): Any, Reconcile parsed rows against declared bank controls with stable diagnostics.…, _reconciliation_summary(), _check(), _fail(), _load_entries(), parsed(), fixture (+13 more) ### Community 62 - "LocalDirectoryBlobStore" Cohesion: 0.39 Nodes (3): LocalDirectoryBlobStore, Path, S3-neutral local store; production swaps in an S3-compatible client. -### Community 63 - "OzonDebitPdfAdapter" -Cohesion: 0.18 -Nodes (6): _ozon_normalize(), OzonDebitPdfAdapter, Ozon debit statement contract, evidenced against the real document. A 'Справка…, ozon_extracted(), TestOzonDebitContract, Pattern +### Community 63 - "TestOzonDebitContract" +Cohesion: 0.15 +Nodes (6): minimal_pdf(), ozon_extracted(), _QuotaSettings, Build a small valid single-font PDF with empty or ASCII-only pages., TestOzonDebitContract, MonkeyPatch ### Community 64 - "Gitea CI and real statement imports" Cohesion: 0.29 @@ -335,40 +349,40 @@ Cohesion: 0.80 Nodes (4): downgrade(), _has_check_constraint(), _has_column(), upgrade() ### Community 67 - "import-hold-resolution.test.tsx" -Cohesion: 0.15 -Nodes (11): ImportDetail, ImportRow, ImportSummary, confirmMock, detailFixture(), getImportMock, postedRow(), getImportMock (+3 more) +Cohesion: 0.17 +Nodes (9): ImportRow, confirmMock, detailFixture(), getImportMock, postedRow(), getImportMock, resolvedHold, resolveHoldMock (+1 more) ### Community 68 - "budgeting/service.py" -Cohesion: 0.16 -Nodes (39): BudgetPeriod, Calendar month budget period in the space timezone (month granularity)., add_expected_income(), archive_category(), _balance_until(), _close_blockers(), close_period(), _closure_snapshot() (+31 more) +Cohesion: 0.15 +Nodes (45): Any, record(), BudgetPeriod, Calendar month budget period in the space timezone (month granularity)., add_expected_income(), archive_category(), _close_blockers(), _closure_snapshot() (+37 more) ### Community 69 - "TestAlfaDebitContract" -Cohesion: 0.18 -Nodes (3): alfa_workbook_bytes(), synthetic_alfa_rows(), TestAlfaDebitContract +Cohesion: 0.11 +Nodes (7): AlfaDebitXlsxAdapter, Alfa debit statement contract, evidenced against the real export layout.…, alfa_workbook_bytes(), «Копилка для сдачи» contract: exact normalized phrase, statement-side source…, synthetic_alfa_rows(), TestAlfaDebitContract, TestAlfaSavingsRule -### Community 71 - "mcc.py" -Cohesion: 0.14 -Nodes (23): _create_tenant_policy(), _default_keys(), downgrade(), _has_table(), _space_ids(), upgrade(), _default_categories(), default_category_system_keys() (+15 more) +### Community 71 - "20260922_0003_savings_system.py" +Cohesion: 0.32 +Nodes (11): _check_constraints(), downgrade(), _has_column(), _has_row(), _has_unique_constraint(), _normalized_sqltext(), Savings system resources, adjustments and reversible conversions., Swap a check constraint for a new value list, dialect-safely. Fresh databases… (+3 more) ### Community 73 - "savings-convert-revert.test.tsx" Cohesion: 0.20 Nodes (6): budgetCategoriesMock, listAccountsMock, listOperationsMock, operations, revertMock, savingsTransferMock ### Community 74 - "get_settings" -Cohesion: 0.12 -Nodes (30): get_settings(), Settings, send_token_email(), accept_invite(), AcceptInviteBody, confirm_password_reset(), create_invite(), InviteBody (+22 more) +Cohesion: 0.16 +Nodes (26): get_settings(), send_token_email(), accept_invite(), AcceptInviteBody, confirm_password_reset(), create_invite(), InviteBody, login() (+18 more) ### Community 75 - "ColumnChart.tsx" Cohesion: 0.24 Nodes (7): CashFlowColumn, ColumnChart(), ColumnChartProps, BarRow, HorizontalBars(), HorizontalBarsProps, rows -### Community 76 - "dependencies.py" -Cohesion: 0.09 -Nodes (39): current_context(), current_session(), alias, Context, CurrentSession, Db, Header, User (+31 more) +### Community 76 - "spaces/router.py" +Cohesion: 0.19 +Nodes (20): forbidden(), cancel_deletion(), current(), deletion_status(), DeletionBody, invite_member(), MemberInviteBody, alias (+12 more) -### Community 79 - "test_savings.py" -Cohesion: 0.14 -Nodes (33): adjust_balance(), convert_expense_to_savings(), ensure_savings_resources(), Account, date, Operation, User, UUID (+25 more) +### Community 79 - "AppError" +Cohesion: 0.12 +Nodes (43): AppError, conflict(), Any, Domain error rendered as a machine-readable JSON error payload., unprocessable(), cancel_deletion(), adjust_balance(), convert_expense_to_savings() (+35 more) ### Community 80 - "test_category_definitions.py" Cohesion: 0.50 @@ -378,38 +392,30 @@ Nodes (8): bootstrap(), TestClient, HTTP contract for category definitions, syst Cohesion: 0.25 Nodes (7): BudgetSummary, categories, categoriesMock, month, summary, summaryMock, updatePlanMock -### Community 82 - "imports/service.py" -Cohesion: 0.18 -Nodes (29): Any, record(), utcnow(), conflict(), not_found(), magic_kind(), _apply_hold_matches(), _category_id_for_source() (+21 more) +### Community 82 - "spaces/service.py" +Cohesion: 0.20 +Nodes (16): User, HoldResolution, Append-only, tenant-scoped settlement of one HOLD source record. The extracted…, Account, Financial account. Balance is always derived: opening + confirmed postings., FinancialSpace, Membership, get_membership() (+8 more) ### Community 83 - "exports/service.py" -Cohesion: 0.13 -Nodes (19): DataExport, build_export(), consume_export(), _csv_bytes(), get_export(), _json_rows(), purge_due_spaces(), datetime (+11 more) - -### Community 84 - "test_imports.py" -Cohesion: 0.17 -Nodes (29): DedupCandidate, ParseRun, Immutable extracted bank fact with document origin coordinates., SourceRecord, SourceRecordLink, StatementDocument, _build_candidates(), _match_hold_resolutions() (+21 more) +Cohesion: 0.11 +Nodes (22): DataExport, build_export(), consume_export(), _csv_bytes(), get_export(), _json_rows(), purge_due_spaces(), datetime (+14 more) ### Community 85 - "identity/service.py" -Cohesion: 0.26 -Nodes (20): bad_request(), unauthorized(), accept_invitation(), authenticate(), create_invitation(), create_password_reset(), create_session(), get_active_session() (+12 more) +Cohesion: 0.30 +Nodes (16): accept_invitation(), authenticate(), create_invitation(), create_password_reset(), create_session(), normalize_email(), User, UUID (+8 more) -### Community 86 - "Session" -Cohesion: 0.16 -Nodes (41): Session, add_record(), _draft(), hold_document(), make_document(), date, Path, TestClient (+33 more) +### Community 86 - "test_import_holds.py" +Cohesion: 0.13 +Nodes (41): normalize_description(), date, record_fingerprint(), add_record(), _draft(), hold_document(), make_document(), date (+33 more) ### Community 87 - "get_or_create_period" -Cohesion: 0.34 -Nodes (14): get_or_create_period(), validate_year_month(), Budget semantics for savings transfers, adjustments and archived history., savings_row(), seed(), test_adjustment_changes_only_envelope_available_not_pool(), test_adjustment_on_regular_account_keeps_pool_and_totals(), test_archived_category_history_stays_in_totals() (+6 more) +Cohesion: 0.21 +Nodes (25): close_period(), compute_period_state(), create_category(), get_or_create_period(), Deterministic budget state. Resource model: - income lands in the general pool;…, Budget semantics for savings transfers, adjustments and archived history., savings_row(), seed() (+17 more) ### Community 88 - "20260923_0005_optional_hold_reason.py" Cohesion: 0.83 Nodes (3): downgrade(), _reason_constraint_name(), upgrade() -### Community 89 - "test_import_savings.py" -Cohesion: 0.32 -Nodes (17): get_savings_account(), add_record(), make_document(), date, User, Import contract for the «Копилка для сдачи» savings_transfer decision., seed(), test_confirm_creates_savings_transfer_with_system_category() (+9 more) - ### Community 90 - "conftest.py" Cohesion: 0.27 Nodes (6): client(), db(), db_factory(), fixture, sessionmaker, TestClient @@ -418,33 +424,37 @@ Nodes (6): client(), db(), db_factory(), fixture, sessionmaker, TestClient Cohesion: 0.60 Nodes (10): bootstrap(), category_ids(), create_account(), create_expense(), operations_by_id(), TestClient, test_batch_assigns_picked_categories_and_moves_leftovers_to_others(), test_batch_is_atomic_when_one_category_is_unknown() (+2 more) -### Community 92 - "review-queue-save.test.tsx" -Cohesion: 0.25 -Nodes (6): categories, categoriesMock, categorizeBatchMock, categorizeMock, importsListMock, operationsListMock +### Community 93 - "useImports.ts" +Cohesion: 0.26 +Nodes (10): ConfirmImportPayload, ImportStatus, SaveRowDecisionPayload, useImport(), ACTIVE_STATUSES, IMPORT_POLL_MS, importListPollInterval(), importPollInterval() (+2 more) -### Community 94 - "account-adjustment.test.tsx" -Cohesion: 0.20 -Nodes (5): Account, adjustBalanceMock, listMock, createMock, listMock +### Community 95 - "dependencies.py" +Cohesion: 0.17 +Nodes (15): current_context(), current_session(), alias, Context, CurrentSession, Db, Header, User (+7 more) + +### Community 96 - "_login" +Cohesion: 1.00 +Nodes (3): _login(), TestClient, test_expected_income_month_api_crud_and_summary() ## Knowledge Gaps -- **267 isolated node(s):** `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type`, `/home/k1nq/.local/bin/graphify-mcp`, `/home/k1nq/repos/finance/graphify-out/graph.json` (+262 more) - These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 468 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) +- **268 isolated node(s):** `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type`, `/home/k1nq/.local/bin/graphify-mcp`, `/home/k1nq/repos/finance/graphify-out/graph.json` (+263 more) + These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 475 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) - **16 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Session` connect `Session` to `Category`, `budgeting/router.py`, `db/models.py`, `imports/router.py`, `alfa_xlsx.py`, `ledger/service.py`, `Base`, `ledger/models.py`, `budgeting/service.py`, `mcc.py`, `dependencies.py`, `test_savings.py`, `imports/service.py`, `exports/service.py`, `test_imports.py`, `identity/service.py`, `get_or_create_period`, `test_import_savings.py`, `conftest.py`?** - _High betweenness centrality (0.067) - this node is a cross-community bridge._ -- **Why does `AppError` connect `AppError` to `imports/router.py`, `alfa_xlsx.py`, `test_adapter_contracts.py`, `budgeting/service.py`, `get_settings`, `dependencies.py`, `ledger/service.py`, `test_savings.py`, `imports/service.py`, `test_imports.py`, `identity/service.py`, `adapters/base.py`, `get_or_create_period`, `Session`, `test_import_savings.py`, `OzonDebitPdfAdapter`?** - _High betweenness centrality (0.049) - this node is a cross-community bridge._ -- **Why does `TestRocketbankDebitContract` connect `test_adapter_contracts.py` to `AppError`, `adapters/base.py`?** +- **Why does `Session` connect `Session` to `Base`, `main.py`, `budgeting/service.py`, `imports/service.py`, `20260922_0003_savings_system.py`, `spaces/router.py`, `mcc.py`, `AppError`, `ledger/service.py`, `spaces/service.py`, `exports/service.py`, `UTCDateTime`, `identity/service.py`, `test_import_holds.py`, `get_or_create_period`, `set_space_context`, `conftest.py`, `dependencies.py`?** + _High betweenness centrality (0.071) - this node is a cross-community bridge._ +- **Why does `AppError` connect `AppError` to `main.py`, `budgeting/service.py`, `alfa_xlsx.py`, `imports/service.py`, `TestRocketbankDebitContract`, `get_settings`, `spaces/router.py`, `ledger/service.py`, `exports/service.py`, `UnsupportedStatementLayout`, `test_import_holds.py`, `get_or_create_period`, `set_space_context`, `TestOzonDebitContract`, `test_adapter_contracts.py`, `dependencies.py`?** + _High betweenness centrality (0.047) - this node is a cross-community bridge._ +- **Why does `get_settings()` connect `get_settings` to `Settings`, `main.py`, `imports/service.py`, `alfa_xlsx.py`, `celery_app.py`, `spaces/service.py`, `exports/service.py`, `identity/service.py`, `UnsupportedStatementLayout`, `test_import_holds.py`, `conftest.py`, `dependencies.py`?** _High betweenness centrality (0.019) - this node is a cross-community bridge._ - **Are the 4 inferred relationships involving `Session` (e.g. with `upgrade()` and `upgrade()`) actually correct?** _`Session` has 4 INFERRED edges - model-reasoned connections that need verification._ -- **Are the 39 inferred relationships involving `AppError` (e.g. with `request_export()` and `login()`) actually correct?** - _`AppError` has 39 INFERRED edges - model-reasoned connections that need verification._ +- **Are the 42 inferred relationships involving `AppError` (e.g. with `request_export()` and `login()`) actually correct?** + _`AppError` has 42 INFERRED edges - model-reasoned connections that need verification._ - **Are the 3 inferred relationships involving `Base` (e.g. with `downgrade()` and `upgrade()`) actually correct?** _`Base` has 3 INFERRED edges - model-reasoned connections that need verification._ - **What connects `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type` to the rest of the system?** - _267 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file + _268 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file diff --git a/graphify-out/2026-09-23/graph.json b/graphify-out/2026-09-23/graph.json index 07c4831..52238ae 100644 --- a/graphify-out/2026-09-23/graph.json +++ b/graphify-out/2026-09-23/graph.json @@ -53,17 +53,17 @@ }, "nodes": [ { - "id": "backend_app_ledger_models_category", - "label": "Category", + "id": "backend_app_config_settings", + "label": "Settings", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 0, - "community_name": "Category", + "community_name": "Settings", "file_type": "code", - "norm_label": "category", - "source_file": "backend/app/ledger/models.py", - "source_location": "L168" + "norm_label": "settings", + "source_file": "backend/app/config.py", + "source_location": "L8" }, { "id": "backend_app_budgeting_router_assignmentitem", @@ -115,7 +115,7 @@ "file_type": "code", "norm_label": "categorydefinitionpatchbody", "source_file": "backend/app/budgeting/router.py", - "source_location": "L182" + "source_location": "L202" }, { "id": "backend_app_budgeting_router_categoryfundingbody", @@ -128,7 +128,7 @@ "file_type": "code", "norm_label": "categoryfundingbody", "source_file": "backend/app/budgeting/router.py", - "source_location": "L58" + "source_location": "L76" }, { "id": "backend_app_budgeting_router_expectedincomebody", @@ -143,6 +143,32 @@ "source_file": "backend/app/budgeting/router.py", "source_location": "L39" }, + { + "id": "backend_app_budgeting_router_expectedincomematchbody", + "label": "ExpectedIncomeMatchBody", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "expectedincomematchbody", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L57" + }, + { + "id": "backend_app_budgeting_router_expectedincomepatchbody", + "label": "ExpectedIncomePatchBody", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "expectedincomepatchbody", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L48" + }, { "id": "backend_app_budgeting_router_fundingbody", "label": "FundingBody", @@ -167,7 +193,7 @@ "file_type": "code", "norm_label": "monthbody", "source_file": "backend/app/budgeting/router.py", - "source_location": "L50" + "source_location": "L68" }, { "id": "backend_app_budgeting_router_planbody", @@ -180,7 +206,7 @@ "file_type": "code", "norm_label": "planbody", "source_file": "backend/app/budgeting/router.py", - "source_location": "L54" + "source_location": "L72" }, { "id": "frontend_src_components_charts_planfactbars_planfactbarsprops", @@ -189,7 +215,7 @@ "_callable_class": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "planfactbarsprops", "source_file": "frontend/src/components/charts/PlanFactBars.tsx", @@ -202,25 +228,12 @@ "_callable_class": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "planfactrow", "source_file": "frontend/src/components/charts/PlanFactBars.tsx", "source_location": "L3" }, - { - "id": "frontend_src_components_ui_emptystate_emptystateprops", - "label": "EmptyStateProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "emptystateprops", - "source_file": "frontend/src/components/ui/EmptyState.tsx", - "source_location": "L4" - }, { "id": "frontend_src_components_ui_monthswitcher_monthswitcherprops", "label": "MonthSwitcherProps", @@ -228,7 +241,7 @@ "_callable_class": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "monthswitcherprops", "source_file": "frontend/src/components/ui/MonthSwitcher.tsx", @@ -241,25 +254,12 @@ "_callable_class": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "pageheaderprops", "source_file": "frontend/src/components/ui/PageHeader.tsx", "source_location": "L3" }, - { - "id": "frontend_src_components_ui_querygate_querygateprops", - "label": "QueryGateProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "querygateprops", - "source_file": "frontend/src/components/ui/QueryGate.tsx", - "source_location": "L7" - }, { "id": "frontend_src_lib_categorylabel_namedcategory", "label": "NamedCategory", @@ -267,12 +267,25 @@ "_callable_class": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "namedcategory", "source_file": "frontend/src/lib/categoryLabel.ts", "source_location": "L3" }, + { + "id": "backend_app_categorization_mcc_defaultcategory", + "label": "DefaultCategory", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "defaultcategory", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L31" + }, { "id": "backend_app_ledger_models_operation", "label": "Operation", @@ -284,7 +297,7 @@ "file_type": "code", "norm_label": "operation", "source_file": "backend/app/ledger/models.py", - "source_location": "L58" + "source_location": "L56" }, { "id": "backend_app_ledger_models_posting", @@ -297,72 +310,7 @@ "file_type": "code", "norm_label": "posting", "source_file": "backend/app/ledger/models.py", - "source_location": "L134" - }, - { - "id": "frontend_src_api_types_holdresolutionaction", - "label": "HoldResolutionAction", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "holdresolutionaction", - "source_file": "frontend/src/api/types.ts", - "source_location": "L293" - }, - { - "id": "frontend_src_api_types_importstatus", - "label": "ImportStatus", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importstatus", - "source_file": "frontend/src/api/types.ts", - "source_location": "L251" - }, - { - "id": "frontend_src_api_types_operationfilters", - "label": "OperationFilters", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "operationfilters", - "source_file": "frontend/src/api/types.ts", - "source_location": "L126" - }, - { - "id": "frontend_src_api_types_rowdecision", - "label": "RowDecision", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "rowdecision", - "source_file": "frontend/src/api/types.ts", - "source_location": "L289" - }, - { - "id": "frontend_src_pages_settingspage_deletionformvalues", - "label": "DeletionFormValues", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "deletionformvalues", - "source_file": "frontend/src/pages/SettingsPage.tsx", - "source_location": "L19" + "source_location": "L132" }, { "id": "frontend_src_api_types_categorizebatchpayload", @@ -370,8 +318,8 @@ "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", + "community": 17, + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "categorizebatchpayload", "source_file": "frontend/src/api/types.ts", @@ -383,25 +331,51 @@ "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", + "community": 17, + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "createoperationpayload", "source_file": "frontend/src/api/types.ts", "source_location": "L91" }, { - "id": "frontend_src_api_types_locale", - "label": "Locale", + "id": "frontend_src_api_types_operationfilters", + "label": "OperationFilters", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 17, + "community_name": "useOperations.ts", + "file_type": "code", + "norm_label": "operationfilters", + "source_file": "frontend/src/api/types.ts", + "source_location": "L126" + }, + { + "id": "frontend_src_api_types_account", + "label": "Account", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 18, "community_name": "OperationsPage.tsx", "file_type": "code", - "norm_label": "locale", + "norm_label": "account", "source_file": "frontend/src/api/types.ts", - "source_location": "L1" + "source_location": "L14" + }, + { + "id": "frontend_src_api_types_operation", + "label": "Operation", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 18, + "community_name": "OperationsPage.tsx", + "file_type": "code", + "norm_label": "operation", + "source_file": "frontend/src/api/types.ts", + "source_location": "L44" }, { "id": "frontend_src_lib_operationformat_operationamountview", @@ -430,108 +404,30 @@ "source_location": "L27" }, { - "id": "backend_app_categorization_models_bankcategorymapping", - "label": "BankCategoryMapping", + "id": "backend_app_identity_models_session", + "label": "Session", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", - "norm_label": "bankcategorymapping", - "source_file": "backend/app/categorization/models.py", - "source_location": "L131" + "norm_label": "session", + "source_file": "backend/app/identity/models.py", + "source_location": "L54" }, { - "id": "backend_app_categorization_models_categorizationrule", - "label": "CategorizationRule", + "id": "backend_app_ledger_models_category", + "label": "Category", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", - "norm_label": "categorizationrule", - "source_file": "backend/app/categorization/models.py", - "source_location": "L64" - }, - { - "id": "backend_app_categorization_models_categorymcc", - "label": "CategoryMcc", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "categorymcc", - "source_file": "backend/app/categorization/models.py", - "source_location": "L103" - }, - { - "id": "backend_app_categorization_models_incomesource", - "label": "IncomeSource", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "incomesource", - "source_file": "backend/app/categorization/models.py", - "source_location": "L17" - }, - { - "id": "backend_app_categorization_models_mcccode", - "label": "MccCode", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "mcccode", - "source_file": "backend/app/categorization/models.py", - "source_location": "L93" - }, - { - "id": "backend_app_categorization_models_payee", - "label": "Payee", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "payee", - "source_file": "backend/app/categorization/models.py", - "source_location": "L31" - }, - { - "id": "backend_app_categorization_models_payeealias", - "label": "PayeeAlias", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "payeealias", - "source_file": "backend/app/categorization/models.py", - "source_location": "L45" - }, - { - "id": "backend_app_db_base_base", - "label": "Base", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "base", - "source_file": "backend/app/db/base.py", - "source_location": "L17" + "norm_label": "category", + "source_file": "backend/app/ledger/models.py", + "source_location": "L166" }, { "id": "backend_app_audit_models_auditevent", @@ -540,7 +436,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "auditevent", "source_file": "backend/app/audit/models.py", @@ -553,7 +449,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "expectedincome", "source_file": "backend/app/budgeting/models.py", @@ -566,7 +462,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "expectedincomematch", "source_file": "backend/app/budgeting/models.py", @@ -579,7 +475,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "fundingmovement", "source_file": "backend/app/budgeting/models.py", @@ -592,7 +488,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "periodclosure", "source_file": "backend/app/budgeting/models.py", @@ -605,12 +501,116 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "planassignment", "source_file": "backend/app/budgeting/models.py", "source_location": "L47" }, + { + "id": "backend_app_categorization_models_bankcategorymapping", + "label": "BankCategoryMapping", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "bankcategorymapping", + "source_file": "backend/app/categorization/models.py", + "source_location": "L131" + }, + { + "id": "backend_app_categorization_models_categorizationrule", + "label": "CategorizationRule", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "categorizationrule", + "source_file": "backend/app/categorization/models.py", + "source_location": "L64" + }, + { + "id": "backend_app_categorization_models_categorymcc", + "label": "CategoryMcc", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "categorymcc", + "source_file": "backend/app/categorization/models.py", + "source_location": "L103" + }, + { + "id": "backend_app_categorization_models_incomesource", + "label": "IncomeSource", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "incomesource", + "source_file": "backend/app/categorization/models.py", + "source_location": "L17" + }, + { + "id": "backend_app_categorization_models_mcccode", + "label": "MccCode", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "mcccode", + "source_file": "backend/app/categorization/models.py", + "source_location": "L93" + }, + { + "id": "backend_app_categorization_models_payee", + "label": "Payee", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "payee", + "source_file": "backend/app/categorization/models.py", + "source_location": "L31" + }, + { + "id": "backend_app_categorization_models_payeealias", + "label": "PayeeAlias", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "payeealias", + "source_file": "backend/app/categorization/models.py", + "source_location": "L45" + }, + { + "id": "backend_app_db_base_base", + "label": "Base", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "base", + "source_file": "backend/app/db/base.py", + "source_location": "L17" + }, { "id": "backend_app_db_base_pkmixin", "label": "PkMixin", @@ -618,7 +618,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "pkmixin", "source_file": "backend/app/db/base.py", @@ -631,25 +631,12 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "timestampmixin", "source_file": "backend/app/db/base.py", "source_location": "L48" }, - { - "id": "backend_app_db_base_utcdatetime", - "label": "UTCDateTime", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 2, - "community_name": "db/models.py", - "file_type": "code", - "norm_label": "utcdatetime", - "source_file": "backend/app/db/base.py", - "source_location": "L21" - }, { "id": "backend_app_exports_models_deletionledger", "label": "DeletionLedger", @@ -657,7 +644,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "deletionledger", "source_file": "backend/app/exports/models.py", @@ -670,7 +657,7 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "invitation", "source_file": "backend/app/identity/models.py", @@ -683,63 +670,50 @@ "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "passwordreset", "source_file": "backend/app/identity/models.py", "source_location": "L43" }, { - "id": "backend_app_identity_models_user", - "label": "User", + "id": "backend_app_imports_models_dedupcandidate", + "label": "DedupCandidate", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", - "norm_label": "user", - "source_file": "backend/app/identity/models.py", - "source_location": "L10" + "norm_label": "dedupcandidate", + "source_file": "backend/app/imports/models.py", + "source_location": "L174" }, { - "id": "frontend_src_api_types_budgetblocker", - "label": "BudgetBlocker", + "id": "backend_app_imports_models_sourcerecordlink", + "label": "SourceRecordLink", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "sourcerecordlink", + "source_file": "backend/app/imports/models.py", + "source_location": "L148" + }, + { + "id": "frontend_src_api_types_locale", + "label": "Locale", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 20, "community_name": "apiErrors.ts", "file_type": "code", - "norm_label": "budgetblocker", + "norm_label": "locale", "source_file": "frontend/src/api/types.ts", - "source_location": "L184" - }, - { - "id": "frontend_src_components_budget_budgetblockers_budgetblockersprops", - "label": "BudgetBlockersProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "budgetblockersprops", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L53" - }, - { - "id": "frontend_src_components_budget_budgetblockers_cta", - "label": "Cta", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "cta", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L6" + "source_location": "L1" }, { "id": "frontend_src_components_ui_toaster_toastapi", @@ -780,6 +754,19 @@ "source_file": "frontend/src/components/ui/Toaster.tsx", "source_location": "L4" }, + { + "id": "backend_app_imports_adapters_base_sourcerow", + "label": "SourceRow", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "sourcerow", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L25" + }, { "id": "backend_app_imports_adapters_base_statementdraft", "label": "StatementDraft", @@ -787,24 +774,37 @@ "_callable_class": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "statementdraft", "source_file": "backend/app/imports/adapters/base.py", "source_location": "L50" }, { - "id": "backend_app_imports_adapters_ozon_pdf_ozoncreditpdfadapter", - "label": "OzonCreditPdfAdapter", + "id": "backend_app_imports_adapters_base_unsupportedstatementlayout", + "label": "UnsupportedStatementLayout", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", - "norm_label": "ozoncreditpdfadapter", + "norm_label": "unsupportedstatementlayout", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L67" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter", + "label": "OzonDebitPdfAdapter", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "ozondebitpdfadapter", "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L302" + "source_location": "L127" }, { "id": "backend_app_imports_adapters_ozon_pdf_ozonpdfadapterbase", @@ -813,7 +813,7 @@ "_callable_class": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "ozonpdfadapterbase", "source_file": "backend/app/imports/adapters/ozon_pdf.py", @@ -826,38 +826,12 @@ "_callable_class": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "_pendingrecord", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", "source_location": "L266" }, - { - "id": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter", - "label": "RocketbankDebitPdfAdapter", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": "rocketbankdebitpdfadapter", - "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", - "source_location": "L52" - }, - { - "id": "backend_tests_test_adapter_contracts_testmoneyparsing", - "label": "TestMoneyParsing", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": "testmoneyparsing", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L136" - }, { "id": "frontend_src_api_types_creatablecategorykind", "label": "CreatableCategoryKind", @@ -865,12 +839,38 @@ "_callable_class": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "creatablecategorykind", "source_file": "frontend/src/api/types.ts", "source_location": "L212" }, + { + "id": "frontend_src_api_types_createcategorypayload", + "label": "CreateCategoryPayload", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "createcategorypayload", + "source_file": "frontend/src/api/types.ts", + "source_location": "L239" + }, + { + "id": "frontend_src_api_types_patchcategorydefinitionpayload", + "label": "PatchCategoryDefinitionPayload", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "patchcategorydefinitionpayload", + "source_file": "frontend/src/api/types.ts", + "source_location": "L245" + }, { "id": "frontend_src_components_ui_badge_badgetone", "label": "BadgeTone", @@ -878,7 +878,7 @@ "_callable_class": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "badgetone", "source_file": "frontend/src/components/ui/Badge.tsx", @@ -891,7 +891,7 @@ "_callable_class": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "confirmdialogprops", "source_file": "frontend/src/components/ui/ConfirmDialog.tsx", @@ -904,7 +904,7 @@ "_callable_class": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "modalprops", "source_file": "frontend/src/components/ui/Modal.tsx", @@ -963,134 +963,69 @@ "source_location": "L21" }, { - "id": "frontend_src_components_ui_fields_fieldchrome", - "label": "FieldChrome", + "id": "frontend_src_components_ui_emptystate_emptystateprops", + "label": "EmptyStateProps", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", + "community": 28, + "community_name": "ImportsPage.tsx", "file_type": "code", - "norm_label": "fieldchrome", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L17" - }, - { - "id": "frontend_src_components_ui_fields_inputprops", - "label": "InputProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "inputprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L10" - }, - { - "id": "frontend_src_components_ui_fields_moneyfieldprops", - "label": "MoneyFieldProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "moneyfieldprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L73" - }, - { - "id": "frontend_src_components_ui_fields_selectfieldprops", - "label": "SelectFieldProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "selectfieldprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L111" - }, - { - "id": "frontend_src_components_ui_fields_selectprops", - "label": "SelectProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "selectprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L11" - }, - { - "id": "frontend_src_components_ui_fields_textareafieldprops", - "label": "TextareaFieldProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "textareafieldprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L137" - }, - { - "id": "frontend_src_components_ui_fields_textareaprops", - "label": "TextareaProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "textareaprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L12" - }, - { - "id": "frontend_src_components_ui_fields_textfieldprops", - "label": "TextFieldProps", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 24, - "community_name": "fields.tsx", - "file_type": "code", - "norm_label": "textfieldprops", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L50" - }, - { - "id": "backend_app_errors_apperror", - "label": "AppError", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "code", - "norm_label": "apperror", - "source_file": "backend/app/errors.py", + "norm_label": "emptystateprops", + "source_file": "frontend/src/components/ui/EmptyState.tsx", "source_location": "L4" }, { - "id": "backend_app_imports_crypto_encryptedfile", - "label": "EncryptedFile", + "id": "frontend_src_components_ui_querygate_querygateprops", + "label": "QueryGateProps", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 3, - "community_name": "AppError", + "community": 28, + "community_name": "ImportsPage.tsx", "file_type": "code", - "norm_label": "encryptedfile", - "source_file": "backend/app/imports/crypto.py", - "source_location": "L14" + "norm_label": "querygateprops", + "source_file": "frontend/src/components/ui/QueryGate.tsx", + "source_location": "L7" + }, + { + "id": "backend_app_imports_adapters_alfa_xlsx_alfacreditxlsxadapter", + "label": "AlfaCreditXlsxAdapter", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "alfacreditxlsxadapter", + "source_file": "backend/app/imports/adapters/alfa_xlsx.py", + "source_location": "L527" + }, + { + "id": "backend_app_imports_adapters_base_statementadapter", + "label": "StatementAdapter", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "statementadapter", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L78" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozoncreditpdfadapter", + "label": "OzonCreditPdfAdapter", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "ozoncreditpdfadapter", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L302" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract", @@ -1099,24 +1034,37 @@ "_callable_class": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": "testbasecontract", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L76" + "source_location": "L77" }, { - "id": "backend_tests_test_adapter_contracts_quotasettings", - "label": "_QuotaSettings", + "id": "backend_tests_test_adapter_contracts_testmoneyparsing", + "label": "TestMoneyParsing", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "testmoneyparsing", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L137" + }, + { + "id": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter", + "label": "RocketbankDebitPdfAdapter", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", - "norm_label": "_quotasettings", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L886" + "norm_label": "rocketbankdebitpdfadapter", + "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", + "source_location": "L52" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract", @@ -1125,11 +1073,63 @@ "_callable_class": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": "testrocketbankdebitcontract", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L773" + "source_location": "L785" + }, + { + "id": "backend_app_dependencies_requestcontext", + "label": "RequestContext", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "requestcontext", + "source_file": "backend/app/dependencies.py", + "source_location": "L21" + }, + { + "id": "backend_app_imports_models_parserun", + "label": "ParseRun", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "parserun", + "source_file": "backend/app/imports/models.py", + "source_location": "L77" + }, + { + "id": "backend_app_imports_models_sourcerecord", + "label": "SourceRecord", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "sourcerecord", + "source_file": "backend/app/imports/models.py", + "source_location": "L100" + }, + { + "id": "backend_app_imports_models_statementdocument", + "label": "StatementDocument", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "statementdocument", + "source_file": "backend/app/imports/models.py", + "source_location": "L42" }, { "id": "backend_app_imports_router_confirmbody", @@ -1138,7 +1138,7 @@ "_callable_class": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "confirmbody", "source_file": "backend/app/imports/router.py", @@ -1151,7 +1151,7 @@ "_callable_class": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "decisionbody", "source_file": "backend/app/imports/router.py", @@ -1164,7 +1164,7 @@ "_callable_class": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "holdresolvebody", "source_file": "backend/app/imports/router.py", @@ -1177,7 +1177,7 @@ "_callable_class": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "reviewbody", "source_file": "backend/app/imports/router.py", @@ -1248,6 +1248,19 @@ "source_file": "frontend/src/api/generated/schema.d.ts", "source_location": "L899" }, + { + "id": "frontend_src_api_types_adjustbalanceresult", + "label": "AdjustBalanceResult", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "adjustbalanceresult", + "source_file": "frontend/src/api/types.ts", + "source_location": "L71" + }, { "id": "frontend_src_api_types_user", "label": "User", @@ -1255,63 +1268,115 @@ "_callable_class": true, "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "user", "source_file": "frontend/src/api/types.ts", "source_location": "L3" }, { - "id": "backend_app_imports_models_holdresolution", - "label": "HoldResolution", + "id": "frontend_src_components_ui_fields_fieldchrome", + "label": "FieldChrome", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 45, - "community_name": "ledger/models.py", + "community_name": "fields.tsx", "file_type": "code", - "norm_label": "holdresolution", - "source_file": "backend/app/imports/models.py", - "source_location": "L219" + "norm_label": "fieldchrome", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L17" }, { - "id": "backend_app_ledger_models_account", - "label": "Account", + "id": "frontend_src_components_ui_fields_inputprops", + "label": "InputProps", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 45, - "community_name": "ledger/models.py", + "community_name": "fields.tsx", "file_type": "code", - "norm_label": "account", - "source_file": "backend/app/ledger/models.py", - "source_location": "L26" - }, - { - "id": "backend_app_spaces_models_financialspace", - "label": "FinancialSpace", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", - "file_type": "code", - "norm_label": "financialspace", - "source_file": "backend/app/spaces/models.py", + "norm_label": "inputprops", + "source_file": "frontend/src/components/ui/fields.tsx", "source_location": "L10" }, { - "id": "backend_app_spaces_models_membership", - "label": "Membership", + "id": "frontend_src_components_ui_fields_moneyfieldprops", + "label": "MoneyFieldProps", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 45, - "community_name": "ledger/models.py", + "community_name": "fields.tsx", "file_type": "code", - "norm_label": "membership", - "source_file": "backend/app/spaces/models.py", - "source_location": "L18" + "norm_label": "moneyfieldprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L73" + }, + { + "id": "frontend_src_components_ui_fields_selectfieldprops", + "label": "SelectFieldProps", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "selectfieldprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L111" + }, + { + "id": "frontend_src_components_ui_fields_selectprops", + "label": "SelectProps", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "selectprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L11" + }, + { + "id": "frontend_src_components_ui_fields_textareafieldprops", + "label": "TextareaFieldProps", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "textareafieldprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L137" + }, + { + "id": "frontend_src_components_ui_fields_textareaprops", + "label": "TextareaProps", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "textareaprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L12" + }, + { + "id": "frontend_src_components_ui_fields_textfieldprops", + "label": "TextFieldProps", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "textfieldprops", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L50" }, { "id": "frontend_src_api_types_categorydefinition", @@ -1327,30 +1392,43 @@ "source_location": "L228" }, { - "id": "backend_app_imports_adapters_alfa_xlsx_alfacreditxlsxadapter", - "label": "AlfaCreditXlsxAdapter", + "id": "frontend_src_api_types_budgetblocker", + "label": "BudgetBlocker", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", + "community": 48, + "community_name": "BudgetBlockers.tsx", "file_type": "code", - "norm_label": "alfacreditxlsxadapter", - "source_file": "backend/app/imports/adapters/alfa_xlsx.py", - "source_location": "L527" + "norm_label": "budgetblocker", + "source_file": "frontend/src/api/types.ts", + "source_location": "L184" }, { - "id": "backend_app_imports_adapters_alfa_xlsx_alfadebitxlsxadapter", - "label": "AlfaDebitXlsxAdapter", + "id": "frontend_src_components_budget_budgetblockers_budgetblockersprops", + "label": "BudgetBlockersProps", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", + "community": 48, + "community_name": "BudgetBlockers.tsx", "file_type": "code", - "norm_label": "alfadebitxlsxadapter", - "source_file": "backend/app/imports/adapters/alfa_xlsx.py", - "source_location": "L243" + "norm_label": "budgetblockersprops", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L53" + }, + { + "id": "frontend_src_components_budget_budgetblockers_cta", + "label": "Cta", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 48, + "community_name": "BudgetBlockers.tsx", + "file_type": "code", + "norm_label": "cta", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L6" }, { "id": "backend_app_imports_adapters_alfa_xlsx_alfaheadermeta", @@ -1379,56 +1457,17 @@ "source_location": "L67" }, { - "id": "backend_app_imports_adapters_base_sourcerow", - "label": "SourceRow", + "id": "backend_app_db_base_utcdatetime", + "label": "UTCDateTime", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", + "community": 51, + "community_name": "UTCDateTime", "file_type": "code", - "norm_label": "sourcerow", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L25" - }, - { - "id": "backend_app_imports_adapters_base_unsupportedstatementlayout", - "label": "UnsupportedStatementLayout", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": "unsupportedstatementlayout", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L67" - }, - { - "id": "backend_app_imports_adapters_base_statementadapter", - "label": "StatementAdapter", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", - "file_type": "code", - "norm_label": "statementadapter", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L78" - }, - { - "id": "frontend_src_api_types_adjustbalanceresult", - "label": "AdjustBalanceResult", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 6, - "community_name": "system-account-picker.test.tsx", - "file_type": "code", - "norm_label": "adjustbalanceresult", - "source_file": "frontend/src/api/types.ts", - "source_location": "L71" + "norm_label": "utcdatetime", + "source_file": "backend/app/db/base.py", + "source_location": "L21" }, { "id": "frontend_src_api_types_budgetcategory", @@ -1443,19 +1482,6 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L214" }, - { - "id": "frontend_src_api_types_operation", - "label": "Operation", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 6, - "community_name": "system-account-picker.test.tsx", - "file_type": "code", - "norm_label": "operation", - "source_file": "frontend/src/api/types.ts", - "source_location": "L44" - }, { "id": "frontend_src_api_types_page", "label": "Page", @@ -1483,17 +1509,17 @@ "source_location": "L17" }, { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter", - "label": "OzonDebitPdfAdapter", + "id": "backend_tests_test_adapter_contracts_quotasettings", + "label": "_QuotaSettings", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", - "norm_label": "ozondebitpdfadapter", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L127" + "norm_label": "_quotasettings", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L898" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract", @@ -1502,24 +1528,11 @@ "_callable_class": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": "testozondebitcontract", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L651" - }, - { - "id": "frontend_src_api_types_importdetail", - "label": "ImportDetail", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 67, - "community_name": "import-hold-resolution.test.tsx", - "file_type": "code", - "norm_label": "importdetail", - "source_file": "frontend/src/api/types.ts", - "source_location": "L321" + "source_location": "L663" }, { "id": "frontend_src_api_types_importrow", @@ -1534,19 +1547,6 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L304" }, - { - "id": "frontend_src_api_types_importsummary", - "label": "ImportSummary", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 67, - "community_name": "import-hold-resolution.test.tsx", - "file_type": "code", - "norm_label": "importsummary", - "source_file": "frontend/src/api/types.ts", - "source_location": "L260" - }, { "id": "backend_app_budgeting_models_budgetperiod", "label": "BudgetPeriod", @@ -1560,6 +1560,19 @@ "source_file": "backend/app/budgeting/models.py", "source_location": "L25" }, + { + "id": "backend_app_imports_adapters_alfa_xlsx_alfadebitxlsxadapter", + "label": "AlfaDebitXlsxAdapter", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": "alfadebitxlsxadapter", + "source_file": "backend/app/imports/adapters/alfa_xlsx.py", + "source_location": "L243" + }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract", "label": "TestAlfaDebitContract", @@ -1571,7 +1584,33 @@ "file_type": "code", "norm_label": "testalfadebitcontract", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L329" + "source_location": "L330" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule", + "label": "TestAlfaSavingsRule", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": "testalfasavingsrule", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L480" + }, + { + "id": "frontend_src_api_types_acceptinvitepayload", + "label": "AcceptInvitePayload", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 7, + "community_name": "types.ts", + "file_type": "code", + "norm_label": "acceptinvitepayload", + "source_file": "frontend/src/api/types.ts", + "source_location": "L149" }, { "id": "frontend_src_api_types_accountstatus", @@ -1742,19 +1781,6 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L353" }, - { - "id": "frontend_src_api_types_confirmimportpayload", - "label": "ConfirmImportPayload", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 7, - "community_name": "types.ts", - "file_type": "code", - "norm_label": "confirmimportpayload", - "source_file": "frontend/src/api/types.ts", - "source_location": "L349" - }, { "id": "frontend_src_api_types_countblocker", "label": "CountBlocker", @@ -1781,19 +1807,6 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L32" }, - { - "id": "frontend_src_api_types_createcategorypayload", - "label": "CreateCategoryPayload", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 7, - "community_name": "types.ts", - "file_type": "code", - "norm_label": "createcategorypayload", - "source_file": "frontend/src/api/types.ts", - "source_location": "L239" - }, { "id": "frontend_src_api_types_expectedincome", "label": "ExpectedIncome", @@ -1859,6 +1872,32 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L295" }, + { + "id": "frontend_src_api_types_holdresolutionaction", + "label": "HoldResolutionAction", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 7, + "community_name": "types.ts", + "file_type": "code", + "norm_label": "holdresolutionaction", + "source_file": "frontend/src/api/types.ts", + "source_location": "L293" + }, + { + "id": "frontend_src_api_types_importdetail", + "label": "ImportDetail", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 7, + "community_name": "types.ts", + "file_type": "code", + "norm_label": "importdetail", + "source_file": "frontend/src/api/types.ts", + "source_location": "L321" + }, { "id": "frontend_src_api_types_importissue", "label": "ImportIssue", @@ -1872,6 +1911,32 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L273" }, + { + "id": "frontend_src_api_types_importsummary", + "label": "ImportSummary", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 7, + "community_name": "types.ts", + "file_type": "code", + "norm_label": "importsummary", + "source_file": "frontend/src/api/types.ts", + "source_location": "L260" + }, + { + "id": "frontend_src_api_types_loginpayload", + "label": "LoginPayload", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 7, + "community_name": "types.ts", + "file_type": "code", + "norm_label": "loginpayload", + "source_file": "frontend/src/api/types.ts", + "source_location": "L144" + }, { "id": "frontend_src_api_types_operationkind", "label": "OperationKind", @@ -1899,17 +1964,17 @@ "source_location": "L42" }, { - "id": "frontend_src_api_types_patchcategorydefinitionpayload", - "label": "PatchCategoryDefinitionPayload", + "id": "frontend_src_api_types_passwordresetpayload", + "label": "PasswordResetPayload", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 7, "community_name": "types.ts", "file_type": "code", - "norm_label": "patchcategorydefinitionpayload", + "norm_label": "passwordresetpayload", "source_file": "frontend/src/api/types.ts", - "source_location": "L245" + "source_location": "L155" }, { "id": "frontend_src_api_types_planfactitem", @@ -1990,17 +2055,17 @@ "source_location": "L291" }, { - "id": "frontend_src_api_types_saverowdecisionpayload", - "label": "SaveRowDecisionPayload", + "id": "frontend_src_api_types_rowdecision", + "label": "RowDecision", "_callable": true, "_callable_class": true, "_origin": "ast", "community": 7, "community_name": "types.ts", "file_type": "code", - "norm_label": "saverowdecisionpayload", + "norm_label": "rowdecision", "source_file": "frontend/src/api/types.ts", - "source_location": "L338" + "source_location": "L289" }, { "id": "frontend_src_api_types_spacedeletionstatus", @@ -2028,45 +2093,6 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L179" }, - { - "id": "backend_app_categorization_mcc_defaultcategory", - "label": "DefaultCategory", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "defaultcategory", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L31" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule", - "label": "TestAlfaSavingsRule", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": "testalfasavingsrule", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L479" - }, - { - "id": "backend_app_config_settings", - "label": "Settings", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "settings", - "source_file": "backend/app/config.py", - "source_location": "L8" - }, { "id": "backend_app_identity_router_acceptinvitebody", "label": "AcceptInviteBody", @@ -2184,19 +2210,6 @@ "source_file": "frontend/src/components/charts/HorizontalBars.tsx", "source_location": "L9" }, - { - "id": "backend_app_dependencies_requestcontext", - "label": "RequestContext", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "requestcontext", - "source_file": "backend/app/dependencies.py", - "source_location": "L21" - }, { "id": "backend_app_spaces_router_deletionbody", "label": "DeletionBody", @@ -2204,7 +2217,7 @@ "_callable_class": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "deletionbody", "source_file": "backend/app/spaces/router.py", @@ -2217,50 +2230,24 @@ "_callable_class": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "memberinvitebody", "source_file": "backend/app/spaces/router.py", "source_location": "L21" }, { - "id": "frontend_src_api_types_acceptinvitepayload", - "label": "AcceptInvitePayload", + "id": "backend_app_errors_apperror", + "label": "AppError", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 8, - "community_name": "router.tsx", + "community": 79, + "community_name": "AppError", "file_type": "code", - "norm_label": "acceptinvitepayload", - "source_file": "frontend/src/api/types.ts", - "source_location": "L149" - }, - { - "id": "frontend_src_api_types_loginpayload", - "label": "LoginPayload", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 8, - "community_name": "router.tsx", - "file_type": "code", - "norm_label": "loginpayload", - "source_file": "frontend/src/api/types.ts", - "source_location": "L144" - }, - { - "id": "frontend_src_api_types_passwordresetpayload", - "label": "PasswordResetPayload", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 8, - "community_name": "router.tsx", - "file_type": "code", - "norm_label": "passwordresetpayload", - "source_file": "frontend/src/api/types.ts", - "source_location": "L155" + "norm_label": "apperror", + "source_file": "backend/app/errors.py", + "source_location": "L4" }, { "id": "frontend_src_components_layout_applayout_naviconname", @@ -2366,6 +2353,19 @@ "source_file": "frontend/src/pages/ResetPasswordPage.tsx", "source_location": "L13" }, + { + "id": "frontend_src_pages_settingspage_deletionformvalues", + "label": "DeletionFormValues", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "deletionformvalues", + "source_file": "frontend/src/pages/SettingsPage.tsx", + "source_location": "L19" + }, { "id": "frontend_src_api_types_budgetsummary", "label": "BudgetSummary", @@ -2379,6 +2379,71 @@ "source_file": "frontend/src/api/types.ts", "source_location": "L197" }, + { + "id": "backend_app_identity_models_user", + "label": "User", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "user", + "source_file": "backend/app/identity/models.py", + "source_location": "L10" + }, + { + "id": "backend_app_imports_models_holdresolution", + "label": "HoldResolution", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "holdresolution", + "source_file": "backend/app/imports/models.py", + "source_location": "L219" + }, + { + "id": "backend_app_ledger_models_account", + "label": "Account", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "account", + "source_file": "backend/app/ledger/models.py", + "source_location": "L26" + }, + { + "id": "backend_app_spaces_models_financialspace", + "label": "FinancialSpace", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "financialspace", + "source_file": "backend/app/spaces/models.py", + "source_location": "L10" + }, + { + "id": "backend_app_spaces_models_membership", + "label": "Membership", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "membership", + "source_file": "backend/app/spaces/models.py", + "source_location": "L18" + }, { "id": "backend_app_exports_models_dataexport", "label": "DataExport", @@ -2419,82 +2484,17 @@ "source_location": "L42" }, { - "id": "backend_app_imports_models_dedupcandidate", - "label": "DedupCandidate", + "id": "backend_app_imports_crypto_encryptedfile", + "label": "EncryptedFile", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", + "community": 83, + "community_name": "exports/service.py", "file_type": "code", - "norm_label": "dedupcandidate", - "source_file": "backend/app/imports/models.py", - "source_location": "L174" - }, - { - "id": "backend_app_imports_models_parserun", - "label": "ParseRun", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "parserun", - "source_file": "backend/app/imports/models.py", - "source_location": "L77" - }, - { - "id": "backend_app_imports_models_sourcerecord", - "label": "SourceRecord", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "sourcerecord", - "source_file": "backend/app/imports/models.py", - "source_location": "L100" - }, - { - "id": "backend_app_imports_models_sourcerecordlink", - "label": "SourceRecordLink", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "sourcerecordlink", - "source_file": "backend/app/imports/models.py", - "source_location": "L148" - }, - { - "id": "backend_app_imports_models_statementdocument", - "label": "StatementDocument", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "statementdocument", - "source_file": "backend/app/imports/models.py", - "source_location": "L42" - }, - { - "id": "backend_app_identity_models_session", - "label": "Session", - "_callable": true, - "_callable_class": true, - "_origin": "ast", - "community": 86, - "community_name": "Session", - "file_type": "code", - "norm_label": "session", - "source_file": "backend/app/identity/models.py", - "source_location": "L54" + "norm_label": "encryptedfile", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L14" }, { "id": "backend_app_ledger_router_accountbody", @@ -2588,113 +2588,67 @@ "source_location": "L45" }, { - "id": "frontend_src_api_types_account", - "label": "Account", + "id": "frontend_src_api_types_confirmimportpayload", + "label": "ConfirmImportPayload", "_callable": true, "_callable_class": true, "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "account", + "norm_label": "confirmimportpayload", "source_file": "frontend/src/api/types.ts", - "source_location": "L14" + "source_location": "L349" }, { - "id": "backend_app_analytics_service_balances", - "label": "balances()", + "id": "frontend_src_api_types_importstatus", + "label": "ImportStatus", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "importstatus", + "source_file": "frontend/src/api/types.ts", + "source_location": "L251" + }, + { + "id": "frontend_src_api_types_saverowdecisionpayload", + "label": "SaveRowDecisionPayload", + "_callable": true, + "_callable_class": true, + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "saverowdecisionpayload", + "source_file": "frontend/src/api/types.ts", + "source_location": "L338" + }, + { + "id": "backend_app_config_settings_broker_url", + "label": ".broker_url()", "_callable": true, "_origin": "ast", "community": 0, - "community_name": "Category", + "community_name": "Settings", "file_type": "code", - "norm_label": "balances()", - "source_file": "backend/app/analytics/service.py", - "source_location": "L97" + "norm_label": ".broker_url()", + "source_file": "backend/app/config.py", + "source_location": "L50" }, { - "id": "backend_app_analytics_service_cash_flow", - "label": "cash_flow()", + "id": "backend_app_config_settings_kek", + "label": ".kek()", "_callable": true, "_origin": "ast", "community": 0, - "community_name": "Category", + "community_name": "Settings", "file_type": "code", - "norm_label": "cash_flow()", - "source_file": "backend/app/analytics/service.py", - "source_location": "L65" - }, - { - "id": "backend_app_analytics_service_category_spend", - "label": "category_spend()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "category_spend()", - "source_file": "backend/app/analytics/service.py", - "source_location": "L15" - }, - { - "id": "backend_app_analytics_service_plan_fact", - "label": "plan_fact()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "plan_fact()", - "source_file": "backend/app/analytics/service.py", - "source_location": "L88" - }, - { - "id": "backend_app_categorization_service_category_for_mcc", - "label": "category_for_mcc()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "category_for_mcc()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L189" - }, - { - "id": "backend_app_categorization_service_resolve_category_name", - "label": "resolve_category_name()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "resolve_category_name()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L19" - }, - { - "id": "backend_app_categorization_service_resolve_category_name_key", - "label": "resolve_category_name_key()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "resolve_category_name_key()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L32" - }, - { - "id": "backend_app_ledger_savings_savings_category", - "label": "_savings_category()", - "_callable": true, - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "_savings_category()", - "source_file": "backend/app/ledger/savings.py", - "source_location": "L31" + "norm_label": ".kek()", + "source_file": "backend/app/config.py", + "source_location": "L54" }, { "id": "backend_app_analytics_router_balances", @@ -2754,7 +2708,7 @@ "file_type": "code", "norm_label": "assignments()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L284" + "source_location": "L304" }, { "id": "backend_app_budgeting_router_categories", @@ -2766,7 +2720,7 @@ "file_type": "code", "norm_label": "categories()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L120" + "source_location": "L140" }, { "id": "backend_app_budgeting_router_category_definition_json", @@ -2778,7 +2732,7 @@ "file_type": "code", "norm_label": "category_definition_json()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L150" + "source_location": "L170" }, { "id": "backend_app_budgeting_router_category_definitions", @@ -2790,7 +2744,7 @@ "file_type": "code", "norm_label": "category_definitions()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L164" + "source_location": "L184" }, { "id": "backend_app_budgeting_router_close", @@ -2802,7 +2756,7 @@ "file_type": "code", "norm_label": "close()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L332" + "source_location": "L447" }, { "id": "backend_app_budgeting_router_close_frontend", @@ -2814,7 +2768,7 @@ "file_type": "code", "norm_label": "close_frontend()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L355" + "source_location": "L470" }, { "id": "backend_app_budgeting_router_copy_frontend", @@ -2826,7 +2780,7 @@ "file_type": "code", "norm_label": "copy_frontend()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L373" + "source_location": "L488" }, { "id": "backend_app_budgeting_router_copy_previous", @@ -2838,7 +2792,7 @@ "file_type": "code", "norm_label": "copy_previous()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L347" + "source_location": "L462" }, { "id": "backend_app_budgeting_router_create_category", @@ -2850,19 +2804,67 @@ "file_type": "code", "norm_label": "create_category()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L222" + "source_location": "L242" }, { - "id": "backend_app_budgeting_router_expected_income", - "label": "expected_income()", + "id": "backend_app_budgeting_router_create_expected_income", + "label": "create_expected_income()", "_callable": true, "_origin": "ast", "community": 1, "community_name": "budgeting/router.py", "file_type": "code", - "norm_label": "expected_income()", + "norm_label": "create_expected_income()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L312" + "source_location": "L344" + }, + { + "id": "backend_app_budgeting_router_delete_expected_income", + "label": "delete_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "delete_expected_income()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386" + }, + { + "id": "backend_app_budgeting_router_expected_income_item", + "label": "expected_income_item()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "expected_income_item()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L331" + }, + { + "id": "backend_app_budgeting_router_expected_income_json", + "label": "expected_income_json()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "expected_income_json()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L92" + }, + { + "id": "backend_app_budgeting_router_expected_incomes", + "label": "expected_incomes()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "expected_incomes()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L337" }, { "id": "backend_app_budgeting_router_frontend_summary", @@ -2874,7 +2876,7 @@ "file_type": "code", "norm_label": "frontend_summary()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L74" + "source_location": "L108" }, { "id": "backend_app_budgeting_router_fund", @@ -2886,7 +2888,7 @@ "file_type": "code", "norm_label": "fund()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L299" + "source_location": "L319" }, { "id": "backend_app_budgeting_router_fund_category", @@ -2898,7 +2900,19 @@ "file_type": "code", "norm_label": "fund_category()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262" + "source_location": "L282" + }, + { + "id": "backend_app_budgeting_router_match_expected_income", + "label": "match_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "match_expected_income()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402" }, { "id": "backend_app_budgeting_router_parse_month", @@ -2910,7 +2924,7 @@ "file_type": "code", "norm_label": "parse_month()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L62" + "source_location": "L80" }, { "id": "backend_app_budgeting_router_patch_category_definition", @@ -2922,7 +2936,19 @@ "file_type": "code", "norm_label": "patch_category_definition()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189" + "source_location": "L209" + }, + { + "id": "backend_app_budgeting_router_patch_expected_income", + "label": "patch_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "patch_expected_income()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364" }, { "id": "backend_app_budgeting_router_period_for", @@ -2934,7 +2960,7 @@ "file_type": "code", "norm_label": "period_for()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L46" + "source_location": "L64" }, { "id": "backend_app_budgeting_router_reopen", @@ -2946,7 +2972,7 @@ "file_type": "code", "norm_label": "reopen()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L338" + "source_location": "L453" }, { "id": "backend_app_budgeting_router_reopen_frontend", @@ -2958,7 +2984,7 @@ "file_type": "code", "norm_label": "reopen_frontend()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L364" + "source_location": "L479" }, { "id": "backend_app_budgeting_router_summary", @@ -2970,7 +2996,19 @@ "file_type": "code", "norm_label": "summary()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L112" + "source_location": "L132" + }, + { + "id": "backend_app_budgeting_router_unmatch_expected_income", + "label": "unmatch_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "unmatch_expected_income()", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425" }, { "id": "backend_app_budgeting_router_update_plan", @@ -2982,31 +3020,7 @@ "file_type": "code", "norm_label": "update_plan()", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246" - }, - { - "id": "backend_app_categorization_service_get_category_mcc_codes", - "label": "get_category_mcc_codes()", - "_callable": true, - "_origin": "ast", - "community": 1, - "community_name": "budgeting/router.py", - "file_type": "code", - "norm_label": "get_category_mcc_codes()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L203" - }, - { - "id": "backend_app_categorization_service_set_category_mcc_codes", - "label": "set_category_mcc_codes()", - "_callable": true, - "_origin": "ast", - "community": 1, - "community_name": "budgeting/router.py", - "file_type": "code", - "norm_label": "set_category_mcc_codes()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L215" + "source_location": "L266" }, { "id": "frontend_src_components_charts_planfactbars_planfactbars", @@ -3014,31 +3028,19 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "planfactbars()", "source_file": "frontend/src/components/charts/PlanFactBars.tsx", "source_location": "L18" }, - { - "id": "frontend_src_components_ui_emptystate_emptystate", - "label": "EmptyState()", - "_callable": true, - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "emptystate()", - "source_file": "frontend/src/components/ui/EmptyState.tsx", - "source_location": "L9" - }, { "id": "frontend_src_components_ui_monthswitcher_monthswitcher", "label": "MonthSwitcher()", "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "monthswitcher()", "source_file": "frontend/src/components/ui/MonthSwitcher.tsx", @@ -3050,43 +3052,19 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "pageheader()", "source_file": "frontend/src/components/ui/PageHeader.tsx", "source_location": "L9" }, - { - "id": "frontend_src_components_ui_querygate_querygate", - "label": "QueryGate()", - "_callable": true, - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "querygate()", - "source_file": "frontend/src/components/ui/QueryGate.tsx", - "source_location": "L13" - }, - { - "id": "frontend_src_components_ui_spinner_spinner", - "label": "Spinner()", - "_callable": true, - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "spinner()", - "source_file": "frontend/src/components/ui/Spinner.tsx", - "source_location": "L3" - }, { "id": "frontend_src_hooks_useanalytics_useanalyticsbalances", "label": "useAnalyticsBalances()", "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "useanalyticsbalances()", "source_file": "frontend/src/hooks/useAnalytics.ts", @@ -3098,7 +3076,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "useanalyticscashflow()", "source_file": "frontend/src/hooks/useAnalytics.ts", @@ -3110,7 +3088,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "useanalyticscategoryspend()", "source_file": "frontend/src/hooks/useAnalytics.ts", @@ -3122,7 +3100,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "useanalyticsplanfact()", "source_file": "frontend/src/hooks/useAnalytics.ts", @@ -3134,7 +3112,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "usebudgetcategories()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -3146,23 +3124,23 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "usebudgetsummary()", "source_file": "frontend/src/hooks/useBudget.ts", "source_location": "L9" }, { - "id": "frontend_src_hooks_useimports_useimports", - "label": "useImports()", + "id": "frontend_src_hooks_useoperations_useoperations", + "label": "useOperations()", "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", - "norm_label": "useimports()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L15" + "norm_label": "useoperations()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L9" }, { "id": "frontend_src_lib_categorylabel_categorylabel", @@ -3170,7 +3148,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "categorylabel()", "source_file": "frontend/src/lib/categoryLabel.ts", @@ -3182,7 +3160,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "reportitemlabel()", "source_file": "frontend/src/lib/categoryLabel.ts", @@ -3194,7 +3172,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "currentmonth()", "source_file": "frontend/src/lib/dates.ts", @@ -3206,7 +3184,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "formatdatetime()", "source_file": "frontend/src/lib/dates.ts", @@ -3218,7 +3196,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "formatmonth()", "source_file": "frontend/src/lib/dates.ts", @@ -3230,7 +3208,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "formatmonthshort()", "source_file": "frontend/src/lib/dates.ts", @@ -3242,7 +3220,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "isvalidmonth()", "source_file": "frontend/src/lib/dates.ts", @@ -3254,7 +3232,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "lastnmonths()", "source_file": "frontend/src/lib/dates.ts", @@ -3266,7 +3244,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "monthbounds()", "source_file": "frontend/src/lib/dates.ts", @@ -3278,7 +3256,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "monthof()", "source_file": "frontend/src/lib/dates.ts", @@ -3290,7 +3268,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "parsemonth()", "source_file": "frontend/src/lib/dates.ts", @@ -3302,7 +3280,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "shiftmonth()", "source_file": "frontend/src/lib/dates.ts", @@ -3314,7 +3292,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "currentlocale()", "source_file": "frontend/src/lib/locale.ts", @@ -3326,7 +3304,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "analyticspage()", "source_file": "frontend/src/pages/AnalyticsPage.tsx", @@ -3338,23 +3316,35 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "budgetpage()", "source_file": "frontend/src/pages/BudgetPage.tsx", "source_location": "L127" }, { - "id": "frontend_src_pages_importspage_importspage", - "label": "ImportsPage()", + "id": "frontend_src_pages_budgetpage_fundmodal", + "label": "FundModal()", "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", - "norm_label": "importspage()", - "source_file": "frontend/src/pages/ImportsPage.tsx", - "source_location": "L78" + "norm_label": "fundmodal()", + "source_file": "frontend/src/pages/BudgetPage.tsx", + "source_location": "L81" + }, + { + "id": "frontend_src_pages_budgetpage_planmodal", + "label": "PlanModal()", + "_callable": true, + "_origin": "ast", + "community": 12, + "community_name": "BudgetPage.tsx", + "file_type": "code", + "norm_label": "planmodal()", + "source_file": "frontend/src/pages/BudgetPage.tsx", + "source_location": "L33" }, { "id": "frontend_src_pages_notfoundpage_notfoundpage", @@ -3362,7 +3352,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "notfoundpage()", "source_file": "frontend/src/pages/NotFoundPage.tsx", @@ -3374,7 +3364,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "overviewpage()", "source_file": "frontend/src/pages/OverviewPage.tsx", @@ -3386,7 +3376,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "needsattention()", "source_file": "frontend/src/pages/ReviewQueuePage.tsx", @@ -3398,7 +3388,7 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "reviewqueuepage()", "source_file": "frontend/src/pages/ReviewQueuePage.tsx", @@ -3410,23 +3400,191 @@ "_callable": true, "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "uncategorizedrow()", "source_file": "frontend/src/pages/ReviewQueuePage.tsx", "source_location": "L23" }, { - "id": "backend_app_categorization_service_ensure_others_category", - "label": "ensure_others_category()", + "id": "backend_alembic_versions_20260923_0004_mcc_categories_create_tenant_policy", + "label": "_create_tenant_policy()", "_callable": true, "_origin": "ast", - "community": 15, - "community_name": "ledger/service.py", + "community": 13, + "community_name": "mcc.py", "file_type": "code", - "norm_label": "ensure_others_category()", + "norm_label": "_create_tenant_policy()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L26" + }, + { + "id": "backend_alembic_versions_20260923_0004_mcc_categories_default_keys", + "label": "_default_keys()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "_default_keys()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L146" + }, + { + "id": "backend_alembic_versions_20260923_0004_mcc_categories_downgrade", + "label": "downgrade()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "downgrade()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L109" + }, + { + "id": "backend_alembic_versions_20260923_0004_mcc_categories_has_table", + "label": "_has_table()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "_has_table()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L18" + }, + { + "id": "backend_alembic_versions_20260923_0004_mcc_categories_space_ids", + "label": "_space_ids()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "_space_ids()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L22" + }, + { + "id": "backend_alembic_versions_20260923_0004_mcc_categories_upgrade", + "label": "upgrade()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "upgrade()", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L37" + }, + { + "id": "backend_app_categorization_mcc_default_categories", + "label": "_default_categories()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "_default_categories()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L336" + }, + { + "id": "backend_app_categorization_mcc_default_category_system_keys", + "label": "default_category_system_keys()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "default_category_system_keys()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L374" + }, + { + "id": "backend_app_categorization_mcc_english_title", + "label": "english_title()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "english_title()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L344" + }, + { + "id": "backend_app_categorization_mcc_english_titles", + "label": "_english_titles()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "_english_titles()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L322" + }, + { + "id": "backend_app_categorization_mcc_iter_mcc_dictionary", + "label": "iter_mcc_dictionary()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "iter_mcc_dictionary()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L363" + }, + { + "id": "backend_app_categorization_mcc_russian_title", + "label": "russian_title()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "russian_title()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L352" + }, + { + "id": "backend_app_categorization_mcc_transliterate", + "label": "transliterate()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "transliterate()", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L348" + }, + { + "id": "backend_app_categorization_service_ensure_default_categories", + "label": "ensure_default_categories()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "ensure_default_categories()", "source_file": "backend/app/categorization/service.py", - "source_location": "L128" + "source_location": "L147" + }, + { + "id": "backend_app_categorization_service_ensure_mcc_dictionary", + "label": "ensure_mcc_dictionary()", + "_callable": true, + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "ensure_mcc_dictionary()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L118" }, { "id": "backend_app_ledger_service_account_balance", @@ -3765,352 +3923,76 @@ "source_location": "L33" }, { - "id": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", - "label": "test_convert_rejects_income_refund_transfer_and_double_conversion()", - "_callable": true, - "_origin": "ast", - "community": 15, - "community_name": "ledger/service.py", - "file_type": "code", - "norm_label": "test_convert_rejects_income_refund_transfer_and_double_conversion()", - "source_file": "backend/tests/test_savings.py", - "source_location": "L253" - }, - { - "id": "frontend_src_components_ui_toaster_usetoast", - "label": "useToast()", + "id": "frontend_src_hooks_useoperations_usecategorizebatch", + "label": "useCategorizeBatch()", "_callable": true, "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "usetoast()", - "source_file": "frontend/src/components/ui/Toaster.tsx", + "norm_label": "usecategorizebatch()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L59" + }, + { + "id": "frontend_src_hooks_useoperations_usecategorizeoperation", + "label": "useCategorizeOperation()", + "_callable": true, + "_origin": "ast", + "community": 17, + "community_name": "useOperations.ts", + "file_type": "code", + "norm_label": "usecategorizeoperation()", + "source_file": "frontend/src/hooks/useOperations.ts", "source_location": "L51" }, { - "id": "frontend_src_hooks_useaccounts_useadjustbalance", - "label": "useAdjustBalance()", + "id": "frontend_src_hooks_useoperations_useconverttosavings", + "label": "useConvertToSavings()", "_callable": true, "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "useadjustbalance()", - "source_file": "frontend/src/hooks/useAccounts.ts", - "source_location": "L56" + "norm_label": "useconverttosavings()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L66" }, { - "id": "frontend_src_hooks_useaccounts_usearchiveaccount", - "label": "useArchiveAccount()", + "id": "frontend_src_hooks_useoperations_useledgermutation", + "label": "useLedgerMutation()", "_callable": true, "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "usearchiveaccount()", - "source_file": "frontend/src/hooks/useAccounts.ts", - "source_location": "L41" + "norm_label": "useledgermutation()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L17" }, { - "id": "frontend_src_hooks_useaccounts_usecreateaccount", - "label": "useCreateAccount()", + "id": "frontend_src_hooks_useoperations_userevertsavingsconversion", + "label": "useRevertSavingsConversion()", "_callable": true, "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "usecreateaccount()", - "source_file": "frontend/src/hooks/useAccounts.ts", - "source_location": "L26" + "norm_label": "userevertsavingsconversion()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L73" }, { - "id": "frontend_src_hooks_useimports_useconfirmimport", - "label": "useConfirmImport()", + "id": "frontend_src_hooks_useoperations_usevoidoperation", + "label": "useVoidOperation()", "_callable": true, "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "useconfirmimport()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L90" - }, - { - "id": "frontend_src_hooks_useimports_useimport", - "label": "useImport()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "useimport()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L26" - }, - { - "id": "frontend_src_hooks_useimports_useimporterrortoaster", - "label": "useImportErrorToaster()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "useimporterrortoaster()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L35" - }, - { - "id": "frontend_src_hooks_useimports_usereparseimport", - "label": "useReparseImport()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "usereparseimport()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L105" - }, - { - "id": "frontend_src_hooks_useimports_useresolvehold", - "label": "useResolveHold()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "useresolvehold()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L71" - }, - { - "id": "frontend_src_hooks_useimports_userevertimport", - "label": "useRevertImport()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "userevertimport()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L121" - }, - { - "id": "frontend_src_hooks_useimports_usesaverowdecision", - "label": "useSaveRowDecision()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "usesaverowdecision()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L57" - }, - { - "id": "frontend_src_hooks_useimports_useuploadimport", - "label": "useUploadImport()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "useuploadimport()", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L41" - }, - { - "id": "frontend_src_hooks_usespacelifecycle_usecanceldeletion", - "label": "useCancelDeletion()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "usecanceldeletion()", - "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", - "source_location": "L50" - }, - { - "id": "frontend_src_hooks_usespacelifecycle_userequestdeletion", - "label": "useRequestDeletion()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "userequestdeletion()", - "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", - "source_location": "L36" - }, - { - "id": "frontend_src_hooks_usespacelifecycle_userequestexport", - "label": "useRequestExport()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "userequestexport()", - "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", - "source_location": "L12" - }, - { - "id": "frontend_src_hooks_usespacelifecycle_usespacedeletion", - "label": "useSpaceDeletion()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "usespacedeletion()", - "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", - "source_location": "L8" - }, - { - "id": "frontend_src_lib_apierrors_describeapierror", - "label": "describeApiError()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "describeapierror()", - "source_file": "frontend/src/lib/apiErrors.ts", - "source_location": "L5" - }, - { - "id": "frontend_src_lib_importstatus_importlistpollinterval", - "label": "importListPollInterval()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importlistpollinterval()", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L16" - }, - { - "id": "frontend_src_lib_importstatus_importpollinterval", - "label": "importPollInterval()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importpollinterval()", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L11" - }, - { - "id": "frontend_src_lib_importstatus_isterminalimportstatus", - "label": "isTerminalImportStatus()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "isterminalimportstatus()", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L7" - }, - { - "id": "frontend_src_pages_importdetailpage_confirmmodal", - "label": "ConfirmModal()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "confirmmodal()", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L102" - }, - { - "id": "frontend_src_pages_importdetailpage_holdresolvemodal", - "label": "HoldResolveModal()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "holdresolvemodal()", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L42" - }, - { - "id": "frontend_src_pages_importdetailpage_importdetailpage", - "label": "ImportDetailPage()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importdetailpage()", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L148" - }, - { - "id": "frontend_src_pages_importdetailpage_stepindexfor", - "label": "stepIndexFor()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "stepindexfor()", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L35" - }, - { - "id": "frontend_src_pages_settingspage_deletionform", - "label": "DeletionForm()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "deletionform()", - "source_file": "frontend/src/pages/SettingsPage.tsx", - "source_location": "L23" - }, - { - "id": "frontend_src_pages_settingspage_settingspage", - "label": "SettingsPage()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "settingspage()", - "source_file": "frontend/src/pages/SettingsPage.tsx", - "source_location": "L58" - }, - { - "id": "frontend_src_test_import_polling_test_detail", - "label": "detail()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "detail()", - "source_file": "frontend/src/test/import-polling.test.tsx", - "source_location": "L25" - }, - { - "id": "frontend_src_test_import_polling_test_makewrapper", - "label": "makeWrapper()", - "_callable": true, - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "makewrapper()", - "source_file": "frontend/src/test/import-polling.test.tsx", - "source_location": "L60" + "norm_label": "usevoidoperation()", + "source_file": "frontend/src/hooks/useOperations.ts", + "source_location": "L44" }, { "id": "frontend_src_api_types_issystemaccount", @@ -4148,6 +4030,42 @@ "source_file": "frontend/src/hooks/useAccounts.ts", "source_location": "L14" }, + { + "id": "frontend_src_hooks_useaccounts_useadjustbalance", + "label": "useAdjustBalance()", + "_callable": true, + "_origin": "ast", + "community": 18, + "community_name": "OperationsPage.tsx", + "file_type": "code", + "norm_label": "useadjustbalance()", + "source_file": "frontend/src/hooks/useAccounts.ts", + "source_location": "L56" + }, + { + "id": "frontend_src_hooks_useaccounts_usearchiveaccount", + "label": "useArchiveAccount()", + "_callable": true, + "_origin": "ast", + "community": 18, + "community_name": "OperationsPage.tsx", + "file_type": "code", + "norm_label": "usearchiveaccount()", + "source_file": "frontend/src/hooks/useAccounts.ts", + "source_location": "L41" + }, + { + "id": "frontend_src_hooks_useaccounts_usecreateaccount", + "label": "useCreateAccount()", + "_callable": true, + "_origin": "ast", + "community": 18, + "community_name": "OperationsPage.tsx", + "file_type": "code", + "norm_label": "usecreateaccount()", + "source_file": "frontend/src/hooks/useAccounts.ts", + "source_location": "L26" + }, { "id": "frontend_src_hooks_useaccounts_useuseraccounts", "label": "useUserAccounts()", @@ -4160,42 +4078,6 @@ "source_file": "frontend/src/hooks/useAccounts.ts", "source_location": "L21" }, - { - "id": "frontend_src_hooks_useoperations_usecategorizebatch", - "label": "useCategorizeBatch()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "usecategorizebatch()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L59" - }, - { - "id": "frontend_src_hooks_useoperations_usecategorizeoperation", - "label": "useCategorizeOperation()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "usecategorizeoperation()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L51" - }, - { - "id": "frontend_src_hooks_useoperations_useconverttosavings", - "label": "useConvertToSavings()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "useconverttosavings()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L66" - }, { "id": "frontend_src_hooks_useoperations_usecreateoperation", "label": "useCreateOperation()", @@ -4208,54 +4090,6 @@ "source_file": "frontend/src/hooks/useOperations.ts", "source_location": "L37" }, - { - "id": "frontend_src_hooks_useoperations_useledgermutation", - "label": "useLedgerMutation()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "useledgermutation()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L17" - }, - { - "id": "frontend_src_hooks_useoperations_useoperations", - "label": "useOperations()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "useoperations()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L9" - }, - { - "id": "frontend_src_hooks_useoperations_userevertsavingsconversion", - "label": "useRevertSavingsConversion()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "userevertsavingsconversion()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L73" - }, - { - "id": "frontend_src_hooks_useoperations_usevoidoperation", - "label": "useVoidOperation()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "usevoidoperation()", - "source_file": "frontend/src/hooks/useOperations.ts", - "source_location": "L44" - }, { "id": "frontend_src_lib_accountlabel_accountlabel", "label": "accountLabel()", @@ -4412,18 +4246,6 @@ "source_file": "frontend/src/pages/AccountsPage.tsx", "source_location": "L109" }, - { - "id": "frontend_src_pages_importspage_uploadmodal", - "label": "UploadModal()", - "_callable": true, - "_origin": "ast", - "community": 18, - "community_name": "OperationsPage.tsx", - "file_type": "code", - "norm_label": "uploadmodal()", - "source_file": "frontend/src/pages/ImportsPage.tsx", - "source_location": "L18" - }, { "id": "frontend_src_pages_operationspage_accountselect", "label": "AccountSelect()", @@ -4569,28 +4391,88 @@ "source_location": "L408" }, { - "id": "backend_alembic_versions_20260911_0001_initial_schema_downgrade", - "label": "downgrade()", + "id": "backend_app_analytics_service_balances", + "label": "balances()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", - "norm_label": "downgrade()", - "source_file": "backend/alembic/versions/20260911_0001_initial_schema.py", - "source_location": "L80" + "norm_label": "balances()", + "source_file": "backend/app/analytics/service.py", + "source_location": "L94" }, { - "id": "backend_alembic_versions_20260911_0001_initial_schema_upgrade", - "label": "upgrade()", + "id": "backend_app_analytics_service_cash_flow", + "label": "cash_flow()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", - "norm_label": "upgrade()", - "source_file": "backend/alembic/versions/20260911_0001_initial_schema.py", - "source_location": "L36" + "norm_label": "cash_flow()", + "source_file": "backend/app/analytics/service.py", + "source_location": "L62" + }, + { + "id": "backend_app_analytics_service_category_spend", + "label": "category_spend()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "category_spend()", + "source_file": "backend/app/analytics/service.py", + "source_location": "L15" + }, + { + "id": "backend_app_analytics_service_plan_fact", + "label": "plan_fact()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "plan_fact()", + "source_file": "backend/app/analytics/service.py", + "source_location": "L85" + }, + { + "id": "backend_app_budgeting_service_balance_until", + "label": "_balance_until()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "_balance_until()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L99" + }, + { + "id": "backend_app_budgeting_service_ensure_credit_reserve_category", + "label": "ensure_credit_reserve_category()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "ensure_credit_reserve_category()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L572" + }, + { + "id": "backend_app_budgeting_service_list_categories", + "label": "list_categories()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "list_categories()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L592" }, { "id": "backend_app_categorization_service_add_alias", @@ -4598,43 +4480,79 @@ "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "add_alias()", "source_file": "backend/app/categorization/service.py", "source_location": "L64" }, + { + "id": "backend_app_categorization_service_category_for_mcc", + "label": "category_for_mcc()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "category_for_mcc()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L189" + }, { "id": "backend_app_categorization_service_ensure_income_source", "label": "ensure_income_source()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "ensure_income_source()", "source_file": "backend/app/categorization/service.py", "source_location": "L44" }, + { + "id": "backend_app_categorization_service_ensure_others_category", + "label": "ensure_others_category()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "ensure_others_category()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L128" + }, { "id": "backend_app_categorization_service_find_payee_by_description", "label": "find_payee_by_description()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "find_payee_by_description()", "source_file": "backend/app/categorization/service.py", "source_location": "L79" }, + { + "id": "backend_app_categorization_service_get_category_mcc_codes", + "label": "get_category_mcc_codes()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "get_category_mcc_codes()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L203" + }, { "id": "backend_app_categorization_service_get_income_source", "label": "get_income_source()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "get_income_source()", "source_file": "backend/app/categorization/service.py", @@ -4646,59 +4564,107 @@ "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "get_or_create_payee()", "source_file": "backend/app/categorization/service.py", "source_location": "L53" }, + { + "id": "backend_app_categorization_service_resolve_category_name", + "label": "resolve_category_name()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "resolve_category_name()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L19" + }, + { + "id": "backend_app_categorization_service_resolve_category_name_key", + "label": "resolve_category_name_key()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "resolve_category_name_key()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L32" + }, { "id": "backend_app_categorization_service_rule_category_for_payee", "label": "rule_category_for_payee()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "rule_category_for_payee()", "source_file": "backend/app/categorization/service.py", "source_location": "L93" }, + { + "id": "backend_app_categorization_service_set_category_mcc_codes", + "label": "set_category_mcc_codes()", + "_callable": true, + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "set_category_mcc_codes()", + "source_file": "backend/app/categorization/service.py", + "source_location": "L215" + }, { "id": "backend_app_categorization_service_set_payee_rule", "label": "set_payee_rule()", "_callable": true, "_origin": "ast", "community": 19, - "community_name": "Base", + "community_name": "Session", "file_type": "code", "norm_label": "set_payee_rule()", "source_file": "backend/app/categorization/service.py", "source_location": "L99" }, { - "id": "backend_app_db_base_utcdatetime_process_bind_param", - "label": ".process_bind_param()", + "id": "backend_app_ledger_savings_savings_category", + "label": "_savings_category()", "_callable": true, "_origin": "ast", - "community": 2, - "community_name": "db/models.py", + "community": 19, + "community_name": "Session", "file_type": "code", - "norm_label": ".process_bind_param()", - "source_file": "backend/app/db/base.py", - "source_location": "L27" + "norm_label": "_savings_category()", + "source_file": "backend/app/ledger/savings.py", + "source_location": "L29" }, { - "id": "backend_app_db_base_utcdatetime_process_result_value", - "label": ".process_result_value()", + "id": "backend_alembic_versions_20260911_0001_initial_schema_downgrade", + "label": "downgrade()", "_callable": true, "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", - "norm_label": ".process_result_value()", - "source_file": "backend/app/db/base.py", - "source_location": "L34" + "norm_label": "downgrade()", + "source_file": "backend/alembic/versions/20260911_0001_initial_schema.py", + "source_location": "L80" + }, + { + "id": "backend_alembic_versions_20260911_0001_initial_schema_upgrade", + "label": "upgrade()", + "_callable": true, + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "upgrade()", + "source_file": "backend/alembic/versions/20260911_0001_initial_schema.py", + "source_location": "L36" }, { "id": "frontend_src_api_client_isapierror", @@ -4736,42 +4702,6 @@ "source_file": "frontend/src/app/router.tsx", "source_location": "L63" }, - { - "id": "frontend_src_components_budget_budgetblockers_blockercta", - "label": "blockerCta()", - "_callable": true, - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "blockercta()", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L30" - }, - { - "id": "frontend_src_components_budget_budgetblockers_blockertext", - "label": "blockerText()", - "_callable": true, - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "blockertext()", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L11" - }, - { - "id": "frontend_src_components_budget_budgetblockers_budgetblockers", - "label": "BudgetBlockers()", - "_callable": true, - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "budgetblockers()", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L58" - }, { "id": "frontend_src_components_layout_langswitcher_langswitcher", "label": "LangSwitcher()", @@ -4874,19 +4804,31 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "account_fingerprint()", "source_file": "backend/app/imports/adapters/base.py", "source_location": "L126" }, + { + "id": "backend_app_imports_adapters_base_amount_to_kopecks", + "label": "amount_to_kopecks()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "amount_to_kopecks()", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L85" + }, { "id": "backend_app_imports_adapters_base_mask_digits", "label": "_mask_digits()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "_mask_digits()", "source_file": "backend/app/imports/adapters/base.py", @@ -4898,35 +4840,35 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "money_to_kopecks()", "source_file": "backend/app/imports/adapters/base.py", "source_location": "L111" }, { - "id": "backend_app_imports_adapters_base_normalize_description", - "label": "normalize_description()", + "id": "backend_app_imports_adapters_base_sourcerow_post_init", + "label": ".__post_init__()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", - "norm_label": "normalize_description()", + "norm_label": ".__post_init__()", "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L131" + "source_location": "L40" }, { - "id": "backend_app_imports_adapters_base_record_fingerprint", - "label": "record_fingerprint()", + "id": "backend_app_imports_adapters_base_unsupportedstatementlayout_init", + "label": ".__init__()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", - "norm_label": "record_fingerprint()", + "norm_label": ".__init__()", "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L137" + "source_location": "L70" }, { "id": "backend_app_imports_adapters_ozon_pdf_first_page_text", @@ -4934,19 +4876,103 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "_first_page_text()", "source_file": "backend/app/imports/adapters/ozon_pdf.py", "source_location": "L120" }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozon_cell", + "label": "_ozon_cell()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "_ozon_cell()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L296" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozon_normalize", + "label": "_ozon_normalize()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "_ozon_normalize()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L292" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_detect", + "label": ".detect()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": ".detect()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L159" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_draft_from_extracted", + "label": "._draft_from_extracted()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "._draft_from_extracted()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L188" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_parse", + "label": ".parse()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": ".parse()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L171" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_required_line", + "label": "._required_line()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "._required_line()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L237" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_table_row", + "label": "._table_row()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "._table_row()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L243" + }, { "id": "backend_app_imports_adapters_ozon_pdf_ozonpdfadapterbase_detect", "label": ".detect()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": ".detect()", "source_file": "backend/app/imports/adapters/ozon_pdf.py", @@ -4958,19 +4984,31 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": ".parse()", "source_file": "backend/app/imports/adapters/ozon_pdf.py", "source_location": "L48" }, + { + "id": "backend_app_imports_adapters_ozon_pdf_parse_row", + "label": "_parse_row()", + "_callable": true, + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "code", + "norm_label": "_parse_row()", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L99" + }, { "id": "backend_app_imports_adapters_rocketbank_pdf_date_from", "label": "_date_from()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "_date_from()", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", @@ -4982,31 +5020,19 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": ".__init__()", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", "source_location": "L269" }, - { - "id": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter_detect", - "label": ".detect()", - "_callable": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": ".detect()", - "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", - "source_location": "L82" - }, { "id": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter_draft_from_lines", "label": "._draft_from_lines()", "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "._draft_from_lines()", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", @@ -5018,7 +5044,7 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": ".parse()", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", @@ -5030,7 +5056,7 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "._record()", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", @@ -5042,67 +5068,19 @@ "_callable": true, "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "open_pdf()", "source_file": "backend/app/imports/readers.py", "source_location": "L52" }, - { - "id": "backend_app_imports_readers_quota_error", - "label": "_quota_error()", - "_callable": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": "_quota_error()", - "source_file": "backend/app/imports/readers.py", - "source_location": "L14" - }, - { - "id": "backend_tests_test_adapter_contracts_testmoneyparsing_test_malformed_amount_fails_closed_without_leaking_digits", - "label": ".test_malformed_amount_fails_closed_without_leaking_digits()", - "_callable": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": ".test_malformed_amount_fails_closed_without_leaking_digits()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L144" - }, - { - "id": "backend_tests_test_adapter_contracts_testmoneyparsing_test_plain_and_separated_amounts", - "label": ".test_plain_and_separated_amounts()", - "_callable": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": ".test_plain_and_separated_amounts()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L137" - }, - { - "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_setup_method", - "label": ".setup_method()", - "_callable": true, - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": ".setup_method()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L774" - }, { "id": "frontend_src_components_budget_categorymanagermodal_categorymanagermodal", "label": "CategoryManagerModal()", "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "categorymanagermodal()", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -5114,7 +5092,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "createcategoryform()", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -5126,7 +5104,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "mcccodesmodal()", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -5138,7 +5116,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "parsemcccodes()", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -5150,7 +5128,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "renamemodal()", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -5162,7 +5140,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "badge()", "source_file": "frontend/src/components/ui/Badge.tsx", @@ -5174,7 +5152,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "confirmdialog()", "source_file": "frontend/src/components/ui/ConfirmDialog.tsx", @@ -5186,19 +5164,31 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "modal()", "source_file": "frontend/src/components/ui/Modal.tsx", "source_location": "L12" }, + { + "id": "frontend_src_components_ui_toaster_usetoast", + "label": "useToast()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "usetoast()", + "source_file": "frontend/src/components/ui/Toaster.tsx", + "source_location": "L51" + }, { "id": "frontend_src_hooks_usebudget_usebudgeterrortoaster", "label": "useBudgetErrorToaster()", "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usebudgeterrortoaster()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5210,7 +5200,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usecategorydefinitioninvalidation()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5222,7 +5212,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usecategorydefinitions()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5234,7 +5224,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "useclosemonth()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5246,7 +5236,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usecopypreviousmonth()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5258,7 +5248,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usecreatecategory()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5270,7 +5260,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usefundcategory()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5282,7 +5272,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "useperiodmutation()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5294,7 +5284,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usereopenmonth()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5306,7 +5296,7 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "useupdatecategorydefinition()", "source_file": "frontend/src/hooks/useBudget.ts", @@ -5318,35 +5308,131 @@ "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "useupdateplan()", "source_file": "frontend/src/hooks/useBudget.ts", "source_location": "L86" }, { - "id": "frontend_src_pages_budgetpage_fundmodal", - "label": "FundModal()", + "id": "frontend_src_hooks_useimports_useconfirmimport", + "label": "useConfirmImport()", "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", - "norm_label": "fundmodal()", - "source_file": "frontend/src/pages/BudgetPage.tsx", - "source_location": "L81" + "norm_label": "useconfirmimport()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L90" }, { - "id": "frontend_src_pages_budgetpage_planmodal", - "label": "PlanModal()", + "id": "frontend_src_hooks_useimports_useimporterrortoaster", + "label": "useImportErrorToaster()", "_callable": true, "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", - "norm_label": "planmodal()", - "source_file": "frontend/src/pages/BudgetPage.tsx", - "source_location": "L33" + "norm_label": "useimporterrortoaster()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L35" + }, + { + "id": "frontend_src_hooks_useimports_usereparseimport", + "label": "useReparseImport()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "usereparseimport()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L105" + }, + { + "id": "frontend_src_hooks_useimports_useresolvehold", + "label": "useResolveHold()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "useresolvehold()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L71" + }, + { + "id": "frontend_src_hooks_useimports_userevertimport", + "label": "useRevertImport()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "userevertimport()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L121" + }, + { + "id": "frontend_src_hooks_useimports_usesaverowdecision", + "label": "useSaveRowDecision()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "usesaverowdecision()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L57" + }, + { + "id": "frontend_src_pages_importdetailpage_confirmmodal", + "label": "ConfirmModal()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "confirmmodal()", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L102" + }, + { + "id": "frontend_src_pages_importdetailpage_holdresolvemodal", + "label": "HoldResolveModal()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "holdresolvemodal()", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L42" + }, + { + "id": "frontend_src_pages_importdetailpage_importdetailpage", + "label": "ImportDetailPage()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "importdetailpage()", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L148" + }, + { + "id": "frontend_src_pages_importdetailpage_stepindexfor", + "label": "stepIndexFor()", + "_callable": true, + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "stepindexfor()", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L35" }, { "id": "frontend_src_api_client_apierror_constructor", @@ -5421,112 +5507,340 @@ "source_location": "L67" }, { - "id": "frontend_src_components_ui_fields_fieldchromewrap", - "label": "FieldChromeWrap()", + "id": "backend_app_db_session_session_scope", + "label": "session_scope()", "_callable": true, "_origin": "ast", "community": 24, - "community_name": "fields.tsx", + "community_name": "set_space_context", "file_type": "code", - "norm_label": "fieldchromewrap()", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L23" + "norm_label": "session_scope()", + "source_file": "backend/app/db/session.py", + "source_location": "L59" }, { - "id": "frontend_src_components_ui_fields_moneyfield", - "label": "MoneyField()", + "id": "backend_app_db_session_set_space_context", + "label": "set_space_context()", "_callable": true, "_origin": "ast", "community": 24, - "community_name": "fields.tsx", + "community_name": "set_space_context", "file_type": "code", - "norm_label": "moneyfield()", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L80" + "norm_label": "set_space_context()", + "source_file": "backend/app/db/session.py", + "source_location": "L49" }, { - "id": "frontend_src_components_ui_fields_selectfield", - "label": "SelectField()", + "id": "backend_app_exports_router_download", + "label": "download()", "_callable": true, "_origin": "ast", "community": 24, - "community_name": "fields.tsx", + "community_name": "set_space_context", "file_type": "code", - "norm_label": "selectfield()", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L118" + "norm_label": "download()", + "source_file": "backend/app/exports/router.py", + "source_location": "L54" }, { - "id": "frontend_src_components_ui_fields_textareafield", - "label": "TextareaField()", + "id": "backend_app_exports_router_export_status", + "label": "export_status()", "_callable": true, "_origin": "ast", "community": 24, - "community_name": "fields.tsx", + "community_name": "set_space_context", "file_type": "code", - "norm_label": "textareafield()", - "source_file": "frontend/src/components/ui/fields.tsx", - "source_location": "L143" + "norm_label": "export_status()", + "source_file": "backend/app/exports/router.py", + "source_location": "L41" }, { - "id": "backend_app_errors_apperror_init", - "label": ".__init__()", + "id": "backend_app_exports_router_request_export", + "label": "request_export()", "_callable": true, "_origin": "ast", - "community": 3, - "community_name": "AppError", + "community": 24, + "community_name": "set_space_context", "file_type": "code", - "norm_label": ".__init__()", - "source_file": "backend/app/errors.py", + "norm_label": "request_export()", + "source_file": "backend/app/exports/router.py", + "source_location": "L13" + }, + { + "id": "backend_app_exports_tasks_build_export_task", + "label": "build_export_task()", + "_callable": true, + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "build_export_task()", + "source_file": "backend/app/exports/tasks.py", + "source_location": "L9" + }, + { + "id": "backend_app_exports_tasks_enqueue_export", + "label": "enqueue_export()", + "_callable": true, + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "enqueue_export()", + "source_file": "backend/app/exports/tasks.py", + "source_location": "L20" + }, + { + "id": "backend_app_exports_tasks_purge_due_spaces_task", + "label": "purge_due_spaces_task()", + "_callable": true, + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "purge_due_spaces_task()", + "source_file": "backend/app/exports/tasks.py", + "source_location": "L25" + }, + { + "id": "frontend_src_components_ui_emptystate_emptystate", + "label": "EmptyState()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "emptystate()", + "source_file": "frontend/src/components/ui/EmptyState.tsx", + "source_location": "L9" + }, + { + "id": "frontend_src_components_ui_errorstate_errorstate", + "label": "ErrorState()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "errorstate()", + "source_file": "frontend/src/components/ui/ErrorState.tsx", "source_location": "L10" }, { - "id": "backend_app_errors_unprocessable", - "label": "unprocessable()", + "id": "frontend_src_components_ui_querygate_querygate", + "label": "QueryGate()", "_callable": true, "_origin": "ast", - "community": 3, - "community_name": "AppError", + "community": 28, + "community_name": "ImportsPage.tsx", "file_type": "code", - "norm_label": "unprocessable()", - "source_file": "backend/app/errors.py", - "source_location": "L47" + "norm_label": "querygate()", + "source_file": "frontend/src/components/ui/QueryGate.tsx", + "source_location": "L13" }, { - "id": "backend_app_imports_crypto_decrypt_file", - "label": "decrypt_file()", + "id": "frontend_src_components_ui_spinner_spinner", + "label": "Spinner()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "spinner()", + "source_file": "frontend/src/components/ui/Spinner.tsx", + "source_location": "L3" + }, + { + "id": "frontend_src_hooks_useimports_useimports", + "label": "useImports()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "useimports()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L15" + }, + { + "id": "frontend_src_hooks_useimports_useuploadimport", + "label": "useUploadImport()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "useuploadimport()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L41" + }, + { + "id": "frontend_src_pages_importspage_importspage", + "label": "ImportsPage()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "importspage()", + "source_file": "frontend/src/pages/ImportsPage.tsx", + "source_location": "L78" + }, + { + "id": "frontend_src_pages_importspage_uploadmodal", + "label": "UploadModal()", + "_callable": true, + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "uploadmodal()", + "source_file": "frontend/src/pages/ImportsPage.tsx", + "source_location": "L18" + }, + { + "id": "backend_app_db_session_get_db", + "label": "get_db()", "_callable": true, "_origin": "ast", "community": 3, - "community_name": "AppError", + "community_name": "main.py", "file_type": "code", - "norm_label": "decrypt_file()", - "source_file": "backend/app/imports/crypto.py", + "norm_label": "get_db()", + "source_file": "backend/app/db/session.py", "source_location": "L37" }, { - "id": "backend_app_imports_crypto_encrypt_file", - "label": "encrypt_file()", + "id": "backend_app_db_session_get_engine", + "label": "get_engine()", "_callable": true, "_origin": "ast", "community": 3, - "community_name": "AppError", + "community_name": "main.py", "file_type": "code", - "norm_label": "encrypt_file()", - "source_file": "backend/app/imports/crypto.py", - "source_location": "L21" + "norm_label": "get_engine()", + "source_file": "backend/app/db/session.py", + "source_location": "L15" }, { - "id": "backend_app_imports_crypto_shred_dek_material", - "label": "shred_dek_material()", + "id": "backend_app_db_session_get_session_factory", + "label": "get_session_factory()", "_callable": true, "_origin": "ast", "community": 3, - "community_name": "AppError", + "community_name": "main.py", "file_type": "code", - "norm_label": "shred_dek_material()", - "source_file": "backend/app/imports/crypto.py", - "source_location": "L56" + "norm_label": "get_session_factory()", + "source_file": "backend/app/db/session.py", + "source_location": "L30" + }, + { + "id": "backend_app_main_app_error_handler", + "label": "app_error_handler()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "app_error_handler()", + "source_file": "backend/app/main.py", + "source_location": "L27" + }, + { + "id": "backend_app_main_health", + "label": "health()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "health()", + "source_file": "backend/app/main.py", + "source_location": "L54" + }, + { + "id": "backend_app_main_healthz", + "label": "healthz()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "healthz()", + "source_file": "backend/app/main.py", + "source_location": "L59" + }, + { + "id": "backend_app_main_readiness", + "label": "readiness()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "readiness()", + "source_file": "backend/app/main.py", + "source_location": "L64" + }, + { + "id": "backend_app_main_security_headers", + "label": "security_headers()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "security_headers()", + "source_file": "backend/app/main.py", + "source_location": "L43" + }, + { + "id": "backend_app_main_stale_data_handler", + "label": "stale_data_handler()", + "_callable": true, + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "stale_data_handler()", + "source_file": "backend/app/main.py", + "source_location": "L35" + }, + { + "id": "backend_app_imports_adapters_base_statementadapter_detect", + "label": ".detect()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": ".detect()", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L81" + }, + { + "id": "backend_app_imports_adapters_base_statementadapter_parse", + "label": ".parse()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": ".parse()", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L82" + }, + { + "id": "backend_app_imports_adapters_init_detect_adapter", + "label": "detect_adapter()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "detect_adapter()", + "source_file": "backend/app/imports/adapters/__init__.py", + "source_location": "L30" }, { "id": "backend_tests_test_adapter_contracts_make_draft", @@ -5534,11 +5848,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": "make_draft()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L58" + "source_location": "L59" }, { "id": "backend_tests_test_adapter_contracts_make_source_row", @@ -5546,11 +5860,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": "make_source_row()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L41" + "source_location": "L42" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_service_reconciliation_flags_mismatch", @@ -5558,11 +5872,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_service_reconciliation_flags_mismatch()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L441" + "source_location": "L442" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_credit_adapters_stay_present_but_unregistered", @@ -5570,11 +5884,23 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_credit_adapters_stay_present_but_unregistered()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L110" + "source_location": "L111" + }, + { + "id": "backend_tests_test_adapter_contracts_testbasecontract_test_detect_adapter_fails_closed_on_unknown_xlsx", + "label": ".test_detect_adapter_fails_closed_on_unknown_xlsx()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": ".test_detect_adapter_fails_closed_on_unknown_xlsx()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L119" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_draft_declared_totals_default_to_none", @@ -5582,23 +5908,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_draft_declared_totals_default_to_none()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L88" - }, - { - "id": "backend_tests_test_adapter_contracts_testbasecontract_test_magic_kind", - "label": ".test_magic_kind()", - "_callable": true, - "_origin": "ast", - "community": 30, - "community_name": "TestBaseContract", - "file_type": "code", - "norm_label": ".test_magic_kind()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L130" + "source_location": "L89" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_negative_amount_is_rejected", @@ -5606,11 +5920,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_negative_amount_is_rejected()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L80" + "source_location": "L81" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_per_contract_parser_versions", @@ -5618,11 +5932,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_per_contract_parser_versions()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L94" + "source_location": "L95" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_registry_lists_only_verified_contracts", @@ -5630,11 +5944,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_registry_lists_only_verified_contracts()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L103" + "source_location": "L104" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_source_row_defaults_to_posted", @@ -5642,11 +5956,11 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_source_row_defaults_to_posted()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L77" + "source_location": "L78" }, { "id": "backend_tests_test_adapter_contracts_testbasecontract_test_unknown_bank_status_is_rejected", @@ -5654,23 +5968,47 @@ "_callable": true, "_origin": "ast", "community": 30, - "community_name": "TestBaseContract", + "community_name": "test_adapter_contracts.py", "file_type": "code", "norm_label": ".test_unknown_bank_status_is_rejected()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L84" + "source_location": "L85" }, { - "id": "backend_tests_test_adapter_contracts_minimal_pdf", - "label": "minimal_pdf()", + "id": "backend_tests_test_adapter_contracts_testmoneyparsing_test_malformed_amount_fails_closed_without_leaking_digits", + "label": ".test_malformed_amount_fails_closed_without_leaking_digits()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": ".test_malformed_amount_fails_closed_without_leaking_digits()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L145" + }, + { + "id": "backend_tests_test_adapter_contracts_testmoneyparsing_test_plain_and_separated_amounts", + "label": ".test_plain_and_separated_amounts()", + "_callable": true, + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": ".test_plain_and_separated_amounts()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L138" + }, + { + "id": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter_detect", + "label": ".detect()", "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", - "norm_label": "minimal_pdf()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L890" + "norm_label": ".detect()", + "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", + "source_location": "L82" }, { "id": "backend_tests_test_adapter_contracts_same_page_rocket_lines", @@ -5678,11 +6016,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": "same_page_rocket_lines()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L721" + "source_location": "L733" }, { "id": "backend_tests_test_adapter_contracts_synthetic_rocket_lines", @@ -5690,59 +6028,23 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": "synthetic_rocket_lines()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L740" + "source_location": "L752" }, { - "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_row_quota_is_enforced", - "label": ".test_row_quota_is_enforced()", + "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_setup_method", + "label": ".setup_method()", "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", - "norm_label": ".test_row_quota_is_enforced()", + "norm_label": ".setup_method()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L472" - }, - { - "id": "backend_tests_test_adapter_contracts_testbasecontract_test_detect_adapter_fails_closed_on_unknown_pdf", - "label": ".test_detect_adapter_fails_closed_on_unknown_pdf()", - "_callable": true, - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": ".test_detect_adapter_fails_closed_on_unknown_pdf()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L126" - }, - { - "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_detect_and_parse_fail_closed_on_blank_pdf", - "label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", - "_callable": true, - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L705" - }, - { - "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_oversized_pdf_is_rejected_by_quota", - "label": ".test_oversized_pdf_is_rejected_by_quota()", - "_callable": true, - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": ".test_oversized_pdf_is_rejected_by_quota()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L712" + "source_location": "L786" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_day_and_page_state_machine", @@ -5750,23 +6052,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_day_and_page_state_machine()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L777" - }, - { - "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_detect_and_parse_fail_closed_on_blank_pdf", - "label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", - "_callable": true, - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L870" + "source_location": "L789" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_fold_line_cap_fails_closed", @@ -5774,11 +6064,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_fold_line_cap_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L864" + "source_location": "L876" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_missing_header_block_fails_closed", @@ -5786,23 +6076,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_missing_header_block_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L848" - }, - { - "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_oversized_pdf_is_rejected_by_quota", - "label": ".test_oversized_pdf_is_rejected_by_quota()", - "_callable": true, - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": ".test_oversized_pdf_is_rejected_by_quota()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L877" + "source_location": "L860" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_parse_is_deterministic", @@ -5810,11 +6088,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_parse_is_deterministic()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L834" + "source_location": "L846" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_record_before_day_section_fails_closed", @@ -5822,11 +6100,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_record_before_day_section_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L839" + "source_location": "L851" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_record_folding_and_enrichment", @@ -5834,11 +6112,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_record_folding_and_enrichment()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L810" + "source_location": "L822" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_repeated_headers_and_daily_totals_are_ignored", @@ -5846,11 +6124,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_repeated_headers_and_daily_totals_are_ignored()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L827" + "source_location": "L839" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_row_refs_are_unique_within_a_page", @@ -5858,11 +6136,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_row_refs_are_unique_within_a_page()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L784" + "source_location": "L796" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_statement_controls", @@ -5870,11 +6148,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_statement_controls()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L794" + "source_location": "L806" }, { "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_unrecognized_content_fails_closed", @@ -5882,11 +6160,11 @@ "_callable": true, "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "code", "norm_label": ".test_unrecognized_content_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L858" + "source_location": "L870" }, { "id": "frontend_scripts_generate_api_firstreadable", @@ -5913,220 +6191,28 @@ "source_location": "L28" }, { - "id": "backend_alembic_versions_20260922_0003_savings_system_check_constraints", - "label": "_check_constraints()", + "id": "backend_app_db_base_utcnow", + "label": "utcnow()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "_check_constraints()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L25" + "norm_label": "utcnow()", + "source_file": "backend/app/db/base.py", + "source_location": "L40" }, { - "id": "backend_alembic_versions_20260922_0003_savings_system_downgrade", - "label": "downgrade()", + "id": "backend_app_imports_adapters_init_magic_kind", + "label": "magic_kind()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "downgrade()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L128" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_has_column", - "label": "_has_column()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_has_column()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L20" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_has_row", - "label": "_has_row()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_has_row()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L71" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_has_unique_constraint", - "label": "_has_unique_constraint()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_has_unique_constraint()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L30" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_normalized_sqltext", - "label": "_normalized_sqltext()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_normalized_sqltext()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L37" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_replace_check_constraint", - "label": "_replace_check_constraint()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_replace_check_constraint()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L41" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_space_ids", - "label": "_space_ids()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "_space_ids()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L67" - }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_upgrade", - "label": "upgrade()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "upgrade()", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L75" - }, - { - "id": "backend_app_db_session_get_db", - "label": "get_db()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "get_db()", - "source_file": "backend/app/db/session.py", - "source_location": "L37" - }, - { - "id": "backend_app_db_session_get_engine", - "label": "get_engine()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "get_engine()", - "source_file": "backend/app/db/session.py", - "source_location": "L15" - }, - { - "id": "backend_app_db_session_get_session_factory", - "label": "get_session_factory()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "get_session_factory()", - "source_file": "backend/app/db/session.py", - "source_location": "L30" - }, - { - "id": "backend_app_db_session_session_scope", - "label": "session_scope()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "session_scope()", - "source_file": "backend/app/db/session.py", - "source_location": "L59" - }, - { - "id": "backend_app_db_session_set_space_context", - "label": "set_space_context()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "set_space_context()", - "source_file": "backend/app/db/session.py", - "source_location": "L49" - }, - { - "id": "backend_app_exports_router_download", - "label": "download()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "download()", - "source_file": "backend/app/exports/router.py", - "source_location": "L54" - }, - { - "id": "backend_app_exports_router_export_status", - "label": "export_status()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "export_status()", - "source_file": "backend/app/exports/router.py", - "source_location": "L41" - }, - { - "id": "backend_app_exports_router_request_export", - "label": "request_export()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "request_export()", - "source_file": "backend/app/exports/router.py", - "source_location": "L13" - }, - { - "id": "backend_app_exports_tasks_enqueue_export", - "label": "enqueue_export()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "enqueue_export()", - "source_file": "backend/app/exports/tasks.py", - "source_location": "L20" + "norm_label": "magic_kind()", + "source_file": "backend/app/imports/adapters/__init__.py", + "source_location": "L22" }, { "id": "backend_app_imports_router_confirm", @@ -6134,7 +6220,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "confirm()", "source_file": "backend/app/imports/router.py", @@ -6146,7 +6232,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "decide_row()", "source_file": "backend/app/imports/router.py", @@ -6158,7 +6244,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "delete_source()", "source_file": "backend/app/imports/router.py", @@ -6170,7 +6256,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "detail()", "source_file": "backend/app/imports/router.py", @@ -6182,7 +6268,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "imports()", "source_file": "backend/app/imports/router.py", @@ -6194,7 +6280,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "reparse()", "source_file": "backend/app/imports/router.py", @@ -6206,7 +6292,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "resolve_hold()", "source_file": "backend/app/imports/router.py", @@ -6218,7 +6304,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "revert()", "source_file": "backend/app/imports/router.py", @@ -6230,7 +6316,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "review()", "source_file": "backend/app/imports/router.py", @@ -6242,7 +6328,7 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "summary()", "source_file": "backend/app/imports/router.py", @@ -6254,19 +6340,271 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "upload()", "source_file": "backend/app/imports/router.py", "source_location": "L84" }, + { + "id": "backend_app_imports_service_apply_hold_matches", + "label": "_apply_hold_matches()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_apply_hold_matches()", + "source_file": "backend/app/imports/service.py", + "source_location": "L415" + }, + { + "id": "backend_app_imports_service_build_candidates", + "label": "_build_candidates()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_build_candidates()", + "source_file": "backend/app/imports/service.py", + "source_location": "L239" + }, + { + "id": "backend_app_imports_service_category_id_for_source", + "label": "_category_id_for_source()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_category_id_for_source()", + "source_file": "backend/app/imports/service.py", + "source_location": "L175" + }, + { + "id": "backend_app_imports_service_confirm_document", + "label": "confirm_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "confirm_document()", + "source_file": "backend/app/imports/service.py", + "source_location": "L932" + }, + { + "id": "backend_app_imports_service_create_document", + "label": "create_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "create_document()", + "source_file": "backend/app/imports/service.py", + "source_location": "L52" + }, + { + "id": "backend_app_imports_service_decide_source_record", + "label": "decide_source_record()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "decide_source_record()", + "source_file": "backend/app/imports/service.py", + "source_location": "L696" + }, + { + "id": "backend_app_imports_service_delete_source_file", + "label": "delete_source_file()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "delete_source_file()", + "source_file": "backend/app/imports/service.py", + "source_location": "L1402" + }, + { + "id": "backend_app_imports_service_document", + "label": "_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_document()", + "source_file": "backend/app/imports/service.py", + "source_location": "L43" + }, + { + "id": "backend_app_imports_service_document_detail", + "label": "document_detail()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "document_detail()", + "source_file": "backend/app/imports/service.py", + "source_location": "L606" + }, + { + "id": "backend_app_imports_service_draft_json", + "label": "_draft_json()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_draft_json()", + "source_file": "backend/app/imports/service.py", + "source_location": "L124" + }, + { + "id": "backend_app_imports_service_list_documents", + "label": "list_documents()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "list_documents()", + "source_file": "backend/app/imports/service.py", + "source_location": "L531" + }, + { + "id": "backend_app_imports_service_match_hold_resolutions", + "label": "_match_hold_resolutions()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_match_hold_resolutions()", + "source_file": "backend/app/imports/service.py", + "source_location": "L348" + }, + { + "id": "backend_app_imports_service_parse_month_filter", + "label": "parse_month_filter()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "parse_month_filter()", + "source_file": "backend/app/imports/service.py", + "source_location": "L593" + }, + { + "id": "backend_app_imports_service_prepare_reparse", + "label": "prepare_reparse()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "prepare_reparse()", + "source_file": "backend/app/imports/service.py", + "source_location": "L1210" + }, + { + "id": "backend_app_imports_service_process_statement_document", + "label": "process_statement_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "process_statement_document()", + "source_file": "backend/app/imports/service.py", + "source_location": "L447" + }, + { + "id": "backend_app_imports_service_resolve_hold", + "label": "resolve_hold()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "resolve_hold()", + "source_file": "backend/app/imports/service.py", + "source_location": "L819" + }, + { + "id": "backend_app_imports_service_revert_document", + "label": "revert_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "revert_document()", + "source_file": "backend/app/imports/service.py", + "source_location": "L1235" + }, + { + "id": "backend_app_imports_service_set_review_confirmation", + "label": "set_review_confirmation()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "set_review_confirmation()", + "source_file": "backend/app/imports/service.py", + "source_location": "L776" + }, + { + "id": "backend_app_imports_service_source_from_row", + "label": "_source_from_row()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "_source_from_row()", + "source_file": "backend/app/imports/service.py", + "source_location": "L136" + }, + { + "id": "backend_app_imports_service_unresolved_hold_counts", + "label": "unresolved_hold_counts()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "unresolved_hold_counts()", + "source_file": "backend/app/imports/service.py", + "source_location": "L559" + }, + { + "id": "backend_app_imports_service_unresolved_holds", + "label": "unresolved_holds()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "unresolved_holds()", + "source_file": "backend/app/imports/service.py", + "source_location": "L540" + }, { "id": "backend_app_imports_tasks_enqueue_process_statement", "label": "enqueue_process_statement()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "enqueue_process_statement()", "source_file": "backend/app/imports/tasks.py", @@ -6278,84 +6616,396 @@ "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "process_statement_task()", "source_file": "backend/app/imports/tasks.py", "source_location": "L7" }, { - "id": "backend_app_main_app_error_handler", - "label": "app_error_handler()", + "id": "backend_tests_test_adapter_contracts_testbasecontract_test_magic_kind", + "label": ".test_magic_kind()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "app_error_handler()", - "source_file": "backend/app/main.py", - "source_location": "L27" + "norm_label": ".test_magic_kind()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L131" }, { - "id": "backend_app_main_health", - "label": "health()", + "id": "backend_tests_test_import_savings_add_record", + "label": "add_record()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "health()", - "source_file": "backend/app/main.py", - "source_location": "L54" + "norm_label": "add_record()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L77" }, { - "id": "backend_app_main_healthz", - "label": "healthz()", + "id": "backend_tests_test_import_savings_make_document", + "label": "make_document()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "healthz()", - "source_file": "backend/app/main.py", - "source_location": "L59" + "norm_label": "make_document()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L51" }, { - "id": "backend_app_main_readiness", - "label": "readiness()", + "id": "backend_tests_test_import_savings_seed", + "label": "seed()", "_callable": true, "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "readiness()", - "source_file": "backend/app/main.py", - "source_location": "L64" - }, - { - "id": "backend_app_main_security_headers", - "label": "security_headers()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "security_headers()", - "source_file": "backend/app/main.py", - "source_location": "L43" - }, - { - "id": "backend_app_main_stale_data_handler", - "label": "stale_data_handler()", - "_callable": true, - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "stale_data_handler()", - "source_file": "backend/app/main.py", + "norm_label": "seed()", + "source_file": "backend/tests/test_import_savings.py", "source_location": "L35" }, + { + "id": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", + "label": "test_confirm_creates_savings_transfer_with_system_category()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirm_creates_savings_transfer_with_system_category()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L121" + }, + { + "id": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", + "label": "test_confirm_savings_transfer_rejects_savings_statement_account()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirm_savings_transfer_rejects_savings_statement_account()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L380" + }, + { + "id": "backend_tests_test_import_savings_test_existing_dedup_wins_over_savings_creation", + "label": "test_existing_dedup_wins_over_savings_creation()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_existing_dedup_wins_over_savings_creation()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L253" + }, + { + "id": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", + "label": "test_parsed_savings_hint_becomes_initial_review_decision()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_parsed_savings_hint_becomes_initial_review_decision()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L114" + }, + { + "id": "backend_tests_test_import_savings_test_revert_removes_created_savings_transfer", + "label": "test_revert_removes_created_savings_transfer()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_revert_removes_created_savings_transfer()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L157" + }, + { + "id": "backend_tests_test_import_savings_test_savings_decision_rejects_incoming_rows", + "label": "test_savings_decision_rejects_incoming_rows()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_savings_decision_rejects_incoming_rows()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L212" + }, + { + "id": "backend_tests_test_import_savings_test_savings_transfer_on_hold_row_never_matches", + "label": "test_savings_transfer_on_hold_row_never_matches()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_savings_transfer_on_hold_row_never_matches()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L304" + }, + { + "id": "backend_tests_test_import_savings_test_statement_mapping_rejects_system_account", + "label": "test_statement_mapping_rejects_system_account()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_statement_mapping_rejects_system_account()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L235" + }, + { + "id": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", + "label": "test_unresolved_hold_counts_and_month_filter()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_unresolved_hold_counts_and_month_filter()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L316" + }, + { + "id": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_create", + "label": "test_user_can_switch_savings_decision_to_create()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_user_can_switch_savings_decision_to_create()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L174" + }, + { + "id": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", + "label": "test_user_can_switch_savings_decision_to_discard()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_user_can_switch_savings_decision_to_discard()", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L194" + }, + { + "id": "backend_tests_test_imports_ready_document", + "label": "ready_document()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "ready_document()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L44" + }, + { + "id": "backend_tests_test_imports_seed", + "label": "seed()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "seed()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L28" + }, + { + "id": "backend_tests_test_imports_test_confirm_and_revert_are_idempotent", + "label": "test_confirm_and_revert_are_idempotent()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirm_and_revert_are_idempotent()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L83" + }, + { + "id": "backend_tests_test_imports_test_confirm_rejects_arithmetic_mismatch", + "label": "test_confirm_rejects_arithmetic_mismatch()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirm_rejects_arithmetic_mismatch()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L139" + }, + { + "id": "backend_tests_test_imports_test_confirm_reports_pending_candidate_instead_of_generic_not_ready", + "label": "test_confirm_reports_pending_candidate_instead_of_generic_not_ready()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirm_reports_pending_candidate_instead_of_generic_not_ready()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L498" + }, + { + "id": "backend_tests_test_imports_test_confirmed_import_must_be_reverted_before_reparse", + "label": "test_confirmed_import_must_be_reverted_before_reparse()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_confirmed_import_must_be_reverted_before_reparse()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L147" + }, + { + "id": "backend_tests_test_imports_test_duplicate_candidate_can_reuse_unique_operation_without_client_id", + "label": "test_duplicate_candidate_can_reuse_unique_operation_without_client_id()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_duplicate_candidate_can_reuse_unique_operation_without_client_id()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L209" + }, + { + "id": "backend_tests_test_imports_test_duplicate_candidates_are_retained_before_account_mapping", + "label": "test_duplicate_candidates_are_retained_before_account_mapping()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_duplicate_candidates_are_retained_before_account_mapping()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L416" + }, + { + "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_inactive_parse_runs", + "label": "test_duplicate_candidates_ignore_inactive_parse_runs()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_duplicate_candidates_ignore_inactive_parse_runs()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L298" + }, + { + "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_rows_from_same_parse_run", + "label": "test_duplicate_candidates_ignore_rows_from_same_parse_run()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_duplicate_candidates_ignore_rows_from_same_parse_run()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L265" + }, + { + "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_unconfirmed_documents", + "label": "test_duplicate_candidates_ignore_unconfirmed_documents()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_duplicate_candidates_ignore_unconfirmed_documents()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L372" + }, + { + "id": "backend_tests_test_imports_test_import_detail_exposes_pending_candidate_and_blocker", + "label": "test_import_detail_exposes_pending_candidate_and_blocker()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_import_detail_exposes_pending_candidate_and_blocker()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L461" + }, + { + "id": "backend_tests_test_imports_test_import_mcc_assigns_default_category_and_label", + "label": "test_import_mcc_assigns_default_category_and_label()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_import_mcc_assigns_default_category_and_label()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L122" + }, + { + "id": "backend_tests_test_imports_test_import_review_and_confirmation_do_not_require_reason", + "label": "test_import_review_and_confirmation_do_not_require_reason()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_import_review_and_confirmation_do_not_require_reason()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L98" + }, + { + "id": "backend_tests_test_imports_test_invalid_direction_is_critical", + "label": "test_invalid_direction_is_critical()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_invalid_direction_is_critical()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L155" + }, + { + "id": "backend_tests_test_imports_test_transfer_merge_revert_restores_counterpart_operation", + "label": "test_transfer_merge_revert_restores_counterpart_operation()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_transfer_merge_revert_restores_counterpart_operation()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L518" + }, + { + "id": "backend_tests_test_imports_test_unexpected_parser_failure_reaches_terminal_state", + "label": "test_unexpected_parser_failure_reaches_terminal_state()", + "_callable": true, + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "test_unexpected_parser_failure_reaches_terminal_state()", + "source_file": "backend/tests/test_imports.py", + "source_location": "L177" + }, { "id": "backend_tests_test_api_test_invite_login_and_authenticated_space", "label": "test_invite_login_and_authenticated_space()", @@ -6392,13 +7042,37 @@ "source_file": "frontend/src/test/i18n-parity.test.ts", "source_location": "L7" }, + { + "id": "frontend_src_test_account_adjustment_test_account", + "label": "account()", + "_callable": true, + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "account()", + "source_file": "frontend/src/test/account-adjustment.test.tsx", + "source_location": "L23" + }, + { + "id": "frontend_src_test_accounts_page_test_account", + "label": "account()", + "_callable": true, + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "account()", + "source_file": "frontend/src/test/accounts-page.test.tsx", + "source_location": "L21" + }, { "id": "frontend_src_test_app_layout_test_navigationbars", "label": "navigationBars()", "_callable": true, "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "navigationbars()", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -6410,7 +7084,7 @@ "_callable": true, "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "createtestqueryclient()", "source_file": "frontend/src/test/helpers.tsx", @@ -6422,7 +7096,7 @@ "_callable": true, "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "renderwithproviders()", "source_file": "frontend/src/test/helpers.tsx", @@ -6434,47 +7108,71 @@ "_callable": true, "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "renderlogin()", "source_file": "frontend/src/test/login-page.test.tsx", "source_location": "L32" }, { - "id": "backend_tests_test_postgres_and_s3_test_postgres_rls_requires_matching_transaction_context", - "label": "test_postgres_rls_requires_matching_transaction_context()", + "id": "frontend_src_test_review_queue_save_test_operation", + "label": "operation()", "_callable": true, "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "test_postgres_rls_requires_matching_transaction_context()", - "source_file": "backend/tests/test_postgres_and_s3.py", - "source_location": "L18" + "norm_label": "operation()", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L37" }, { - "id": "backend_tests_test_postgres_and_s3_test_s3_blob_round_trip", - "label": "test_s3_blob_round_trip()", + "id": "frontend_src_components_ui_fields_fieldchromewrap", + "label": "FieldChromeWrap()", "_callable": true, "_origin": "ast", "community": 45, - "community_name": "ledger/models.py", + "community_name": "fields.tsx", "file_type": "code", - "norm_label": "test_s3_blob_round_trip()", - "source_file": "backend/tests/test_postgres_and_s3.py", - "source_location": "L91" + "norm_label": "fieldchromewrap()", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L23" }, { - "id": "backend_tests_test_savings_migration_test_upgrade_backfills_one_pair_without_claiming_same_named_rows", - "label": "test_upgrade_backfills_one_pair_without_claiming_same_named_rows()", + "id": "frontend_src_components_ui_fields_moneyfield", + "label": "MoneyField()", "_callable": true, "_origin": "ast", "community": 45, - "community_name": "ledger/models.py", + "community_name": "fields.tsx", "file_type": "code", - "norm_label": "test_upgrade_backfills_one_pair_without_claiming_same_named_rows()", - "source_file": "backend/tests/test_savings_migration.py", - "source_location": "L16" + "norm_label": "moneyfield()", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L80" + }, + { + "id": "frontend_src_components_ui_fields_selectfield", + "label": "SelectField()", + "_callable": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "selectfield()", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L118" + }, + { + "id": "frontend_src_components_ui_fields_textareafield", + "label": "TextareaField()", + "_callable": true, + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "textareafield()", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L143" }, { "id": "frontend_src_test_category_manager_test_definition", @@ -6500,6 +7198,42 @@ "source_file": "frontend/src/test/category-manager.test.tsx", "source_location": "L125" }, + { + "id": "frontend_src_components_budget_budgetblockers_blockercta", + "label": "blockerCta()", + "_callable": true, + "_origin": "ast", + "community": 48, + "community_name": "BudgetBlockers.tsx", + "file_type": "code", + "norm_label": "blockercta()", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L30" + }, + { + "id": "frontend_src_components_budget_budgetblockers_blockertext", + "label": "blockerText()", + "_callable": true, + "_origin": "ast", + "community": 48, + "community_name": "BudgetBlockers.tsx", + "file_type": "code", + "norm_label": "blockertext()", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L11" + }, + { + "id": "frontend_src_components_budget_budgetblockers_budgetblockers", + "label": "BudgetBlockers()", + "_callable": true, + "_origin": "ast", + "community": 48, + "community_name": "BudgetBlockers.tsx", + "file_type": "code", + "norm_label": "budgetblockers()", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L58" + }, { "id": "backend_app_imports_adapters_alfa_xlsx_alfadebitxlsxadapter_detect", "label": ".detect()", @@ -6740,78 +7474,6 @@ "source_file": "backend/app/imports/adapters/alfa_xlsx.py", "source_location": "L161" }, - { - "id": "backend_app_imports_adapters_base_amount_to_kopecks", - "label": "amount_to_kopecks()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": "amount_to_kopecks()", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L85" - }, - { - "id": "backend_app_imports_adapters_base_sourcerow_post_init", - "label": ".__post_init__()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": ".__post_init__()", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L40" - }, - { - "id": "backend_app_imports_adapters_base_unsupportedstatementlayout_init", - "label": ".__init__()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": ".__init__()", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L70" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozon_cell", - "label": "_ozon_cell()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": "_ozon_cell()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L296" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_table_row", - "label": "._table_row()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": "._table_row()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L243" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_parse_row", - "label": "_parse_row()", - "_callable": true, - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "code", - "norm_label": "_parse_row()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L99" - }, { "id": "backend_app_imports_readers_open_xlsx", "label": "open_xlsx()", @@ -6825,52 +7487,40 @@ "source_location": "L23" }, { - "id": "backend_tests_test_import_savings_test_savings_transfer_on_hold_row_never_matches", - "label": "test_savings_transfer_on_hold_row_never_matches()", + "id": "backend_app_imports_readers_quota_error", + "label": "_quota_error()", "_callable": true, "_origin": "ast", "community": 5, "community_name": "alfa_xlsx.py", "file_type": "code", - "norm_label": "test_savings_transfer_on_hold_row_never_matches()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L302" + "norm_label": "_quota_error()", + "source_file": "backend/app/imports/readers.py", + "source_location": "L14" }, { - "id": "backend_app_imports_adapters_base_statementadapter_detect", - "label": ".detect()", + "id": "backend_app_db_base_utcdatetime_process_bind_param", + "label": ".process_bind_param()", "_callable": true, "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", + "community": 51, + "community_name": "UTCDateTime", "file_type": "code", - "norm_label": ".detect()", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L81" + "norm_label": ".process_bind_param()", + "source_file": "backend/app/db/base.py", + "source_location": "L27" }, { - "id": "backend_app_imports_adapters_base_statementadapter_parse", - "label": ".parse()", + "id": "backend_app_db_base_utcdatetime_process_result_value", + "label": ".process_result_value()", "_callable": true, "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", + "community": 51, + "community_name": "UTCDateTime", "file_type": "code", - "norm_label": ".parse()", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L82" - }, - { - "id": "backend_app_imports_adapters_init_detect_adapter", - "label": "detect_adapter()", - "_callable": true, - "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", - "file_type": "code", - "norm_label": "detect_adapter()", - "source_file": "backend/app/imports/adapters/__init__.py", - "source_location": "L30" + "norm_label": ".process_result_value()", + "source_file": "backend/app/db/base.py", + "source_location": "L34" }, { "id": "backend_app_imports_service_reconciliation_summary", @@ -6894,19 +7544,7 @@ "file_type": "code", "norm_label": ".test_service_reconciliation_contract()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L434" - }, - { - "id": "backend_tests_test_adapter_contracts_testbasecontract_test_detect_adapter_fails_closed_on_unknown_xlsx", - "label": ".test_detect_adapter_fails_closed_on_unknown_xlsx()", - "_callable": true, - "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", - "file_type": "code", - "norm_label": ".test_detect_adapter_fails_closed_on_unknown_xlsx()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L118" + "source_location": "L435" }, { "id": "backend_tests_test_private_fixtures_check", @@ -6918,7 +7556,7 @@ "file_type": "code", "norm_label": "_check()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L74" + "source_location": "L75" }, { "id": "backend_tests_test_private_fixtures_fail", @@ -6930,7 +7568,7 @@ "file_type": "code", "norm_label": "_fail()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L78" + "source_location": "L79" }, { "id": "backend_tests_test_private_fixtures_load_entries", @@ -6942,7 +7580,7 @@ "file_type": "code", "norm_label": "_load_entries()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L34" + "source_location": "L35" }, { "id": "backend_tests_test_private_fixtures_parsed", @@ -6954,7 +7592,7 @@ "file_type": "code", "norm_label": "parsed()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L86" + "source_location": "L87" }, { "id": "backend_tests_test_private_fixtures_test_balances", @@ -6966,7 +7604,7 @@ "file_type": "code", "norm_label": "test_balances()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L180" + "source_location": "L181" }, { "id": "backend_tests_test_private_fixtures_test_control_totals", @@ -6978,7 +7616,7 @@ "file_type": "code", "norm_label": "test_control_totals()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L161" + "source_location": "L162" }, { "id": "backend_tests_test_private_fixtures_test_declared_totals_match_parsed_rows", @@ -6990,7 +7628,7 @@ "file_type": "code", "norm_label": "test_declared_totals_match_parsed_rows()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L194" + "source_location": "L195" }, { "id": "backend_tests_test_private_fixtures_test_hold_totals", @@ -7002,7 +7640,7 @@ "file_type": "code", "norm_label": "test_hold_totals()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L155" + "source_location": "L156" }, { "id": "backend_tests_test_private_fixtures_test_manifest_contract", @@ -7014,7 +7652,7 @@ "file_type": "code", "norm_label": "test_manifest_contract()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L114" + "source_location": "L115" }, { "id": "backend_tests_test_private_fixtures_test_row_counts", @@ -7026,7 +7664,7 @@ "file_type": "code", "norm_label": "test_row_counts()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L124" + "source_location": "L125" }, { "id": "backend_tests_test_private_fixtures_test_row_invariants", @@ -7038,7 +7676,7 @@ "file_type": "code", "norm_label": "test_row_invariants()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L144" + "source_location": "L145" }, { "id": "backend_tests_test_private_fixtures_test_service_reconciliation_matches", @@ -7050,7 +7688,7 @@ "file_type": "code", "norm_label": "test_service_reconciliation_matches()", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L214" + "source_location": "L215" }, { "id": "frontend_src_test_ledger_view_test_account", @@ -7149,64 +7787,16 @@ "source_location": "L28" }, { - "id": "backend_app_imports_adapters_ozon_pdf_ozon_normalize", - "label": "_ozon_normalize()", + "id": "backend_tests_test_adapter_contracts_minimal_pdf", + "label": "minimal_pdf()", "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", - "norm_label": "_ozon_normalize()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L292" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_detect", - "label": ".detect()", - "_callable": true, - "_origin": "ast", - "community": 63, - "community_name": "OzonDebitPdfAdapter", - "file_type": "code", - "norm_label": ".detect()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L159" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_draft_from_extracted", - "label": "._draft_from_extracted()", - "_callable": true, - "_origin": "ast", - "community": 63, - "community_name": "OzonDebitPdfAdapter", - "file_type": "code", - "norm_label": "._draft_from_extracted()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L188" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_parse", - "label": ".parse()", - "_callable": true, - "_origin": "ast", - "community": 63, - "community_name": "OzonDebitPdfAdapter", - "file_type": "code", - "norm_label": ".parse()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L171" - }, - { - "id": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter_required_line", - "label": "._required_line()", - "_callable": true, - "_origin": "ast", - "community": 63, - "community_name": "OzonDebitPdfAdapter", - "file_type": "code", - "norm_label": "._required_line()", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L237" + "norm_label": "minimal_pdf()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L902" }, { "id": "backend_tests_test_adapter_contracts_ozon_extracted", @@ -7214,11 +7804,35 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": "ozon_extracted()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L595" + "source_location": "L607" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_row_quota_is_enforced", + "label": ".test_row_quota_is_enforced()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_row_quota_is_enforced()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L473" + }, + { + "id": "backend_tests_test_adapter_contracts_testbasecontract_test_detect_adapter_fails_closed_on_unknown_pdf", + "label": ".test_detect_adapter_fails_closed_on_unknown_pdf()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_detect_adapter_fails_closed_on_unknown_pdf()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L127" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_setup_method", @@ -7226,11 +7840,11 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".setup_method()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L652" + "source_location": "L664" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_core_contract_fields", @@ -7238,11 +7852,23 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_core_contract_fields()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L656" + "source_location": "L668" + }, + { + "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_detect_and_parse_fail_closed_on_blank_pdf", + "label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L717" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_missing_header_marker_fails_closed", @@ -7250,11 +7876,11 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_missing_header_marker_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L682" + "source_location": "L694" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_missing_totals_fail_closed", @@ -7262,11 +7888,11 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_missing_totals_fail_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L688" + "source_location": "L700" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_multiline_cells_stay_one_transaction", @@ -7274,11 +7900,11 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_multiline_cells_stay_one_transaction()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L670" + "source_location": "L682" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_no_rows_fails_closed", @@ -7286,11 +7912,23 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_no_rows_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L694" + "source_location": "L706" + }, + { + "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_oversized_pdf_is_rejected_by_quota", + "label": ".test_oversized_pdf_is_rejected_by_quota()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_oversized_pdf_is_rejected_by_quota()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L724" }, { "id": "backend_tests_test_adapter_contracts_testozondebitcontract_test_unexpected_row_shape_fails_closed", @@ -7298,11 +7936,35 @@ "_callable": true, "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", "norm_label": ".test_unexpected_row_shape_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L699" + "source_location": "L711" + }, + { + "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_detect_and_parse_fail_closed_on_blank_pdf", + "label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_detect_and_parse_fail_closed_on_blank_pdf()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L882" + }, + { + "id": "backend_tests_test_adapter_contracts_testrocketbankdebitcontract_test_oversized_pdf_is_rejected_by_quota", + "label": ".test_oversized_pdf_is_rejected_by_quota()", + "_callable": true, + "_origin": "ast", + "community": 63, + "community_name": "TestOzonDebitContract", + "file_type": "code", + "norm_label": ".test_oversized_pdf_is_rejected_by_quota()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L889" }, { "id": "backend_alembic_versions_20260918_0002_hold_lifecycle_downgrade", @@ -7400,6 +8062,18 @@ "source_file": "frontend/src/test/import-hold-resolution.test.tsx", "source_location": "L27" }, + { + "id": "backend_app_audit_service_record", + "label": "record()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "record()", + "source_file": "backend/app/audit/service.py", + "source_location": "L8" + }, { "id": "backend_app_budgeting_service_add_expected_income", "label": "add_expected_income()", @@ -7410,7 +8084,7 @@ "file_type": "code", "norm_label": "add_expected_income()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720" + "source_location": "L761" }, { "id": "backend_app_budgeting_service_archive_category", @@ -7422,19 +8096,7 @@ "file_type": "code", "norm_label": "archive_category()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L619" - }, - { - "id": "backend_app_budgeting_service_balance_until", - "label": "_balance_until()", - "_callable": true, - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "code", - "norm_label": "_balance_until()", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L99" + "source_location": "L601" }, { "id": "backend_app_budgeting_service_close_blockers", @@ -7446,19 +8108,7 @@ "file_type": "code", "norm_label": "_close_blockers()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L498" - }, - { - "id": "backend_app_budgeting_service_close_period", - "label": "close_period()", - "_callable": true, - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "code", - "norm_label": "close_period()", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L823" + "source_location": "L480" }, { "id": "backend_app_budgeting_service_closure_snapshot", @@ -7472,18 +8122,6 @@ "source_file": "backend/app/budgeting/service.py", "source_location": "L82" }, - { - "id": "backend_app_budgeting_service_compute_period_state", - "label": "compute_period_state()", - "_callable": true, - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "code", - "norm_label": "compute_period_state()", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L113" - }, { "id": "backend_app_budgeting_service_copy_previous_month", "label": "copy_previous_month()", @@ -7494,31 +8132,43 @@ "file_type": "code", "norm_label": "copy_previous_month()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L923" + "source_location": "L1084" }, { - "id": "backend_app_budgeting_service_create_category", - "label": "create_category()", + "id": "backend_app_budgeting_service_delete_expected_income", + "label": "delete_expected_income()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "create_category()", + "norm_label": "delete_expected_income()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L564" + "source_location": "L927" }, { - "id": "backend_app_budgeting_service_ensure_credit_reserve_category", - "label": "ensure_credit_reserve_category()", + "id": "backend_app_budgeting_service_ensure_expected_date_in_period", + "label": "_ensure_expected_date_in_period()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "ensure_credit_reserve_category()", + "norm_label": "_ensure_expected_date_in_period()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L590" + "source_location": "L721" + }, + { + "id": "backend_app_budgeting_service_expected_income_items", + "label": "expected_income_items()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "expected_income_items()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730" }, { "id": "backend_app_budgeting_service_fund", @@ -7530,7 +8180,7 @@ "file_type": "code", "norm_label": "fund()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L788" + "source_location": "L949" }, { "id": "backend_app_budgeting_service_get_category", @@ -7542,7 +8192,19 @@ "file_type": "code", "norm_label": "get_category()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L557" + "source_location": "L539" + }, + { + "id": "backend_app_budgeting_service_get_expected_income", + "label": "get_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "get_expected_income()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L702" }, { "id": "backend_app_budgeting_service_get_period", @@ -7557,16 +8219,16 @@ "source_location": "L48" }, { - "id": "backend_app_budgeting_service_list_categories", - "label": "list_categories()", + "id": "backend_app_budgeting_service_get_period_expected_income", + "label": "get_period_expected_income()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "list_categories()", + "norm_label": "get_period_expected_income()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L610" + "source_location": "L711" }, { "id": "backend_app_budgeting_service_list_periods", @@ -7590,7 +8252,7 @@ "file_type": "code", "norm_label": "match_expected_income()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L747" + "source_location": "L796" }, { "id": "backend_app_budgeting_service_period_bounds", @@ -7626,7 +8288,7 @@ "file_type": "code", "norm_label": "reopen_period()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L891" + "source_location": "L1052" }, { "id": "backend_app_budgeting_service_require_open", @@ -7638,7 +8300,7 @@ "file_type": "code", "norm_label": "require_open()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L550" + "source_location": "L532" }, { "id": "backend_app_budgeting_service_set_assignments", @@ -7650,7 +8312,7 @@ "file_type": "code", "norm_label": "set_assignments()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L674" + "source_location": "L656" }, { "id": "backend_app_budgeting_service_shift_month", @@ -7664,6 +8326,18 @@ "source_file": "backend/app/budgeting/service.py", "source_location": "L41" }, + { + "id": "backend_app_budgeting_service_unmatch_expected_income", + "label": "unmatch_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "unmatch_expected_income()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847" + }, { "id": "backend_app_budgeting_service_update_category_definition", "label": "update_category_definition()", @@ -7674,7 +8348,31 @@ "file_type": "code", "norm_label": "update_category_definition()", "source_file": "backend/app/budgeting/service.py", - "source_location": "L636" + "source_location": "L618" + }, + { + "id": "backend_app_budgeting_service_update_expected_income", + "label": "update_expected_income()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "update_expected_income()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880" + }, + { + "id": "backend_app_budgeting_service_validate_year_month", + "label": "validate_year_month()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "validate_year_month()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L27" }, { "id": "backend_app_categorization_mcc_is_budgetable_category_key", @@ -7689,7 +8387,31 @@ "source_location": "L378" }, { - "id": "backend_tests_test_budget_seed", + "id": "backend_app_errors_bad_request", + "label": "bad_request()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "bad_request()", + "source_file": "backend/app/errors.py", + "source_location": "L27" + }, + { + "id": "backend_app_errors_not_found", + "label": "not_found()", + "_callable": true, + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "not_found()", + "source_file": "backend/app/errors.py", + "source_location": "L39" + }, + { + "id": "backend_tests_test_expected_income_seed", "label": "seed()", "_callable": true, "_origin": "ast", @@ -7697,68 +8419,44 @@ "community_name": "budgeting/service.py", "file_type": "code", "norm_label": "seed()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L24" + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L23" }, { - "id": "backend_tests_test_budget_test_copy_previous_month_clamps_expected_day", - "label": "test_copy_previous_month_clamps_expected_day()", + "id": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "label": "test_expected_income_crud_and_validation()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "test_copy_previous_month_clamps_expected_day()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L109" + "norm_label": "test_expected_income_crud_and_validation()", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L30" }, { - "id": "backend_tests_test_budget_test_default_mcc_categories_are_budgetable_and_editable_mapping", - "label": "test_default_mcc_categories_are_budgetable_and_editable_mapping()", + "id": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "label": "test_expected_income_match_unmatch_and_delete_cascade()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "test_default_mcc_categories_are_budgetable_and_editable_mapping()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L56" + "norm_label": "test_expected_income_match_unmatch_and_delete_cascade()", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L104" }, { - "id": "backend_tests_test_budget_test_periods_must_close_in_calendar_order", - "label": "test_periods_must_close_in_calendar_order()", + "id": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "label": "test_expected_income_mutations_guard_closed_period()", "_callable": true, "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "test_periods_must_close_in_calendar_order()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L147" - }, - { - "id": "backend_tests_test_budget_test_reopen_preserves_immutable_closure_history", - "label": "test_reopen_preserves_immutable_closure_history()", - "_callable": true, - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "code", - "norm_label": "test_reopen_preserves_immutable_closure_history()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L138" - }, - { - "id": "backend_tests_test_budget_test_uncategorized_expense_blocks_close", - "label": "test_uncategorized_expense_blocks_close()", - "_callable": true, - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "code", - "norm_label": "test_uncategorized_expense_blocks_close()", - "source_file": "backend/tests/test_budget.py", - "source_location": "L31" + "norm_label": "test_expected_income_mutations_guard_closed_period()", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L202" }, { "id": "backend_tests_test_adapter_contracts_alfa_workbook_bytes", @@ -7770,7 +8468,7 @@ "file_type": "code", "norm_label": "alfa_workbook_bytes()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L151" + "source_location": "L152" }, { "id": "backend_tests_test_adapter_contracts_synthetic_alfa_rows", @@ -7782,7 +8480,7 @@ "file_type": "code", "norm_label": "synthetic_alfa_rows()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L161" + "source_location": "L162" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_setup_method", @@ -7794,7 +8492,7 @@ "file_type": "code", "norm_label": ".setup_method()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L330" + "source_location": "L331" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_detect", @@ -7806,7 +8504,7 @@ "file_type": "code", "norm_label": ".test_detect()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L334" + "source_location": "L335" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_detect_rejects_workbook_without_contract_header", @@ -7818,7 +8516,7 @@ "file_type": "code", "norm_label": ".test_detect_rejects_workbook_without_contract_header()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L337" + "source_location": "L338" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_external_ids_from_code_column", @@ -7830,7 +8528,7 @@ "file_type": "code", "norm_label": ".test_external_ids_from_code_column()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L406" + "source_location": "L407" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_footer_is_excluded", @@ -7842,7 +8540,7 @@ "file_type": "code", "norm_label": ".test_footer_is_excluded()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L426" + "source_location": "L427" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_inconsistent_expense_control_fails_closed", @@ -7854,7 +8552,7 @@ "file_type": "code", "norm_label": ".test_inconsistent_expense_control_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L366" + "source_location": "L367" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_malformed_layout_fails_closed", @@ -7866,7 +8564,7 @@ "file_type": "code", "norm_label": ".test_malformed_layout_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L452" + "source_location": "L453" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_mcc_from_description", @@ -7878,7 +8576,7 @@ "file_type": "code", "norm_label": ".test_mcc_from_description()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L416" + "source_location": "L417" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_missing_period_field_fails_closed", @@ -7890,7 +8588,7 @@ "file_type": "code", "norm_label": ".test_missing_period_field_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L359" + "source_location": "L360" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_parse_contract_fields", @@ -7902,7 +8600,7 @@ "file_type": "code", "norm_label": ".test_parse_contract_fields()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L341" + "source_location": "L342" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_parse_is_deterministic", @@ -7914,7 +8612,7 @@ "file_type": "code", "norm_label": ".test_parse_is_deterministic()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L431" + "source_location": "L432" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_parse_rows_with_hold", @@ -7926,7 +8624,7 @@ "file_type": "code", "norm_label": ".test_parse_rows_with_hold()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L387" + "source_location": "L388" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_unexpected_mid_table_row_fails_closed", @@ -7938,7 +8636,7 @@ "file_type": "code", "norm_label": ".test_unexpected_mid_table_row_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L459" + "source_location": "L460" }, { "id": "backend_tests_test_adapter_contracts_testalfadebitcontract_test_unsupported_currency_fails_closed", @@ -7950,7 +8648,91 @@ "file_type": "code", "norm_label": ".test_unsupported_currency_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L466" + "source_location": "L467" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_rule", + "label": ".rule()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".rule()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L491" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_savings_statement_rows", + "label": ".savings_statement_rows()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".savings_statement_rows()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L547" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_exact_phrase_matches", + "label": ".test_exact_phrase_matches()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".test_exact_phrase_matches()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L506" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_hold_row_never_matches", + "label": ".test_hold_row_never_matches()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".test_hold_row_never_matches()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L529" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_incoming_row_never_matches", + "label": ".test_incoming_row_never_matches()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".test_incoming_row_never_matches()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L523" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_masked_statement_account_fails_closed", + "label": ".test_masked_statement_account_fails_closed()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".test_masked_statement_account_fails_closed()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L541" + }, + { + "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_mismatched_source_account_fails_closed", + "label": ".test_mismatched_source_account_fails_closed()", + "_callable": true, + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "code", + "norm_label": ".test_mismatched_source_account_fails_closed()", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L518" }, { "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_parse_leaves_plain_expenses_unmarked", @@ -7962,307 +8744,163 @@ "file_type": "code", "norm_label": ".test_parse_leaves_plain_expenses_unmarked()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L589" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_create_tenant_policy", - "label": "_create_tenant_policy()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_create_tenant_policy()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L26" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_default_keys", - "label": "_default_keys()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_default_keys()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L146" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_downgrade", - "label": "downgrade()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "downgrade()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L109" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_has_table", - "label": "_has_table()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_has_table()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L18" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_space_ids", - "label": "_space_ids()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_space_ids()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L22" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories_upgrade", - "label": "upgrade()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "upgrade()", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", - "source_location": "L37" - }, - { - "id": "backend_app_categorization_mcc_default_categories", - "label": "_default_categories()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_default_categories()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L336" - }, - { - "id": "backend_app_categorization_mcc_default_category_system_keys", - "label": "default_category_system_keys()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "default_category_system_keys()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L374" - }, - { - "id": "backend_app_categorization_mcc_english_title", - "label": "english_title()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "english_title()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L344" - }, - { - "id": "backend_app_categorization_mcc_english_titles", - "label": "_english_titles()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "_english_titles()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L322" - }, - { - "id": "backend_app_categorization_mcc_iter_mcc_dictionary", - "label": "iter_mcc_dictionary()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "iter_mcc_dictionary()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L363" - }, - { - "id": "backend_app_categorization_mcc_russian_title", - "label": "russian_title()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "russian_title()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L352" - }, - { - "id": "backend_app_categorization_mcc_transliterate", - "label": "transliterate()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "transliterate()", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L348" - }, - { - "id": "backend_app_categorization_service_ensure_default_categories", - "label": "ensure_default_categories()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "ensure_default_categories()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L147" - }, - { - "id": "backend_app_categorization_service_ensure_mcc_dictionary", - "label": "ensure_mcc_dictionary()", - "_callable": true, - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "ensure_mcc_dictionary()", - "source_file": "backend/app/categorization/service.py", - "source_location": "L118" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_rule", - "label": ".rule()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".rule()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L490" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_savings_statement_rows", - "label": ".savings_statement_rows()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".savings_statement_rows()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L546" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_exact_phrase_matches", - "label": ".test_exact_phrase_matches()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".test_exact_phrase_matches()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L505" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_hold_row_never_matches", - "label": ".test_hold_row_never_matches()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".test_hold_row_never_matches()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L528" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_incoming_row_never_matches", - "label": ".test_incoming_row_never_matches()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".test_incoming_row_never_matches()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L522" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_masked_statement_account_fails_closed", - "label": ".test_masked_statement_account_fails_closed()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".test_masked_statement_account_fails_closed()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L540" - }, - { - "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_mismatched_source_account_fails_closed", - "label": ".test_mismatched_source_account_fails_closed()", - "_callable": true, - "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "code", - "norm_label": ".test_mismatched_source_account_fails_closed()", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L517" + "source_location": "L601" }, { "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_parse_marks_savings_rows_and_bumps_version", "label": ".test_parse_marks_savings_rows_and_bumps_version()", "_callable": true, "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", + "community": 69, + "community_name": "TestAlfaDebitContract", "file_type": "code", "norm_label": ".test_parse_marks_savings_rows_and_bumps_version()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L571" + "source_location": "L583" }, { "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_similar_description_without_full_pattern_fails_closed", "label": ".test_similar_description_without_full_pattern_fails_closed()", "_callable": true, "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", + "community": 69, + "community_name": "TestAlfaDebitContract", "file_type": "code", "norm_label": ".test_similar_description_without_full_pattern_fails_closed()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L534" + "source_location": "L535" }, { "id": "backend_tests_test_adapter_contracts_testalfasavingsrule_test_spaces_case_and_quotes_are_normalized", "label": ".test_spaces_case_and_quotes_are_normalized()", "_callable": true, "_origin": "ast", - "community": 72, - "community_name": "TestAlfaSavingsRule", + "community": 69, + "community_name": "TestAlfaDebitContract", "file_type": "code", "norm_label": ".test_spaces_case_and_quotes_are_normalized()", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L510" + "source_location": "L511" + }, + { + "id": "backend_app_imports_celery_app_create_celery_app", + "label": "create_celery_app()", + "_callable": true, + "_origin": "ast", + "community": 70, + "community_name": "celery_app.py", + "file_type": "code", + "norm_label": "create_celery_app()", + "source_file": "backend/app/imports/celery_app.py", + "source_location": "L6" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_check_constraints", + "label": "_check_constraints()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_check_constraints()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L25" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_downgrade", + "label": "downgrade()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "downgrade()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L124" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_has_column", + "label": "_has_column()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_has_column()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L20" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_has_row", + "label": "_has_row()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_has_row()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L69" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_has_unique_constraint", + "label": "_has_unique_constraint()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_has_unique_constraint()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L30" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_normalized_sqltext", + "label": "_normalized_sqltext()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_normalized_sqltext()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L35" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_replace_check_constraint", + "label": "_replace_check_constraint()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_replace_check_constraint()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L39" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_space_ids", + "label": "_space_ids()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "_space_ids()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L65" + }, + { + "id": "backend_alembic_versions_20260922_0003_savings_system_upgrade", + "label": "upgrade()", + "_callable": true, + "_origin": "ast", + "community": 71, + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "upgrade()", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L73" }, { "id": "frontend_src_test_savings_convert_revert_test_account", @@ -8312,30 +8950,6 @@ "source_file": "backend/app/config.py", "source_location": "L67" }, - { - "id": "backend_app_config_settings_broker_url", - "label": ".broker_url()", - "_callable": true, - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": ".broker_url()", - "source_file": "backend/app/config.py", - "source_location": "L50" - }, - { - "id": "backend_app_config_settings_kek", - "label": ".kek()", - "_callable": true, - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": ".kek()", - "source_file": "backend/app/config.py", - "source_location": "L54" - }, { "id": "backend_app_identity_mailer_send_token_email", "label": "send_token_email()", @@ -8444,18 +9058,6 @@ "source_file": "backend/app/identity/router.py", "source_location": "L45" }, - { - "id": "backend_app_imports_celery_app_create_celery_app", - "label": "create_celery_app()", - "_callable": true, - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "create_celery_app()", - "source_file": "backend/app/imports/celery_app.py", - "source_location": "L6" - }, { "id": "backend_app_ratelimit_allow", "label": "allow()", @@ -8492,85 +9094,25 @@ "source_file": "frontend/src/components/charts/HorizontalBars.tsx", "source_location": "L16" }, - { - "id": "backend_app_dependencies_current_context", - "label": "current_context()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "current_context()", - "source_file": "backend/app/dependencies.py", - "source_location": "L44" - }, - { - "id": "backend_app_dependencies_current_session", - "label": "current_session()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "current_session()", - "source_file": "backend/app/dependencies.py", - "source_location": "L28" - }, - { - "id": "backend_app_dependencies_require_csrf", - "label": "require_csrf()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "require_csrf()", - "source_file": "backend/app/dependencies.py", - "source_location": "L59" - }, { "id": "backend_app_errors_forbidden", "label": "forbidden()", "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "forbidden()", "source_file": "backend/app/errors.py", "source_location": "L35" }, - { - "id": "backend_app_exports_service_cancel_deletion", - "label": "cancel_deletion()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "cancel_deletion()", - "source_file": "backend/app/exports/service.py", - "source_location": "L163" - }, - { - "id": "backend_app_security_constant_time_equals", - "label": "constant_time_equals()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "constant_time_equals()", - "source_file": "backend/app/security.py", - "source_location": "L29" - }, { "id": "backend_app_spaces_router_cancel_deletion", "label": "cancel_deletion()", "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "cancel_deletion()", "source_file": "backend/app/spaces/router.py", @@ -8582,7 +9124,7 @@ "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "current()", "source_file": "backend/app/spaces/router.py", @@ -8594,7 +9136,7 @@ "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "deletion_status()", "source_file": "backend/app/spaces/router.py", @@ -8606,7 +9148,7 @@ "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "invite_member()", "source_file": "backend/app/spaces/router.py", @@ -8618,43 +9160,19 @@ "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "schedule_deletion()", "source_file": "backend/app/spaces/router.py", "source_location": "L50" }, - { - "id": "backend_app_spaces_service_get_membership", - "label": "get_membership()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "get_membership()", - "source_file": "backend/app/spaces/service.py", - "source_location": "L27" - }, - { - "id": "backend_app_spaces_service_get_space_for_member", - "label": "get_space_for_member()", - "_callable": true, - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "get_space_for_member()", - "source_file": "backend/app/spaces/service.py", - "source_location": "L34" - }, { "id": "backend_app_spaces_service_list_spaces_for_user", "label": "list_spaces_for_user()", "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "list_spaces_for_user()", "source_file": "backend/app/spaces/service.py", @@ -8666,7 +9184,7 @@ "_callable": true, "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "require_owner()", "source_file": "backend/app/spaces/service.py", @@ -8684,17 +9202,65 @@ "source_file": ".kilo/plugins/graphify.js", "source_location": "L6" }, + { + "id": "backend_app_errors_apperror_init", + "label": ".__init__()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": ".__init__()", + "source_file": "backend/app/errors.py", + "source_location": "L10" + }, + { + "id": "backend_app_errors_conflict", + "label": "conflict()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "conflict()", + "source_file": "backend/app/errors.py", + "source_location": "L43" + }, + { + "id": "backend_app_errors_unprocessable", + "label": "unprocessable()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "unprocessable()", + "source_file": "backend/app/errors.py", + "source_location": "L47" + }, + { + "id": "backend_app_exports_service_cancel_deletion", + "label": "cancel_deletion()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "cancel_deletion()", + "source_file": "backend/app/exports/service.py", + "source_location": "L163" + }, { "id": "backend_app_ledger_savings_adjust_balance", "label": "adjust_balance()", "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "adjust_balance()", "source_file": "backend/app/ledger/savings.py", - "source_location": "L112" + "source_location": "L108" }, { "id": "backend_app_ledger_savings_convert_expense_to_savings", @@ -8702,11 +9268,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "convert_expense_to_savings()", "source_file": "backend/app/ledger/savings.py", - "source_location": "L196" + "source_location": "L190" }, { "id": "backend_app_ledger_savings_ensure_savings_resources", @@ -8714,11 +9280,23 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "ensure_savings_resources()", "source_file": "backend/app/ledger/savings.py", - "source_location": "L39" + "source_location": "L35" + }, + { + "id": "backend_app_ledger_savings_get_savings_account", + "label": "get_savings_account()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "get_savings_account()", + "source_file": "backend/app/ledger/savings.py", + "source_location": "L23" }, { "id": "backend_app_ledger_savings_revert_savings_conversion", @@ -8726,11 +9304,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "revert_savings_conversion()", "source_file": "backend/app/ledger/savings.py", - "source_location": "L288" + "source_location": "L280" }, { "id": "backend_app_ledger_savings_transfer_category_for_accounts", @@ -8738,11 +9316,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "transfer_category_for_accounts()", "source_file": "backend/app/ledger/savings.py", - "source_location": "L102" + "source_location": "L98" }, { "id": "backend_app_spaces_service_create_space", @@ -8750,7 +9328,7 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "create_space()", "source_file": "backend/app/spaces/service.py", @@ -8762,7 +9340,7 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "seed()", "source_file": "backend/tests/test_savings.py", @@ -8774,7 +9352,7 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_adjust_balance_creates_single_signed_posting()", "source_file": "backend/tests/test_savings.py", @@ -8786,11 +9364,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_adjust_balance_positive_delta_and_upward_adjustment()", "source_file": "backend/tests/test_savings.py", - "source_location": "L108" + "source_location": "L107" }, { "id": "backend_tests_test_savings_test_adjust_balance_protects_closed_period", @@ -8798,11 +9376,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_adjust_balance_protects_closed_period()", "source_file": "backend/tests/test_savings.py", - "source_location": "L188" + "source_location": "L187" }, { "id": "backend_tests_test_savings_test_adjust_balance_rejects_credit_accounts", @@ -8810,11 +9388,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_adjust_balance_rejects_credit_accounts()", "source_file": "backend/tests/test_savings.py", - "source_location": "L125" + "source_location": "L124" }, { "id": "backend_tests_test_savings_test_adjust_balance_rejects_noop_negative_target_and_missing_reason", @@ -8822,11 +9400,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_adjust_balance_rejects_noop_negative_target_and_missing_reason()", "source_file": "backend/tests/test_savings.py", - "source_location": "L149" + "source_location": "L148" }, { "id": "backend_tests_test_savings_test_convert_expense_to_savings_and_revert_roundtrip", @@ -8834,11 +9412,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_convert_expense_to_savings_and_revert_roundtrip()", "source_file": "backend/tests/test_savings.py", - "source_location": "L205" + "source_location": "L204" }, { "id": "backend_tests_test_savings_test_convert_rejects_closed_period_and_cross_space_operation", @@ -8846,11 +9424,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_convert_rejects_closed_period_and_cross_space_operation()", "source_file": "backend/tests/test_savings.py", - "source_location": "L350" + "source_location": "L339" }, { "id": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", @@ -8858,11 +9436,23 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_convert_rejects_expense_with_confirmed_refund()", "source_file": "backend/tests/test_savings.py", - "source_location": "L324" + "source_location": "L315" + }, + { + "id": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", + "label": "test_convert_rejects_income_refund_transfer_and_double_conversion()", + "_callable": true, + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "test_convert_rejects_income_refund_transfer_and_double_conversion()", + "source_file": "backend/tests/test_savings.py", + "source_location": "L250" }, { "id": "backend_tests_test_savings_test_manual_transfer_with_savings_gets_system_category", @@ -8870,11 +9460,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_manual_transfer_with_savings_gets_system_category()", "source_file": "backend/tests/test_savings.py", - "source_location": "L425" + "source_location": "L410" }, { "id": "backend_tests_test_savings_test_operations_on_other_spaces_are_isolated", @@ -8882,11 +9472,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_operations_on_other_spaces_are_isolated()", "source_file": "backend/tests/test_savings.py", - "source_location": "L481" + "source_location": "L466" }, { "id": "backend_tests_test_savings_test_revert_rejects_plain_transfers_and_unknown_operations", @@ -8894,11 +9484,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_revert_rejects_plain_transfers_and_unknown_operations()", "source_file": "backend/tests/test_savings.py", - "source_location": "L379" + "source_location": "L364" }, { "id": "backend_tests_test_savings_test_same_named_user_account_is_not_captured", @@ -8906,7 +9496,7 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_same_named_user_account_is_not_captured()", "source_file": "backend/tests/test_savings.py", @@ -8918,7 +9508,7 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_space_creation_builds_exactly_one_system_pair()", "source_file": "backend/tests/test_savings.py", @@ -8930,11 +9520,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_system_account_cannot_be_archived_or_deleted()", "source_file": "backend/tests/test_savings.py", - "source_location": "L468" + "source_location": "L453" }, { "id": "backend_tests_test_savings_test_system_account_rejects_external_operations", @@ -8942,11 +9532,11 @@ "_callable": true, "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_system_account_rejects_external_operations()", "source_file": "backend/tests/test_savings.py", - "source_location": "L399" + "source_location": "L384" }, { "id": "frontend_src_app_router_requireauth", @@ -9008,18 +9598,6 @@ "source_file": "frontend/src/components/ui/Button.tsx", "source_location": "L9" }, - { - "id": "frontend_src_components_ui_errorstate_errorstate", - "label": "ErrorState()", - "_callable": true, - "_origin": "ast", - "community": 8, - "community_name": "router.tsx", - "file_type": "code", - "norm_label": "errorstate()", - "source_file": "frontend/src/components/ui/ErrorState.tsx", - "source_location": "L10" - }, { "id": "frontend_src_components_ui_fields_textfield", "label": "TextField()", @@ -9116,6 +9694,66 @@ "source_file": "frontend/src/hooks/useAuth.ts", "source_location": "L15" }, + { + "id": "frontend_src_hooks_usespacelifecycle_usecanceldeletion", + "label": "useCancelDeletion()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "usecanceldeletion()", + "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", + "source_location": "L50" + }, + { + "id": "frontend_src_hooks_usespacelifecycle_userequestdeletion", + "label": "useRequestDeletion()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "userequestdeletion()", + "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", + "source_location": "L36" + }, + { + "id": "frontend_src_hooks_usespacelifecycle_userequestexport", + "label": "useRequestExport()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "userequestexport()", + "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", + "source_location": "L12" + }, + { + "id": "frontend_src_hooks_usespacelifecycle_usespacedeletion", + "label": "useSpaceDeletion()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "usespacedeletion()", + "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", + "source_location": "L8" + }, + { + "id": "frontend_src_lib_apierrors_describeapierror", + "label": "describeApiError()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "describeapierror()", + "source_file": "frontend/src/lib/apiErrors.ts", + "source_location": "L5" + }, { "id": "frontend_src_pages_acceptinvitepage_acceptinvitepage", "label": "AcceptInvitePage()", @@ -9152,6 +9790,30 @@ "source_file": "frontend/src/pages/ResetPasswordPage.tsx", "source_location": "L19" }, + { + "id": "frontend_src_pages_settingspage_deletionform", + "label": "DeletionForm()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "deletionform()", + "source_file": "frontend/src/pages/SettingsPage.tsx", + "source_location": "L23" + }, + { + "id": "frontend_src_pages_settingspage_settingspage", + "label": "SettingsPage()", + "_callable": true, + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "settingspage()", + "source_file": "frontend/src/pages/SettingsPage.tsx", + "source_location": "L58" + }, { "id": "backend_tests_test_category_definitions_bootstrap", "label": "bootstrap()", @@ -9225,268 +9887,64 @@ "source_location": "L26" }, { - "id": "backend_app_audit_service_record", - "label": "record()", + "id": "backend_app_spaces_service_get_membership", + "label": "get_membership()", "_callable": true, "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "record()", - "source_file": "backend/app/audit/service.py", - "source_location": "L8" + "norm_label": "get_membership()", + "source_file": "backend/app/spaces/service.py", + "source_location": "L27" }, { - "id": "backend_app_db_base_utcnow", - "label": "utcnow()", + "id": "backend_app_spaces_service_get_space_for_member", + "label": "get_space_for_member()", "_callable": true, "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "utcnow()", - "source_file": "backend/app/db/base.py", - "source_location": "L40" + "norm_label": "get_space_for_member()", + "source_file": "backend/app/spaces/service.py", + "source_location": "L34" }, { - "id": "backend_app_errors_conflict", - "label": "conflict()", + "id": "backend_tests_test_postgres_and_s3_test_postgres_rls_requires_matching_transaction_context", + "label": "test_postgres_rls_requires_matching_transaction_context()", "_callable": true, "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "conflict()", - "source_file": "backend/app/errors.py", - "source_location": "L43" + "norm_label": "test_postgres_rls_requires_matching_transaction_context()", + "source_file": "backend/tests/test_postgres_and_s3.py", + "source_location": "L18" }, { - "id": "backend_app_errors_not_found", - "label": "not_found()", + "id": "backend_tests_test_postgres_and_s3_test_s3_blob_round_trip", + "label": "test_s3_blob_round_trip()", "_callable": true, "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "not_found()", - "source_file": "backend/app/errors.py", - "source_location": "L39" + "norm_label": "test_s3_blob_round_trip()", + "source_file": "backend/tests/test_postgres_and_s3.py", + "source_location": "L91" }, { - "id": "backend_app_imports_adapters_init_magic_kind", - "label": "magic_kind()", + "id": "backend_tests_test_savings_migration_test_upgrade_backfills_one_pair_without_claiming_same_named_rows", + "label": "test_upgrade_backfills_one_pair_without_claiming_same_named_rows()", "_callable": true, "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "magic_kind()", - "source_file": "backend/app/imports/adapters/__init__.py", - "source_location": "L22" - }, - { - "id": "backend_app_imports_service_apply_hold_matches", - "label": "_apply_hold_matches()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "_apply_hold_matches()", - "source_file": "backend/app/imports/service.py", - "source_location": "L415" - }, - { - "id": "backend_app_imports_service_category_id_for_source", - "label": "_category_id_for_source()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "_category_id_for_source()", - "source_file": "backend/app/imports/service.py", - "source_location": "L175" - }, - { - "id": "backend_app_imports_service_confirm_document", - "label": "confirm_document()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "confirm_document()", - "source_file": "backend/app/imports/service.py", - "source_location": "L932" - }, - { - "id": "backend_app_imports_service_create_document", - "label": "create_document()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "create_document()", - "source_file": "backend/app/imports/service.py", - "source_location": "L52" - }, - { - "id": "backend_app_imports_service_decide_source_record", - "label": "decide_source_record()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "decide_source_record()", - "source_file": "backend/app/imports/service.py", - "source_location": "L696" - }, - { - "id": "backend_app_imports_service_delete_source_file", - "label": "delete_source_file()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "delete_source_file()", - "source_file": "backend/app/imports/service.py", - "source_location": "L1402" - }, - { - "id": "backend_app_imports_service_document", - "label": "_document()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "_document()", - "source_file": "backend/app/imports/service.py", - "source_location": "L43" - }, - { - "id": "backend_app_imports_service_document_detail", - "label": "document_detail()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "document_detail()", - "source_file": "backend/app/imports/service.py", - "source_location": "L606" - }, - { - "id": "backend_app_imports_service_draft_json", - "label": "_draft_json()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "_draft_json()", - "source_file": "backend/app/imports/service.py", - "source_location": "L124" - }, - { - "id": "backend_app_imports_service_list_documents", - "label": "list_documents()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "list_documents()", - "source_file": "backend/app/imports/service.py", - "source_location": "L531" - }, - { - "id": "backend_app_imports_service_prepare_reparse", - "label": "prepare_reparse()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "prepare_reparse()", - "source_file": "backend/app/imports/service.py", - "source_location": "L1210" - }, - { - "id": "backend_app_imports_service_process_statement_document", - "label": "process_statement_document()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "process_statement_document()", - "source_file": "backend/app/imports/service.py", - "source_location": "L447" - }, - { - "id": "backend_app_imports_service_resolve_hold", - "label": "resolve_hold()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "resolve_hold()", - "source_file": "backend/app/imports/service.py", - "source_location": "L819" - }, - { - "id": "backend_app_imports_service_revert_document", - "label": "revert_document()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "revert_document()", - "source_file": "backend/app/imports/service.py", - "source_location": "L1235" - }, - { - "id": "backend_app_imports_service_set_review_confirmation", - "label": "set_review_confirmation()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "set_review_confirmation()", - "source_file": "backend/app/imports/service.py", - "source_location": "L776" - }, - { - "id": "backend_app_imports_service_source_from_row", - "label": "_source_from_row()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "_source_from_row()", - "source_file": "backend/app/imports/service.py", - "source_location": "L136" - }, - { - "id": "backend_app_imports_service_unresolved_hold_counts", - "label": "unresolved_hold_counts()", - "_callable": true, - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "unresolved_hold_counts()", - "source_file": "backend/app/imports/service.py", - "source_location": "L559" + "norm_label": "test_upgrade_backfills_one_pair_without_claiming_same_named_rows()", + "source_file": "backend/tests/test_savings_migration.py", + "source_location": "L16" }, { "id": "backend_app_exports_service_build_export", @@ -9584,30 +10042,6 @@ "source_file": "backend/app/exports/service.py", "source_location": "L148" }, - { - "id": "backend_app_exports_tasks_build_export_task", - "label": "build_export_task()", - "_callable": true, - "_origin": "ast", - "community": 83, - "community_name": "exports/service.py", - "file_type": "code", - "norm_label": "build_export_task()", - "source_file": "backend/app/exports/tasks.py", - "source_location": "L9" - }, - { - "id": "backend_app_exports_tasks_purge_due_spaces_task", - "label": "purge_due_spaces_task()", - "_callable": true, - "_origin": "ast", - "community": 83, - "community_name": "exports/service.py", - "file_type": "code", - "norm_label": "purge_due_spaces_task()", - "source_file": "backend/app/exports/tasks.py", - "source_location": "L25" - }, { "id": "backend_app_imports_blob_blobstore_delete", "label": ".delete()", @@ -9717,268 +10151,40 @@ "source_location": "L58" }, { - "id": "backend_app_imports_service_build_candidates", - "label": "_build_candidates()", + "id": "backend_app_imports_crypto_decrypt_file", + "label": "decrypt_file()", "_callable": true, "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", + "community": 83, + "community_name": "exports/service.py", "file_type": "code", - "norm_label": "_build_candidates()", - "source_file": "backend/app/imports/service.py", - "source_location": "L239" + "norm_label": "decrypt_file()", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L37" }, { - "id": "backend_app_imports_service_match_hold_resolutions", - "label": "_match_hold_resolutions()", + "id": "backend_app_imports_crypto_encrypt_file", + "label": "encrypt_file()", "_callable": true, "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", + "community": 83, + "community_name": "exports/service.py", "file_type": "code", - "norm_label": "_match_hold_resolutions()", - "source_file": "backend/app/imports/service.py", - "source_location": "L348" + "norm_label": "encrypt_file()", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L21" }, { - "id": "backend_app_imports_service_unresolved_holds", - "label": "unresolved_holds()", + "id": "backend_app_imports_crypto_shred_dek_material", + "label": "shred_dek_material()", "_callable": true, "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", + "community": 83, + "community_name": "exports/service.py", "file_type": "code", - "norm_label": "unresolved_holds()", - "source_file": "backend/app/imports/service.py", - "source_location": "L540" - }, - { - "id": "backend_tests_test_imports_ready_document", - "label": "ready_document()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "ready_document()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L42" - }, - { - "id": "backend_tests_test_imports_seed", - "label": "seed()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "seed()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L26" - }, - { - "id": "backend_tests_test_imports_test_confirm_and_revert_are_idempotent", - "label": "test_confirm_and_revert_are_idempotent()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_confirm_and_revert_are_idempotent()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L81" - }, - { - "id": "backend_tests_test_imports_test_confirm_rejects_arithmetic_mismatch", - "label": "test_confirm_rejects_arithmetic_mismatch()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_confirm_rejects_arithmetic_mismatch()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L135" - }, - { - "id": "backend_tests_test_imports_test_confirm_reports_pending_candidate_instead_of_generic_not_ready", - "label": "test_confirm_reports_pending_candidate_instead_of_generic_not_ready()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_confirm_reports_pending_candidate_instead_of_generic_not_ready()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L492" - }, - { - "id": "backend_tests_test_imports_test_confirmed_import_must_be_reverted_before_reparse", - "label": "test_confirmed_import_must_be_reverted_before_reparse()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_confirmed_import_must_be_reverted_before_reparse()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L143" - }, - { - "id": "backend_tests_test_imports_test_duplicate_candidate_can_reuse_unique_operation_without_client_id", - "label": "test_duplicate_candidate_can_reuse_unique_operation_without_client_id()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_duplicate_candidate_can_reuse_unique_operation_without_client_id()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L205" - }, - { - "id": "backend_tests_test_imports_test_duplicate_candidates_are_retained_before_account_mapping", - "label": "test_duplicate_candidates_are_retained_before_account_mapping()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_duplicate_candidates_are_retained_before_account_mapping()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L412" - }, - { - "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_inactive_parse_runs", - "label": "test_duplicate_candidates_ignore_inactive_parse_runs()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_duplicate_candidates_ignore_inactive_parse_runs()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L294" - }, - { - "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_rows_from_same_parse_run", - "label": "test_duplicate_candidates_ignore_rows_from_same_parse_run()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_duplicate_candidates_ignore_rows_from_same_parse_run()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L261" - }, - { - "id": "backend_tests_test_imports_test_duplicate_candidates_ignore_unconfirmed_documents", - "label": "test_duplicate_candidates_ignore_unconfirmed_documents()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_duplicate_candidates_ignore_unconfirmed_documents()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L368" - }, - { - "id": "backend_tests_test_imports_test_import_detail_exposes_pending_candidate_and_blocker", - "label": "test_import_detail_exposes_pending_candidate_and_blocker()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_import_detail_exposes_pending_candidate_and_blocker()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L457" - }, - { - "id": "backend_tests_test_imports_test_import_mcc_assigns_default_category_and_label", - "label": "test_import_mcc_assigns_default_category_and_label()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_import_mcc_assigns_default_category_and_label()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L120" - }, - { - "id": "backend_tests_test_imports_test_import_review_and_confirmation_do_not_require_reason", - "label": "test_import_review_and_confirmation_do_not_require_reason()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_import_review_and_confirmation_do_not_require_reason()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L96" - }, - { - "id": "backend_tests_test_imports_test_invalid_direction_is_critical", - "label": "test_invalid_direction_is_critical()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_invalid_direction_is_critical()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L151" - }, - { - "id": "backend_tests_test_imports_test_transfer_merge_revert_restores_counterpart_operation", - "label": "test_transfer_merge_revert_restores_counterpart_operation()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_transfer_merge_revert_restores_counterpart_operation()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L512" - }, - { - "id": "backend_tests_test_imports_test_unexpected_parser_failure_reaches_terminal_state", - "label": "test_unexpected_parser_failure_reaches_terminal_state()", - "_callable": true, - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "test_unexpected_parser_failure_reaches_terminal_state()", - "source_file": "backend/tests/test_imports.py", - "source_location": "L173" - }, - { - "id": "backend_app_errors_bad_request", - "label": "bad_request()", - "_callable": true, - "_origin": "ast", - "community": 85, - "community_name": "identity/service.py", - "file_type": "code", - "norm_label": "bad_request()", - "source_file": "backend/app/errors.py", - "source_location": "L27" - }, - { - "id": "backend_app_errors_unauthorized", - "label": "unauthorized()", - "_callable": true, - "_origin": "ast", - "community": 85, - "community_name": "identity/service.py", - "file_type": "code", - "norm_label": "unauthorized()", - "source_file": "backend/app/errors.py", - "source_location": "L31" + "norm_label": "shred_dek_material()", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L56" }, { "id": "backend_app_identity_service_accept_invitation", @@ -10040,18 +10246,6 @@ "source_file": "backend/app/identity/service.py", "source_location": "L115" }, - { - "id": "backend_app_identity_service_get_active_session", - "label": "get_active_session()", - "_callable": true, - "_origin": "ast", - "community": 85, - "community_name": "identity/service.py", - "file_type": "code", - "norm_label": "get_active_session()", - "source_file": "backend/app/identity/service.py", - "source_location": "L131" - }, { "id": "backend_app_identity_service_normalize_email", "label": "normalize_email()", @@ -10100,18 +10294,6 @@ "source_file": "backend/app/identity/service.py", "source_location": "L19" }, - { - "id": "backend_app_imports_service_parse_month_filter", - "label": "parse_month_filter()", - "_callable": true, - "_origin": "ast", - "community": 85, - "community_name": "identity/service.py", - "file_type": "code", - "norm_label": "parse_month_filter()", - "source_file": "backend/app/imports/service.py", - "source_location": "L593" - }, { "id": "backend_app_security_hash_password", "label": "hash_password()", @@ -10160,13 +10342,37 @@ "source_file": "backend/app/security.py", "source_location": "L14" }, + { + "id": "backend_app_imports_adapters_base_normalize_description", + "label": "normalize_description()", + "_callable": true, + "_origin": "ast", + "community": 86, + "community_name": "test_import_holds.py", + "file_type": "code", + "norm_label": "normalize_description()", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L131" + }, + { + "id": "backend_app_imports_adapters_base_record_fingerprint", + "label": "record_fingerprint()", + "_callable": true, + "_origin": "ast", + "community": 86, + "community_name": "test_import_holds.py", + "file_type": "code", + "norm_label": "record_fingerprint()", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L137" + }, { "id": "backend_tests_test_import_holds_add_record", "label": "add_record()", "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "add_record()", "source_file": "backend/tests/test_import_holds.py", @@ -10178,7 +10384,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "_draft()", "source_file": "backend/tests/test_import_holds.py", @@ -10190,7 +10396,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "hold_document()", "source_file": "backend/tests/test_import_holds.py", @@ -10202,7 +10408,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "make_document()", "source_file": "backend/tests/test_import_holds.py", @@ -10214,7 +10420,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "_row()", "source_file": "backend/tests/test_import_holds.py", @@ -10226,7 +10432,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "seed()", "source_file": "backend/tests/test_import_holds.py", @@ -10238,7 +10444,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_ambiguous_overlap_remains_unresolved()", "source_file": "backend/tests/test_import_holds.py", @@ -10250,7 +10456,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_bank_status_defaults_to_posted_and_is_constrained()", "source_file": "backend/tests/test_import_holds.py", @@ -10262,31 +10468,19 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_confirm_as_posted_accepts_blank_reason()", "source_file": "backend/tests/test_import_holds.py", "source_location": "L235" }, - { - "id": "backend_tests_test_import_holds_test_discard_as_cancelled_without_reason_unblocks_month", - "label": "test_discard_as_cancelled_without_reason_unblocks_month()", - "_callable": true, - "_origin": "ast", - "community": 86, - "community_name": "Session", - "file_type": "code", - "norm_label": "test_discard_as_cancelled_without_reason_unblocks_month()", - "source_file": "backend/tests/test_import_holds.py", - "source_location": "L210" - }, { "id": "backend_tests_test_import_holds_test_discarded_posted_record_does_not_resolve_hold", "label": "test_discarded_posted_record_does_not_resolve_hold()", "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_discarded_posted_record_does_not_resolve_hold()", "source_file": "backend/tests/test_import_holds.py", @@ -10298,7 +10492,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_external_id_match_survives_description_drift()", "source_file": "backend/tests/test_import_holds.py", @@ -10310,7 +10504,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_fingerprint_match_without_external_id_resolves()", "source_file": "backend/tests/test_import_holds.py", @@ -10322,7 +10516,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_hold_cannot_be_resolved_before_document_confirmation()", "source_file": "backend/tests/test_import_holds.py", @@ -10334,7 +10528,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_hold_matching_is_tenant_scoped()", "source_file": "backend/tests/test_import_holds.py", @@ -10346,7 +10540,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_hold_resolution_rejects_unknown_kind()", "source_file": "backend/tests/test_import_holds.py", @@ -10358,7 +10552,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_hold_row_creates_no_operation_on_confirm()", "source_file": "backend/tests/test_import_holds.py", @@ -10370,7 +10564,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_manual_confirm_creates_one_operation_and_late_import_dedupes()", "source_file": "backend/tests/test_import_holds.py", @@ -10382,7 +10576,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_manual_confirm_honors_closed_period()", "source_file": "backend/tests/test_import_holds.py", @@ -10394,7 +10588,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_manual_confirm_of_income_hold_creates_income()", "source_file": "backend/tests/test_import_holds.py", @@ -10406,7 +10600,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_manual_confirm_rejects_bad_action_and_non_hold_row()", "source_file": "backend/tests/test_import_holds.py", @@ -10418,7 +10612,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_manual_resolution_accepts_no_reason_at_database_level()", "source_file": "backend/tests/test_import_holds.py", @@ -10430,7 +10624,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_matcher_rejects_two_posted_candidates_for_one_hold()", "source_file": "backend/tests/test_import_holds.py", @@ -10442,7 +10636,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_reconciliation_balance_equation_ignores_holds()", "source_file": "backend/tests/test_import_holds.py", @@ -10454,7 +10648,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_reconciliation_declared_outflow_mismatch_blocks()", "source_file": "backend/tests/test_import_holds.py", @@ -10466,7 +10660,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_reconciliation_hold_mismatch_is_review_blocking()", "source_file": "backend/tests/test_import_holds.py", @@ -10478,7 +10672,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_reconciliation_separates_posted_and_hold_totals()", "source_file": "backend/tests/test_import_holds.py", @@ -10490,7 +10684,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_reconciliation_without_declared_totals_keeps_legacy_semantics()", "source_file": "backend/tests/test_import_holds.py", @@ -10502,7 +10696,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_resolve_endpoint_requires_csrf_and_resolves_hold()", "source_file": "backend/tests/test_import_holds.py", @@ -10514,7 +10708,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_revert_clears_automatic_match_and_reblocks_month()", "source_file": "backend/tests/test_import_holds.py", @@ -10526,7 +10720,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_revert_preserves_manual_hold_operation_and_provenance()", "source_file": "backend/tests/test_import_holds.py", @@ -10538,7 +10732,7 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_source_row_without_bank_status_defaults_posted()", "source_file": "backend/tests/test_import_holds.py", @@ -10550,36 +10744,60 @@ "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_unique_posted_record_resolves_hold_on_confirmation()", "source_file": "backend/tests/test_import_holds.py", "source_location": "L430" }, - { - "id": "backend_tests_test_import_holds_test_unresolved_hold_blocks_only_its_occurred_month", - "label": "test_unresolved_hold_blocks_only_its_occurred_month()", - "_callable": true, - "_origin": "ast", - "community": 86, - "community_name": "Session", - "file_type": "code", - "norm_label": "test_unresolved_hold_blocks_only_its_occurred_month()", - "source_file": "backend/tests/test_import_holds.py", - "source_location": "L193" - }, { "id": "backend_tests_test_import_holds_test_upgrade_drops_legacy_manual_reason_constraint", "label": "test_upgrade_drops_legacy_manual_reason_constraint()", "_callable": true, "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_upgrade_drops_legacy_manual_reason_constraint()", "source_file": "backend/tests/test_import_holds.py", "source_location": "L757" }, + { + "id": "backend_app_budgeting_service_close_period", + "label": "close_period()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "close_period()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L984" + }, + { + "id": "backend_app_budgeting_service_compute_period_state", + "label": "compute_period_state()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "compute_period_state()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L113" + }, + { + "id": "backend_app_budgeting_service_create_category", + "label": "create_category()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "create_category()", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L546" + }, { "id": "backend_app_budgeting_service_get_or_create_period", "label": "get_or_create_period()", @@ -10592,18 +10810,6 @@ "source_file": "backend/app/budgeting/service.py", "source_location": "L55" }, - { - "id": "backend_app_budgeting_service_validate_year_month", - "label": "validate_year_month()", - "_callable": true, - "_origin": "ast", - "community": 87, - "community_name": "get_or_create_period", - "file_type": "code", - "norm_label": "validate_year_month()", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L27" - }, { "id": "backend_tests_test_budget_savings_savings_row", "label": "savings_row()", @@ -10736,6 +10942,102 @@ "source_file": "backend/tests/test_budget_savings.py", "source_location": "L44" }, + { + "id": "backend_tests_test_budget_seed", + "label": "seed()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "seed()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L24" + }, + { + "id": "backend_tests_test_budget_test_copy_previous_month_clamps_expected_day", + "label": "test_copy_previous_month_clamps_expected_day()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_copy_previous_month_clamps_expected_day()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L115" + }, + { + "id": "backend_tests_test_budget_test_default_mcc_categories_are_budgetable_and_editable_mapping", + "label": "test_default_mcc_categories_are_budgetable_and_editable_mapping()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_default_mcc_categories_are_budgetable_and_editable_mapping()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L56" + }, + { + "id": "backend_tests_test_budget_test_periods_must_close_in_calendar_order", + "label": "test_periods_must_close_in_calendar_order()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_periods_must_close_in_calendar_order()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L153" + }, + { + "id": "backend_tests_test_budget_test_reopen_preserves_immutable_closure_history", + "label": "test_reopen_preserves_immutable_closure_history()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_reopen_preserves_immutable_closure_history()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L144" + }, + { + "id": "backend_tests_test_budget_test_uncategorized_expense_blocks_close", + "label": "test_uncategorized_expense_blocks_close()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_uncategorized_expense_blocks_close()", + "source_file": "backend/tests/test_budget.py", + "source_location": "L31" + }, + { + "id": "backend_tests_test_import_holds_test_discard_as_cancelled_without_reason_unblocks_month", + "label": "test_discard_as_cancelled_without_reason_unblocks_month()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_discard_as_cancelled_without_reason_unblocks_month()", + "source_file": "backend/tests/test_import_holds.py", + "source_location": "L210" + }, + { + "id": "backend_tests_test_import_holds_test_unresolved_hold_blocks_only_its_occurred_month", + "label": "test_unresolved_hold_blocks_only_its_occurred_month()", + "_callable": true, + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_unresolved_hold_blocks_only_its_occurred_month()", + "source_file": "backend/tests/test_import_holds.py", + "source_location": "L193" + }, { "id": "backend_alembic_versions_20260923_0005_optional_hold_reason_downgrade", "label": "downgrade()", @@ -10772,174 +11074,6 @@ "source_file": "backend/alembic/versions/20260923_0005_optional_hold_reason.py", "source_location": "L24" }, - { - "id": "backend_app_ledger_savings_get_savings_account", - "label": "get_savings_account()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "get_savings_account()", - "source_file": "backend/app/ledger/savings.py", - "source_location": "L23" - }, - { - "id": "backend_tests_test_import_savings_add_record", - "label": "add_record()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "add_record()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75" - }, - { - "id": "backend_tests_test_import_savings_make_document", - "label": "make_document()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "make_document()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L49" - }, - { - "id": "backend_tests_test_import_savings_seed", - "label": "seed()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "seed()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L33" - }, - { - "id": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", - "label": "test_confirm_creates_savings_transfer_with_system_category()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_confirm_creates_savings_transfer_with_system_category()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L119" - }, - { - "id": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", - "label": "test_confirm_savings_transfer_rejects_savings_statement_account()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_confirm_savings_transfer_rejects_savings_statement_account()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L378" - }, - { - "id": "backend_tests_test_import_savings_test_existing_dedup_wins_over_savings_creation", - "label": "test_existing_dedup_wins_over_savings_creation()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_existing_dedup_wins_over_savings_creation()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L251" - }, - { - "id": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", - "label": "test_parsed_savings_hint_becomes_initial_review_decision()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_parsed_savings_hint_becomes_initial_review_decision()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L112" - }, - { - "id": "backend_tests_test_import_savings_test_revert_removes_created_savings_transfer", - "label": "test_revert_removes_created_savings_transfer()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_revert_removes_created_savings_transfer()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L154" - }, - { - "id": "backend_tests_test_import_savings_test_savings_decision_rejects_incoming_rows", - "label": "test_savings_decision_rejects_incoming_rows()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_savings_decision_rejects_incoming_rows()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L211" - }, - { - "id": "backend_tests_test_import_savings_test_statement_mapping_rejects_system_account", - "label": "test_statement_mapping_rejects_system_account()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_statement_mapping_rejects_system_account()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L234" - }, - { - "id": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", - "label": "test_unresolved_hold_counts_and_month_filter()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_unresolved_hold_counts_and_month_filter()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L314" - }, - { - "id": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_create", - "label": "test_user_can_switch_savings_decision_to_create()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_user_can_switch_savings_decision_to_create()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L173" - }, - { - "id": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", - "label": "test_user_can_switch_savings_decision_to_discard()", - "_callable": true, - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_user_can_switch_savings_decision_to_discard()", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L193" - }, { "id": "backend_app_ledger_router_account_json", "label": "account_json()", @@ -11238,7 +11372,7 @@ "file_type": "code", "norm_label": "operations_by_id()", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L67" + "source_location": "L65" }, { "id": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", @@ -11250,7 +11384,7 @@ "file_type": "code", "norm_label": "test_batch_assigns_picked_categories_and_moves_leftovers_to_others()", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L73" + "source_location": "L71" }, { "id": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", @@ -11262,7 +11396,7 @@ "file_type": "code", "norm_label": "test_batch_is_atomic_when_one_category_is_unknown()", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L146" + "source_location": "L144" }, { "id": "backend_tests_test_review_queue_batch_test_batch_never_overwrites_existing_categories_or_voided_operations", @@ -11274,7 +11408,7 @@ "file_type": "code", "norm_label": "test_batch_never_overwrites_existing_categories_or_voided_operations()", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L104" + "source_location": "L102" }, { "id": "backend_tests_test_review_queue_batch_test_batch_rejects_empty_payload", @@ -11286,121 +11420,187 @@ "file_type": "code", "norm_label": "test_batch_rejects_empty_payload()", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L170" + "source_location": "L168" }, { - "id": "frontend_src_test_review_queue_save_test_operation", - "label": "operation()", + "id": "frontend_src_hooks_useimports_useimport", + "label": "useImport()", "_callable": true, "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "operation()", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L37" + "norm_label": "useimport()", + "source_file": "frontend/src/hooks/useImports.ts", + "source_location": "L26" }, { - "id": "frontend_src_test_account_adjustment_test_account", - "label": "account()", + "id": "frontend_src_lib_importstatus_importlistpollinterval", + "label": "importListPollInterval()", "_callable": true, "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "account()", - "source_file": "frontend/src/test/account-adjustment.test.tsx", - "source_location": "L23" + "norm_label": "importlistpollinterval()", + "source_file": "frontend/src/lib/importStatus.ts", + "source_location": "L16" }, { - "id": "frontend_src_test_accounts_page_test_account", - "label": "account()", + "id": "frontend_src_lib_importstatus_importpollinterval", + "label": "importPollInterval()", "_callable": true, "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "account()", - "source_file": "frontend/src/test/accounts-page.test.tsx", - "source_location": "L21" + "norm_label": "importpollinterval()", + "source_file": "frontend/src/lib/importStatus.ts", + "source_location": "L11" }, { - "id": "backend_app_analytics_service", - "label": "analytics/service.py", + "id": "frontend_src_lib_importstatus_isterminalimportstatus", + "label": "isTerminalImportStatus()", + "_callable": true, + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "isterminalimportstatus()", + "source_file": "frontend/src/lib/importStatus.ts", + "source_location": "L7" + }, + { + "id": "frontend_src_test_import_polling_test_detail", + "label": "detail()", + "_callable": true, + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "detail()", + "source_file": "frontend/src/test/import-polling.test.tsx", + "source_location": "L25" + }, + { + "id": "frontend_src_test_import_polling_test_makewrapper", + "label": "makeWrapper()", + "_callable": true, + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "makewrapper()", + "source_file": "frontend/src/test/import-polling.test.tsx", + "source_location": "L60" + }, + { + "id": "backend_app_dependencies_current_context", + "label": "current_context()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "current_context()", + "source_file": "backend/app/dependencies.py", + "source_location": "L44" + }, + { + "id": "backend_app_dependencies_current_session", + "label": "current_session()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "current_session()", + "source_file": "backend/app/dependencies.py", + "source_location": "L28" + }, + { + "id": "backend_app_dependencies_require_csrf", + "label": "require_csrf()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "require_csrf()", + "source_file": "backend/app/dependencies.py", + "source_location": "L59" + }, + { + "id": "backend_app_errors_unauthorized", + "label": "unauthorized()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "unauthorized()", + "source_file": "backend/app/errors.py", + "source_location": "L31" + }, + { + "id": "backend_app_identity_service_get_active_session", + "label": "get_active_session()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "get_active_session()", + "source_file": "backend/app/identity/service.py", + "source_location": "L131" + }, + { + "id": "backend_app_security_constant_time_equals", + "label": "constant_time_equals()", + "_callable": true, + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "constant_time_equals()", + "source_file": "backend/app/security.py", + "source_location": "L29" + }, + { + "id": "backend_tests_test_expected_income_login", + "label": "_login()", + "_callable": true, + "_origin": "ast", + "community": 96, + "community_name": "_login", + "file_type": "code", + "norm_label": "_login()", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L230" + }, + { + "id": "backend_tests_test_expected_income_test_expected_income_month_api_crud_and_summary", + "label": "test_expected_income_month_api_crud_and_summary()", + "_callable": true, + "_origin": "ast", + "community": 96, + "community_name": "_login", + "file_type": "code", + "norm_label": "test_expected_income_month_api_crud_and_summary()", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L250" + }, + { + "id": "basesettings", + "label": "BaseSettings", "_origin": "ast", "community": 0, - "community_name": "Category", + "community_name": "Settings", "file_type": "code", - "norm_label": "analytics/service.py", - "source_file": "backend/app/analytics/service.py", - "source_location": "L1" - }, - { - "id": "backend_app_analytics_service_py_date", - "label": "date", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "date", + "norm_label": "basesettings", "source_file": "", "source_location": "" }, - { - "id": "backend_app_analytics_service_py_uuid", - "label": "UUID", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "code", - "norm_label": "uuid", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_categorization_service_rationale_190", - "label": "Category owning the MCC code, else the system \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback.", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "rationale", - "norm_label": "category owning the mcc code, else the system \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback.", - "source_file": "backend/app/categorization/service.py", - "source_location": "L190" - }, - { - "id": "backend_app_categorization_service_rationale_20", - "label": "Literal display name, or None when the name localizes via the system key.\u2026", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "rationale", - "norm_label": "literal display name, or none when the name localizes via the system key....", - "source_file": "backend/app/categorization/service.py", - "source_location": "L20" - }, - { - "id": "backend_app_categorization_service_rationale_33", - "label": "Pure localization key for system categories; None for user categories.", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "rationale", - "norm_label": "pure localization key for system categories; none for user categories.", - "source_file": "backend/app/categorization/service.py", - "source_location": "L33" - }, - { - "id": "backend_app_ledger_models_rationale_169", - "label": "Budget category. Kept in ledger module to avoid circular imports.", - "_origin": "ast", - "community": 0, - "community_name": "Category", - "file_type": "rationale", - "norm_label": "budget category. kept in ledger module to avoid circular imports.", - "source_file": "backend/app/ledger/models.py", - "source_location": "L169" - }, { "id": "backend_app_analytics_init", "label": "analytics/__init__.py", @@ -11544,6 +11744,17 @@ "source_file": "", "source_location": "" }, + { + "id": "backend_app_budgeting_router_py_delete", + "label": "delete", + "_origin": "ast", + "community": 1, + "community_name": "budgeting/router.py", + "file_type": "code", + "norm_label": "delete", + "source_file": "", + "source_location": "" + }, { "id": "backend_app_budgeting_router_py_get", "label": "get", @@ -11589,18 +11800,18 @@ "source_location": "" }, { - "id": "backend_app_budgeting_router_py_uuid", - "label": "UUID", + "id": "backend_app_budgeting_router_py_response", + "label": "Response", "_origin": "ast", "community": 1, "community_name": "budgeting/router.py", "file_type": "code", - "norm_label": "uuid", + "norm_label": "response", "source_file": "", "source_location": "" }, { - "id": "backend_app_categorization_service_py_uuid", + "id": "backend_app_budgeting_router_py_uuid", "label": "UUID", "_origin": "ast", "community": 1, @@ -11621,17 +11832,6 @@ "source_file": "", "source_location": "" }, - { - "id": "backend_app_categorization_service_rationale_222", - "label": "Replace the category's MCC code set; codes are unique per space.", - "_origin": "ast", - "community": 1, - "community_name": "budgeting/router.py", - "file_type": "rationale", - "norm_label": "replace the category's mcc code set; codes are unique per space.", - "source_file": "backend/app/categorization/service.py", - "source_location": "L222" - }, { "id": "frontend_package_devdependencies_testing_library_jest_dom", "label": "@testing-library/jest-dom", @@ -11641,7 +11841,7 @@ "file_type": "code", "norm_label": "@testing-library/jest-dom", "source_file": "frontend/package.json", - "source_location": "L32" + "source_location": "L33" }, { "id": "testing_library_jest_dom", @@ -11652,7 +11852,7 @@ "file_type": "concept", "norm_label": "@testing-library/jest-dom", "source_file": "frontend/package.json", - "source_location": "L32" + "source_location": "L33" }, { "id": "frontend_tsconfig", @@ -11978,7 +12178,7 @@ "label": "NotFoundPage", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "notfoundpage", "source_file": "frontend/src/app/router.tsx", @@ -11989,29 +12189,18 @@ "label": "PlanFactBars.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "planfactbars.tsx", "source_file": "frontend/src/components/charts/PlanFactBars.tsx", "source_location": "L1" }, - { - "id": "frontend_src_components_ui_emptystate", - "label": "EmptyState.tsx", - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "emptystate.tsx", - "source_file": "frontend/src/components/ui/EmptyState.tsx", - "source_location": "L1" - }, { "id": "frontend_src_components_ui_monthswitcher", "label": "MonthSwitcher.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "monthswitcher.tsx", "source_file": "frontend/src/components/ui/MonthSwitcher.tsx", @@ -12022,40 +12211,18 @@ "label": "PageHeader.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "pageheader.tsx", "source_file": "frontend/src/components/ui/PageHeader.tsx", "source_location": "L1" }, - { - "id": "frontend_src_components_ui_querygate", - "label": "QueryGate.tsx", - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "querygate.tsx", - "source_file": "frontend/src/components/ui/QueryGate.tsx", - "source_location": "L1" - }, - { - "id": "frontend_src_components_ui_spinner", - "label": "Spinner.tsx", - "_origin": "ast", - "community": 12, - "community_name": "ReviewQueuePage.tsx", - "file_type": "code", - "norm_label": "spinner.tsx", - "source_file": "frontend/src/components/ui/Spinner.tsx", - "source_location": "L1" - }, { "id": "frontend_src_hooks_useanalytics", "label": "useAnalytics.ts", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "useanalytics.ts", "source_file": "frontend/src/hooks/useAnalytics.ts", @@ -12066,7 +12233,7 @@ "label": "categoryLabel.ts", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "categorylabel.ts", "source_file": "frontend/src/lib/categoryLabel.ts", @@ -12077,7 +12244,7 @@ "label": "dates.ts", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "dates.ts", "source_file": "frontend/src/lib/dates.ts", @@ -12088,7 +12255,7 @@ "label": "INTL_LOCALES", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "intl_locales", "source_file": "frontend/src/lib/dates.ts", @@ -12099,7 +12266,7 @@ "label": "locale.ts", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "locale.ts", "source_file": "frontend/src/lib/locale.ts", @@ -12110,7 +12277,7 @@ "label": "AnalyticsPage.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "analyticspage.tsx", "source_file": "frontend/src/pages/AnalyticsPage.tsx", @@ -12121,29 +12288,40 @@ "label": "RANGE_CHOICES", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "range_choices", "source_file": "frontend/src/pages/AnalyticsPage.tsx", "source_location": "L21" }, { - "id": "frontend_src_pages_importspage", - "label": "ImportsPage.tsx", + "id": "frontend_src_pages_budgetpage", + "label": "BudgetPage.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", - "norm_label": "importspage.tsx", - "source_file": "frontend/src/pages/ImportsPage.tsx", + "norm_label": "budgetpage.tsx", + "source_file": "frontend/src/pages/BudgetPage.tsx", "source_location": "L1" }, + { + "id": "frontend_src_pages_budgetpage_blocker_warning_codes", + "label": "BLOCKER_WARNING_CODES", + "_origin": "ast", + "community": 12, + "community_name": "BudgetPage.tsx", + "file_type": "code", + "norm_label": "blocker_warning_codes", + "source_file": "frontend/src/pages/BudgetPage.tsx", + "source_location": "L31" + }, { "id": "frontend_src_pages_notfoundpage", "label": "NotFoundPage.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "notfoundpage.tsx", "source_file": "frontend/src/pages/NotFoundPage.tsx", @@ -12154,7 +12332,7 @@ "label": "OverviewPage.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "overviewpage.tsx", "source_file": "frontend/src/pages/OverviewPage.tsx", @@ -12165,33 +12343,110 @@ "label": "ReviewQueuePage.tsx", "_origin": "ast", "community": 12, - "community_name": "ReviewQueuePage.tsx", + "community_name": "BudgetPage.tsx", "file_type": "code", "norm_label": "reviewqueuepage.tsx", "source_file": "frontend/src/pages/ReviewQueuePage.tsx", "source_location": "L1" }, { - "id": "frontend_package_devdependencies_testing_library_user_event", - "label": "@testing-library/user-event", + "id": "backend_alembic_versions_20260923_0004_mcc_categories", + "label": "20260923_0004_mcc_categories.py", "_origin": "ast", "community": 13, - "community_name": "@testing-library/user-event", + "community_name": "mcc.py", "file_type": "code", - "norm_label": "@testing-library/user-event", - "source_file": "frontend/package.json", - "source_location": "L34" + "norm_label": "20260923_0004_mcc_categories.py", + "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "source_location": "L1" }, { - "id": "testing_library_user_event", - "label": "@testing-library/user-event", + "id": "backend_app_categorization_mcc", + "label": "mcc.py", "_origin": "ast", "community": 13, - "community_name": "@testing-library/user-event", - "file_type": "concept", - "norm_label": "@testing-library/user-event", - "source_file": "frontend/package.json", - "source_location": "L34" + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "mcc.py", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L1" + }, + { + "id": "namedtuple", + "label": "NamedTuple", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "code", + "norm_label": "namedtuple", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_categorization_mcc_rationale_1", + "label": "MCC catalog backed by the iso18245 library with Russian labels. The global\u2026", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "mcc catalog backed by the iso18245 library with russian labels. the global...", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L1" + }, + { + "id": "backend_app_categorization_mcc_rationale_353", + "label": "Curated Russian translation, else a Cyrillic transcription of the label.", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "curated russian translation, else a cyrillic transcription of the label.", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L353" + }, + { + "id": "backend_app_categorization_mcc_rationale_364", + "label": "Yield ``(code, russian_title)`` for every MCC known to iso18245.", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "yield ``(code, russian_title)`` for every mcc known to iso18245.", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L364" + }, + { + "id": "backend_app_categorization_mcc_rationale_370", + "label": "The 20 pre-created popular categories with validated MCC code lists.", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "the 20 pre-created popular categories with validated mcc code lists.", + "source_file": "backend/app/categorization/mcc.py", + "source_location": "L370" + }, + { + "id": "backend_app_categorization_service_rationale_119", + "label": "Idempotently seed the global ``mcc_codes`` table from iso18245.", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "idempotently seed the global ``mcc_codes`` table from iso18245.", + "source_file": "backend/app/categorization/service.py", + "source_location": "L119" + }, + { + "id": "backend_app_categorization_service_rationale_148", + "label": "Idempotently pre-create the 20 popular categories plus \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb. Each\u2026", + "_origin": "ast", + "community": 13, + "community_name": "mcc.py", + "file_type": "rationale", + "norm_label": "idempotently pre-create the 20 popular categories plus \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb. each...", + "source_file": "backend/app/categorization/service.py", + "source_location": "L148" }, { "id": "frontend_package_devdependencies", @@ -12202,7 +12457,7 @@ "file_type": "code", "norm_label": "devdependencies", "source_file": "frontend/package.json", - "source_location": "L29" + "source_location": "L30" }, { "id": "frontend_package_devdependencies_eslint", @@ -12213,7 +12468,7 @@ "file_type": "code", "norm_label": "eslint", "source_file": "frontend/package.json", - "source_location": "L38" + "source_location": "L39" }, { "id": "frontend_package_devdependencies_eslint_js", @@ -12224,7 +12479,7 @@ "file_type": "code", "norm_label": "@eslint/js", "source_file": "frontend/package.json", - "source_location": "L30" + "source_location": "L31" }, { "id": "frontend_package_devdependencies_eslint_plugin_jsx_a11y", @@ -12235,7 +12490,7 @@ "file_type": "code", "norm_label": "eslint-plugin-jsx-a11y", "source_file": "frontend/package.json", - "source_location": "L39" + "source_location": "L40" }, { "id": "frontend_package_devdependencies_globals", @@ -12246,17 +12501,6 @@ "file_type": "code", "norm_label": "globals", "source_file": "frontend/package.json", - "source_location": "L41" - }, - { - "id": "frontend_package_devdependencies_jsdom", - "label": "jsdom", - "_origin": "ast", - "community": 14, - "community_name": "devDependencies", - "file_type": "code", - "norm_label": "jsdom", - "source_file": "frontend/package.json", "source_location": "L42" }, { @@ -12268,7 +12512,7 @@ "file_type": "code", "norm_label": "openapi-typescript", "source_file": "frontend/package.json", - "source_location": "L43" + "source_location": "L44" }, { "id": "frontend_package_devdependencies_testing_library_dom", @@ -12279,41 +12523,63 @@ "file_type": "code", "norm_label": "@testing-library/dom", "source_file": "frontend/package.json", - "source_location": "L31" + "source_location": "L32" }, { - "id": "frontend_package_devdependencies_testing_library_react", - "label": "@testing-library/react", + "id": "frontend_package_devdependencies_testing_library_user_event", + "label": "@testing-library/user-event", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "code", - "norm_label": "@testing-library/react", + "norm_label": "@testing-library/user-event", "source_file": "frontend/package.json", - "source_location": "L33" + "source_location": "L35" }, { - "id": "frontend_package_devdependencies_typescript", - "label": "typescript", + "id": "frontend_package_devdependencies_types_react", + "label": "@types/react", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "code", - "norm_label": "typescript", + "norm_label": "@types/react", "source_file": "frontend/package.json", - "source_location": "L44" + "source_location": "L36" }, { - "id": "frontend_package_devdependencies_vitejs_plugin_react", - "label": "@vitejs/plugin-react", + "id": "frontend_package_devdependencies_types_react_dom", + "label": "@types/react-dom", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "code", - "norm_label": "@vitejs/plugin-react", + "norm_label": "@types/react-dom", "source_file": "frontend/package.json", "source_location": "L37" }, + { + "id": "frontend_package_devdependencies_vite", + "label": "vite", + "_origin": "ast", + "community": 14, + "community_name": "devDependencies", + "file_type": "code", + "norm_label": "vite", + "source_file": "frontend/package.json", + "source_location": "L47" + }, + { + "id": "frontend_package_devdependencies_vitest", + "label": "vitest", + "_origin": "ast", + "community": 14, + "community_name": "devDependencies", + "file_type": "code", + "norm_label": "vitest", + "source_file": "frontend/package.json", + "source_location": "L48" + }, { "id": "eslint", "label": "eslint", @@ -12323,7 +12589,7 @@ "file_type": "concept", "norm_label": "eslint", "source_file": "frontend/package.json", - "source_location": "L38" + "source_location": "L39" }, { "id": "eslint_js", @@ -12334,7 +12600,7 @@ "file_type": "concept", "norm_label": "@eslint/js", "source_file": "frontend/package.json", - "source_location": "L30" + "source_location": "L31" }, { "id": "eslint_plugin_jsx_a11y", @@ -12345,7 +12611,7 @@ "file_type": "concept", "norm_label": "eslint-plugin-jsx-a11y", "source_file": "frontend/package.json", - "source_location": "L39" + "source_location": "L40" }, { "id": "globals", @@ -12356,17 +12622,6 @@ "file_type": "concept", "norm_label": "globals", "source_file": "frontend/package.json", - "source_location": "L41" - }, - { - "id": "jsdom", - "label": "jsdom", - "_origin": "ast", - "community": 14, - "community_name": "devDependencies", - "file_type": "concept", - "norm_label": "jsdom", - "source_file": "frontend/package.json", "source_location": "L42" }, { @@ -12378,7 +12633,7 @@ "file_type": "concept", "norm_label": "openapi-typescript", "source_file": "frontend/package.json", - "source_location": "L43" + "source_location": "L44" }, { "id": "testing_library_dom", @@ -12389,41 +12644,63 @@ "file_type": "concept", "norm_label": "@testing-library/dom", "source_file": "frontend/package.json", - "source_location": "L31" + "source_location": "L32" }, { - "id": "testing_library_react", - "label": "@testing-library/react", + "id": "testing_library_user_event", + "label": "@testing-library/user-event", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "concept", - "norm_label": "@testing-library/react", + "norm_label": "@testing-library/user-event", "source_file": "frontend/package.json", - "source_location": "L33" + "source_location": "L35" }, { - "id": "typescript", - "label": "typescript", + "id": "types_react", + "label": "@types/react", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "concept", - "norm_label": "typescript", + "norm_label": "@types/react", "source_file": "frontend/package.json", - "source_location": "L44" + "source_location": "L36" }, { - "id": "vitejs_plugin_react", - "label": "@vitejs/plugin-react", + "id": "types_react_dom", + "label": "@types/react-dom", "_origin": "ast", "community": 14, "community_name": "devDependencies", "file_type": "concept", - "norm_label": "@vitejs/plugin-react", + "norm_label": "@types/react-dom", "source_file": "frontend/package.json", "source_location": "L37" }, + { + "id": "vite", + "label": "vite", + "_origin": "ast", + "community": 14, + "community_name": "devDependencies", + "file_type": "concept", + "norm_label": "vite", + "source_file": "frontend/package.json", + "source_location": "L47" + }, + { + "id": "vitest", + "label": "vitest", + "_origin": "ast", + "community": 14, + "community_name": "devDependencies", + "file_type": "concept", + "norm_label": "vitest", + "source_file": "frontend/package.json", + "source_location": "L48" + }, { "id": "backend_app_ledger_service", "label": "ledger/service.py", @@ -12546,18 +12823,7 @@ "source_location": "" }, { - "id": "backend_app_categorization_service_rationale_129", - "label": "The system \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback category, created on first use.", - "_origin": "ast", - "community": 15, - "community_name": "ledger/service.py", - "file_type": "rationale", - "norm_label": "the system \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback category, created on first use.", - "source_file": "backend/app/categorization/service.py", - "source_location": "L129" - }, - { - "id": "backend_app_ledger_models_rationale_135", + "id": "backend_app_ledger_models_rationale_133", "label": "Signed balance change of one account within one operation. Sign convention\u2026", "_origin": "ast", "community": 15, @@ -12565,10 +12831,10 @@ "file_type": "rationale", "norm_label": "signed balance change of one account within one operation. sign convention...", "source_file": "backend/app/ledger/models.py", - "source_location": "L135" + "source_location": "L133" }, { - "id": "backend_app_ledger_models_rationale_59", + "id": "backend_app_ledger_models_rationale_57", "label": "User financial fact. amount_kopecks is always positive; direction lives in\u2026", "_origin": "ast", "community": 15, @@ -12576,7 +12842,7 @@ "file_type": "rationale", "norm_label": "user financial fact. amount_kopecks is always positive; direction lives in...", "source_file": "backend/app/ledger/models.py", - "source_location": "L59" + "source_location": "L57" }, { "id": "backend_app_ledger_service_rationale_141", @@ -12655,6 +12921,17 @@ "source_file": "frontend/package.json", "source_location": "L18" }, + { + "id": "frontend_package_dependencies_fontsource_onest", + "label": "@fontsource/onest", + "_origin": "ast", + "community": 16, + "community_name": "dependencies", + "file_type": "code", + "norm_label": "@fontsource/onest", + "source_file": "frontend/package.json", + "source_location": "L19" + }, { "id": "frontend_package_dependencies_hookform_resolvers", "label": "@hookform/resolvers", @@ -12664,7 +12941,7 @@ "file_type": "code", "norm_label": "@hookform/resolvers", "source_file": "frontend/package.json", - "source_location": "L19" + "source_location": "L20" }, { "id": "frontend_package_dependencies_i18next", @@ -12675,7 +12952,7 @@ "file_type": "code", "norm_label": "i18next", "source_file": "frontend/package.json", - "source_location": "L21" + "source_location": "L22" }, { "id": "frontend_package_dependencies_react", @@ -12686,7 +12963,7 @@ "file_type": "code", "norm_label": "react", "source_file": "frontend/package.json", - "source_location": "L22" + "source_location": "L23" }, { "id": "frontend_package_dependencies_react_dom", @@ -12697,7 +12974,7 @@ "file_type": "code", "norm_label": "react-dom", "source_file": "frontend/package.json", - "source_location": "L23" + "source_location": "L24" }, { "id": "frontend_package_dependencies_react_hook_form", @@ -12708,7 +12985,7 @@ "file_type": "code", "norm_label": "react-hook-form", "source_file": "frontend/package.json", - "source_location": "L24" + "source_location": "L25" }, { "id": "frontend_package_dependencies_react_i18next", @@ -12719,7 +12996,7 @@ "file_type": "code", "norm_label": "react-i18next", "source_file": "frontend/package.json", - "source_location": "L25" + "source_location": "L26" }, { "id": "frontend_package_dependencies_react_router_dom", @@ -12730,7 +13007,7 @@ "file_type": "code", "norm_label": "react-router-dom", "source_file": "frontend/package.json", - "source_location": "L26" + "source_location": "L27" }, { "id": "frontend_package_dependencies_tanstack_react_query", @@ -12741,7 +13018,7 @@ "file_type": "code", "norm_label": "@tanstack/react-query", "source_file": "frontend/package.json", - "source_location": "L20" + "source_location": "L21" }, { "id": "frontend_package_dependencies_zod", @@ -12752,7 +13029,7 @@ "file_type": "code", "norm_label": "zod", "source_file": "frontend/package.json", - "source_location": "L27" + "source_location": "L28" }, { "id": "fontsource_funnel_sans", @@ -12776,6 +13053,17 @@ "source_file": "frontend/package.json", "source_location": "L18" }, + { + "id": "fontsource_onest", + "label": "@fontsource/onest", + "_origin": "ast", + "community": 16, + "community_name": "dependencies", + "file_type": "concept", + "norm_label": "@fontsource/onest", + "source_file": "frontend/package.json", + "source_location": "L19" + }, { "id": "hookform_resolvers", "label": "@hookform/resolvers", @@ -12785,7 +13073,7 @@ "file_type": "concept", "norm_label": "@hookform/resolvers", "source_file": "frontend/package.json", - "source_location": "L19" + "source_location": "L20" }, { "id": "i18next", @@ -12796,7 +13084,7 @@ "file_type": "concept", "norm_label": "i18next", "source_file": "frontend/package.json", - "source_location": "L21" + "source_location": "L22" }, { "id": "react", @@ -12807,7 +13095,7 @@ "file_type": "concept", "norm_label": "react", "source_file": "frontend/package.json", - "source_location": "L22" + "source_location": "L23" }, { "id": "react_dom", @@ -12818,7 +13106,7 @@ "file_type": "concept", "norm_label": "react-dom", "source_file": "frontend/package.json", - "source_location": "L23" + "source_location": "L24" }, { "id": "react_hook_form", @@ -12829,7 +13117,7 @@ "file_type": "concept", "norm_label": "react-hook-form", "source_file": "frontend/package.json", - "source_location": "L24" + "source_location": "L25" }, { "id": "react_i18next", @@ -12840,7 +13128,7 @@ "file_type": "concept", "norm_label": "react-i18next", "source_file": "frontend/package.json", - "source_location": "L25" + "source_location": "L26" }, { "id": "react_router_dom", @@ -12851,7 +13139,7 @@ "file_type": "concept", "norm_label": "react-router-dom", "source_file": "frontend/package.json", - "source_location": "L26" + "source_location": "L27" }, { "id": "tanstack_react_query", @@ -12862,7 +13150,7 @@ "file_type": "concept", "norm_label": "@tanstack/react-query", "source_file": "frontend/package.json", - "source_location": "L20" + "source_location": "L21" }, { "id": "zod", @@ -12873,14 +13161,14 @@ "file_type": "concept", "norm_label": "zod", "source_file": "frontend/package.json", - "source_location": "L27" + "source_location": "L28" }, { "id": "i1", "label": "i1", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "confidence": "EXTRACTED", "file_type": "code", "norm_label": "i1", @@ -12891,29 +13179,18 @@ "label": "i2", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "confidence": "EXTRACTED", "file_type": "code", "norm_label": "i2", "source_file": "i2" }, - { - "id": "frontend_src_api_endpoints_api", - "label": "api", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "api", - "source_file": "frontend/src/api/endpoints.ts", - "source_location": "L35" - }, { "id": "frontend_src_api_querykeys", "label": "queryKeys.ts", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "querykeys.ts", "source_file": "frontend/src/api/queryKeys.ts", @@ -12924,7 +13201,7 @@ "label": "invalidationRoots", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "invalidationroots", "source_file": "frontend/src/api/queryKeys.ts", @@ -12935,7 +13212,7 @@ "label": "queryKeys", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "querykeys", "source_file": "frontend/src/api/queryKeys.ts", @@ -12946,7 +13223,7 @@ "label": "SESSION_ROOT", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "session_root", "source_file": "frontend/src/api/queryKeys.ts", @@ -12957,7 +13234,7 @@ "label": "sessionInvalidationRoot", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "sessioninvalidationroot", "source_file": "frontend/src/api/queryKeys.ts", @@ -12968,7 +13245,7 @@ "label": "SPACE_ROOT", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "space_root", "source_file": "frontend/src/api/queryKeys.ts", @@ -12979,150 +13256,29 @@ "label": "spaceInvalidationRoot", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "spaceinvalidationroot", "source_file": "frontend/src/api/queryKeys.ts", "source_location": "L8" }, { - "id": "frontend_src_hooks_useaccounts", - "label": "useAccounts.ts", + "id": "frontend_src_hooks_useoperations", + "label": "useOperations.ts", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", - "norm_label": "useaccounts.ts", - "source_file": "frontend/src/hooks/useAccounts.ts", + "norm_label": "useoperations.ts", + "source_file": "frontend/src/hooks/useOperations.ts", "source_location": "L1" }, - { - "id": "frontend_src_hooks_useimports", - "label": "useImports.ts", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "useimports.ts", - "source_file": "frontend/src/hooks/useImports.ts", - "source_location": "L1" - }, - { - "id": "frontend_src_hooks_usespacelifecycle", - "label": "useSpaceLifecycle.ts", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "usespacelifecycle.ts", - "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", - "source_location": "L1" - }, - { - "id": "frontend_src_lib_importstatus", - "label": "importStatus.ts", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importstatus.ts", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L1" - }, - { - "id": "frontend_src_lib_importstatus_active_statuses", - "label": "ACTIVE_STATUSES", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "active_statuses", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L5" - }, - { - "id": "frontend_src_lib_importstatus_import_poll_ms", - "label": "IMPORT_POLL_MS", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "import_poll_ms", - "source_file": "frontend/src/lib/importStatus.ts", - "source_location": "L3" - }, - { - "id": "frontend_src_pages_importdetailpage", - "label": "ImportDetailPage.tsx", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "importdetailpage.tsx", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L1" - }, - { - "id": "frontend_src_pages_importdetailpage_decisions", - "label": "DECISIONS", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "decisions", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L25" - }, - { - "id": "frontend_src_pages_importdetailpage_step_order", - "label": "STEP_ORDER", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "step_order", - "source_file": "frontend/src/pages/ImportDetailPage.tsx", - "source_location": "L33" - }, - { - "id": "frontend_src_pages_settingspage", - "label": "SettingsPage.tsx", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "settingspage.tsx", - "source_file": "frontend/src/pages/SettingsPage.tsx", - "source_location": "L1" - }, - { - "id": "frontend_src_test_import_polling_test", - "label": "import-polling.test.tsx", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "import-polling.test.tsx", - "source_file": "frontend/src/test/import-polling.test.tsx", - "source_location": "L1" - }, - { - "id": "frontend_src_test_import_polling_test_getimport", - "label": "getImport", - "_origin": "ast", - "community": 17, - "community_name": "ImportDetailPage.tsx", - "file_type": "code", - "norm_label": "getimport", - "source_file": "frontend/src/test/import-polling.test.tsx", - "source_location": "L23" - }, { "id": "frontend_src_test_query_keys_test", "label": "query-keys.test.ts", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "query-keys.test.ts", "source_file": "frontend/src/test/query-keys.test.ts", @@ -13133,7 +13289,7 @@ "label": "SAMPLE_FILTERS", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "sample_filters", "source_file": "frontend/src/test/query-keys.test.ts", @@ -13144,21 +13300,32 @@ "label": "SAMPLE_KEYS", "_origin": "ast", "community": 17, - "community_name": "ImportDetailPage.tsx", + "community_name": "useOperations.ts", "file_type": "code", "norm_label": "sample_keys", "source_file": "frontend/src/test/query-keys.test.ts", "source_location": "L12" }, { - "id": "frontend_src_hooks_useoperations", - "label": "useOperations.ts", + "id": "frontend_src_hooks_useaccounts", + "label": "useAccounts.ts", "_origin": "ast", "community": 18, "community_name": "OperationsPage.tsx", "file_type": "code", - "norm_label": "useoperations.ts", - "source_file": "frontend/src/hooks/useOperations.ts", + "norm_label": "useaccounts.ts", + "source_file": "frontend/src/hooks/useAccounts.ts", + "source_location": "L1" + }, + { + "id": "frontend_src_lib_accountlabel", + "label": "accountLabel.ts", + "_origin": "ast", + "community": 18, + "community_name": "OperationsPage.tsx", + "file_type": "code", + "norm_label": "accountlabel.ts", + "source_file": "frontend/src/lib/accountLabel.ts", "source_location": "L1" }, { @@ -13260,166 +13427,210 @@ "source_file": "frontend/src/test/money.test.ts", "source_location": "L1" }, + { + "id": "backend_app_analytics_service", + "label": "analytics/service.py", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "analytics/service.py", + "source_file": "backend/app/analytics/service.py", + "source_location": "L1" + }, + { + "id": "backend_app_analytics_service_py_date", + "label": "date", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "date", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_analytics_service_py_uuid", + "label": "UUID", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "uuid", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_budgeting_service_py_account", + "label": "Account", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "account", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_categorization_service", + "label": "categorization/service.py", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "categorization/service.py", + "source_file": "backend/app/categorization/service.py", + "source_location": "L1" + }, + { + "id": "backend_app_categorization_service_py_uuid", + "label": "UUID", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "code", + "norm_label": "uuid", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_categorization_service_rationale_129", + "label": "The system \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback category, created on first use.", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "the system \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback category, created on first use.", + "source_file": "backend/app/categorization/service.py", + "source_location": "L129" + }, + { + "id": "backend_app_categorization_service_rationale_190", + "label": "Category owning the MCC code, else the system \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback.", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "category owning the mcc code, else the system \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb fallback.", + "source_file": "backend/app/categorization/service.py", + "source_location": "L190" + }, + { + "id": "backend_app_categorization_service_rationale_20", + "label": "Literal display name, or None when the name localizes via the system key.\u2026", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "literal display name, or none when the name localizes via the system key....", + "source_file": "backend/app/categorization/service.py", + "source_location": "L20" + }, + { + "id": "backend_app_categorization_service_rationale_222", + "label": "Replace the category's MCC code set; codes are unique per space.", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "replace the category's mcc code set; codes are unique per space.", + "source_file": "backend/app/categorization/service.py", + "source_location": "L222" + }, + { + "id": "backend_app_categorization_service_rationale_33", + "label": "Pure localization key for system categories; None for user categories.", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "pure localization key for system categories; none for user categories.", + "source_file": "backend/app/categorization/service.py", + "source_location": "L33" + }, + { + "id": "backend_app_ledger_models_rationale_167", + "label": "Budget category. Kept in ledger module to avoid circular imports.", + "_origin": "ast", + "community": 19, + "community_name": "Session", + "file_type": "rationale", + "norm_label": "budget category. kept in ledger module to avoid circular imports.", + "source_file": "backend/app/ledger/models.py", + "source_location": "L167" + }, { "id": "backend_alembic_versions_20260911_0001_initial_schema", "label": "20260911_0001_initial_schema.py", "_origin": "ast", - "community": 19, + "community": 2, "community_name": "Base", "file_type": "code", "norm_label": "20260911_0001_initial_schema.py", "source_file": "backend/alembic/versions/20260911_0001_initial_schema.py", "source_location": "L1" }, - { - "id": "backend_app_categorization_init", - "label": "categorization/__init__.py", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "categorization/__init__.py", - "source_file": "backend/app/categorization/__init__.py", - "source_location": "L1" - }, - { - "id": "backend_app_categorization_models", - "label": "categorization/models.py", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "categorization/models.py", - "source_file": "backend/app/categorization/models.py", - "source_location": "L1" - }, - { - "id": "backend_app_categorization_service", - "label": "categorization/service.py", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "categorization/service.py", - "source_file": "backend/app/categorization/service.py", - "source_location": "L1" - }, - { - "id": "declarativebase", - "label": "DeclarativeBase", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "code", - "norm_label": "declarativebase", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_categorization_models_rationale_104", - "label": "Space-scoped MCC codes of a category: many codes per category, but every code\u2026", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "rationale", - "norm_label": "space-scoped mcc codes of a category: many codes per category, but every code...", - "source_file": "backend/app/categorization/models.py", - "source_location": "L104" - }, - { - "id": "backend_app_categorization_models_rationale_132", - "label": "Maps a bank's raw category string to an MCC for suggestion purposes.", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "rationale", - "norm_label": "maps a bank's raw category string to an mcc for suggestion purposes.", - "source_file": "backend/app/categorization/models.py", - "source_location": "L132" - }, - { - "id": "backend_app_categorization_models_rationale_65", - "label": "Confirmed payee rule: auto-applies category to matching future operations.", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "rationale", - "norm_label": "confirmed payee rule: auto-applies category to matching future operations.", - "source_file": "backend/app/categorization/models.py", - "source_location": "L65" - }, - { - "id": "backend_app_categorization_models_rationale_94", - "label": "Global versioned MCC dictionary (not space-scoped, outside RLS).", - "_origin": "ast", - "community": 19, - "community_name": "Base", - "file_type": "rationale", - "norm_label": "global versioned mcc dictionary (not space-scoped, outside rls).", - "source_file": "backend/app/categorization/models.py", - "source_location": "L94" - }, { "id": "backend_app_audit_models", "label": "audit/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "audit/models.py", "source_file": "backend/app/audit/models.py", "source_location": "L1" }, + { + "id": "backend_app_audit_service", + "label": "audit/service.py", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "audit/service.py", + "source_file": "backend/app/audit/service.py", + "source_location": "L1" + }, { "id": "backend_app_budgeting_models", "label": "budgeting/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "budgeting/models.py", "source_file": "backend/app/budgeting/models.py", "source_location": "L1" }, + { + "id": "backend_app_categorization_models", + "label": "categorization/models.py", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "categorization/models.py", + "source_file": "backend/app/categorization/models.py", + "source_location": "L1" + }, { "id": "backend_app_db_base", "label": "db/base.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "db/base.py", "source_file": "backend/app/db/base.py", "source_location": "L1" }, - { - "id": "backend_app_db_base_py_any", - "label": "Any", - "_origin": "ast", - "community": 2, - "community_name": "db/models.py", - "file_type": "code", - "norm_label": "any", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_db_base_py_datetime", - "label": "datetime", - "_origin": "ast", - "community": 2, - "community_name": "db/models.py", - "file_type": "code", - "norm_label": "datetime", - "source_file": "", - "source_location": "" - }, { "id": "backend_app_db_models", "label": "db/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "db/models.py", "source_file": "backend/app/db/models.py", @@ -13430,7 +13641,7 @@ "label": "exports/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "exports/models.py", "source_file": "backend/app/exports/models.py", @@ -13441,20 +13652,31 @@ "label": "identity/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", "norm_label": "identity/models.py", "source_file": "backend/app/identity/models.py", "source_location": "L1" }, { - "id": "typedecorator", - "label": "TypeDecorator", + "id": "backend_app_imports_models", + "label": "imports/models.py", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "code", - "norm_label": "typedecorator", + "norm_label": "imports/models.py", + "source_file": "backend/app/imports/models.py", + "source_location": "L1" + }, + { + "id": "declarativebase", + "label": "DeclarativeBase", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "code", + "norm_label": "declarativebase", "source_file": "", "source_location": "" }, @@ -13463,7 +13685,7 @@ "label": "Append-only domain/security event. Never stores raw financial payloads.", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "append-only domain/security event. never stores raw financial payloads.", "source_file": "backend/app/audit/models.py", @@ -13474,7 +13696,7 @@ "label": "Links one actual income operation to one expected income (1:1 per operation).", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "links one actual income operation to one expected income (1:1 per operation).", "source_file": "backend/app/budgeting/models.py", @@ -13485,7 +13707,7 @@ "label": "Manual money movement between the general pool and a category/reserve.", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "manual money movement between the general pool and a category/reserve.", "source_file": "backend/app/budgeting/models.py", @@ -13496,29 +13718,62 @@ "label": "Immutable-at-rest snapshot written when a period closes.", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "immutable-at-rest snapshot written when a period closes.", "source_file": "backend/app/budgeting/models.py", "source_location": "L167" }, { - "id": "backend_app_db_base_rationale_22", - "label": "Datetimes stored as naive UTC in the DB and exposed tz-aware (UTC) in Python.", + "id": "backend_app_categorization_models_rationale_104", + "label": "Space-scoped MCC codes of a category: many codes per category, but every code\u2026", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", - "norm_label": "datetimes stored as naive utc in the db and exposed tz-aware (utc) in python.", - "source_file": "backend/app/db/base.py", - "source_location": "L22" + "norm_label": "space-scoped mcc codes of a category: many codes per category, but every code...", + "source_file": "backend/app/categorization/models.py", + "source_location": "L104" + }, + { + "id": "backend_app_categorization_models_rationale_132", + "label": "Maps a bank's raw category string to an MCC for suggestion purposes.", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "rationale", + "norm_label": "maps a bank's raw category string to an mcc for suggestion purposes.", + "source_file": "backend/app/categorization/models.py", + "source_location": "L132" + }, + { + "id": "backend_app_categorization_models_rationale_65", + "label": "Confirmed payee rule: auto-applies category to matching future operations.", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "rationale", + "norm_label": "confirmed payee rule: auto-applies category to matching future operations.", + "source_file": "backend/app/categorization/models.py", + "source_location": "L65" + }, + { + "id": "backend_app_categorization_models_rationale_94", + "label": "Global versioned MCC dictionary (not space-scoped, outside RLS).", + "_origin": "ast", + "community": 2, + "community_name": "Base", + "file_type": "rationale", + "norm_label": "global versioned mcc dictionary (not space-scoped, outside rls).", + "source_file": "backend/app/categorization/models.py", + "source_location": "L94" }, { "id": "backend_app_db_models_rationale_1", "label": "Import every mapped class so Alembic sees complete metadata.", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "import every mapped class so alembic sees complete metadata.", "source_file": "backend/app/db/models.py", @@ -13529,7 +13784,7 @@ "label": "Durable deletion marker reapplied after disaster restore.", "_origin": "ast", "community": 2, - "community_name": "db/models.py", + "community_name": "Base", "file_type": "rationale", "norm_label": "durable deletion marker reapplied after disaster restore.", "source_file": "backend/app/exports/models.py", @@ -13557,17 +13812,6 @@ "source_file": "frontend/src/App.tsx", "source_location": "L9" }, - { - "id": "frontend_src_components_budget_budgetblockers", - "label": "BudgetBlockers.tsx", - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "budgetblockers.tsx", - "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", - "source_location": "L1" - }, { "id": "frontend_src_components_layout_langswitcher", "label": "LangSwitcher.tsx", @@ -13667,17 +13911,6 @@ "source_file": "frontend/src/main.tsx", "source_location": "L15" }, - { - "id": "frontend_src_test_budget_blockers_test", - "label": "budget-blockers.test.tsx", - "_origin": "ast", - "community": 20, - "community_name": "apiErrors.ts", - "file_type": "code", - "norm_label": "budget-blockers.test.tsx", - "source_file": "frontend/src/test/budget-blockers.test.tsx", - "source_location": "L1" - }, { "id": "frontend_src_test_setup", "label": "setup.ts", @@ -13694,29 +13927,18 @@ "label": "adapters/base.py", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "adapters/base.py", "source_file": "backend/app/imports/adapters/base.py", "source_location": "L1" }, - { - "id": "backend_app_imports_adapters_base_py_date", - "label": "date", - "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "code", - "norm_label": "date", - "source_file": "", - "source_location": "" - }, { "id": "backend_app_imports_adapters_ozon_pdf", "label": "ozon_pdf.py", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "ozon_pdf.py", "source_file": "backend/app/imports/adapters/ozon_pdf.py", @@ -13727,7 +13949,7 @@ "label": "rocketbank_pdf.py", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "rocketbank_pdf.py", "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", @@ -13738,62 +13960,84 @@ "label": "date", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", "norm_label": "date", "source_file": "", "source_location": "" }, { - "id": "backend_app_imports_readers", - "label": "readers.py", + "id": "pattern", + "label": "Pattern", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "code", - "norm_label": "readers.py", - "source_file": "backend/app/imports/readers.py", - "source_location": "L1" + "norm_label": "pattern", + "source_file": "", + "source_location": "" }, { "id": "backend_app_imports_adapters_base_rationale_112", "label": "Parse statement money strings like '-1 234,56 RUR', '+ 500.00 \u20bd', '12 345'.\u2026", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "rationale", "norm_label": "parse statement money strings like '-1 234,56 rur', '+ 500.00 \u20bd', '12 345'....", "source_file": "backend/app/imports/adapters/base.py", "source_location": "L112" }, + { + "id": "backend_app_imports_adapters_base_rationale_68", + "label": "Stable diagnostic for unknown bank layouts; never guesses.", + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "rationale", + "norm_label": "stable diagnostic for unknown bank layouts; never guesses.", + "source_file": "backend/app/imports/adapters/base.py", + "source_location": "L68" + }, + { + "id": "backend_app_imports_adapters_ozon_pdf_rationale_128", + "label": "Ozon debit statement contract, evidenced against the real document. A '\u0421\u043f\u0440\u0430\u0432\u043a\u0430\u2026", + "_origin": "ast", + "community": 21, + "community_name": "UnsupportedStatementLayout", + "file_type": "rationale", + "norm_label": "ozon debit statement contract, evidenced against the real document. a '\u0441\u043f\u0440\u0430\u0432\u043a\u0430...", + "source_file": "backend/app/imports/adapters/ozon_pdf.py", + "source_location": "L128" + }, { "id": "backend_app_imports_adapters_ozon_pdf_rationale_31", "label": "Ozon statement contract: text-layer PDF, per-page line scanning.", "_origin": "ast", "community": 21, - "community_name": "adapters/base.py", + "community_name": "UnsupportedStatementLayout", "file_type": "rationale", "norm_label": "ozon statement contract: text-layer pdf, per-page line scanning.", "source_file": "backend/app/imports/adapters/ozon_pdf.py", "source_location": "L31" }, { - "id": "backend_app_imports_adapters_rocketbank_pdf_rationale_53", - "label": "Rocketbank debit statement contract, evidenced against the real document.\u2026", + "id": "frontend_src_app_router_importdetailpage", + "label": "ImportDetailPage", "_origin": "ast", - "community": 21, - "community_name": "adapters/base.py", - "file_type": "rationale", - "norm_label": "rocketbank debit statement contract, evidenced against the real document....", - "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", - "source_location": "L53" + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "importdetailpage", + "source_file": "frontend/src/app/router.tsx", + "source_location": "L19" }, { "id": "frontend_src_components_budget_categorymanagermodal", "label": "CategoryManagerModal.tsx", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "categorymanagermodal.tsx", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -13804,7 +14048,7 @@ "label": "CREATE_KINDS", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "create_kinds", "source_file": "frontend/src/components/budget/CategoryManagerModal.tsx", @@ -13815,7 +14059,7 @@ "label": "Badge.tsx", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "badge.tsx", "source_file": "frontend/src/components/ui/Badge.tsx", @@ -13826,7 +14070,7 @@ "label": "ConfirmDialog.tsx", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "confirmdialog.tsx", "source_file": "frontend/src/components/ui/ConfirmDialog.tsx", @@ -13837,7 +14081,7 @@ "label": "Modal.tsx", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "modal.tsx", "source_file": "frontend/src/components/ui/Modal.tsx", @@ -13848,33 +14092,44 @@ "label": "useBudget.ts", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", "norm_label": "usebudget.ts", "source_file": "frontend/src/hooks/useBudget.ts", "source_location": "L1" }, { - "id": "frontend_src_pages_budgetpage", - "label": "BudgetPage.tsx", + "id": "frontend_src_pages_importdetailpage", + "label": "ImportDetailPage.tsx", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", - "norm_label": "budgetpage.tsx", - "source_file": "frontend/src/pages/BudgetPage.tsx", + "norm_label": "importdetailpage.tsx", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", "source_location": "L1" }, { - "id": "frontend_src_pages_budgetpage_blocker_warning_codes", - "label": "BLOCKER_WARNING_CODES", + "id": "frontend_src_pages_importdetailpage_decisions", + "label": "DECISIONS", "_origin": "ast", "community": 22, - "community_name": "BudgetPage.tsx", + "community_name": "ImportDetailPage.tsx", "file_type": "code", - "norm_label": "blocker_warning_codes", - "source_file": "frontend/src/pages/BudgetPage.tsx", - "source_location": "L31" + "norm_label": "decisions", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L25" + }, + { + "id": "frontend_src_pages_importdetailpage_step_order", + "label": "STEP_ORDER", + "_origin": "ast", + "community": 22, + "community_name": "ImportDetailPage.tsx", + "file_type": "code", + "norm_label": "step_order", + "source_file": "frontend/src/pages/ImportDetailPage.tsx", + "source_location": "L33" }, { "id": "frontend_src_api_client", @@ -13899,16 +14154,170 @@ "source_location": "L113" }, { - "id": "frontend_src_components_ui_fields", - "label": "fields.tsx", + "id": "backend_app_db_session_py_any", + "label": "Any", "_origin": "ast", "community": 24, - "community_name": "fields.tsx", + "community_name": "set_space_context", "file_type": "code", - "norm_label": "fields.tsx", - "source_file": "frontend/src/components/ui/fields.tsx", + "norm_label": "any", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_init", + "label": "exports/__init__.py", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "exports/__init__.py", + "source_file": "backend/app/exports/__init__.py", "source_location": "L1" }, + { + "id": "backend_app_exports_router", + "label": "exports/router.py", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "exports/router.py", + "source_file": "backend/app/exports/router.py", + "source_location": "L1" + }, + { + "id": "backend_app_exports_router_py_context", + "label": "Context", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "context", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_csrf", + "label": "Csrf", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "csrf", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_db", + "label": "Db", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "db", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_get", + "label": "get", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "get", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_post", + "label": "post", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "post", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_response", + "label": "Response", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "response", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_router_py_uuid", + "label": "UUID", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "uuid", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_tasks", + "label": "exports/tasks.py", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "exports/tasks.py", + "source_file": "backend/app/exports/tasks.py", + "source_location": "L1" + }, + { + "id": "backend_app_exports_tasks_py_task", + "label": "task", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "task", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_exports_tasks_py_uuid", + "label": "UUID", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "code", + "norm_label": "uuid", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_db_session_rationale_50", + "label": "Transaction-local RLS context. No-op on SQLite (tests); fail-closed on\u2026", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "rationale", + "norm_label": "transaction-local rls context. no-op on sqlite (tests); fail-closed on...", + "source_file": "backend/app/db/session.py", + "source_location": "L50" + }, + { + "id": "backend_app_db_session_rationale_60", + "label": "Transactional scope for workers/endpoints that own the transaction lifecycle.", + "_origin": "ast", + "community": 24, + "community_name": "set_space_context", + "file_type": "rationale", + "norm_label": "transactional scope for workers/endpoints that own the transaction lifecycle.", + "source_file": "backend/app/db/session.py", + "source_location": "L60" + }, { "id": "frontend_package_scripts", "label": "scripts", @@ -14009,92 +14418,224 @@ "source_location": "L10" }, { - "id": "frontend_package_devdependencies_types_react", - "label": "@types/react", + "id": "frontend_src_app_router_importspage", + "label": "ImportsPage", "_origin": "ast", "community": 28, - "community_name": "@types/react", + "community_name": "ImportsPage.tsx", "file_type": "code", - "norm_label": "@types/react", - "source_file": "frontend/package.json", - "source_location": "L35" - }, - { - "id": "types_react", - "label": "@types/react", - "_origin": "ast", - "community": 28, - "community_name": "@types/react", - "file_type": "concept", - "norm_label": "@types/react", - "source_file": "frontend/package.json", - "source_location": "L35" - }, - { - "id": "backend_app_errors_py_any", - "label": "Any", - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "code", - "norm_label": "any", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_imports_crypto", - "label": "crypto.py", - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "code", - "norm_label": "crypto.py", - "source_file": "backend/app/imports/crypto.py", - "source_location": "L1" - }, - { - "id": "exception", - "label": "Exception", - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "code", - "norm_label": "exception", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_errors_rationale_5", - "label": "Domain error rendered as a machine-readable JSON error payload.", - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "rationale", - "norm_label": "domain error rendered as a machine-readable json error payload.", - "source_file": "backend/app/errors.py", - "source_location": "L5" - }, - { - "id": "backend_app_imports_crypto_rationale_22", - "label": "Per-file random DEK; DEK wrapped with the KEK from the secret manager.", - "_origin": "ast", - "community": 3, - "community_name": "AppError", - "file_type": "rationale", - "norm_label": "per-file random dek; dek wrapped with the kek from the secret manager.", - "source_file": "backend/app/imports/crypto.py", + "norm_label": "importspage", + "source_file": "frontend/src/app/router.tsx", "source_location": "L22" }, { - "id": "backend_app_imports_crypto_rationale_57", - "label": "Crypto-shred hook: deleting wrapped DEK rows in DB plus blobs removes access.", + "id": "frontend_src_components_ui_emptystate", + "label": "EmptyState.tsx", + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "emptystate.tsx", + "source_file": "frontend/src/components/ui/EmptyState.tsx", + "source_location": "L1" + }, + { + "id": "frontend_src_components_ui_querygate", + "label": "QueryGate.tsx", + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "querygate.tsx", + "source_file": "frontend/src/components/ui/QueryGate.tsx", + "source_location": "L1" + }, + { + "id": "frontend_src_components_ui_spinner", + "label": "Spinner.tsx", + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "spinner.tsx", + "source_file": "frontend/src/components/ui/Spinner.tsx", + "source_location": "L1" + }, + { + "id": "frontend_src_pages_importspage", + "label": "ImportsPage.tsx", + "_origin": "ast", + "community": 28, + "community_name": "ImportsPage.tsx", + "file_type": "code", + "norm_label": "importspage.tsx", + "source_file": "frontend/src/pages/ImportsPage.tsx", + "source_location": "L1" + }, + { + "id": "backend_app_db_session", + "label": "session.py", "_origin": "ast", "community": 3, - "community_name": "AppError", + "community_name": "main.py", + "file_type": "code", + "norm_label": "session.py", + "source_file": "backend/app/db/session.py", + "source_location": "L1" + }, + { + "id": "backend_app_db_session_py_sessionmaker", + "label": "sessionmaker", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "sessionmaker", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_main", + "label": "main.py", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "main.py", + "source_file": "backend/app/main.py", + "source_location": "L1" + }, + { + "id": "backend_app_main_py_get", + "label": "get", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "get", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_main_py_request", + "label": "Request", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "request", + "source_file": "", + "source_location": "" + }, + { + "id": "engine", + "label": "Engine", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "engine", + "source_file": "", + "source_location": "" + }, + { + "id": "exception_handler", + "label": "exception_handler", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "exception_handler", + "source_file": "", + "source_location": "" + }, + { + "id": "jsonresponse", + "label": "JSONResponse", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "jsonresponse", + "source_file": "", + "source_location": "" + }, + { + "id": "middleware", + "label": "middleware", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "middleware", + "source_file": "", + "source_location": "" + }, + { + "id": "staledataerror", + "label": "StaleDataError", + "_origin": "ast", + "community": 3, + "community_name": "main.py", + "file_type": "code", + "norm_label": "staledataerror", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_imports_adapters_base_py_protocol", + "label": "Protocol", + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "protocol", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_imports_adapters_init", + "label": "adapters/__init__.py", + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "adapters/__init__.py", + "source_file": "backend/app/imports/adapters/__init__.py", + "source_location": "L1" + }, + { + "id": "backend_tests_test_adapter_contracts", + "label": "test_adapter_contracts.py", + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "test_adapter_contracts.py", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L1" + }, + { + "id": "workbook", + "label": "Workbook", + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", + "file_type": "code", + "norm_label": "workbook", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_tests_test_adapter_contracts_rationale_1", + "label": "Sanitized synthetic contract tests for the evidenced statement adapters. These\u2026", + "_origin": "ast", + "community": 30, + "community_name": "test_adapter_contracts.py", "file_type": "rationale", - "norm_label": "crypto-shred hook: deleting wrapped dek rows in db plus blobs removes access.", - "source_file": "backend/app/imports/crypto.py", - "source_location": "L57" + "norm_label": "sanitized synthetic contract tests for the evidenced statement adapters. these...", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L1" }, { "id": "frontend_package", @@ -14152,48 +14693,15 @@ "source_location": "L4" }, { - "id": "backend_tests_test_adapter_contracts", - "label": "test_adapter_contracts.py", + "id": "backend_app_imports_adapters_rocketbank_pdf_rationale_53", + "label": "Rocketbank debit statement contract, evidenced against the real document.\u2026", "_origin": "ast", "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": "test_adapter_contracts.py", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L1" - }, - { - "id": "monkeypatch", - "label": "MonkeyPatch", - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "code", - "norm_label": "monkeypatch", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_tests_test_adapter_contracts_rationale_1", - "label": "Sanitized synthetic contract tests for the evidenced statement adapters. These\u2026", - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", + "community_name": "TestRocketbankDebitContract", "file_type": "rationale", - "norm_label": "sanitized synthetic contract tests for the evidenced statement adapters. these...", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L1" - }, - { - "id": "backend_tests_test_adapter_contracts_rationale_891", - "label": "Build a small valid single-font PDF with empty or ASCII-only pages.", - "_origin": "ast", - "community": 38, - "community_name": "test_adapter_contracts.py", - "file_type": "rationale", - "norm_label": "build a small valid single-font pdf with empty or ascii-only pages.", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L891" + "norm_label": "rocketbank debit statement contract, evidenced against the real document....", + "source_file": "backend/app/imports/adapters/rocketbank_pdf.py", + "source_location": "L53" }, { "id": "frontend_scripts_generate_api", @@ -14240,165 +14748,44 @@ "source_location": "L11" }, { - "id": "backend_alembic_versions_20260922_0003_savings_system", - "label": "20260922_0003_savings_system.py", + "id": "backend_app_audit_init", + "label": "audit/__init__.py", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "20260922_0003_savings_system.py", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "norm_label": "audit/__init__.py", + "source_file": "backend/app/audit/__init__.py", "source_location": "L1" }, { - "id": "backend_app_db_session", - "label": "session.py", + "id": "backend_app_db_base_py_datetime", + "label": "datetime", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "session.py", - "source_file": "backend/app/db/session.py", + "norm_label": "datetime", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_imports_init", + "label": "imports/__init__.py", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "imports/__init__.py", + "source_file": "backend/app/imports/__init__.py", "source_location": "L1" }, - { - "id": "backend_app_db_session_py_any", - "label": "Any", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "any", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_db_session_py_sessionmaker", - "label": "sessionmaker", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "sessionmaker", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_init", - "label": "exports/__init__.py", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "exports/__init__.py", - "source_file": "backend/app/exports/__init__.py", - "source_location": "L1" - }, - { - "id": "backend_app_exports_router", - "label": "exports/router.py", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "exports/router.py", - "source_file": "backend/app/exports/router.py", - "source_location": "L1" - }, - { - "id": "backend_app_exports_router_py_context", - "label": "Context", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "context", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_csrf", - "label": "Csrf", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "csrf", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_db", - "label": "Db", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "db", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_get", - "label": "get", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "get", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_post", - "label": "post", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "post", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_response", - "label": "Response", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "response", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_router_py_uuid", - "label": "UUID", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "uuid", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_exports_tasks_py_uuid", - "label": "UUID", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "uuid", - "source_file": "", - "source_location": "" - }, { "id": "backend_app_imports_router", "label": "imports/router.py", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "imports/router.py", "source_file": "backend/app/imports/router.py", @@ -14409,7 +14796,7 @@ "label": "alias", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "alias", "source_file": "", @@ -14420,7 +14807,7 @@ "label": "Any", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "any", "source_file": "", @@ -14431,7 +14818,7 @@ "label": "BaseModel", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "basemodel", "source_file": "", @@ -14442,7 +14829,7 @@ "label": "Context", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "context", "source_file": "", @@ -14453,7 +14840,7 @@ "label": "Csrf", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "csrf", "source_file": "", @@ -14464,7 +14851,7 @@ "label": "Db", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "db", "source_file": "", @@ -14475,7 +14862,7 @@ "label": "delete", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "delete", "source_file": "", @@ -14486,7 +14873,7 @@ "label": "get", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "get", "source_file": "", @@ -14497,7 +14884,7 @@ "label": "patch", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "patch", "source_file": "", @@ -14508,7 +14895,7 @@ "label": "post", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "post", "source_file": "", @@ -14519,7 +14906,7 @@ "label": "Query", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "query", "source_file": "", @@ -14530,7 +14917,40 @@ "label": "UUID", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "uuid", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_imports_service", + "label": "imports/service.py", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "imports/service.py", + "source_file": "backend/app/imports/service.py", + "source_location": "L1" + }, + { + "id": "backend_app_imports_service_py_user", + "label": "User", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "code", + "norm_label": "user", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_imports_service_py_uuid", + "label": "UUID", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", "file_type": "code", "norm_label": "uuid", "source_file": "", @@ -14541,7 +14961,7 @@ "label": "imports/tasks.py", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "imports/tasks.py", "source_file": "backend/app/imports/tasks.py", @@ -14552,7 +14972,7 @@ "label": "task", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "task", "source_file": "", @@ -14563,73 +14983,62 @@ "label": "UUID", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "uuid", "source_file": "", "source_location": "" }, { - "id": "backend_app_main", - "label": "main.py", + "id": "backend_tests_test_import_savings", + "label": "test_import_savings.py", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "main.py", - "source_file": "backend/app/main.py", + "norm_label": "test_import_savings.py", + "source_file": "backend/tests/test_import_savings.py", "source_location": "L1" }, { - "id": "backend_app_main_py_get", - "label": "get", + "id": "backend_tests_test_import_savings_py_date", + "label": "date", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "get", + "norm_label": "date", "source_file": "", "source_location": "" }, { - "id": "backend_app_main_py_request", - "label": "Request", + "id": "backend_tests_test_import_savings_py_user", + "label": "User", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "request", + "norm_label": "user", "source_file": "", "source_location": "" }, { - "id": "engine", - "label": "Engine", + "id": "backend_tests_test_imports", + "label": "test_imports.py", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "engine", - "source_file": "", - "source_location": "" - }, - { - "id": "exception_handler", - "label": "exception_handler", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "exception_handler", - "source_file": "", - "source_location": "" + "norm_label": "test_imports.py", + "source_file": "backend/tests/test_imports.py", + "source_location": "L1" }, { "id": "file", "label": "File", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "file", "source_file": "", @@ -14640,42 +15049,31 @@ "label": "Form", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "form", "source_file": "", "source_location": "" }, { - "id": "jsonresponse", - "label": "JSONResponse", + "id": "holdresolution", + "label": "HoldResolution", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "jsonresponse", + "norm_label": "holdresolution", "source_file": "", "source_location": "" }, { - "id": "middleware", - "label": "middleware", + "id": "parametrize", + "label": "parametrize", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", - "norm_label": "middleware", - "source_file": "", - "source_location": "" - }, - { - "id": "staledataerror", - "label": "StaleDataError", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "code", - "norm_label": "staledataerror", + "norm_label": "parametrize", "source_file": "", "source_location": "" }, @@ -14684,56 +15082,78 @@ "label": "UploadFile", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "code", "norm_label": "uploadfile", "source_file": "", "source_location": "" }, { - "id": "backend_alembic_versions_20260922_0003_savings_system_rationale_1", - "label": "Savings system resources, adjustments and reversible conversions.", + "id": "backend_app_imports_models_rationale_101", + "label": "Immutable extracted bank fact with document origin coordinates.", "_origin": "ast", "community": 4, - "community_name": "imports/router.py", + "community_name": "imports/service.py", "file_type": "rationale", - "norm_label": "savings system resources, adjustments and reversible conversions.", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "norm_label": "immutable extracted bank fact with document origin coordinates.", + "source_file": "backend/app/imports/models.py", + "source_location": "L101" + }, + { + "id": "backend_app_imports_service_rationale_351", + "label": "Conservatively match unresolved confirmed-doc HOLDs to new posted records.\u2026", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "rationale", + "norm_label": "conservatively match unresolved confirmed-doc holds to new posted records....", + "source_file": "backend/app/imports/service.py", + "source_location": "L351" + }, + { + "id": "backend_app_imports_service_rationale_543", + "label": "Unresolved HOLD rows of the document's active parse run.", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "rationale", + "norm_label": "unresolved hold rows of the document's active parse run.", + "source_file": "backend/app/imports/service.py", + "source_location": "L543" + }, + { + "id": "backend_app_imports_service_rationale_566", + "label": "Count unresolved HOLD rows for active parse runs in one query.", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "rationale", + "norm_label": "count unresolved hold rows for active parse runs in one query.", + "source_file": "backend/app/imports/service.py", + "source_location": "L566" + }, + { + "id": "backend_app_imports_service_rationale_830", + "label": "Manually settle one HOLD: book it as a normal operation or discard it.", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "rationale", + "norm_label": "manually settle one hold: book it as a normal operation or discard it.", + "source_file": "backend/app/imports/service.py", + "source_location": "L830" + }, + { + "id": "backend_tests_test_import_savings_rationale_1", + "label": "Import contract for the \u00ab\u041a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb savings_transfer decision.", + "_origin": "ast", + "community": 4, + "community_name": "imports/service.py", + "file_type": "rationale", + "norm_label": "import contract for the \u00ab\u043a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb savings_transfer decision.", + "source_file": "backend/tests/test_import_savings.py", "source_location": "L1" }, - { - "id": "backend_alembic_versions_20260922_0003_savings_system_rationale_42", - "label": "Swap a check constraint for a new value list, dialect-safely. Fresh databases\u2026", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "rationale", - "norm_label": "swap a check constraint for a new value list, dialect-safely. fresh databases...", - "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L42" - }, - { - "id": "backend_app_db_session_rationale_50", - "label": "Transaction-local RLS context. No-op on SQLite (tests); fail-closed on\u2026", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "rationale", - "norm_label": "transaction-local rls context. no-op on sqlite (tests); fail-closed on...", - "source_file": "backend/app/db/session.py", - "source_location": "L50" - }, - { - "id": "backend_app_db_session_rationale_60", - "label": "Transactional scope for workers/endpoints that own the transaction lifecycle.", - "_origin": "ast", - "community": 4, - "community_name": "imports/router.py", - "file_type": "rationale", - "norm_label": "transactional scope for workers/endpoints that own the transaction lifecycle.", - "source_file": "backend/app/db/session.py", - "source_location": "L60" - }, { "id": "frontend_src_api_generated_schema_d", "label": "schema.d.ts", @@ -14800,12 +15220,89 @@ "source_file": "frontend/src/test/i18n-parity.test.ts", "source_location": "L29" }, + { + "id": "frontend_src_api_endpoints_api", + "label": "api", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "api", + "source_file": "frontend/src/api/endpoints.ts", + "source_location": "L35" + }, + { + "id": "frontend_src_test_account_adjustment_test", + "label": "account-adjustment.test.tsx", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "account-adjustment.test.tsx", + "source_file": "frontend/src/test/account-adjustment.test.tsx", + "source_location": "L1" + }, + { + "id": "frontend_src_test_account_adjustment_test_adjustbalancemock", + "label": "adjustBalanceMock", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "adjustbalancemock", + "source_file": "frontend/src/test/account-adjustment.test.tsx", + "source_location": "L21" + }, + { + "id": "frontend_src_test_account_adjustment_test_listmock", + "label": "listMock", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "listmock", + "source_file": "frontend/src/test/account-adjustment.test.tsx", + "source_location": "L20" + }, + { + "id": "frontend_src_test_accounts_page_test", + "label": "accounts-page.test.tsx", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "accounts-page.test.tsx", + "source_file": "frontend/src/test/accounts-page.test.tsx", + "source_location": "L1" + }, + { + "id": "frontend_src_test_accounts_page_test_createmock", + "label": "createMock", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "createmock", + "source_file": "frontend/src/test/accounts-page.test.tsx", + "source_location": "L19" + }, + { + "id": "frontend_src_test_accounts_page_test_listmock", + "label": "listMock", + "_origin": "ast", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "listmock", + "source_file": "frontend/src/test/accounts-page.test.tsx", + "source_location": "L18" + }, { "id": "frontend_src_test_app_layout_test", "label": "app-layout.test.tsx", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "app-layout.test.tsx", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -14816,7 +15313,7 @@ "label": "DESKTOP_NAV", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "desktop_nav", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -14827,7 +15324,7 @@ "label": "meMock", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "memock", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -14838,7 +15335,7 @@ "label": "MOBILE_NAV", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "mobile_nav", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -14849,7 +15346,7 @@ "label": "user", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "user", "source_file": "frontend/src/test/app-layout.test.tsx", @@ -14860,7 +15357,7 @@ "label": "helpers.tsx", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "helpers.tsx", "source_file": "frontend/src/test/helpers.tsx", @@ -14871,7 +15368,7 @@ "label": "login-page.test.tsx", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "login-page.test.tsx", "source_file": "frontend/src/test/login-page.test.tsx", @@ -14882,7 +15379,7 @@ "label": "loginMock", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "loginmock", "source_file": "frontend/src/test/login-page.test.tsx", @@ -14893,7 +15390,7 @@ "label": "meMock", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "memock", "source_file": "frontend/src/test/login-page.test.tsx", @@ -14904,100 +15401,100 @@ "label": "user", "_origin": "ast", "community": 44, - "community_name": "helpers.tsx", + "community_name": "api", "file_type": "code", "norm_label": "user", "source_file": "frontend/src/test/login-page.test.tsx", "source_location": "L24" }, { - "id": "backend_app_ledger_models", - "label": "ledger/models.py", + "id": "frontend_src_test_review_queue_save_test", + "label": "review-queue-save.test.tsx", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "ledger/models.py", - "source_file": "backend/app/ledger/models.py", + "norm_label": "review-queue-save.test.tsx", + "source_file": "frontend/src/test/review-queue-save.test.tsx", "source_location": "L1" }, { - "id": "backend_app_spaces_models", - "label": "spaces/models.py", + "id": "frontend_src_test_review_queue_save_test_categories", + "label": "categories", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "spaces/models.py", - "source_file": "backend/app/spaces/models.py", - "source_location": "L1" + "norm_label": "categories", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L32" }, { - "id": "backend_tests_test_postgres_and_s3", - "label": "test_postgres_and_s3.py", + "id": "frontend_src_test_review_queue_save_test_categoriesmock", + "label": "categoriesMock", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "test_postgres_and_s3.py", - "source_file": "backend/tests/test_postgres_and_s3.py", - "source_location": "L1" + "norm_label": "categoriesmock", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L28" }, { - "id": "backend_tests_test_savings_migration", - "label": "test_savings_migration.py", + "id": "frontend_src_test_review_queue_save_test_categorizebatchmock", + "label": "categorizeBatchMock", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "test_savings_migration.py", - "source_file": "backend/tests/test_savings_migration.py", - "source_location": "L1" + "norm_label": "categorizebatchmock", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L29" }, { - "id": "backend_tests_test_savings_migration_py_path", - "label": "Path", + "id": "frontend_src_test_review_queue_save_test_categorizemock", + "label": "categorizeMock", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "path", - "source_file": "", - "source_location": "" + "norm_label": "categorizemock", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L30" }, { - "id": "skipif", - "label": "skipif", + "id": "frontend_src_test_review_queue_save_test_importslistmock", + "label": "importsListMock", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", + "community": 44, + "community_name": "api", "file_type": "code", - "norm_label": "skipif", - "source_file": "", - "source_location": "" + "norm_label": "importslistmock", + "source_file": "frontend/src/test/review-queue-save.test.tsx", + "source_location": "L26" }, { - "id": "backend_app_imports_models_rationale_220", - "label": "Append-only, tenant-scoped settlement of one HOLD source record. The extracted\u2026", + "id": "frontend_src_test_review_queue_save_test_operationslistmock", + "label": "operationsListMock", "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", - "file_type": "rationale", - "norm_label": "append-only, tenant-scoped settlement of one hold source record. the extracted...", - "source_file": "backend/app/imports/models.py", - "source_location": "L220" - }, - { - "id": "backend_app_ledger_models_rationale_27", - "label": "Financial account. Balance is always derived: opening + confirmed postings.", - "_origin": "ast", - "community": 45, - "community_name": "ledger/models.py", - "file_type": "rationale", - "norm_label": "financial account. balance is always derived: opening + confirmed postings.", - "source_file": "backend/app/ledger/models.py", + "community": 44, + "community_name": "api", + "file_type": "code", + "norm_label": "operationslistmock", + "source_file": "frontend/src/test/review-queue-save.test.tsx", "source_location": "L27" }, + { + "id": "frontend_src_components_ui_fields", + "label": "fields.tsx", + "_origin": "ast", + "community": 45, + "community_name": "fields.tsx", + "file_type": "code", + "norm_label": "fields.tsx", + "source_file": "frontend/src/components/ui/fields.tsx", + "source_location": "L1" + }, { "id": "frontend_src_test_category_manager_test", "label": "category-manager.test.tsx", @@ -15252,26 +15749,26 @@ "source_location": "L9" }, { - "id": "frontend_package_devdependencies_types_react_dom", - "label": "@types/react-dom", + "id": "frontend_src_components_budget_budgetblockers", + "label": "BudgetBlockers.tsx", "_origin": "ast", "community": 48, - "community_name": "@types/react-dom", + "community_name": "BudgetBlockers.tsx", "file_type": "code", - "norm_label": "@types/react-dom", - "source_file": "frontend/package.json", - "source_location": "L36" + "norm_label": "budgetblockers.tsx", + "source_file": "frontend/src/components/budget/BudgetBlockers.tsx", + "source_location": "L1" }, { - "id": "types_react_dom", - "label": "@types/react-dom", + "id": "frontend_src_test_budget_blockers_test", + "label": "budget-blockers.test.tsx", "_origin": "ast", "community": 48, - "community_name": "@types/react-dom", - "file_type": "concept", - "norm_label": "@types/react-dom", - "source_file": "frontend/package.json", - "source_location": "L36" + "community_name": "BudgetBlockers.tsx", + "file_type": "code", + "norm_label": "budget-blockers.test.tsx", + "source_file": "frontend/src/test/budget-blockers.test.tsx", + "source_location": "L1" }, { "id": "frontend_package_devdependencies_typescript_eslint", @@ -15282,7 +15779,7 @@ "file_type": "code", "norm_label": "typescript-eslint", "source_file": "frontend/package.json", - "source_location": "L45" + "source_location": "L46" }, { "id": "typescript_eslint", @@ -15293,7 +15790,7 @@ "file_type": "concept", "norm_label": "typescript-eslint", "source_file": "frontend/package.json", - "source_location": "L45" + "source_location": "L46" }, { "id": "backend_app_imports_adapters_alfa_xlsx", @@ -15317,6 +15814,17 @@ "source_file": "", "source_location": "" }, + { + "id": "backend_app_imports_readers", + "label": "readers.py", + "_origin": "ast", + "community": 5, + "community_name": "alfa_xlsx.py", + "file_type": "code", + "norm_label": "readers.py", + "source_file": "backend/app/imports/readers.py", + "source_location": "L1" + }, { "id": "typeddict", "label": "TypedDict", @@ -15328,17 +15836,6 @@ "source_file": "", "source_location": "" }, - { - "id": "backend_app_imports_adapters_alfa_xlsx_rationale_244", - "label": "Alfa debit statement contract, evidenced against the real export layout.\u2026", - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "rationale", - "norm_label": "alfa debit statement contract, evidenced against the real export layout....", - "source_file": "backend/app/imports/adapters/alfa_xlsx.py", - "source_location": "L244" - }, { "id": "backend_app_imports_adapters_alfa_xlsx_rationale_68", "label": "Alfa statement contract: XLSX with a header row and bank marker '\u0410\u043b\u044c\u0444\u0430'.", @@ -15350,17 +15847,6 @@ "source_file": "backend/app/imports/adapters/alfa_xlsx.py", "source_location": "L68" }, - { - "id": "backend_app_imports_adapters_base_rationale_68", - "label": "Stable diagnostic for unknown bank layouts; never guesses.", - "_origin": "ast", - "community": 5, - "community_name": "alfa_xlsx.py", - "file_type": "rationale", - "norm_label": "stable diagnostic for unknown bank layouts; never guesses.", - "source_file": "backend/app/imports/adapters/base.py", - "source_location": "L68" - }, { "id": "kilo_plans_1790055652854_savings_import_categories_blockers", "label": "1790055652854-savings-import-categories-blockers.md", @@ -15614,26 +16100,37 @@ "source_location": "L14" }, { - "id": "frontend_package_devdependencies_vitest", - "label": "vitest", + "id": "backend_app_db_base_py_any", + "label": "Any", "_origin": "ast", "community": 51, - "community_name": "vitest", + "community_name": "UTCDateTime", "file_type": "code", - "norm_label": "vitest", - "source_file": "frontend/package.json", - "source_location": "L47" + "norm_label": "any", + "source_file": "", + "source_location": "" }, { - "id": "vitest", - "label": "vitest", + "id": "typedecorator", + "label": "TypeDecorator", "_origin": "ast", "community": 51, - "community_name": "vitest", - "file_type": "concept", - "norm_label": "vitest", - "source_file": "frontend/package.json", - "source_location": "L47" + "community_name": "UTCDateTime", + "file_type": "code", + "norm_label": "typedecorator", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_db_base_rationale_22", + "label": "Datetimes stored as naive UTC in the DB and exposed tz-aware (UTC) in Python.", + "_origin": "ast", + "community": 51, + "community_name": "UTCDateTime", + "file_type": "rationale", + "norm_label": "datetimes stored as naive utc in the db and exposed tz-aware (utc) in python.", + "source_file": "backend/app/db/base.py", + "source_location": "L22" }, { "id": "infra_postgres_init_app_role", @@ -15698,28 +16195,6 @@ "source_file": "frontend/eslint.config.js", "source_location": "L1" }, - { - "id": "backend_app_imports_adapters_base_py_protocol", - "label": "Protocol", - "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", - "file_type": "code", - "norm_label": "protocol", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_imports_adapters_init", - "label": "adapters/__init__.py", - "_origin": "ast", - "community": 58, - "community_name": "test_private_fixtures.py", - "file_type": "code", - "norm_label": "adapters/__init__.py", - "source_file": "backend/app/imports/adapters/__init__.py", - "source_location": "L1" - }, { "id": "backend_app_imports_service_py_any", "label": "Any", @@ -15776,13 +16251,13 @@ "source_location": "" }, { - "id": "workbook", - "label": "Workbook", + "id": "noreturn", + "label": "NoReturn", "_origin": "ast", "community": 58, "community_name": "test_private_fixtures.py", "file_type": "code", - "norm_label": "workbook", + "norm_label": "noreturn", "source_file": "", "source_location": "" }, @@ -15809,7 +16284,7 @@ "source_location": "L1" }, { - "id": "backend_tests_test_private_fixtures_rationale_35", + "id": "backend_tests_test_private_fixtures_rationale_36", "label": "Resolve fixture entries. Returns (directory, entries, explicit_error). An\u2026", "_origin": "ast", "community": 58, @@ -15817,7 +16292,7 @@ "file_type": "rationale", "norm_label": "resolve fixture entries. returns (directory, entries, explicit_error). an...", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L35" + "source_location": "L36" }, { "id": "frontend_src_vite_env_d", @@ -16032,26 +16507,26 @@ "source_location": "L18" }, { - "id": "pattern", - "label": "Pattern", + "id": "monkeypatch", + "label": "MonkeyPatch", "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "code", - "norm_label": "pattern", + "norm_label": "monkeypatch", "source_file": "", "source_location": "" }, { - "id": "backend_app_imports_adapters_ozon_pdf_rationale_128", - "label": "Ozon debit statement contract, evidenced against the real document. A '\u0421\u043f\u0440\u0430\u0432\u043a\u0430\u2026", + "id": "backend_tests_test_adapter_contracts_rationale_903", + "label": "Build a small valid single-font PDF with empty or ASCII-only pages.", "_origin": "ast", "community": 63, - "community_name": "OzonDebitPdfAdapter", + "community_name": "TestOzonDebitContract", "file_type": "rationale", - "norm_label": "ozon debit statement contract, evidenced against the real document. a '\u0441\u043f\u0440\u0430\u0432\u043a\u0430...", - "source_file": "backend/app/imports/adapters/ozon_pdf.py", - "source_location": "L128" + "norm_label": "build a small valid single-font pdf with empty or ascii-only pages.", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L903" }, { "id": "kilo_plans_1789727434954_gitea_ci_real_statement_imports", @@ -16157,7 +16632,7 @@ "file_type": "code", "norm_label": "eslint-plugin-react-hooks", "source_file": "frontend/package.json", - "source_location": "L40" + "source_location": "L41" }, { "id": "eslint_plugin_react_hooks", @@ -16168,7 +16643,7 @@ "file_type": "concept", "norm_label": "eslint-plugin-react-hooks", "source_file": "frontend/package.json", - "source_location": "L40" + "source_location": "L41" }, { "id": "frontend_src_test_import_confirm_test", @@ -16258,6 +16733,17 @@ "source_file": "frontend/src/test/import-hold-resolution.test.tsx", "source_location": "L47" }, + { + "id": "backend_app_audit_service_py_any", + "label": "Any", + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "code", + "norm_label": "any", + "source_file": "", + "source_location": "" + }, { "id": "backend_app_budgeting_service", "label": "budgeting/service.py", @@ -16270,13 +16756,13 @@ "source_location": "L1" }, { - "id": "backend_app_budgeting_service_py_account", - "label": "Account", + "id": "backend_app_budgeting_service_py_any", + "label": "Any", "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "account", + "norm_label": "any", "source_file": "", "source_location": "" }, @@ -16314,14 +16800,14 @@ "source_location": "" }, { - "id": "backend_tests_test_budget", - "label": "test_budget.py", + "id": "backend_tests_test_expected_income", + "label": "test_expected_income.py", "_origin": "ast", "community": 68, "community_name": "budgeting/service.py", "file_type": "code", - "norm_label": "test_budget.py", - "source_file": "backend/tests/test_budget.py", + "norm_label": "test_expected_income.py", + "source_file": "backend/tests/test_expected_income.py", "source_location": "L1" }, { @@ -16347,18 +16833,7 @@ "source_location": "L26" }, { - "id": "backend_app_budgeting_service_rationale_114", - "label": "Deterministic budget state. Resource model: - income lands in the general pool;\u2026", - "_origin": "ast", - "community": 68, - "community_name": "budgeting/service.py", - "file_type": "rationale", - "norm_label": "deterministic budget state. resource model: - income lands in the general pool;...", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L114" - }, - { - "id": "backend_app_budgeting_service_rationale_645", + "id": "backend_app_budgeting_service_rationale_627", "label": "Rename and/or archive/restore one user category definition. System categories\u2026", "_origin": "ast", "community": 68, @@ -16366,7 +16841,62 @@ "file_type": "rationale", "norm_label": "rename and/or archive/restore one user category definition. system categories...", "source_file": "backend/app/budgeting/service.py", - "source_location": "L645" + "source_location": "L627" + }, + { + "id": "backend_app_budgeting_service_rationale_714", + "label": "Load an expected income scoped to the route's year/month period.", + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "rationale", + "norm_label": "load an expected income scoped to the route's year/month period.", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L714" + }, + { + "id": "backend_app_budgeting_service_rationale_733", + "label": "Aggregate expected incomes of the period with matched totals.", + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "rationale", + "norm_label": "aggregate expected incomes of the period with matched totals.", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L733" + }, + { + "id": "backend_app_budgeting_service_rationale_889", + "label": "Partially update expected_on/amount_kopecks/source_name/note of one entry.", + "_origin": "ast", + "community": 68, + "community_name": "budgeting/service.py", + "file_type": "rationale", + "norm_label": "partially update expected_on/amount_kopecks/source_name/note of one entry.", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L889" + }, + { + "id": "backend_app_imports_adapters_alfa_xlsx_rationale_244", + "label": "Alfa debit statement contract, evidenced against the real export layout.\u2026", + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "rationale", + "norm_label": "alfa debit statement contract, evidenced against the real export layout....", + "source_file": "backend/app/imports/adapters/alfa_xlsx.py", + "source_location": "L244" + }, + { + "id": "backend_tests_test_adapter_contracts_rationale_481", + "label": "\u00ab\u041a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb contract: exact normalized phrase, statement-side source\u2026", + "_origin": "ast", + "community": 69, + "community_name": "TestAlfaDebitContract", + "file_type": "rationale", + "norm_label": "\u00ab\u043a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb contract: exact normalized phrase, statement-side source...", + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L481" }, { "id": "frontend_src_api_endpoints", @@ -16391,136 +16921,92 @@ "source_location": "L1" }, { - "id": "frontend_package_devdependencies_vite", - "label": "vite", + "id": "backend_app_imports_celery_app", + "label": "celery_app.py", "_origin": "ast", "community": 70, - "community_name": "vite", + "community_name": "celery_app.py", "file_type": "code", - "norm_label": "vite", - "source_file": "frontend/package.json", - "source_location": "L46" - }, - { - "id": "vite", - "label": "vite", - "_origin": "ast", - "community": 70, - "community_name": "vite", - "file_type": "concept", - "norm_label": "vite", - "source_file": "frontend/package.json", - "source_location": "L46" - }, - { - "id": "backend_alembic_versions_20260923_0004_mcc_categories", - "label": "20260923_0004_mcc_categories.py", - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "code", - "norm_label": "20260923_0004_mcc_categories.py", - "source_file": "backend/alembic/versions/20260923_0004_mcc_categories.py", + "norm_label": "celery_app.py", + "source_file": "backend/app/imports/celery_app.py", "source_location": "L1" }, { - "id": "backend_app_categorization_mcc", - "label": "mcc.py", + "id": "backend_app_worker", + "label": "worker.py", "_origin": "ast", - "community": 71, - "community_name": "mcc.py", + "community": 70, + "community_name": "celery_app.py", "file_type": "code", - "norm_label": "mcc.py", - "source_file": "backend/app/categorization/mcc.py", + "norm_label": "worker.py", + "source_file": "backend/app/worker.py", "source_location": "L1" }, { - "id": "namedtuple", - "label": "NamedTuple", + "id": "celery", + "label": "Celery", "_origin": "ast", - "community": 71, - "community_name": "mcc.py", + "community": 70, + "community_name": "celery_app.py", "file_type": "code", - "norm_label": "namedtuple", + "norm_label": "celery", "source_file": "", "source_location": "" }, { - "id": "backend_app_categorization_mcc_rationale_1", - "label": "MCC catalog backed by the iso18245 library with Russian labels. The global\u2026", + "id": "backend_alembic_versions_20260922_0003_savings_system", + "label": "20260922_0003_savings_system.py", "_origin": "ast", "community": 71, - "community_name": "mcc.py", - "file_type": "rationale", - "norm_label": "mcc catalog backed by the iso18245 library with russian labels. the global...", - "source_file": "backend/app/categorization/mcc.py", + "community_name": "20260922_0003_savings_system.py", + "file_type": "code", + "norm_label": "20260922_0003_savings_system.py", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", "source_location": "L1" }, { - "id": "backend_app_categorization_mcc_rationale_353", - "label": "Curated Russian translation, else a Cyrillic transcription of the label.", + "id": "backend_alembic_versions_20260922_0003_savings_system_rationale_1", + "label": "Savings system resources, adjustments and reversible conversions.", "_origin": "ast", "community": 71, - "community_name": "mcc.py", + "community_name": "20260922_0003_savings_system.py", "file_type": "rationale", - "norm_label": "curated russian translation, else a cyrillic transcription of the label.", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L353" + "norm_label": "savings system resources, adjustments and reversible conversions.", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L1" }, { - "id": "backend_app_categorization_mcc_rationale_364", - "label": "Yield ``(code, russian_title)`` for every MCC known to iso18245.", + "id": "backend_alembic_versions_20260922_0003_savings_system_rationale_40", + "label": "Swap a check constraint for a new value list, dialect-safely. Fresh databases\u2026", "_origin": "ast", "community": 71, - "community_name": "mcc.py", + "community_name": "20260922_0003_savings_system.py", "file_type": "rationale", - "norm_label": "yield ``(code, russian_title)`` for every mcc known to iso18245.", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L364" + "norm_label": "swap a check constraint for a new value list, dialect-safely. fresh databases...", + "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", + "source_location": "L40" }, { - "id": "backend_app_categorization_mcc_rationale_370", - "label": "The 20 pre-created popular categories with validated MCC code lists.", - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "rationale", - "norm_label": "the 20 pre-created popular categories with validated mcc code lists.", - "source_file": "backend/app/categorization/mcc.py", - "source_location": "L370" - }, - { - "id": "backend_app_categorization_service_rationale_119", - "label": "Idempotently seed the global ``mcc_codes`` table from iso18245.", - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "rationale", - "norm_label": "idempotently seed the global ``mcc_codes`` table from iso18245.", - "source_file": "backend/app/categorization/service.py", - "source_location": "L119" - }, - { - "id": "backend_app_categorization_service_rationale_148", - "label": "Idempotently pre-create the 20 popular categories plus \u00ab\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb. Each\u2026", - "_origin": "ast", - "community": 71, - "community_name": "mcc.py", - "file_type": "rationale", - "norm_label": "idempotently pre-create the 20 popular categories plus \u00ab\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435\u00bb. each...", - "source_file": "backend/app/categorization/service.py", - "source_location": "L148" - }, - { - "id": "backend_tests_test_adapter_contracts_rationale_480", - "label": "\u00ab\u041a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb contract: exact normalized phrase, statement-side source\u2026", + "id": "frontend_package_devdependencies_jsdom", + "label": "jsdom", "_origin": "ast", "community": 72, - "community_name": "TestAlfaSavingsRule", - "file_type": "rationale", - "norm_label": "\u00ab\u043a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb contract: exact normalized phrase, statement-side source...", - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L480" + "community_name": "jsdom", + "file_type": "code", + "norm_label": "jsdom", + "source_file": "frontend/package.json", + "source_location": "L43" + }, + { + "id": "jsdom", + "label": "jsdom", + "_origin": "ast", + "community": 72, + "community_name": "jsdom", + "file_type": "concept", + "norm_label": "jsdom", + "source_file": "frontend/package.json", + "source_location": "L43" }, { "id": "frontend_src_test_savings_convert_revert_test", @@ -16742,17 +17228,6 @@ "source_file": "", "source_location": "" }, - { - "id": "backend_app_imports_celery_app", - "label": "celery_app.py", - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "celery_app.py", - "source_file": "backend/app/imports/celery_app.py", - "source_location": "L1" - }, { "id": "backend_app_ratelimit", "label": "ratelimit.py", @@ -16764,39 +17239,6 @@ "source_file": "backend/app/ratelimit.py", "source_location": "L1" }, - { - "id": "backend_app_worker", - "label": "worker.py", - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "worker.py", - "source_file": "backend/app/worker.py", - "source_location": "L1" - }, - { - "id": "basesettings", - "label": "BaseSettings", - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "basesettings", - "source_file": "", - "source_location": "" - }, - { - "id": "celery", - "label": "Celery", - "_origin": "ast", - "community": 74, - "community_name": "get_settings", - "file_type": "code", - "norm_label": "celery", - "source_file": "", - "source_location": "" - }, { "id": "backend_app_ratelimit_rationale_16", "label": "Distributed fixed-window limiter with a local fail-safe fallback.", @@ -16852,100 +17294,12 @@ "source_file": "frontend/src/test/chart-accessible-table.test.tsx", "source_location": "L6" }, - { - "id": "backend_app_dependencies", - "label": "dependencies.py", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "dependencies.py", - "source_file": "backend/app/dependencies.py", - "source_location": "L1" - }, - { - "id": "backend_app_dependencies_py_alias", - "label": "alias", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "alias", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_dependencies_py_context", - "label": "Context", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "context", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_dependencies_py_currentsession", - "label": "CurrentSession", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "currentsession", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_dependencies_py_db", - "label": "Db", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "db", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_dependencies_py_header", - "label": "Header", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "header", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_dependencies_py_user", - "label": "User", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "user", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_errors", - "label": "errors.py", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "errors.py", - "source_file": "backend/app/errors.py", - "source_location": "L1" - }, { "id": "backend_app_spaces_router", "label": "spaces/router.py", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "spaces/router.py", "source_file": "backend/app/spaces/router.py", @@ -16956,7 +17310,7 @@ "label": "alias", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "alias", "source_file": "", @@ -16967,7 +17321,7 @@ "label": "BaseModel", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "basemodel", "source_file": "", @@ -16978,7 +17332,7 @@ "label": "Context", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "context", "source_file": "", @@ -16989,7 +17343,7 @@ "label": "Csrf", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "csrf", "source_file": "", @@ -17000,7 +17354,7 @@ "label": "CurrentSession", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "currentsession", "source_file": "", @@ -17011,7 +17365,7 @@ "label": "Db", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "db", "source_file": "", @@ -17022,7 +17376,7 @@ "label": "delete", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "delete", "source_file": "", @@ -17033,7 +17387,7 @@ "label": "get", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "get", "source_file": "", @@ -17044,7 +17398,7 @@ "label": "Header", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "header", "source_file": "", @@ -17055,78 +17409,12 @@ "label": "post", "_origin": "ast", "community": 76, - "community_name": "dependencies.py", + "community_name": "spaces/router.py", "file_type": "code", "norm_label": "post", "source_file": "", "source_location": "" }, - { - "id": "backend_app_spaces_service", - "label": "spaces/service.py", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "spaces/service.py", - "source_file": "backend/app/spaces/service.py", - "source_location": "L1" - }, - { - "id": "backend_app_spaces_service_py_user", - "label": "User", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "user", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_spaces_service_py_uuid", - "label": "UUID", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "uuid", - "source_file": "", - "source_location": "" - }, - { - "id": "cookie", - "label": "Cookie", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "cookie", - "source_file": "", - "source_location": "" - }, - { - "id": "session_cookie_name", - "label": "session_cookie_name", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "session_cookie_name", - "source_file": "", - "source_location": "" - }, - { - "id": "usersession", - "label": "UserSession", - "_origin": "ast", - "community": 76, - "community_name": "dependencies.py", - "file_type": "code", - "norm_label": "usersession", - "source_file": "", - "source_location": "" - }, { "id": "agents", "label": "AGENTS.md", @@ -17162,12 +17450,45 @@ "source_file": ".kilo/plugins/graphify.js", "source_location": "L1" }, + { + "id": "backend_app_errors", + "label": "errors.py", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "errors.py", + "source_file": "backend/app/errors.py", + "source_location": "L1" + }, + { + "id": "backend_app_errors_py_any", + "label": "Any", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "any", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_ledger_savings", + "label": "savings.py", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "savings.py", + "source_file": "backend/app/ledger/savings.py", + "source_location": "L1" + }, { "id": "backend_app_ledger_savings_py_account", "label": "Account", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "account", "source_file": "", @@ -17178,7 +17499,7 @@ "label": "date", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "date", "source_file": "", @@ -17189,7 +17510,7 @@ "label": "Operation", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "operation", "source_file": "", @@ -17200,7 +17521,7 @@ "label": "User", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "user", "source_file": "", @@ -17211,7 +17532,7 @@ "label": "UUID", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "uuid", "source_file": "", @@ -17222,73 +17543,106 @@ "label": "test_savings.py", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "code", "norm_label": "test_savings.py", "source_file": "backend/tests/test_savings.py", "source_location": "L1" }, { - "id": "backend_app_ledger_savings_rationale_105", + "id": "exception", + "label": "Exception", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "code", + "norm_label": "exception", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_errors_rationale_5", + "label": "Domain error rendered as a machine-readable JSON error payload.", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "rationale", + "norm_label": "domain error rendered as a machine-readable json error payload.", + "source_file": "backend/app/errors.py", + "source_location": "L5" + }, + { + "id": "backend_app_ledger_savings_rationale_1", + "label": "System savings account/envelope, balance adjustments and reversible\u2026", + "_origin": "ast", + "community": 79, + "community_name": "AppError", + "file_type": "rationale", + "norm_label": "system savings account/envelope, balance adjustments and reversible...", + "source_file": "backend/app/ledger/savings.py", + "source_location": "L1" + }, + { + "id": "backend_app_ledger_savings_rationale_101", "label": "System category for a manual transfer touching the savings account.", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "system category for a manual transfer touching the savings account.", "source_file": "backend/app/ledger/savings.py", - "source_location": "L105" + "source_location": "L101" }, { - "id": "backend_app_ledger_savings_rationale_122", + "id": "backend_app_ledger_savings_rationale_118", "label": "Reconcile a derived balance with reality via one audited adjustment. The\u2026", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "reconcile a derived balance with reality via one audited adjustment. the...", "source_file": "backend/app/ledger/savings.py", - "source_location": "L122" + "source_location": "L118" }, { - "id": "backend_app_ledger_savings_rationale_199", + "id": "backend_app_ledger_savings_rationale_193", "label": "Turn a confirmed expense into a transfer into the system savings account. Keeps\u2026", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "turn a confirmed expense into a transfer into the system savings account. keeps...", "source_file": "backend/app/ledger/savings.py", - "source_location": "L199" + "source_location": "L193" }, { - "id": "backend_app_ledger_savings_rationale_291", + "id": "backend_app_ledger_savings_rationale_283", "label": "Undo a marked conversion: restore the expense type, category and postings.", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "undo a marked conversion: restore the expense type, category and postings.", "source_file": "backend/app/ledger/savings.py", - "source_location": "L291" + "source_location": "L283" }, { - "id": "backend_app_ledger_savings_rationale_40", + "id": "backend_app_ledger_savings_rationale_36", "label": "Idempotently return the single system savings account and its envelope. Any\u2026", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "idempotently return the single system savings account and its envelope. any...", "source_file": "backend/app/ledger/savings.py", - "source_location": "L40" + "source_location": "L36" }, { "id": "backend_tests_test_savings_rationale_1", "label": "Savings system resources, adjustments and convert/revert contracts.", "_origin": "ast", "community": 79, - "community_name": "test_savings.py", + "community_name": "AppError", "file_type": "rationale", "norm_label": "savings system resources, adjustments and convert/revert contracts.", "source_file": "backend/tests/test_savings.py", @@ -17349,28 +17703,6 @@ "source_file": "frontend/src/app/router.tsx", "source_location": "L16" }, - { - "id": "frontend_src_app_router_importdetailpage", - "label": "ImportDetailPage", - "_origin": "ast", - "community": 8, - "community_name": "router.tsx", - "file_type": "code", - "norm_label": "importdetailpage", - "source_file": "frontend/src/app/router.tsx", - "source_location": "L19" - }, - { - "id": "frontend_src_app_router_importspage", - "label": "ImportsPage", - "_origin": "ast", - "community": 8, - "community_name": "router.tsx", - "file_type": "code", - "norm_label": "importspage", - "source_file": "frontend/src/app/router.tsx", - "source_location": "L22" - }, { "id": "frontend_src_app_router_loginpage", "label": "LoginPage", @@ -17536,6 +17868,17 @@ "source_file": "frontend/src/hooks/useAuth.ts", "source_location": "L1" }, + { + "id": "frontend_src_hooks_usespacelifecycle", + "label": "useSpaceLifecycle.ts", + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "usespacelifecycle.ts", + "source_file": "frontend/src/hooks/useSpaceLifecycle.ts", + "source_location": "L1" + }, { "id": "frontend_src_pages_acceptinvitepage", "label": "AcceptInvitePage.tsx", @@ -17569,6 +17912,17 @@ "source_file": "frontend/src/pages/ResetPasswordPage.tsx", "source_location": "L1" }, + { + "id": "frontend_src_pages_settingspage", + "label": "SettingsPage.tsx", + "_origin": "ast", + "community": 8, + "community_name": "router.tsx", + "file_type": "code", + "norm_label": "settingspage.tsx", + "source_file": "frontend/src/pages/SettingsPage.tsx", + "source_location": "L1" + }, { "id": "backend_tests_test_category_definitions", "label": "test_category_definitions.py", @@ -17680,125 +18034,125 @@ "source_location": "L25" }, { - "id": "backend_app_audit_init", - "label": "audit/__init__.py", + "id": "backend_app_ledger_models", + "label": "ledger/models.py", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "audit/__init__.py", - "source_file": "backend/app/audit/__init__.py", + "norm_label": "ledger/models.py", + "source_file": "backend/app/ledger/models.py", "source_location": "L1" }, { - "id": "backend_app_audit_service", - "label": "audit/service.py", + "id": "backend_app_spaces_models", + "label": "spaces/models.py", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "audit/service.py", - "source_file": "backend/app/audit/service.py", + "norm_label": "spaces/models.py", + "source_file": "backend/app/spaces/models.py", "source_location": "L1" }, { - "id": "backend_app_audit_service_py_any", - "label": "Any", + "id": "backend_app_spaces_service", + "label": "spaces/service.py", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "any", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_imports_service", - "label": "imports/service.py", - "_origin": "ast", - "community": 82, - "community_name": "imports/service.py", - "file_type": "code", - "norm_label": "imports/service.py", - "source_file": "backend/app/imports/service.py", + "norm_label": "spaces/service.py", + "source_file": "backend/app/spaces/service.py", "source_location": "L1" }, { - "id": "backend_app_imports_service_py_user", + "id": "backend_app_spaces_service_py_user", "label": "User", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", "norm_label": "user", "source_file": "", "source_location": "" }, { - "id": "backend_app_imports_service_py_uuid", + "id": "backend_app_spaces_service_py_uuid", "label": "UUID", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", "norm_label": "uuid", "source_file": "", "source_location": "" }, { - "id": "backend_app_ledger_savings", - "label": "savings.py", + "id": "backend_tests_test_postgres_and_s3", + "label": "test_postgres_and_s3.py", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "savings.py", - "source_file": "backend/app/ledger/savings.py", + "norm_label": "test_postgres_and_s3.py", + "source_file": "backend/tests/test_postgres_and_s3.py", "source_location": "L1" }, { - "id": "holdresolution", - "label": "HoldResolution", + "id": "backend_tests_test_savings_migration", + "label": "test_savings_migration.py", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "code", - "norm_label": "holdresolution", + "norm_label": "test_savings_migration.py", + "source_file": "backend/tests/test_savings_migration.py", + "source_location": "L1" + }, + { + "id": "backend_tests_test_savings_migration_py_path", + "label": "Path", + "_origin": "ast", + "community": 82, + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "path", "source_file": "", "source_location": "" }, { - "id": "backend_app_imports_service_rationale_566", - "label": "Count unresolved HOLD rows for active parse runs in one query.", + "id": "skipif", + "label": "skipif", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", - "file_type": "rationale", - "norm_label": "count unresolved hold rows for active parse runs in one query.", - "source_file": "backend/app/imports/service.py", - "source_location": "L566" + "community_name": "spaces/service.py", + "file_type": "code", + "norm_label": "skipif", + "source_file": "", + "source_location": "" }, { - "id": "backend_app_imports_service_rationale_830", - "label": "Manually settle one HOLD: book it as a normal operation or discard it.", + "id": "backend_app_imports_models_rationale_220", + "label": "Append-only, tenant-scoped settlement of one HOLD source record. The extracted\u2026", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "rationale", - "norm_label": "manually settle one hold: book it as a normal operation or discard it.", - "source_file": "backend/app/imports/service.py", - "source_location": "L830" + "norm_label": "append-only, tenant-scoped settlement of one hold source record. the extracted...", + "source_file": "backend/app/imports/models.py", + "source_location": "L220" }, { - "id": "backend_app_ledger_savings_rationale_1", - "label": "System savings account/envelope, balance adjustments and reversible\u2026", + "id": "backend_app_ledger_models_rationale_27", + "label": "Financial account. Balance is always derived: opening + confirmed postings.", "_origin": "ast", "community": 82, - "community_name": "imports/service.py", + "community_name": "spaces/service.py", "file_type": "rationale", - "norm_label": "system savings account/envelope, balance adjustments and reversible...", - "source_file": "backend/app/ledger/savings.py", - "source_location": "L1" + "norm_label": "financial account. balance is always derived: opening + confirmed postings.", + "source_file": "backend/app/ledger/models.py", + "source_location": "L27" }, { "id": "backend_app_exports_service", @@ -17833,28 +18187,6 @@ "source_file": "", "source_location": "" }, - { - "id": "backend_app_exports_tasks", - "label": "exports/tasks.py", - "_origin": "ast", - "community": 83, - "community_name": "exports/service.py", - "file_type": "code", - "norm_label": "exports/tasks.py", - "source_file": "backend/app/exports/tasks.py", - "source_location": "L1" - }, - { - "id": "backend_app_exports_tasks_py_task", - "label": "task", - "_origin": "ast", - "community": 83, - "community_name": "exports/service.py", - "file_type": "code", - "norm_label": "task", - "source_file": "", - "source_location": "" - }, { "id": "backend_app_imports_blob", "label": "blob.py", @@ -17878,70 +18210,59 @@ "source_location": "" }, { - "id": "backend_app_imports_models", - "label": "imports/models.py", + "id": "backend_app_imports_crypto", + "label": "crypto.py", "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", + "community": 83, + "community_name": "exports/service.py", "file_type": "code", - "norm_label": "imports/models.py", - "source_file": "backend/app/imports/models.py", + "norm_label": "crypto.py", + "source_file": "backend/app/imports/crypto.py", "source_location": "L1" }, { - "id": "backend_tests_test_imports", - "label": "test_imports.py", + "id": "backend_app_imports_crypto_rationale_22", + "label": "Per-file random DEK; DEK wrapped with the KEK from the secret manager.", + "_origin": "ast", + "community": 83, + "community_name": "exports/service.py", + "file_type": "rationale", + "norm_label": "per-file random dek; dek wrapped with the kek from the secret manager.", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L22" + }, + { + "id": "backend_app_imports_crypto_rationale_57", + "label": "Crypto-shred hook: deleting wrapped DEK rows in DB plus blobs removes access.", + "_origin": "ast", + "community": 83, + "community_name": "exports/service.py", + "file_type": "rationale", + "norm_label": "crypto-shred hook: deleting wrapped dek rows in db plus blobs removes access.", + "source_file": "backend/app/imports/crypto.py", + "source_location": "L57" + }, + { + "id": "frontend_package_devdependencies_testing_library_react", + "label": "@testing-library/react", "_origin": "ast", "community": 84, - "community_name": "test_imports.py", + "community_name": "@testing-library/react", "file_type": "code", - "norm_label": "test_imports.py", - "source_file": "backend/tests/test_imports.py", - "source_location": "L1" + "norm_label": "@testing-library/react", + "source_file": "frontend/package.json", + "source_location": "L34" }, { - "id": "parametrize", - "label": "parametrize", + "id": "testing_library_react", + "label": "@testing-library/react", "_origin": "ast", "community": 84, - "community_name": "test_imports.py", - "file_type": "code", - "norm_label": "parametrize", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_app_imports_models_rationale_101", - "label": "Immutable extracted bank fact with document origin coordinates.", - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "rationale", - "norm_label": "immutable extracted bank fact with document origin coordinates.", - "source_file": "backend/app/imports/models.py", - "source_location": "L101" - }, - { - "id": "backend_app_imports_service_rationale_351", - "label": "Conservatively match unresolved confirmed-doc HOLDs to new posted records.\u2026", - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "rationale", - "norm_label": "conservatively match unresolved confirmed-doc holds to new posted records....", - "source_file": "backend/app/imports/service.py", - "source_location": "L351" - }, - { - "id": "backend_app_imports_service_rationale_543", - "label": "Unresolved HOLD rows of the document's active parse run.", - "_origin": "ast", - "community": 84, - "community_name": "test_imports.py", - "file_type": "rationale", - "norm_label": "unresolved hold rows of the document's active parse run.", - "source_file": "backend/app/imports/service.py", - "source_location": "L543" + "community_name": "@testing-library/react", + "file_type": "concept", + "norm_label": "@testing-library/react", + "source_file": "frontend/package.json", + "source_location": "L34" }, { "id": "backend_app_identity_service", @@ -17998,12 +18319,23 @@ "source_file": "", "source_location": "" }, + { + "id": "backend_app_imports_adapters_base_py_date", + "label": "date", + "_origin": "ast", + "community": 86, + "community_name": "test_import_holds.py", + "file_type": "code", + "norm_label": "date", + "source_file": "", + "source_location": "" + }, { "id": "backend_tests_test_import_holds", "label": "test_import_holds.py", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "test_import_holds.py", "source_file": "backend/tests/test_import_holds.py", @@ -18014,7 +18346,7 @@ "label": "date", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "date", "source_file": "", @@ -18025,7 +18357,7 @@ "label": "Path", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "path", "source_file": "", @@ -18036,7 +18368,7 @@ "label": "TestClient", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "testclient", "source_file": "", @@ -18047,7 +18379,7 @@ "label": "User", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "code", "norm_label": "user", "source_file": "", @@ -18058,12 +18390,34 @@ "label": "A confirmed import whose active run contains exactly one unresolved hold.", "_origin": "ast", "community": 86, - "community_name": "Session", + "community_name": "test_import_holds.py", "file_type": "rationale", "norm_label": "a confirmed import whose active run contains exactly one unresolved hold.", "source_file": "backend/tests/test_import_holds.py", "source_location": "L119" }, + { + "id": "backend_app_categorization_init", + "label": "categorization/__init__.py", + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "categorization/__init__.py", + "source_file": "backend/app/categorization/__init__.py", + "source_location": "L1" + }, + { + "id": "backend_tests_test_budget", + "label": "test_budget.py", + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "code", + "norm_label": "test_budget.py", + "source_file": "backend/tests/test_budget.py", + "source_location": "L1" + }, { "id": "backend_tests_test_budget_savings", "label": "test_budget_savings.py", @@ -18075,6 +18429,17 @@ "source_file": "backend/tests/test_budget_savings.py", "source_location": "L1" }, + { + "id": "backend_app_budgeting_service_rationale_114", + "label": "Deterministic budget state. Resource model: - income lands in the general pool;\u2026", + "_origin": "ast", + "community": 87, + "community_name": "get_or_create_period", + "file_type": "rationale", + "norm_label": "deterministic budget state. resource model: - income lands in the general pool;...", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L114" + }, { "id": "backend_tests_test_budget_savings_rationale_1", "label": "Budget semantics for savings transfers, adjustments and archived history.", @@ -18098,59 +18463,26 @@ "source_location": "L1" }, { - "id": "backend_app_imports_init", - "label": "imports/__init__.py", + "id": "frontend_package_devdependencies_typescript", + "label": "typescript", "_origin": "ast", "community": 89, - "community_name": "test_import_savings.py", + "community_name": "typescript", "file_type": "code", - "norm_label": "imports/__init__.py", - "source_file": "backend/app/imports/__init__.py", - "source_location": "L1" + "norm_label": "typescript", + "source_file": "frontend/package.json", + "source_location": "L45" }, { - "id": "backend_tests_test_import_savings", - "label": "test_import_savings.py", + "id": "typescript", + "label": "typescript", "_origin": "ast", "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "test_import_savings.py", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L1" - }, - { - "id": "backend_tests_test_import_savings_py_date", - "label": "date", - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "date", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_tests_test_import_savings_py_user", - "label": "User", - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "code", - "norm_label": "user", - "source_file": "", - "source_location": "" - }, - { - "id": "backend_tests_test_import_savings_rationale_1", - "label": "Import contract for the \u00ab\u041a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb savings_transfer decision.", - "_origin": "ast", - "community": 89, - "community_name": "test_import_savings.py", - "file_type": "rationale", - "norm_label": "import contract for the \u00ab\u043a\u043e\u043f\u0438\u043b\u043a\u0430 \u0434\u043b\u044f \u0441\u0434\u0430\u0447\u0438\u00bb savings_transfer decision.", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L1" + "community_name": "typescript", + "file_type": "concept", + "norm_label": "typescript", + "source_file": "frontend/package.json", + "source_location": "L45" }, { "id": "backend_app_ledger_init", @@ -18439,158 +18771,237 @@ "source_location": "" }, { - "id": "frontend_src_test_review_queue_save_test", - "label": "review-queue-save.test.tsx", + "id": "frontend_package_devdependencies_vitejs_plugin_react", + "label": "@vitejs/plugin-react", "_origin": "ast", "community": 92, - "community_name": "review-queue-save.test.tsx", + "community_name": "@vitejs/plugin-react", "file_type": "code", - "norm_label": "review-queue-save.test.tsx", - "source_file": "frontend/src/test/review-queue-save.test.tsx", + "norm_label": "@vitejs/plugin-react", + "source_file": "frontend/package.json", + "source_location": "L38" + }, + { + "id": "vitejs_plugin_react", + "label": "@vitejs/plugin-react", + "_origin": "ast", + "community": 92, + "community_name": "@vitejs/plugin-react", + "file_type": "concept", + "norm_label": "@vitejs/plugin-react", + "source_file": "frontend/package.json", + "source_location": "L38" + }, + { + "id": "frontend_src_hooks_useimports", + "label": "useImports.ts", + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "useimports.ts", + "source_file": "frontend/src/hooks/useImports.ts", "source_location": "L1" }, { - "id": "frontend_src_test_review_queue_save_test_categories", - "label": "categories", + "id": "frontend_src_lib_importstatus", + "label": "importStatus.ts", "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "categories", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L32" - }, - { - "id": "frontend_src_test_review_queue_save_test_categoriesmock", - "label": "categoriesMock", - "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", - "file_type": "code", - "norm_label": "categoriesmock", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L28" - }, - { - "id": "frontend_src_test_review_queue_save_test_categorizebatchmock", - "label": "categorizeBatchMock", - "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", - "file_type": "code", - "norm_label": "categorizebatchmock", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L29" - }, - { - "id": "frontend_src_test_review_queue_save_test_categorizemock", - "label": "categorizeMock", - "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", - "file_type": "code", - "norm_label": "categorizemock", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L30" - }, - { - "id": "frontend_src_test_review_queue_save_test_importslistmock", - "label": "importsListMock", - "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", - "file_type": "code", - "norm_label": "importslistmock", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L26" - }, - { - "id": "frontend_src_test_review_queue_save_test_operationslistmock", - "label": "operationsListMock", - "_origin": "ast", - "community": 92, - "community_name": "review-queue-save.test.tsx", - "file_type": "code", - "norm_label": "operationslistmock", - "source_file": "frontend/src/test/review-queue-save.test.tsx", - "source_location": "L27" - }, - { - "id": "frontend_src_lib_accountlabel", - "label": "accountLabel.ts", - "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", - "file_type": "code", - "norm_label": "accountlabel.ts", - "source_file": "frontend/src/lib/accountLabel.ts", + "norm_label": "importstatus.ts", + "source_file": "frontend/src/lib/importStatus.ts", "source_location": "L1" }, { - "id": "frontend_src_test_account_adjustment_test", - "label": "account-adjustment.test.tsx", + "id": "frontend_src_lib_importstatus_active_statuses", + "label": "ACTIVE_STATUSES", "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "account-adjustment.test.tsx", - "source_file": "frontend/src/test/account-adjustment.test.tsx", + "norm_label": "active_statuses", + "source_file": "frontend/src/lib/importStatus.ts", + "source_location": "L5" + }, + { + "id": "frontend_src_lib_importstatus_import_poll_ms", + "label": "IMPORT_POLL_MS", + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "import_poll_ms", + "source_file": "frontend/src/lib/importStatus.ts", + "source_location": "L3" + }, + { + "id": "frontend_src_test_import_polling_test", + "label": "import-polling.test.tsx", + "_origin": "ast", + "community": 93, + "community_name": "useImports.ts", + "file_type": "code", + "norm_label": "import-polling.test.tsx", + "source_file": "frontend/src/test/import-polling.test.tsx", "source_location": "L1" }, { - "id": "frontend_src_test_account_adjustment_test_adjustbalancemock", - "label": "adjustBalanceMock", + "id": "frontend_src_test_import_polling_test_getimport", + "label": "getImport", "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 93, + "community_name": "useImports.ts", "file_type": "code", - "norm_label": "adjustbalancemock", - "source_file": "frontend/src/test/account-adjustment.test.tsx", - "source_location": "L21" + "norm_label": "getimport", + "source_file": "frontend/src/test/import-polling.test.tsx", + "source_location": "L23" }, { - "id": "frontend_src_test_account_adjustment_test_listmock", - "label": "listMock", + "id": "backend_app_dependencies", + "label": "dependencies.py", "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 95, + "community_name": "dependencies.py", "file_type": "code", - "norm_label": "listmock", - "source_file": "frontend/src/test/account-adjustment.test.tsx", - "source_location": "L20" - }, - { - "id": "frontend_src_test_accounts_page_test", - "label": "accounts-page.test.tsx", - "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", - "file_type": "code", - "norm_label": "accounts-page.test.tsx", - "source_file": "frontend/src/test/accounts-page.test.tsx", + "norm_label": "dependencies.py", + "source_file": "backend/app/dependencies.py", "source_location": "L1" }, { - "id": "frontend_src_test_accounts_page_test_createmock", - "label": "createMock", + "id": "backend_app_dependencies_py_alias", + "label": "alias", "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 95, + "community_name": "dependencies.py", "file_type": "code", - "norm_label": "createmock", - "source_file": "frontend/src/test/accounts-page.test.tsx", - "source_location": "L19" + "norm_label": "alias", + "source_file": "", + "source_location": "" }, { - "id": "frontend_src_test_accounts_page_test_listmock", - "label": "listMock", + "id": "backend_app_dependencies_py_context", + "label": "Context", "_origin": "ast", - "community": 94, - "community_name": "account-adjustment.test.tsx", + "community": 95, + "community_name": "dependencies.py", "file_type": "code", - "norm_label": "listmock", - "source_file": "frontend/src/test/accounts-page.test.tsx", - "source_location": "L18" + "norm_label": "context", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_dependencies_py_currentsession", + "label": "CurrentSession", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "currentsession", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_dependencies_py_db", + "label": "Db", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "db", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_dependencies_py_header", + "label": "Header", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "header", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_app_dependencies_py_user", + "label": "User", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "user", + "source_file": "", + "source_location": "" + }, + { + "id": "cookie", + "label": "Cookie", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "cookie", + "source_file": "", + "source_location": "" + }, + { + "id": "session_cookie_name", + "label": "session_cookie_name", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "session_cookie_name", + "source_file": "", + "source_location": "" + }, + { + "id": "usersession", + "label": "UserSession", + "_origin": "ast", + "community": 95, + "community_name": "dependencies.py", + "file_type": "code", + "norm_label": "usersession", + "source_file": "", + "source_location": "" + }, + { + "id": "backend_tests_test_expected_income_py_testclient", + "label": "TestClient", + "_origin": "ast", + "community": 96, + "community_name": "_login", + "file_type": "code", + "norm_label": "testclient", + "source_file": "", + "source_location": "" + }, + { + "id": "docs_questions_\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438", + "label": "\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438.md", + "_origin": "ast", + "community": 97, + "community_name": "\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438.md", + "source_file": "docs/questions/\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438.md", + "source_location": "L1" + }, + { + "id": "docs_tasks_0002_fixes", + "label": "0002-fixes.md", + "_origin": "ast", + "community": 98, + "community_name": "0002-fixes.md", + "file_type": "document", + "node_kind": "page", + "norm_label": "0002-fixes.md", + "source_file": "docs/tasks/0002-fixes.md", + "source_location": "L1" }, { "id": "docs_tasks_0001_fixes", @@ -19953,7 +20364,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L166", + "source_location": "L162", "weight": 1.0 }, { @@ -19965,7 +20376,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L181", + "source_location": "L173", "weight": 1.0 }, { @@ -19977,7 +20388,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L184", + "source_location": "L176", "weight": 1.0 }, { @@ -19989,7 +20400,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L185", + "source_location": "L177", "weight": 1.0 }, { @@ -20001,7 +20412,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L50", + "source_location": "L48", "weight": 1.0 }, { @@ -20013,7 +20424,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L54", + "source_location": "L52", "weight": 1.0 }, { @@ -20025,7 +20436,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L120", + "source_location": "L116", "weight": 1.0 }, { @@ -20037,7 +20448,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L121", + "source_location": "L117", "weight": 1.0 }, { @@ -20049,7 +20460,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L122", + "source_location": "L118", "weight": 1.0 }, { @@ -20061,7 +20472,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L79", + "source_location": "L77", "weight": 1.0 }, { @@ -20073,7 +20484,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L81", + "source_location": "L79", "weight": 1.0 }, { @@ -20085,7 +20496,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L86", + "source_location": "L84", "weight": 1.0 }, { @@ -20289,7 +20700,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/analytics/service.py", - "source_location": "L100", + "source_location": "L97", "weight": 1.0 }, { @@ -20301,7 +20712,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/analytics/service.py", - "source_location": "L50", + "source_location": "L47", "weight": 1.0 }, { @@ -20313,7 +20724,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/analytics/service.py", - "source_location": "L55", + "source_location": "L52", "weight": 1.0 }, { @@ -20325,7 +20736,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/analytics/service.py", - "source_location": "L89", + "source_location": "L86", "weight": 1.0 }, { @@ -20337,7 +20748,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/analytics/service.py", - "source_location": "L94", + "source_location": "L91", "weight": 1.0 }, { @@ -20361,7 +20772,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L287", + "source_location": "L307", "weight": 1.0 }, { @@ -20373,7 +20784,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L121", + "source_location": "L141", "weight": 1.0 }, { @@ -20385,7 +20796,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L122", + "source_location": "L142", "weight": 1.0 }, { @@ -20397,7 +20808,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L153", + "source_location": "L173", "weight": 1.0 }, { @@ -20409,7 +20820,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L154", + "source_location": "L174", "weight": 1.0 }, { @@ -20421,7 +20832,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L179", + "source_location": "L199", "weight": 1.0 }, { @@ -20433,7 +20844,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L333", + "source_location": "L448", "weight": 1.0 }, { @@ -20445,7 +20856,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L356", + "source_location": "L471", "weight": 1.0 }, { @@ -20457,7 +20868,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L357", + "source_location": "L472", "weight": 1.0 }, { @@ -20469,7 +20880,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L360", + "source_location": "L475", "weight": 1.0 }, { @@ -20481,7 +20892,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L374", + "source_location": "L489", "weight": 1.0 }, { @@ -20493,7 +20904,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L375", + "source_location": "L490", "weight": 1.0 }, { @@ -20505,7 +20916,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L378", + "source_location": "L493", "weight": 1.0 }, { @@ -20517,7 +20928,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L348", + "source_location": "L463", "weight": 1.0 }, { @@ -20529,7 +20940,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L231", + "source_location": "L251", "weight": 1.0 }, { @@ -20541,7 +20952,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L237", + "source_location": "L257", "weight": 1.0 }, { @@ -20553,11 +20964,11 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L239", + "source_location": "L259", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_period_for", "relation": "calls", "_origin": "ast", @@ -20565,7 +20976,79 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L320", + "source_location": "L352", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_create_expected_income", + "target": "backend_app_budgeting_router_expected_income_item", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L360", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_create_expected_income", + "target": "backend_app_budgeting_router_expected_income_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L360", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_period_for", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L394", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_incomes", + "target": "backend_app_budgeting_router_period_for", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L338", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_incomes", + "target": "backend_app_budgeting_router_expected_income_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L340", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_frontend_summary", + "target": "backend_app_budgeting_router_expected_income_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L127", "weight": 1.0 }, { @@ -20577,7 +21060,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L300", + "source_location": "L320", "weight": 1.0 }, { @@ -20589,7 +21072,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L269", + "source_location": "L289", "weight": 1.0 }, { @@ -20601,7 +21084,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L270", + "source_location": "L290", "weight": 1.0 }, { @@ -20613,7 +21096,43 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L280", + "source_location": "L300", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_period_for", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L411", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_expected_income_item", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L421", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_expected_income_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L421", "weight": 1.0 }, { @@ -20625,7 +21144,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L69", + "source_location": "L87", "weight": 1.0 }, { @@ -20637,7 +21156,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L207", + "source_location": "L227", "weight": 1.0 }, { @@ -20649,7 +21168,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L213", + "source_location": "L233", "weight": 1.0 }, { @@ -20661,7 +21180,43 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L215", + "source_location": "L235", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_period_for", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L373", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_expected_income_item", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L382", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_expected_income_json", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L382", "weight": 1.0 }, { @@ -20673,7 +21228,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L339", + "source_location": "L454", "weight": 1.0 }, { @@ -20685,7 +21240,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L365", + "source_location": "L480", "weight": 1.0 }, { @@ -20697,7 +21252,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L366", + "source_location": "L481", "weight": 1.0 }, { @@ -20709,7 +21264,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L369", + "source_location": "L484", "weight": 1.0 }, { @@ -20721,7 +21276,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L113", + "source_location": "L133", "weight": 1.0 }, { @@ -20733,7 +21288,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L114", + "source_location": "L134", "weight": 1.0 }, { @@ -20745,7 +21300,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L116", + "source_location": "L136", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_period_for", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L434", "weight": 1.0 }, { @@ -20757,7 +21324,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L249", + "source_location": "L269", "weight": 1.0 }, { @@ -20769,7 +21336,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L250", + "source_location": "L270", "weight": 1.0 }, { @@ -20781,7 +21348,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/router.py", - "source_location": "L258", + "source_location": "L278", "weight": 1.0 }, { @@ -20793,7 +21360,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L731", + "source_location": "L772", "weight": 1.0 }, { @@ -20805,7 +21372,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L733", + "source_location": "L774", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_add_expected_income", + "target": "backend_app_budgeting_service_ensure_expected_date_in_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L775", "weight": 1.0 }, { @@ -20817,7 +21396,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L734", + "source_location": "L776", "weight": 1.0 }, { @@ -20829,7 +21408,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L734", + "source_location": "L776", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_add_expected_income", + "target": "backend_app_audit_service_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L786", "weight": 1.0 }, { @@ -20841,7 +21432,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L622", + "source_location": "L604", "weight": 1.0 }, { @@ -20853,7 +21444,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L624", + "source_location": "L606", "weight": 1.0 }, { @@ -20865,7 +21456,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L626", + "source_location": "L608", "weight": 1.0 }, { @@ -20877,31 +21468,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L521", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service_close_period", - "target": "backend_app_budgeting_service_require_open", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L827", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service_close_period", - "target": "backend_app_budgeting_service_previous_ym", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/app/budgeting/service.py", - "source_location": "L828", + "source_location": "L503", "weight": 1.0 }, { @@ -20913,7 +21480,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L845", + "source_location": "L1006", "weight": 1.0 }, { @@ -20925,7 +21492,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L850", + "source_location": "L1011", "weight": 1.0 }, { @@ -20937,7 +21504,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L871", + "source_location": "L1032", "weight": 1.0 }, { @@ -20949,7 +21516,31 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L881", + "source_location": "L1042", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_close_period", + "target": "backend_app_budgeting_service_require_open", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L988", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_close_period", + "target": "backend_app_budgeting_service_previous_ym", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L989", "weight": 1.0 }, { @@ -21024,6 +21615,18 @@ "source_location": "L355", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_compute_period_state", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L425", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_compute_period_state", "target": "backend_app_budgeting_service_close_blockers", @@ -21033,7 +21636,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L487", + "source_location": "L469", "weight": 1.0 }, { @@ -21045,7 +21648,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L926", + "source_location": "L1087", "weight": 1.0 }, { @@ -21057,7 +21660,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L927", + "source_location": "L1088", "weight": 1.0 }, { @@ -21069,7 +21672,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L934", + "source_location": "L1095", "weight": 1.0 }, { @@ -21081,7 +21684,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L937", + "source_location": "L1098", "weight": 1.0 }, { @@ -21093,7 +21696,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L947", + "source_location": "L1108", "weight": 1.0 }, { @@ -21105,7 +21708,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L960", + "source_location": "L1121", "weight": 1.0 }, { @@ -21117,7 +21720,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L960", + "source_location": "L1121", "weight": 1.0 }, { @@ -21129,7 +21732,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L963", + "source_location": "L1124", "weight": 1.0 }, { @@ -21141,7 +21744,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L971", + "source_location": "L1132", "weight": 1.0 }, { @@ -21153,7 +21756,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L573", + "source_location": "L555", "weight": 1.0 }, { @@ -21165,7 +21768,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L577", + "source_location": "L559", "weight": 1.0 }, { @@ -21177,7 +21780,43 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L580", + "source_location": "L562", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_budgeting_service_require_open", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L935", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L936", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_audit_service_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L940", "weight": 1.0 }, { @@ -21189,7 +21828,31 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L599", + "source_location": "L581", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_ensure_expected_date_in_period", + "target": "backend_app_budgeting_service_period_bounds", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L722", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_ensure_expected_date_in_period", + "target": "backend_app_errors_bad_request", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L724", "weight": 1.0 }, { @@ -21201,7 +21864,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L799", + "source_location": "L960", "weight": 1.0 }, { @@ -21213,7 +21876,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L801", + "source_location": "L962", "weight": 1.0 }, { @@ -21225,7 +21888,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L804", + "source_location": "L965", "weight": 1.0 }, { @@ -21237,7 +21900,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L805", + "source_location": "L966", "weight": 1.0 }, { @@ -21249,7 +21912,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L806", + "source_location": "L967", "weight": 1.0 }, { @@ -21261,7 +21924,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L809", + "source_location": "L970", "weight": 1.0 }, { @@ -21273,7 +21936,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L560", + "source_location": "L542", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_expected_income", + "target": "backend_app_errors_not_found", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L707", "weight": 1.0 }, { @@ -21312,6 +21987,42 @@ "source_location": "L51", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "backend_app_budgeting_service_get_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L715", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "backend_app_errors_not_found", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L717", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_match_expected_income", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L806", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_match_expected_income", "target": "backend_app_errors_not_found", @@ -21321,7 +22032,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L760", + "source_location": "L811", "weight": 1.0 }, { @@ -21333,7 +22044,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L766", + "source_location": "L814", "weight": 1.0 }, { @@ -21345,7 +22056,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L773", + "source_location": "L821", "weight": 1.0 }, { @@ -21357,7 +22068,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L777", + "source_location": "L825", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_match_expected_income", + "target": "backend_app_audit_service_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L833", "weight": 1.0 }, { @@ -21381,7 +22104,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L898", + "source_location": "L1059", "weight": 1.0 }, { @@ -21393,7 +22116,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L913", + "source_location": "L1074", "weight": 1.0 }, { @@ -21405,7 +22128,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L552", + "source_location": "L534", "weight": 1.0 }, { @@ -21417,7 +22140,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L682", + "source_location": "L664", "weight": 1.0 }, { @@ -21429,7 +22152,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L685", + "source_location": "L667", "weight": 1.0 }, { @@ -21441,7 +22164,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L686", + "source_location": "L668", "weight": 1.0 }, { @@ -21453,7 +22176,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L687", + "source_location": "L669", "weight": 1.0 }, { @@ -21465,7 +22188,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L692", + "source_location": "L674", "weight": 1.0 }, { @@ -21477,7 +22200,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L699", + "source_location": "L681", "weight": 1.0 }, { @@ -21489,7 +22212,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L710", + "source_location": "L692", "weight": 1.0 }, { @@ -21504,6 +22227,42 @@ "source_location": "L45", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L856", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_errors_not_found", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L865", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_audit_service_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L868", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_update_category_definition", "target": "backend_app_budgeting_service_get_category", @@ -21513,7 +22272,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L650", + "source_location": "L632", "weight": 1.0 }, { @@ -21525,7 +22284,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L652", + "source_location": "L634", "weight": 1.0 }, { @@ -21537,7 +22296,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L657", + "source_location": "L639", "weight": 1.0 }, { @@ -21549,7 +22308,67 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/budgeting/service.py", - "source_location": "L664", + "source_location": "L646", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_require_open", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L890", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L891", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_errors_bad_request", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L895", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_ensure_expected_date_in_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L898", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_audit_service_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L910", "weight": 1.0 }, { @@ -26169,7 +26988,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/router.py", - "source_location": "L354", + "source_location": "L352", "weight": 1.0 }, { @@ -26181,7 +27000,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/router.py", - "source_location": "L357", + "source_location": "L355", "weight": 1.0 }, { @@ -26205,7 +27024,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L129", + "source_location": "L125", "weight": 1.0 }, { @@ -26217,7 +27036,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L137", + "source_location": "L133", "weight": 1.0 }, { @@ -26229,7 +27048,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L139", + "source_location": "L135", "weight": 1.0 }, { @@ -26241,7 +27060,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L151", + "source_location": "L145", "weight": 1.0 }, { @@ -26253,7 +27072,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L152", + "source_location": "L146", "weight": 1.0 }, { @@ -26265,7 +27084,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L160", + "source_location": "L154", "weight": 1.0 }, { @@ -26277,7 +27096,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L160", + "source_location": "L154", "weight": 1.0 }, { @@ -26289,7 +27108,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L172", + "source_location": "L166", "weight": 1.0 }, { @@ -26301,7 +27120,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L179", + "source_location": "L173", "weight": 1.0 }, { @@ -26313,7 +27132,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L212", + "source_location": "L206", "weight": 1.0 }, { @@ -26325,7 +27144,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L214", + "source_location": "L208", "weight": 1.0 }, { @@ -26337,7 +27156,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L255", + "source_location": "L249", "weight": 1.0 }, { @@ -26349,7 +27168,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L256", + "source_location": "L250", "weight": 1.0 }, { @@ -26361,7 +27180,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L264", + "source_location": "L258", "weight": 1.0 }, { @@ -26373,7 +27192,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L271", + "source_location": "L265", "weight": 1.0 }, { @@ -26385,7 +27204,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L47", + "source_location": "L43", "weight": 1.0 }, { @@ -26397,7 +27216,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L54", + "source_location": "L50", "weight": 1.0 }, { @@ -26409,7 +27228,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L54", + "source_location": "L50", "weight": 1.0 }, { @@ -26421,7 +27240,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L80", + "source_location": "L76", "weight": 1.0 }, { @@ -26433,7 +27252,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L90", + "source_location": "L86", "weight": 1.0 }, { @@ -26445,7 +27264,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L299", + "source_location": "L291", "weight": 1.0 }, { @@ -26457,7 +27276,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L301", + "source_location": "L293", "weight": 1.0 }, { @@ -26469,7 +27288,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L312", + "source_location": "L304", "weight": 1.0 }, { @@ -26481,7 +27300,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L327", + "source_location": "L319", "weight": 1.0 }, { @@ -26493,7 +27312,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/app/ledger/savings.py", - "source_location": "L108", + "source_location": "L104", "weight": 1.0 }, { @@ -27801,7 +28620,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L73", + "source_location": "L74", "weight": 1.0 }, { @@ -27813,7 +28632,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L55", + "source_location": "L56", "weight": 1.0 }, { @@ -27825,7 +28644,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L331", + "source_location": "L332", "weight": 1.0 }, { @@ -27837,7 +28656,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L332", + "source_location": "L333", "weight": 1.0 }, { @@ -27849,7 +28668,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L332", + "source_location": "L333", "weight": 1.0 }, { @@ -27861,7 +28680,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L338", + "source_location": "L339", "weight": 1.0 }, { @@ -27873,7 +28692,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L367", + "source_location": "L368", "weight": 1.0 }, { @@ -27885,7 +28704,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L384", + "source_location": "L385", "weight": 1.0 }, { @@ -27897,7 +28716,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L453", + "source_location": "L454", "weight": 1.0 }, { @@ -27909,7 +28728,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L360", + "source_location": "L361", "weight": 1.0 }, { @@ -27921,7 +28740,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L363", + "source_location": "L364", "weight": 1.0 }, { @@ -27933,7 +28752,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L348", + "source_location": "L349", "weight": 1.0 }, { @@ -27945,7 +28764,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L436", + "source_location": "L437", "weight": 1.0 }, { @@ -27957,7 +28776,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L442", + "source_location": "L443", "weight": 1.0 }, { @@ -27969,7 +28788,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L446", + "source_location": "L447", "weight": 1.0 }, { @@ -27981,7 +28800,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L448", + "source_location": "L449", "weight": 1.0 }, { @@ -27993,7 +28812,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L460", + "source_location": "L461", "weight": 1.0 }, { @@ -28005,7 +28824,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L463", + "source_location": "L464", "weight": 1.0 }, { @@ -28017,7 +28836,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L467", + "source_location": "L468", "weight": 1.0 }, { @@ -28029,7 +28848,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L470", + "source_location": "L471", "weight": 1.0 }, { @@ -28041,7 +28860,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L498", + "source_location": "L499", "weight": 1.0 }, { @@ -28053,7 +28872,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L547", + "source_location": "L548", "weight": 1.0 }, { @@ -28065,7 +28884,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L506", + "source_location": "L507", "weight": 1.0 }, { @@ -28077,7 +28896,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L529", + "source_location": "L530", "weight": 1.0 }, { @@ -28089,7 +28908,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L523", + "source_location": "L524", "weight": 1.0 }, { @@ -28101,7 +28920,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L541", + "source_location": "L542", "weight": 1.0 }, { @@ -28113,7 +28932,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L518", + "source_location": "L519", "weight": 1.0 }, { @@ -28125,7 +28944,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L590", + "source_location": "L602", "weight": 1.0 }, { @@ -28137,7 +28956,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L591", + "source_location": "L603", "weight": 1.0 }, { @@ -28149,7 +28968,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L591", + "source_location": "L603", "weight": 1.0 }, { @@ -28161,7 +28980,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L572", + "source_location": "L584", "weight": 1.0 }, { @@ -28173,7 +28992,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L573", + "source_location": "L585", "weight": 1.0 }, { @@ -28185,7 +29004,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L573", + "source_location": "L585", "weight": 1.0 }, { @@ -28197,7 +29016,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L535", + "source_location": "L536", "weight": 1.0 }, { @@ -28209,7 +29028,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L515", + "source_location": "L516", "weight": 1.0 }, { @@ -28221,7 +29040,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L128", + "source_location": "L129", "weight": 1.0 }, { @@ -28233,7 +29052,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L128", + "source_location": "L129", "weight": 1.0 }, { @@ -28245,7 +29064,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L123", + "source_location": "L124", "weight": 1.0 }, { @@ -28257,7 +29076,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L89", + "source_location": "L90", "weight": 1.0 }, { @@ -28269,7 +29088,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L131", + "source_location": "L132", "weight": 1.0 }, { @@ -28281,7 +29100,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L82", + "source_location": "L83", "weight": 1.0 }, { @@ -28293,7 +29112,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L78", + "source_location": "L79", "weight": 1.0 }, { @@ -28305,7 +29124,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L86", + "source_location": "L87", "weight": 1.0 }, { @@ -28317,7 +29136,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L146", + "source_location": "L147", "weight": 1.0 }, { @@ -28329,7 +29148,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L138", + "source_location": "L139", "weight": 1.0 }, { @@ -28341,7 +29160,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L653", + "source_location": "L665", "weight": 1.0 }, { @@ -28353,7 +29172,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L654", + "source_location": "L666", "weight": 1.0 }, { @@ -28365,7 +29184,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L661", + "source_location": "L673", "weight": 1.0 }, { @@ -28377,7 +29196,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L706", + "source_location": "L718", "weight": 1.0 }, { @@ -28389,7 +29208,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L683", + "source_location": "L695", "weight": 1.0 }, { @@ -28401,7 +29220,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L689", + "source_location": "L701", "weight": 1.0 }, { @@ -28413,7 +29232,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L695", + "source_location": "L707", "weight": 1.0 }, { @@ -28425,7 +29244,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L715", + "source_location": "L727", "weight": 1.0 }, { @@ -28437,7 +29256,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L717", + "source_location": "L729", "weight": 1.0 }, { @@ -28449,7 +29268,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L700", + "source_location": "L712", "weight": 1.0 }, { @@ -28461,7 +29280,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L775", + "source_location": "L787", "weight": 1.0 }, { @@ -28473,7 +29292,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L778", + "source_location": "L790", "weight": 1.0 }, { @@ -28485,7 +29304,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L871", + "source_location": "L883", "weight": 1.0 }, { @@ -28497,7 +29316,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L866", + "source_location": "L878", "weight": 1.0 }, { @@ -28509,7 +29328,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L880", + "source_location": "L892", "weight": 1.0 }, { @@ -28521,7 +29340,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L882", + "source_location": "L894", "weight": 1.0 }, { @@ -28533,7 +29352,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L836", + "source_location": "L848", "weight": 1.0 }, { @@ -28545,7 +29364,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L811", + "source_location": "L823", "weight": 1.0 }, { @@ -28557,7 +29376,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L828", + "source_location": "L840", "weight": 1.0 }, { @@ -28569,7 +29388,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L785", + "source_location": "L797", "weight": 1.0 }, { @@ -28581,7 +29400,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L789", + "source_location": "L801", "weight": 1.0 }, { @@ -28593,7 +29412,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L795", + "source_location": "L807", "weight": 1.0 }, { @@ -28605,7 +29424,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L799", + "source_location": "L811", "weight": 1.0 }, { @@ -28617,7 +29436,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L859", + "source_location": "L871", "weight": 1.0 }, { @@ -29289,7 +30108,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L112", + "source_location": "L118", "weight": 1.0 }, { @@ -29301,7 +30120,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L113", + "source_location": "L119", "weight": 1.0 }, { @@ -29313,7 +30132,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L114", + "source_location": "L120", "weight": 1.0 }, { @@ -29325,7 +30144,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L116", + "source_location": "L122", "weight": 1.0 }, { @@ -29337,7 +30156,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L123", + "source_location": "L129", "weight": 1.0 }, { @@ -29349,7 +30168,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L132", + "source_location": "L138", "weight": 1.0 }, { @@ -29361,7 +30180,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L134", + "source_location": "L140", "weight": 1.0 }, { @@ -29457,7 +30276,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L93", + "source_location": "L95", "weight": 1.0 }, { @@ -29469,7 +30288,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L94", + "source_location": "L96", "weight": 1.0 }, { @@ -29481,7 +30300,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L148", + "source_location": "L154", "weight": 1.0 }, { @@ -29493,7 +30312,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L149", + "source_location": "L155", "weight": 1.0 }, { @@ -29505,7 +30324,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L152", + "source_location": "L158", "weight": 1.0 }, { @@ -29517,7 +30336,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L139", + "source_location": "L145", "weight": 1.0 }, { @@ -29529,7 +30348,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L140", + "source_location": "L146", "weight": 1.0 }, { @@ -29541,7 +30360,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L141", + "source_location": "L147", "weight": 1.0 }, { @@ -29553,7 +30372,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_budget.py", - "source_location": "L142", + "source_location": "L148", "weight": 1.0 }, { @@ -29676,6 +30495,294 @@ "source_location": "L27", "weight": 1.0 }, + { + "source": "backend_tests_test_expected_income_seed", + "target": "backend_app_identity_models_user", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_seed", + "target": "backend_app_spaces_service_create_space", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L27", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_budgeting_service_delete_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_tests_test_expected_income_seed", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L31", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_budgeting_service_get_or_create_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L32", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_budgeting_service_add_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L34", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L55", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_budgeting_service_update_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L66", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_tests_test_expected_income_seed", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L105", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_get_or_create_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L106", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_ledger_service_create_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L107", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_add_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L115", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_ledger_service_create_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L124", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_match_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L133", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L153", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_unmatch_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L168", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_budgeting_service_delete_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L196", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_month_api_crud_and_summary", + "target": "backend_tests_test_expected_income_login", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L251", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_tests_test_expected_income_seed", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L203", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_budgeting_service_get_or_create_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L204", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_budgeting_service_add_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L205", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_budgeting_service_close_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L214", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_budgeting_service_update_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L216", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_budgeting_service_delete_expected_income", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L226", + "weight": 1.0 + }, { "source": "backend_tests_test_import_holds_add_record", "target": "backend_app_imports_models_sourcerecord", @@ -30924,18 +32031,6 @@ "source_location": "L786", "weight": 1.0 }, - { - "source": "backend_tests_test_import_savings_add_record", - "target": "backend_app_imports_models_sourcerecord", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L86", - "weight": 1.0 - }, { "source": "backend_tests_test_import_savings_add_record", "target": "backend_app_imports_adapters_alfa_xlsx_detect_savings_transfer", @@ -30945,7 +32040,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L99", + "source_location": "L101", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings_add_record", + "target": "backend_app_imports_models_sourcerecord", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L88", "weight": 1.0 }, { @@ -30957,7 +32064,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L50", + "source_location": "L52", "weight": 1.0 }, { @@ -30969,7 +32076,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L63", + "source_location": "L65", "weight": 1.0 }, { @@ -30981,7 +32088,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L34", + "source_location": "L36", "weight": 1.0 }, { @@ -30993,7 +32100,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L34", + "source_location": "L36", "weight": 1.0 }, { @@ -31005,7 +32112,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L37", + "source_location": "L39", "weight": 1.0 }, { @@ -31017,7 +32124,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L38", + "source_location": "L40", "weight": 1.0 }, { @@ -31029,7 +32136,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L44", + "source_location": "L46", "weight": 1.0 }, { @@ -31041,33 +32148,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L120", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L121", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", - "target": "backend_tests_test_import_savings_add_record", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L122", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", + "target": "backend_tests_test_import_savings_make_document", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L123", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", + "target": "backend_tests_test_import_savings_add_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L124", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_confirm_creates_savings_transfer_with_system_category", "target": "backend_tests_test_import_savings_py_date", @@ -31077,7 +32184,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L128", + "source_location": "L130", "weight": 1.0 }, { @@ -31089,7 +32196,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L134", + "source_location": "L136", "weight": 1.0 }, { @@ -31101,33 +32208,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L379", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", - "target": "backend_app_ledger_savings_get_savings_account", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L380", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L381", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", + "target": "backend_app_ledger_savings_get_savings_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L382", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", + "target": "backend_tests_test_import_savings_make_document", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L384", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_confirm_savings_transfer_rejects_savings_statement_account", "target": "backend_tests_test_import_savings_add_record", @@ -31137,7 +32244,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L383", + "source_location": "L386", "weight": 1.0 }, { @@ -31149,7 +32256,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L252", + "source_location": "L254", "weight": 1.0 }, { @@ -31161,21 +32268,21 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L253", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_existing_dedup_wins_over_savings_creation", - "target": "backend_app_imports_models_sourcerecord", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L255", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_existing_dedup_wins_over_savings_creation", + "target": "backend_app_imports_models_sourcerecord", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L257", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_existing_dedup_wins_over_savings_creation", "target": "backend_tests_test_import_savings_py_date", @@ -31185,7 +32292,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L260", + "source_location": "L262", "weight": 1.0 }, { @@ -31197,7 +32304,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L273", + "source_location": "L275", "weight": 1.0 }, { @@ -31209,33 +32316,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L113", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L114", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", - "target": "backend_tests_test_import_savings_add_record", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L115", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", + "target": "backend_tests_test_import_savings_make_document", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L116", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings_test_parsed_savings_hint_becomes_initial_review_decision", + "target": "backend_tests_test_import_savings_add_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L117", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_revert_removes_created_savings_transfer", "target": "backend_tests_test_import_savings_seed", @@ -31245,7 +32352,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L155", + "source_location": "L158", "weight": 1.0 }, { @@ -31257,7 +32364,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L156", + "source_location": "L159", "weight": 1.0 }, { @@ -31269,7 +32376,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L157", + "source_location": "L160", "weight": 1.0 }, { @@ -31281,24 +32388,12 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L212", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_savings_decision_rejects_incoming_rows", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L213", "weight": 1.0 }, { "source": "backend_tests_test_import_savings_test_savings_decision_rejects_incoming_rows", - "target": "backend_tests_test_import_savings_add_record", + "target": "backend_tests_test_import_savings_make_document", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -31308,6 +32403,18 @@ "source_location": "L214", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_savings_decision_rejects_incoming_rows", + "target": "backend_tests_test_import_savings_add_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L215", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_savings_transfer_on_hold_row_never_matches", "target": "backend_app_imports_adapters_alfa_xlsx_detect_savings_transfer", @@ -31317,7 +32424,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L304", + "source_location": "L306", "weight": 1.0 }, { @@ -31329,24 +32436,12 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L235", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_statement_mapping_rejects_system_account", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L236", "weight": 1.0 }, { "source": "backend_tests_test_import_savings_test_statement_mapping_rejects_system_account", - "target": "backend_app_ledger_savings_get_savings_account", + "target": "backend_tests_test_import_savings_make_document", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -31356,6 +32451,18 @@ "source_location": "L237", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_statement_mapping_rejects_system_account", + "target": "backend_app_ledger_savings_get_savings_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L238", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", "target": "backend_tests_test_import_savings_seed", @@ -31365,33 +32472,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L315", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L316", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", - "target": "backend_tests_test_import_savings_add_record", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L317", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", + "target": "backend_tests_test_import_savings_make_document", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L318", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", + "target": "backend_tests_test_import_savings_add_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L319", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", "target": "backend_tests_test_import_savings_py_date", @@ -31401,7 +32508,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L323", + "source_location": "L325", "weight": 1.0 }, { @@ -31413,7 +32520,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L364", + "source_location": "L366", "weight": 1.0 }, { @@ -31425,24 +32532,12 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L174", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_create", - "target": "backend_tests_test_import_savings_make_document", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L175", "weight": 1.0 }, { "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_create", - "target": "backend_tests_test_import_savings_add_record", + "target": "backend_tests_test_import_savings_make_document", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -31453,20 +32548,20 @@ "weight": 1.0 }, { - "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", - "target": "backend_tests_test_import_savings_seed", + "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_create", + "target": "backend_tests_test_import_savings_add_record", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L194", + "source_location": "L177", "weight": 1.0 }, { "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", - "target": "backend_tests_test_import_savings_make_document", + "target": "backend_tests_test_import_savings_seed", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -31478,7 +32573,7 @@ }, { "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", - "target": "backend_tests_test_import_savings_add_record", + "target": "backend_tests_test_import_savings_make_document", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -31488,6 +32583,18 @@ "source_location": "L196", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings_test_user_can_switch_savings_decision_to_discard", + "target": "backend_tests_test_import_savings_add_record", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L197", + "weight": 1.0 + }, { "source": "backend_tests_test_imports_ready_document", "target": "backend_tests_test_imports_seed", @@ -31497,7 +32604,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L43", + "source_location": "L45", "weight": 1.0 }, { @@ -31509,7 +32616,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L44", + "source_location": "L46", "weight": 1.0 }, { @@ -31521,7 +32628,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L57", + "source_location": "L59", "weight": 1.0 }, { @@ -31533,7 +32640,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L66", + "source_location": "L68", "weight": 1.0 }, { @@ -31545,7 +32652,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L27", + "source_location": "L29", "weight": 1.0 }, { @@ -31557,7 +32664,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L30", + "source_location": "L32", "weight": 1.0 }, { @@ -31569,7 +32676,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L31", + "source_location": "L33", "weight": 1.0 }, { @@ -31581,7 +32688,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L82", + "source_location": "L84", "weight": 1.0 }, { @@ -31593,7 +32700,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L136", + "source_location": "L140", "weight": 1.0 }, { @@ -31605,7 +32712,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L493", + "source_location": "L499", "weight": 1.0 }, { @@ -31617,7 +32724,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L497", + "source_location": "L503", "weight": 1.0 }, { @@ -31629,7 +32736,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L144", + "source_location": "L148", "weight": 1.0 }, { @@ -31641,7 +32748,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L206", + "source_location": "L210", "weight": 1.0 }, { @@ -31653,7 +32760,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L211", + "source_location": "L215", "weight": 1.0 }, { @@ -31665,7 +32772,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L223", + "source_location": "L227", "weight": 1.0 }, { @@ -31677,7 +32784,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L232", + "source_location": "L236", "weight": 1.0 }, { @@ -31689,7 +32796,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L413", + "source_location": "L417", "weight": 1.0 }, { @@ -31701,7 +32808,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L418", + "source_location": "L422", "weight": 1.0 }, { @@ -31713,7 +32820,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L430", + "source_location": "L434", "weight": 1.0 }, { @@ -31725,7 +32832,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L439", + "source_location": "L443", "weight": 1.0 }, { @@ -31737,7 +32844,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L295", + "source_location": "L299", "weight": 1.0 }, { @@ -31749,7 +32856,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L301", + "source_location": "L305", "weight": 1.0 }, { @@ -31761,7 +32868,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L309", + "source_location": "L313", "weight": 1.0 }, { @@ -31773,7 +32880,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L322", + "source_location": "L326", "weight": 1.0 }, { @@ -31785,7 +32892,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L329", + "source_location": "L333", "weight": 1.0 }, { @@ -31797,21 +32904,21 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L262", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_rows_from_same_parse_run", - "target": "backend_app_imports_models_sourcerecord", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_imports.py", "source_location": "L266", "weight": 1.0 }, + { + "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_rows_from_same_parse_run", + "target": "backend_app_imports_models_sourcerecord", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_imports.py", + "source_location": "L270", + "weight": 1.0 + }, { "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_rows_from_same_parse_run", "target": "backend_app_imports_models_sourcerecordlink", @@ -31821,7 +32928,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L279", + "source_location": "L283", "weight": 1.0 }, { @@ -31833,21 +32940,21 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L369", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_unconfirmed_documents", - "target": "backend_app_imports_models_statementdocument", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_imports.py", "source_location": "L373", "weight": 1.0 }, + { + "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_unconfirmed_documents", + "target": "backend_app_imports_models_statementdocument", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_imports.py", + "source_location": "L377", + "weight": 1.0 + }, { "source": "backend_tests_test_imports_test_duplicate_candidates_ignore_unconfirmed_documents", "target": "backend_app_imports_models_parserun", @@ -31857,7 +32964,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L385", + "source_location": "L389", "weight": 1.0 }, { @@ -31869,7 +32976,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L395", + "source_location": "L399", "weight": 1.0 }, { @@ -31881,7 +32988,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L458", + "source_location": "L462", "weight": 1.0 }, { @@ -31893,7 +33000,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L461", + "source_location": "L465", "weight": 1.0 }, { @@ -31905,7 +33012,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L470", + "source_location": "L474", "weight": 1.0 }, { @@ -31917,7 +33024,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L123", + "source_location": "L125", "weight": 1.0 }, { @@ -31929,7 +33036,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L97", + "source_location": "L99", "weight": 1.0 }, { @@ -31941,7 +33048,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L156", + "source_location": "L160", "weight": 1.0 }, { @@ -31953,7 +33060,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L513", + "source_location": "L519", "weight": 1.0 }, { @@ -31965,7 +33072,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L518", + "source_location": "L524", "weight": 1.0 }, { @@ -31977,7 +33084,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L526", + "source_location": "L532", "weight": 1.0 }, { @@ -31989,7 +33096,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L538", + "source_location": "L544", "weight": 1.0 }, { @@ -32001,7 +33108,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L547", + "source_location": "L553", "weight": 1.0 }, { @@ -32013,7 +33120,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L174", + "source_location": "L178", "weight": 1.0 }, { @@ -32025,7 +33132,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_imports.py", - "source_location": "L175", + "source_location": "L179", "weight": 1.0 }, { @@ -32361,31 +33468,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L45", - "weight": 1.0 - }, - { - "source": "backend_tests_test_private_fixtures_parsed", - "target": "backend_tests_test_private_fixtures_fail", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L93", - "weight": 1.0 - }, - { - "source": "backend_tests_test_private_fixtures_parsed", - "target": "backend_app_imports_adapters_init_magic_kind", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L95", + "source_location": "L46", "weight": 1.0 }, { @@ -32397,7 +33480,31 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L99", + "source_location": "L100", + "weight": 1.0 + }, + { + "source": "backend_tests_test_private_fixtures_parsed", + "target": "backend_tests_test_private_fixtures_fail", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_private_fixtures.py", + "source_location": "L94", + "weight": 1.0 + }, + { + "source": "backend_tests_test_private_fixtures_parsed", + "target": "backend_app_imports_adapters_init_magic_kind", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_private_fixtures.py", + "source_location": "L96", "weight": 1.0 }, { @@ -32409,7 +33516,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L182", + "source_location": "L183", "weight": 1.0 }, { @@ -32421,7 +33528,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L163", + "source_location": "L164", "weight": 1.0 }, { @@ -32433,7 +33540,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L209", + "source_location": "L210", "weight": 1.0 }, { @@ -32445,7 +33552,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L158", + "source_location": "L159", "weight": 1.0 }, { @@ -32457,7 +33564,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L116", + "source_location": "L117", "weight": 1.0 }, { @@ -32469,7 +33576,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L127", + "source_location": "L128", "weight": 1.0 }, { @@ -32481,7 +33588,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L147", + "source_location": "L148", "weight": 1.0 }, { @@ -32493,7 +33600,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L216", + "source_location": "L217", "weight": 1.0 }, { @@ -32505,7 +33612,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L217", + "source_location": "L218", "weight": 1.0 }, { @@ -32517,12 +33624,36 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", + "source_location": "L74", + "weight": 1.0 + }, + { + "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", + "target": "backend_tests_test_review_queue_batch_create_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_review_queue_batch.py", + "source_location": "L75", + "weight": 1.0 + }, + { + "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", + "target": "backend_tests_test_review_queue_batch_category_ids", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_review_queue_batch.py", "source_location": "L76", "weight": 1.0 }, { "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", - "target": "backend_tests_test_review_queue_batch_create_account", + "target": "backend_tests_test_review_queue_batch_create_expense", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -32532,30 +33663,6 @@ "source_location": "L77", "weight": 1.0 }, - { - "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", - "target": "backend_tests_test_review_queue_batch_category_ids", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L78", - "weight": 1.0 - }, - { - "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", - "target": "backend_tests_test_review_queue_batch_create_expense", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L79", - "weight": 1.0 - }, { "source": "backend_tests_test_review_queue_batch_test_batch_assigns_picked_categories_and_moves_leftovers_to_others", "target": "backend_tests_test_review_queue_batch_operations_by_id", @@ -32565,7 +33672,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L95", + "source_location": "L93", "weight": 1.0 }, { @@ -32577,33 +33684,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", + "source_location": "L145", + "weight": 1.0 + }, + { + "source": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", + "target": "backend_tests_test_review_queue_batch_create_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_review_queue_batch.py", + "source_location": "L146", + "weight": 1.0 + }, + { + "source": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", + "target": "backend_tests_test_review_queue_batch_create_expense", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_review_queue_batch.py", "source_location": "L147", "weight": 1.0 }, - { - "source": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", - "target": "backend_tests_test_review_queue_batch_create_account", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L148", - "weight": 1.0 - }, - { - "source": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", - "target": "backend_tests_test_review_queue_batch_create_expense", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L149", - "weight": 1.0 - }, { "source": "backend_tests_test_review_queue_batch_test_batch_is_atomic_when_one_category_is_unknown", "target": "backend_tests_test_review_queue_batch_operations_by_id", @@ -32613,7 +33720,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L165", + "source_location": "L163", "weight": 1.0 }, { @@ -32625,7 +33732,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L107", + "source_location": "L105", "weight": 1.0 }, { @@ -32637,7 +33744,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L108", + "source_location": "L106", "weight": 1.0 }, { @@ -32649,7 +33756,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L109", + "source_location": "L107", "weight": 1.0 }, { @@ -32661,7 +33768,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L110", + "source_location": "L108", "weight": 1.0 }, { @@ -32673,7 +33780,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L141", + "source_location": "L139", "weight": 1.0 }, { @@ -32685,7 +33792,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L171", + "source_location": "L169", "weight": 1.0 }, { @@ -32853,7 +33960,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L109", + "source_location": "L108", "weight": 1.0 }, { @@ -32865,7 +33972,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L110", + "source_location": "L109", "weight": 1.0 }, { @@ -32877,7 +33984,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L122", + "source_location": "L121", "weight": 1.0 }, { @@ -32889,12 +33996,24 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", + "source_location": "L188", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_adjust_balance_protects_closed_period", + "target": "backend_app_budgeting_service_get_or_create_period", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", "source_location": "L189", "weight": 1.0 }, { "source": "backend_tests_test_savings_test_adjust_balance_protects_closed_period", - "target": "backend_app_budgeting_service_get_or_create_period", + "target": "backend_app_budgeting_service_close_period", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -32904,18 +34023,6 @@ "source_location": "L190", "weight": 1.0 }, - { - "source": "backend_tests_test_savings_test_adjust_balance_protects_closed_period", - "target": "backend_app_budgeting_service_close_period", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L191", - "weight": 1.0 - }, { "source": "backend_tests_test_savings_test_adjust_balance_protects_closed_period", "target": "backend_app_ledger_savings_adjust_balance", @@ -32925,7 +34032,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L193", + "source_location": "L192", "weight": 1.0 }, { @@ -32937,21 +34044,21 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", + "source_location": "L125", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_adjust_balance_rejects_credit_accounts", + "target": "backend_app_ledger_service_create_account", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", "source_location": "L126", "weight": 1.0 }, - { - "source": "backend_tests_test_savings_test_adjust_balance_rejects_credit_accounts", - "target": "backend_app_ledger_service_create_account", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L127", - "weight": 1.0 - }, { "source": "backend_tests_test_savings_test_adjust_balance_rejects_credit_accounts", "target": "backend_app_ledger_savings_adjust_balance", @@ -32961,7 +34068,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L137", + "source_location": "L136", "weight": 1.0 }, { @@ -32973,7 +34080,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L152", + "source_location": "L151", "weight": 1.0 }, { @@ -32985,7 +34092,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L154", + "source_location": "L153", "weight": 1.0 }, { @@ -32997,12 +34104,24 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", + "source_location": "L205", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_convert_expense_to_savings_and_revert_roundtrip", + "target": "backend_app_ledger_savings_ensure_savings_resources", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", "source_location": "L206", "weight": 1.0 }, { "source": "backend_tests_test_savings_test_convert_expense_to_savings_and_revert_roundtrip", - "target": "backend_app_ledger_savings_ensure_savings_resources", + "target": "backend_app_ledger_models_category", "relation": "calls", "_origin": "ast", "confidence": "EXTRACTED", @@ -33012,18 +34131,6 @@ "source_location": "L207", "weight": 1.0 }, - { - "source": "backend_tests_test_savings_test_convert_expense_to_savings_and_revert_roundtrip", - "target": "backend_app_ledger_models_category", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L208", - "weight": 1.0 - }, { "source": "backend_tests_test_savings_test_convert_expense_to_savings_and_revert_roundtrip", "target": "backend_app_ledger_service_create_expense", @@ -33033,7 +34140,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L211", + "source_location": "L210", "weight": 1.0 }, { @@ -33045,7 +34152,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L222", + "source_location": "L221", "weight": 1.0 }, { @@ -33057,7 +34164,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L235", + "source_location": "L234", "weight": 1.0 }, { @@ -33069,7 +34176,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L238", + "source_location": "L237", "weight": 1.0 }, { @@ -33081,7 +34188,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L351", + "source_location": "L340", "weight": 1.0 }, { @@ -33093,7 +34200,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L352", + "source_location": "L341", "weight": 1.0 }, { @@ -33105,7 +34212,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L353", + "source_location": "L342", "weight": 1.0 }, { @@ -33117,7 +34224,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L356", + "source_location": "L345", "weight": 1.0 }, { @@ -33129,7 +34236,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L365", + "source_location": "L354", "weight": 1.0 }, { @@ -33141,7 +34248,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L366", + "source_location": "L355", "weight": 1.0 }, { @@ -33153,7 +34260,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L368", + "source_location": "L357", "weight": 1.0 }, { @@ -33165,33 +34272,33 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", + "source_location": "L316", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", + "target": "backend_app_ledger_service_create_expense", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", + "source_location": "L317", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", + "target": "backend_app_ledger_service_create_refund", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", "source_location": "L325", "weight": 1.0 }, - { - "source": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", - "target": "backend_app_ledger_service_create_expense", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L326", - "weight": 1.0 - }, - { - "source": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", - "target": "backend_app_ledger_service_create_refund", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L334", - "weight": 1.0 - }, { "source": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", "target": "backend_app_ledger_savings_convert_expense_to_savings", @@ -33201,7 +34308,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L344", + "source_location": "L335", "weight": 1.0 }, { @@ -33213,7 +34320,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L256", + "source_location": "L253", "weight": 1.0 }, { @@ -33225,7 +34332,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L257", + "source_location": "L254", "weight": 1.0 }, { @@ -33237,21 +34344,21 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", + "source_location": "L263", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", + "target": "backend_app_ledger_service_create_expense", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", "source_location": "L266", "weight": 1.0 }, - { - "source": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", - "target": "backend_app_ledger_service_create_expense", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L271", - "weight": 1.0 - }, { "source": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", "target": "backend_app_ledger_service_create_refund", @@ -33261,19 +34368,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L279", - "weight": 1.0 - }, - { - "source": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", - "target": "backend_app_ledger_service_create_transfer", - "relation": "calls", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "call", - "source_file": "backend/tests/test_savings.py", - "source_location": "L308", + "source_location": "L274", "weight": 1.0 }, { @@ -33285,7 +34380,19 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L313", + "source_location": "L299", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings_test_convert_rejects_income_refund_transfer_and_double_conversion", + "target": "backend_app_ledger_service_create_transfer", + "relation": "calls", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "call", + "source_file": "backend/tests/test_savings.py", + "source_location": "L301", "weight": 1.0 }, { @@ -33297,7 +34404,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L426", + "source_location": "L411", "weight": 1.0 }, { @@ -33309,7 +34416,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L427", + "source_location": "L412", "weight": 1.0 }, { @@ -33321,7 +34428,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L435", + "source_location": "L420", "weight": 1.0 }, { @@ -33333,7 +34440,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L436", + "source_location": "L421", "weight": 1.0 }, { @@ -33345,7 +34452,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L482", + "source_location": "L467", "weight": 1.0 }, { @@ -33357,7 +34464,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L483", + "source_location": "L468", "weight": 1.0 }, { @@ -33369,7 +34476,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L484", + "source_location": "L469", "weight": 1.0 }, { @@ -33381,7 +34488,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L492", + "source_location": "L477", "weight": 1.0 }, { @@ -33393,7 +34500,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L380", + "source_location": "L365", "weight": 1.0 }, { @@ -33405,7 +34512,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L381", + "source_location": "L366", "weight": 1.0 }, { @@ -33417,7 +34524,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L382", + "source_location": "L367", "weight": 1.0 }, { @@ -33429,7 +34536,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L392", + "source_location": "L377", "weight": 1.0 }, { @@ -33513,7 +34620,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L469", + "source_location": "L454", "weight": 1.0 }, { @@ -33525,7 +34632,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L470", + "source_location": "L455", "weight": 1.0 }, { @@ -33537,7 +34644,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L474", + "source_location": "L459", "weight": 1.0 }, { @@ -33549,7 +34656,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L477", + "source_location": "L462", "weight": 1.0 }, { @@ -33561,7 +34668,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L400", + "source_location": "L385", "weight": 1.0 }, { @@ -33573,7 +34680,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L401", + "source_location": "L386", "weight": 1.0 }, { @@ -33585,7 +34692,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L403", + "source_location": "L388", "weight": 1.0 }, { @@ -33597,7 +34704,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "backend/tests/test_savings.py", - "source_location": "L413", + "source_location": "L398", "weight": 1.0 }, { @@ -35949,7 +37056,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "frontend/src/pages/OperationsPage.tsx", - "source_location": "L705", + "source_location": "L711", "weight": 1.0 }, { @@ -35961,7 +37068,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "frontend/src/pages/OperationsPage.tsx", - "source_location": "L713", + "source_location": "L719", "weight": 1.0 }, { @@ -35973,7 +37080,7 @@ "confidence_score": 1.0, "context": "call", "source_file": "frontend/src/pages/OperationsPage.tsx", - "source_location": "L728", + "source_location": "L734", "weight": 1.0 }, { @@ -36741,7 +37848,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L283", + "source_location": "L303", "weight": 1.0 }, { @@ -36753,7 +37860,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L119", + "source_location": "L139", "weight": 1.0 }, { @@ -36765,7 +37872,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L163", + "source_location": "L183", "weight": 1.0 }, { @@ -36777,7 +37884,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L331", + "source_location": "L446", "weight": 1.0 }, { @@ -36789,7 +37896,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L354", + "source_location": "L469", "weight": 1.0 }, { @@ -36801,7 +37908,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L372", + "source_location": "L487", "weight": 1.0 }, { @@ -36813,7 +37920,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L346", + "source_location": "L461", "weight": 1.0 }, { @@ -36825,11 +37932,11 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L221", + "source_location": "L241", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_py_post", "relation": "references", "_origin": "ast", @@ -36837,7 +37944,31 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L311", + "source_location": "L343", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_delete", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "decorator", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L385", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_incomes", + "target": "backend_app_budgeting_router_py_get", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "decorator", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L336", "weight": 1.0 }, { @@ -36849,7 +37980,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L298", + "source_location": "L318", "weight": 1.0 }, { @@ -36861,7 +37992,19 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L261", + "source_location": "L281", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_py_post", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "decorator", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L401", "weight": 1.0 }, { @@ -36873,7 +38016,19 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L188", + "source_location": "L208", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_py_patch", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "decorator", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L363", "weight": 1.0 }, { @@ -36885,7 +38040,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L337", + "source_location": "L452", "weight": 1.0 }, { @@ -36897,7 +38052,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L363", + "source_location": "L478", "weight": 1.0 }, { @@ -36909,7 +38064,19 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L111", + "source_location": "L131", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_delete", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "decorator", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L424", "weight": 1.0 }, { @@ -36921,7 +38088,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/app/budgeting/router.py", - "source_location": "L245", + "source_location": "L265", "weight": 1.0 }, { @@ -37533,7 +38700,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/tests/test_imports.py", - "source_location": "L112", + "source_location": "L114", "weight": 1.0 }, { @@ -37593,7 +38760,7 @@ "confidence_score": 1.0, "context": "decorator", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L82", + "source_location": "L83", "weight": 1.0 }, { @@ -37701,7 +38868,7 @@ "confidence_score": 1.0, "context": "generic_arg", "source_file": "backend/app/budgeting/router.py", - "source_location": "L164", + "source_location": "L184", "weight": 1.0 }, { @@ -37713,7 +38880,19 @@ "confidence_score": 1.0, "context": "generic_arg", "source_file": "backend/app/budgeting/router.py", - "source_location": "L164", + "source_location": "L184", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_expected_income_items", + "target": "backend_app_budgeting_service_py_any", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "generic_arg", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730", "weight": 1.0 }, { @@ -37725,7 +38904,7 @@ "confidence_score": 1.0, "context": "generic_arg", "source_file": "backend/app/budgeting/service.py", - "source_location": "L610", + "source_location": "L592", "weight": 1.0 }, { @@ -37749,7 +38928,19 @@ "confidence_score": 1.0, "context": "generic_arg", "source_file": "backend/app/budgeting/service.py", - "source_location": "L891", + "source_location": "L1052", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_py_any", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "generic_arg", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", "weight": 1.0 }, { @@ -38638,7 +39829,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L115", + "source_location": "L111", "weight": 1.0 }, { @@ -38650,7 +39841,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L116", + "source_location": "L112", "weight": 1.0 }, { @@ -38962,7 +40153,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/budgeting/router.py", - "source_location": "L67", + "source_location": "L85", "weight": 1.0 }, { @@ -39178,7 +40369,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/budgeting/service.py", - "source_location": "L506", + "source_location": "L488", "weight": 1.0 }, { @@ -39190,7 +40381,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/budgeting/service.py", - "source_location": "L506", + "source_location": "L488", "weight": 1.0 }, { @@ -39202,7 +40393,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/budgeting/service.py", - "source_location": "L506", + "source_location": "L488", "weight": 1.0 }, { @@ -41686,7 +42877,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/ledger/savings.py", - "source_location": "L149", + "source_location": "L143", "weight": 1.0 }, { @@ -41698,7 +42889,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/app/ledger/savings.py", - "source_location": "L149", + "source_location": "L143", "weight": 1.0 }, { @@ -42262,7 +43453,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L14", + "source_location": "L15", "weight": 1.0 }, { @@ -42274,7 +43465,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L15", + "source_location": "L16", "weight": 1.0 }, { @@ -42286,7 +43477,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L15", + "source_location": "L16", "weight": 1.0 }, { @@ -42298,7 +43489,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L17", + "source_location": "L18", "weight": 1.0 }, { @@ -42310,7 +43501,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L17", + "source_location": "L18", "weight": 1.0 }, { @@ -42322,7 +43513,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L17", + "source_location": "L18", "weight": 1.0 }, { @@ -42334,7 +43525,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -42346,7 +43537,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -42358,7 +43549,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -42370,7 +43561,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -42382,7 +43573,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -42394,7 +43585,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -42406,7 +43597,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -42418,7 +43609,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L35", + "source_location": "L36", "weight": 1.0 }, { @@ -42430,7 +43621,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L36", + "source_location": "L37", "weight": 1.0 }, { @@ -42442,7 +43633,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_budget.py", - "source_location": "L110", + "source_location": "L116", "weight": 1.0 }, { @@ -42781,6 +43972,174 @@ "source_location": "L9", "weight": 1.0 }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_errors_apperror", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L17", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_identity_models_user", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_ledger_service_create_account", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_ledger_service_create_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_models_expectedincomematch", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L197", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_spaces_service_create_space", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_add_expected_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_close_period", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_delete_expected_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_get_or_create_period", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_match_expected_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_unmatch_expected_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service_update_expected_income", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, { "source": "backend_tests_test_import_holds", "target": "backend_app_budgeting_service_close_period", @@ -42987,19 +44346,7 @@ }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_errors_apperror", - "relation": "imports", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L10", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_identity_models_user", + "target": "backend_app_dependencies_requestcontext", "relation": "imports", "_origin": "ast", "confidence": "EXTRACTED", @@ -43011,14 +44358,26 @@ }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_imports_adapters_alfa_xlsx_detect_savings_transfer", + "target": "backend_app_errors_apperror", "relation": "imports", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L14", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_identity_models_user", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L13", "weight": 1.0 }, { @@ -43030,7 +44389,19 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L141", + "source_location": "L144", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_imports_adapters_alfa_xlsx_detect_savings_transfer", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L16", "weight": 1.0 }, { @@ -43042,7 +44413,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L15", + "source_location": "L17", "weight": 1.0 }, { @@ -43054,7 +44425,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L15", + "source_location": "L17", "weight": 1.0 }, { @@ -43066,7 +44437,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L15", + "source_location": "L17", "weight": 1.0 }, { @@ -43078,7 +44449,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L15", + "source_location": "L17", "weight": 1.0 }, { @@ -43090,7 +44461,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L15", + "source_location": "L17", "weight": 1.0 }, { @@ -43102,36 +44473,12 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L22", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_ledger_savings_get_savings_account", - "relation": "imports", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L23", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_ledger_service_create_account", - "relation": "imports", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L24", "weight": 1.0 }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_spaces_service_create_space", + "target": "backend_app_ledger_savings_get_savings_account", "relation": "imports", "_origin": "ast", "confidence": "EXTRACTED", @@ -43141,9 +44488,33 @@ "source_location": "L25", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_ledger_service_create_account", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_spaces_service_create_space", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L27", + "weight": 1.0 + }, { "source": "backend_tests_test_imports", - "target": "backend_app_identity_models_user", + "target": "backend_app_dependencies_requestcontext", "relation": "imports", "_origin": "ast", "confidence": "EXTRACTED", @@ -43153,6 +44524,30 @@ "source_location": "L10", "weight": 1.0 }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_errors_apperror", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_identity_models_user", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L12", + "weight": 1.0 + }, { "source": "backend_tests_test_imports", "target": "backend_app_imports_adapters_base_sourcerow", @@ -43162,7 +44557,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L13", + "source_location": "L15", "weight": 1.0 }, { @@ -43174,7 +44569,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L14", + "source_location": "L16", "weight": 1.0 }, { @@ -43186,7 +44581,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L14", + "source_location": "L16", "weight": 1.0 }, { @@ -43198,7 +44593,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L14", + "source_location": "L16", "weight": 1.0 }, { @@ -43210,7 +44605,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L14", + "source_location": "L16", "weight": 1.0 }, { @@ -43222,7 +44617,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L14", + "source_location": "L16", "weight": 1.0 }, { @@ -43234,7 +44629,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L21", + "source_location": "L23", "weight": 1.0 }, { @@ -43246,7 +44641,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L21", + "source_location": "L23", "weight": 1.0 }, { @@ -43258,7 +44653,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L22", + "source_location": "L24", "weight": 1.0 }, { @@ -43270,19 +44665,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L23", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports", - "target": "backend_app_errors_apperror", - "relation": "imports", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_imports.py", - "source_location": "L9", + "source_location": "L25", "weight": 1.0 }, { @@ -43522,7 +44905,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L26", + "source_location": "L27", "weight": 1.0 }, { @@ -43534,7 +44917,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L26", + "source_location": "L27", "weight": 1.0 }, { @@ -43546,7 +44929,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L27", + "source_location": "L28", "weight": 1.0 }, { @@ -43798,7 +45181,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_savings.py", - "source_location": "L471", + "source_location": "L456", "weight": 1.0 }, { @@ -43810,7 +45193,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_savings.py", - "source_location": "L471", + "source_location": "L456", "weight": 1.0 }, { @@ -43933,6 +45316,18 @@ "source_location": "L18", "weight": 1.0 }, + { + "source": "frontend_package_dependencies_fontsource_onest", + "target": "fontsource_onest", + "relation": "imports", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "frontend/package.json", + "source_location": "L19", + "weight": 1.0 + }, { "source": "frontend_package_dependencies_hookform_resolvers", "target": "hookform_resolvers", @@ -43942,7 +45337,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L19", + "source_location": "L20", "weight": 1.0 }, { @@ -43954,7 +45349,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L21", + "source_location": "L22", "weight": 1.0 }, { @@ -43966,7 +45361,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -43978,7 +45373,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L23", + "source_location": "L24", "weight": 1.0 }, { @@ -43990,7 +45385,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L24", + "source_location": "L25", "weight": 1.0 }, { @@ -44002,7 +45397,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L25", + "source_location": "L26", "weight": 1.0 }, { @@ -44014,7 +45409,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L26", + "source_location": "L27", "weight": 1.0 }, { @@ -44026,7 +45421,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L20", + "source_location": "L21", "weight": 1.0 }, { @@ -44038,7 +45433,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L27", + "source_location": "L28", "weight": 1.0 }, { @@ -44050,7 +45445,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L38", + "source_location": "L39", "weight": 1.0 }, { @@ -44062,7 +45457,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L30", + "source_location": "L31", "weight": 1.0 }, { @@ -44074,7 +45469,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L39", + "source_location": "L40", "weight": 1.0 }, { @@ -44086,7 +45481,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L40", + "source_location": "L41", "weight": 1.0 }, { @@ -44098,7 +45493,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L41", + "source_location": "L42", "weight": 1.0 }, { @@ -44110,7 +45505,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L42", + "source_location": "L43", "weight": 1.0 }, { @@ -44122,7 +45517,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L43", + "source_location": "L44", "weight": 1.0 }, { @@ -44134,7 +45529,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L31", + "source_location": "L32", "weight": 1.0 }, { @@ -44146,7 +45541,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L32", + "source_location": "L33", "weight": 1.0 }, { @@ -44158,7 +45553,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L33", + "source_location": "L34", "weight": 1.0 }, { @@ -44170,7 +45565,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -44182,7 +45577,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L35", + "source_location": "L36", "weight": 1.0 }, { @@ -44194,7 +45589,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L36", + "source_location": "L37", "weight": 1.0 }, { @@ -44206,7 +45601,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L44", + "source_location": "L45", "weight": 1.0 }, { @@ -44218,7 +45613,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L45", + "source_location": "L46", "weight": 1.0 }, { @@ -44230,7 +45625,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L46", + "source_location": "L47", "weight": 1.0 }, { @@ -44242,7 +45637,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L37", + "source_location": "L38", "weight": 1.0 }, { @@ -44254,7 +45649,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "frontend/package.json", - "source_location": "L47", + "source_location": "L48", "weight": 1.0 }, { @@ -51334,7 +52729,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L14", + "source_location": "L15", "weight": 1.0 }, { @@ -51346,7 +52741,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L16", + "source_location": "L17", "weight": 1.0 }, { @@ -51358,7 +52753,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L22", + "source_location": "L23", "weight": 1.0 }, { @@ -51370,7 +52765,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -51382,7 +52777,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L35", + "source_location": "L36", "weight": 1.0 }, { @@ -51394,7 +52789,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L36", + "source_location": "L37", "weight": 1.0 }, { @@ -51565,6 +52960,66 @@ "source_location": "L9", "weight": 1.0 }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_errors", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L17", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_identity_models", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L18", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_ledger_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L19", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_spaces_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L20", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_app_budgeting_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L7", + "weight": 1.0 + }, { "source": "backend_tests_test_import_holds", "target": "backend_app_budgeting_service", @@ -51687,19 +53142,7 @@ }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_errors", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L10", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_identity_models", + "target": "backend_app_dependencies", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51711,7 +53154,19 @@ }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_imports_init", + "target": "backend_app_errors", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L12", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_identity_models", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51723,19 +53178,7 @@ }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_imports_adapters_alfa_xlsx", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L14", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_imports_models", + "target": "backend_app_imports_init", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51745,6 +53188,30 @@ "source_location": "L15", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_imports_adapters_alfa_xlsx", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L16", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_imports_models", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L17", + "weight": 1.0 + }, { "source": "backend_tests_test_import_savings", "target": "backend_app_ledger_models", @@ -51754,36 +53221,12 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L22", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_ledger_savings", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", - "source_location": "L23", - "weight": 1.0 - }, - { - "source": "backend_tests_test_import_savings", - "target": "backend_app_ledger_service", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_import_savings.py", "source_location": "L24", "weight": 1.0 }, { "source": "backend_tests_test_import_savings", - "target": "backend_app_spaces_service", + "target": "backend_app_ledger_savings", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51793,9 +53236,33 @@ "source_location": "L25", "weight": 1.0 }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_ledger_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L26", + "weight": 1.0 + }, + { + "source": "backend_tests_test_import_savings", + "target": "backend_app_spaces_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L27", + "weight": 1.0 + }, { "source": "backend_tests_test_imports", - "target": "backend_app_identity_models", + "target": "backend_app_dependencies", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51807,7 +53274,19 @@ }, { "source": "backend_tests_test_imports", - "target": "backend_app_imports_init", + "target": "backend_app_errors", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L11", + "weight": 1.0 + }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_identity_models", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51819,19 +53298,7 @@ }, { "source": "backend_tests_test_imports", - "target": "backend_app_imports_adapters_base", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_imports.py", - "source_location": "L13", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports", - "target": "backend_app_imports_models", + "target": "backend_app_imports_init", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", @@ -51841,6 +53308,30 @@ "source_location": "L14", "weight": 1.0 }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_imports_adapters_base", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L15", + "weight": 1.0 + }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_imports_models", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L16", + "weight": 1.0 + }, { "source": "backend_tests_test_imports", "target": "backend_app_ledger_models", @@ -51850,43 +53341,31 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L21", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports", - "target": "backend_app_ledger_service", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_imports.py", - "source_location": "L22", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports", - "target": "backend_app_spaces_service", - "relation": "imports_from", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "context": "import", - "source_file": "backend/tests/test_imports.py", "source_location": "L23", "weight": 1.0 }, { "source": "backend_tests_test_imports", - "target": "backend_app_errors", + "target": "backend_app_ledger_service", "relation": "imports_from", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_imports.py", - "source_location": "L9", + "source_location": "L24", + "weight": 1.0 + }, + { + "source": "backend_tests_test_imports", + "target": "backend_app_spaces_service", + "relation": "imports_from", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "import", + "source_file": "backend/tests/test_imports.py", + "source_location": "L25", "weight": 1.0 }, { @@ -52018,7 +53497,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L26", + "source_location": "L27", "weight": 1.0 }, { @@ -52030,7 +53509,7 @@ "confidence_score": 1.0, "context": "import", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L27", + "source_location": "L28", "weight": 1.0 }, { @@ -55679,7 +57158,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L97", + "source_location": "L94", "weight": 1.0 }, { @@ -55691,7 +57170,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L97", + "source_location": "L94", "weight": 1.0 }, { @@ -55703,7 +57182,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L65", + "source_location": "L62", "weight": 1.0 }, { @@ -55715,7 +57194,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L65", + "source_location": "L62", "weight": 1.0 }, { @@ -55727,7 +57206,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L65", + "source_location": "L62", "weight": 1.0 }, { @@ -55775,7 +57254,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L88", + "source_location": "L85", "weight": 1.0 }, { @@ -55787,7 +57266,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/analytics/service.py", - "source_location": "L88", + "source_location": "L85", "weight": 1.0 }, { @@ -55811,7 +57290,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L284", + "source_location": "L304", "weight": 1.0 }, { @@ -55823,7 +57302,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L284", + "source_location": "L304", "weight": 1.0 }, { @@ -55835,7 +57314,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L284", + "source_location": "L304", "weight": 1.0 }, { @@ -55847,7 +57326,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L284", + "source_location": "L304", "weight": 1.0 }, { @@ -55859,7 +57338,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L120", + "source_location": "L140", "weight": 1.0 }, { @@ -55871,7 +57350,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L120", + "source_location": "L140", "weight": 1.0 }, { @@ -55883,7 +57362,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L164", + "source_location": "L184", "weight": 1.0 }, { @@ -55895,7 +57374,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L164", + "source_location": "L184", "weight": 1.0 }, { @@ -55907,7 +57386,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L332", + "source_location": "L447", "weight": 1.0 }, { @@ -55919,7 +57398,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L332", + "source_location": "L447", "weight": 1.0 }, { @@ -55931,7 +57410,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L332", + "source_location": "L447", "weight": 1.0 }, { @@ -55943,7 +57422,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L355", + "source_location": "L470", "weight": 1.0 }, { @@ -55955,7 +57434,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L355", + "source_location": "L470", "weight": 1.0 }, { @@ -55967,7 +57446,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L355", + "source_location": "L470", "weight": 1.0 }, { @@ -55979,7 +57458,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L355", + "source_location": "L470", "weight": 1.0 }, { @@ -55991,7 +57470,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L373", + "source_location": "L488", "weight": 1.0 }, { @@ -56003,7 +57482,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L373", + "source_location": "L488", "weight": 1.0 }, { @@ -56015,7 +57494,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L373", + "source_location": "L488", "weight": 1.0 }, { @@ -56027,7 +57506,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L373", + "source_location": "L488", "weight": 1.0 }, { @@ -56039,7 +57518,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L347", + "source_location": "L462", "weight": 1.0 }, { @@ -56051,7 +57530,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L347", + "source_location": "L462", "weight": 1.0 }, { @@ -56063,7 +57542,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L347", + "source_location": "L462", "weight": 1.0 }, { @@ -56075,7 +57554,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L222", + "source_location": "L242", "weight": 1.0 }, { @@ -56087,7 +57566,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L222", + "source_location": "L242", "weight": 1.0 }, { @@ -56099,7 +57578,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L222", + "source_location": "L242", "weight": 1.0 }, { @@ -56111,11 +57590,11 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L222", + "source_location": "L242", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_expectedincomebody", "relation": "references", "_origin": "ast", @@ -56123,11 +57602,11 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L312", + "source_location": "L344", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_py_context", "relation": "references", "_origin": "ast", @@ -56135,11 +57614,11 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L312", + "source_location": "L344", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_py_csrf", "relation": "references", "_origin": "ast", @@ -56147,11 +57626,11 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L312", + "source_location": "L344", "weight": 1.0 }, { - "source": "backend_app_budgeting_router_expected_income", + "source": "backend_app_budgeting_router_create_expected_income", "target": "backend_app_budgeting_router_py_db", "relation": "references", "_origin": "ast", @@ -56159,7 +57638,115 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L312", + "source_location": "L344", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_csrf", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_income_item", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L331", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_income_item", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L331", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_income_item", + "target": "backend_app_budgeting_router_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L331", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_incomes", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L337", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expected_incomes", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L337", "weight": 1.0 }, { @@ -56171,7 +57758,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L299", + "source_location": "L319", "weight": 1.0 }, { @@ -56183,7 +57770,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L299", + "source_location": "L319", "weight": 1.0 }, { @@ -56195,7 +57782,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L299", + "source_location": "L319", "weight": 1.0 }, { @@ -56207,7 +57794,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L299", + "source_location": "L319", "weight": 1.0 }, { @@ -56219,7 +57806,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L282", "weight": 1.0 }, { @@ -56231,7 +57818,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L282", "weight": 1.0 }, { @@ -56243,7 +57830,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L282", "weight": 1.0 }, { @@ -56255,7 +57842,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L282", "weight": 1.0 }, { @@ -56267,7 +57854,67 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L282", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_expectedincomematchbody", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_py_csrf", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_match_expected_income", + "target": "backend_app_budgeting_router_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", "weight": 1.0 }, { @@ -56279,7 +57926,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", + "source_location": "L209", "weight": 1.0 }, { @@ -56291,7 +57938,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", + "source_location": "L209", "weight": 1.0 }, { @@ -56303,7 +57950,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", + "source_location": "L209", "weight": 1.0 }, { @@ -56315,7 +57962,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", + "source_location": "L209", "weight": 1.0 }, { @@ -56327,7 +57974,67 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", + "source_location": "L209", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_expectedincomepatchbody", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_py_csrf", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_patch_expected_income", + "target": "backend_app_budgeting_router_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L364", "weight": 1.0 }, { @@ -56339,7 +58046,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L46", + "source_location": "L64", "weight": 1.0 }, { @@ -56351,7 +58058,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L46", + "source_location": "L64", "weight": 1.0 }, { @@ -56363,7 +58070,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L338", + "source_location": "L453", "weight": 1.0 }, { @@ -56375,7 +58082,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L338", + "source_location": "L453", "weight": 1.0 }, { @@ -56387,7 +58094,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L338", + "source_location": "L453", "weight": 1.0 }, { @@ -56399,7 +58106,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L364", + "source_location": "L479", "weight": 1.0 }, { @@ -56411,7 +58118,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L364", + "source_location": "L479", "weight": 1.0 }, { @@ -56423,7 +58130,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L364", + "source_location": "L479", "weight": 1.0 }, { @@ -56435,7 +58142,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L364", + "source_location": "L479", "weight": 1.0 }, { @@ -56447,7 +58154,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L112", + "source_location": "L132", "weight": 1.0 }, { @@ -56459,7 +58166,55 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L112", + "source_location": "L132", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_context", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_csrf", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_db", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", "weight": 1.0 }, { @@ -56471,7 +58226,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", + "source_location": "L266", "weight": 1.0 }, { @@ -56483,7 +58238,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", + "source_location": "L266", "weight": 1.0 }, { @@ -56495,7 +58250,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", + "source_location": "L266", "weight": 1.0 }, { @@ -56507,7 +58262,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", + "source_location": "L266", "weight": 1.0 }, { @@ -56519,7 +58274,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", + "source_location": "L266", "weight": 1.0 }, { @@ -56531,7 +58286,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", + "source_location": "L761", "weight": 1.0 }, { @@ -56543,7 +58298,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", + "source_location": "L761", "weight": 1.0 }, { @@ -56555,7 +58310,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", + "source_location": "L761", "weight": 1.0 }, { @@ -56567,7 +58322,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", + "source_location": "L761", "weight": 1.0 }, { @@ -56579,7 +58334,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", + "source_location": "L761", "weight": 1.0 }, { @@ -56591,7 +58346,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L619", + "source_location": "L601", "weight": 1.0 }, { @@ -56603,7 +58358,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L619", + "source_location": "L601", "weight": 1.0 }, { @@ -56615,7 +58370,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L619", + "source_location": "L601", "weight": 1.0 }, { @@ -56663,7 +58418,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L498", + "source_location": "L480", "weight": 1.0 }, { @@ -56675,7 +58430,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L498", + "source_location": "L480", "weight": 1.0 }, { @@ -56687,7 +58442,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L498", + "source_location": "L480", "weight": 1.0 }, { @@ -56699,7 +58454,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L823", + "source_location": "L984", "weight": 1.0 }, { @@ -56711,7 +58466,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L823", + "source_location": "L984", "weight": 1.0 }, { @@ -56723,7 +58478,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L823", + "source_location": "L984", "weight": 1.0 }, { @@ -56735,7 +58490,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L823", + "source_location": "L984", "weight": 1.0 }, { @@ -56807,7 +58562,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L923", + "source_location": "L1084", "weight": 1.0 }, { @@ -56819,7 +58574,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L923", + "source_location": "L1084", "weight": 1.0 }, { @@ -56831,7 +58586,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L923", + "source_location": "L1084", "weight": 1.0 }, { @@ -56843,7 +58598,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L923", + "source_location": "L1084", "weight": 1.0 }, { @@ -56855,7 +58610,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L564", + "source_location": "L546", "weight": 1.0 }, { @@ -56867,7 +58622,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L564", + "source_location": "L546", "weight": 1.0 }, { @@ -56879,7 +58634,55 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L564", + "source_location": "L546", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L927", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_budgeting_service_py_user", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L927", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L927", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_delete_expected_income", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L927", "weight": 1.0 }, { @@ -56891,7 +58694,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L590", + "source_location": "L572", "weight": 1.0 }, { @@ -56903,7 +58706,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L590", + "source_location": "L572", "weight": 1.0 }, { @@ -56915,7 +58718,67 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L590", + "source_location": "L572", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_ensure_expected_date_in_period", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L721", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_ensure_expected_date_in_period", + "target": "backend_app_budgeting_service_py_date", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L721", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_expected_income_items", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_expected_income_items", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_expected_income_items", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730", "weight": 1.0 }, { @@ -56927,7 +58790,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L788", + "source_location": "L949", "weight": 1.0 }, { @@ -56939,7 +58802,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L788", + "source_location": "L949", "weight": 1.0 }, { @@ -56951,7 +58814,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L788", + "source_location": "L949", "weight": 1.0 }, { @@ -56963,7 +58826,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L788", + "source_location": "L949", "weight": 1.0 }, { @@ -56975,7 +58838,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L557", + "source_location": "L539", "weight": 1.0 }, { @@ -56987,7 +58850,31 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L557", + "source_location": "L539", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_expected_income", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L702", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_expected_income", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L702", "weight": 1.0 }, { @@ -57038,6 +58925,42 @@ "source_location": "L48", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L711", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L711", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L711", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_list_categories", "target": "backend_app_budgeting_service_py_uuid", @@ -57047,7 +58970,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L610", + "source_location": "L592", "weight": 1.0 }, { @@ -57059,7 +58982,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L610", + "source_location": "L592", "weight": 1.0 }, { @@ -57086,6 +59009,18 @@ "source_location": "L69", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_match_expected_income", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L796", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_match_expected_income", "target": "backend_app_budgeting_service_py_user", @@ -57095,7 +59030,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L747", + "source_location": "L796", "weight": 1.0 }, { @@ -57107,7 +59042,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L747", + "source_location": "L796", "weight": 1.0 }, { @@ -57119,7 +59054,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L747", + "source_location": "L796", "weight": 1.0 }, { @@ -57131,7 +59066,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L891", + "source_location": "L1052", "weight": 1.0 }, { @@ -57143,7 +59078,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L891", + "source_location": "L1052", "weight": 1.0 }, { @@ -57155,7 +59090,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L891", + "source_location": "L1052", "weight": 1.0 }, { @@ -57167,7 +59102,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L550", + "source_location": "L532", "weight": 1.0 }, { @@ -57179,7 +59114,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L674", + "source_location": "L656", "weight": 1.0 }, { @@ -57191,7 +59126,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L674", + "source_location": "L656", "weight": 1.0 }, { @@ -57203,7 +59138,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L674", + "source_location": "L656", "weight": 1.0 }, { @@ -57215,7 +59150,55 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L674", + "source_location": "L656", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_budgeting_service_py_user", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_unmatch_expected_income", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847", "weight": 1.0 }, { @@ -57227,7 +59210,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L636", + "source_location": "L618", "weight": 1.0 }, { @@ -57239,7 +59222,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L636", + "source_location": "L618", "weight": 1.0 }, { @@ -57251,7 +59234,55 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L636", + "source_location": "L618", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_models_budgetperiod", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_py_user", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_budgeting_service_py_uuid", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", "weight": 1.0 }, { @@ -60167,7 +62198,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L112", + "source_location": "L108", "weight": 1.0 }, { @@ -60179,7 +62210,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L112", + "source_location": "L108", "weight": 1.0 }, { @@ -60191,7 +62222,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L112", + "source_location": "L108", "weight": 1.0 }, { @@ -60203,7 +62234,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L112", + "source_location": "L108", "weight": 1.0 }, { @@ -60215,7 +62246,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L196", + "source_location": "L190", "weight": 1.0 }, { @@ -60227,7 +62258,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L196", + "source_location": "L190", "weight": 1.0 }, { @@ -60239,7 +62270,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L196", + "source_location": "L190", "weight": 1.0 }, { @@ -60251,7 +62282,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L39", + "source_location": "L35", "weight": 1.0 }, { @@ -60263,7 +62294,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L39", + "source_location": "L35", "weight": 1.0 }, { @@ -60299,7 +62330,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L288", + "source_location": "L280", "weight": 1.0 }, { @@ -60311,7 +62342,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L288", + "source_location": "L280", "weight": 1.0 }, { @@ -60323,7 +62354,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L288", + "source_location": "L280", "weight": 1.0 }, { @@ -60335,7 +62366,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L31", + "source_location": "L29", "weight": 1.0 }, { @@ -60347,7 +62378,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L31", + "source_location": "L29", "weight": 1.0 }, { @@ -60359,7 +62390,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L102", + "source_location": "L98", "weight": 1.0 }, { @@ -60371,7 +62402,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L102", + "source_location": "L98", "weight": 1.0 }, { @@ -60383,7 +62414,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L102", + "source_location": "L98", "weight": 1.0 }, { @@ -61475,7 +63506,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L472", + "source_location": "L473", "weight": 1.0 }, { @@ -61487,7 +63518,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L712", + "source_location": "L724", "weight": 1.0 }, { @@ -61499,7 +63530,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L877", + "source_location": "L889", "weight": 1.0 }, { @@ -61667,7 +63698,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_budget.py", - "source_location": "L109", + "source_location": "L115", "weight": 1.0 }, { @@ -61691,7 +63722,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_budget.py", - "source_location": "L147", + "source_location": "L153", "weight": 1.0 }, { @@ -61703,7 +63734,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_budget.py", - "source_location": "L138", + "source_location": "L144", "weight": 1.0 }, { @@ -61790,6 +63821,78 @@ "source_location": "L26", "weight": 1.0 }, + { + "source": "backend_tests_test_expected_income_login", + "target": "backend_tests_test_expected_income_py_testclient", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L230", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_seed", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L30", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L104", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_month_api_crud_and_summary", + "target": "backend_tests_test_expected_income_py_testclient", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_identity_models_session", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "parameter_type", + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L202", + "weight": 1.0 + }, { "source": "backend_tests_test_import_holds_add_record", "target": "backend_app_identity_models_session", @@ -62183,7 +64286,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75", + "source_location": "L77", "weight": 1.0 }, { @@ -62195,7 +64298,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75", + "source_location": "L77", "weight": 1.0 }, { @@ -62207,7 +64310,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75", + "source_location": "L77", "weight": 1.0 }, { @@ -62219,7 +64322,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75", + "source_location": "L77", "weight": 1.0 }, { @@ -62231,7 +64334,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L49", + "source_location": "L51", "weight": 1.0 }, { @@ -62243,7 +64346,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L49", + "source_location": "L51", "weight": 1.0 }, { @@ -62255,7 +64358,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L33", + "source_location": "L35", "weight": 1.0 }, { @@ -62267,7 +64370,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L119", + "source_location": "L121", "weight": 1.0 }, { @@ -62279,7 +64382,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L378", + "source_location": "L380", "weight": 1.0 }, { @@ -62291,7 +64394,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L251", + "source_location": "L253", "weight": 1.0 }, { @@ -62303,7 +64406,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L112", + "source_location": "L114", "weight": 1.0 }, { @@ -62315,7 +64418,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L154", + "source_location": "L157", "weight": 1.0 }, { @@ -62327,7 +64430,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L211", + "source_location": "L212", "weight": 1.0 }, { @@ -62339,7 +64442,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L302", + "source_location": "L304", "weight": 1.0 }, { @@ -62351,7 +64454,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L234", + "source_location": "L235", "weight": 1.0 }, { @@ -62363,7 +64466,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L314", + "source_location": "L316", "weight": 1.0 }, { @@ -62375,7 +64478,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L173", + "source_location": "L174", "weight": 1.0 }, { @@ -62387,7 +64490,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L193", + "source_location": "L194", "weight": 1.0 }, { @@ -62399,7 +64502,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L42", + "source_location": "L44", "weight": 1.0 }, { @@ -62411,7 +64514,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L26", + "source_location": "L28", "weight": 1.0 }, { @@ -62423,7 +64526,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L81", + "source_location": "L83", "weight": 1.0 }, { @@ -62435,7 +64538,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L135", + "source_location": "L139", "weight": 1.0 }, { @@ -62447,7 +64550,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L492", + "source_location": "L498", "weight": 1.0 }, { @@ -62459,7 +64562,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L143", + "source_location": "L147", "weight": 1.0 }, { @@ -62471,7 +64574,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L205", + "source_location": "L209", "weight": 1.0 }, { @@ -62483,7 +64586,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L412", + "source_location": "L416", "weight": 1.0 }, { @@ -62495,7 +64598,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L294", + "source_location": "L298", "weight": 1.0 }, { @@ -62507,7 +64610,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L261", + "source_location": "L265", "weight": 1.0 }, { @@ -62519,7 +64622,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L368", + "source_location": "L372", "weight": 1.0 }, { @@ -62531,7 +64634,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L457", + "source_location": "L461", "weight": 1.0 }, { @@ -62543,7 +64646,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L120", + "source_location": "L122", "weight": 1.0 }, { @@ -62555,7 +64658,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L96", + "source_location": "L98", "weight": 1.0 }, { @@ -62567,7 +64670,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L512", + "source_location": "L518", "weight": 1.0 }, { @@ -62579,7 +64682,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_imports.py", - "source_location": "L173", + "source_location": "L177", "weight": 1.0 }, { @@ -62651,7 +64754,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L86", + "source_location": "L87", "weight": 1.0 }, { @@ -62711,7 +64814,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L67", + "source_location": "L65", "weight": 1.0 }, { @@ -62723,7 +64826,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L73", + "source_location": "L71", "weight": 1.0 }, { @@ -62735,7 +64838,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L146", + "source_location": "L144", "weight": 1.0 }, { @@ -62747,7 +64850,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L104", + "source_location": "L102", "weight": 1.0 }, { @@ -62759,7 +64862,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L170", + "source_location": "L168", "weight": 1.0 }, { @@ -62795,7 +64898,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L108", + "source_location": "L107", "weight": 1.0 }, { @@ -62807,7 +64910,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L188", + "source_location": "L187", "weight": 1.0 }, { @@ -62819,7 +64922,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L125", + "source_location": "L124", "weight": 1.0 }, { @@ -62831,7 +64934,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L149", + "source_location": "L148", "weight": 1.0 }, { @@ -62843,7 +64946,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L205", + "source_location": "L204", "weight": 1.0 }, { @@ -62855,7 +64958,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L350", + "source_location": "L339", "weight": 1.0 }, { @@ -62867,7 +64970,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L324", + "source_location": "L315", "weight": 1.0 }, { @@ -62879,7 +64982,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L253", + "source_location": "L250", "weight": 1.0 }, { @@ -62891,7 +64994,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L425", + "source_location": "L410", "weight": 1.0 }, { @@ -62903,7 +65006,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L481", + "source_location": "L466", "weight": 1.0 }, { @@ -62915,7 +65018,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L379", + "source_location": "L364", "weight": 1.0 }, { @@ -62951,7 +65054,7 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L468", + "source_location": "L453", "weight": 1.0 }, { @@ -62963,7 +65066,31 @@ "confidence_score": 1.0, "context": "parameter_type", "source_file": "backend/tests/test_savings.py", - "source_location": "L399", + "source_location": "L384", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_delete_expected_income", + "target": "backend_app_budgeting_router_py_response", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L386", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_unmatch_expected_income", + "target": "backend_app_budgeting_router_py_response", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", "weight": 1.0 }, { @@ -62975,7 +65102,7 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L619", + "source_location": "L601", "weight": 1.0 }, { @@ -62987,7 +65114,19 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L557", + "source_location": "L539", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_get_expected_income", + "target": "expectedincome", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L702", "weight": 1.0 }, { @@ -63002,6 +65141,18 @@ "source_location": "L48", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service_get_period_expected_income", + "target": "expectedincome", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L711", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service_update_category_definition", "target": "backend_app_ledger_models_category", @@ -63011,7 +65162,19 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/budgeting/service.py", - "source_location": "L636", + "source_location": "L618", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_update_expected_income", + "target": "expectedincome", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", "weight": 1.0 }, { @@ -63371,7 +65534,7 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L196", + "source_location": "L190", "weight": 1.0 }, { @@ -63395,7 +65558,7 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L288", + "source_location": "L280", "weight": 1.0 }, { @@ -63407,7 +65570,7 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L31", + "source_location": "L29", "weight": 1.0 }, { @@ -63419,7 +65582,7 @@ "confidence_score": 1.0, "context": "return_type", "source_file": "backend/app/ledger/savings.py", - "source_location": "L102", + "source_location": "L98", "weight": 1.0 }, { @@ -63518,6 +65681,18 @@ "source_location": "L27", "weight": 1.0 }, + { + "source": "backend_tests_test_private_fixtures_fail", + "target": "noreturn", + "relation": "references", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "context": "return_type", + "source_file": "backend/tests/test_private_fixtures.py", + "source_location": "L79", + "weight": 1.0 + }, { "source": "backend_alembic_env", "target": "backend_app_db_models", @@ -63839,7 +66014,7 @@ "confidence_score": 1.0, "context": "submodule_import", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L16", + "source_location": "L17", "weight": 1.0 }, { @@ -63875,7 +66050,7 @@ "confidence_score": 1.0, "context": "submodule_import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L12", + "source_location": "L14", "weight": 1.0 }, { @@ -63887,7 +66062,7 @@ "confidence_score": 1.0, "context": "submodule_import", "source_file": "backend/tests/test_import_savings.py", - "source_location": "L13", + "source_location": "L15", "weight": 1.0 }, { @@ -63899,7 +66074,7 @@ "confidence_score": 1.0, "context": "submodule_import", "source_file": "backend/tests/test_imports.py", - "source_location": "L11", + "source_location": "L13", "weight": 1.0 }, { @@ -63911,7 +66086,7 @@ "confidence_score": 1.0, "context": "submodule_import", "source_file": "backend/tests/test_imports.py", - "source_location": "L12", + "source_location": "L14", "weight": 1.0 }, { @@ -64093,7 +66268,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L128", + "source_location": "L124", "weight": 1.0 }, { @@ -64137,7 +66312,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L37", + "source_location": "L35", "weight": 1.0 }, { @@ -64148,7 +66323,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L41", + "source_location": "L39", "weight": 1.0 }, { @@ -64159,7 +66334,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L67", + "source_location": "L65", "weight": 1.0 }, { @@ -64170,7 +66345,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L71", + "source_location": "L69", "weight": 1.0 }, { @@ -64181,7 +66356,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L75", + "source_location": "L73", "weight": 1.0 }, { @@ -64346,7 +66521,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/analytics/service.py", - "source_location": "L65", + "source_location": "L62", "weight": 1.0 }, { @@ -64357,7 +66532,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/analytics/service.py", - "source_location": "L88", + "source_location": "L85", "weight": 1.0 }, { @@ -64368,7 +66543,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/analytics/service.py", - "source_location": "L97", + "source_location": "L94", "weight": 1.0 }, { @@ -64459,6 +66634,17 @@ "source_location": "L77", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_frontend_summary", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L108", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router", "target": "backend_app_budgeting_router_summary", @@ -64467,7 +66653,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L112", + "source_location": "L132", "weight": 1.0 }, { @@ -64478,29 +66664,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L120", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_category_definition_json", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L150", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_category_definitions", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L164", + "source_location": "L140", "weight": 1.0 }, { @@ -64514,6 +66678,28 @@ "source_location": "L17", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_category_definition_json", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L170", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_category_definitions", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L184", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router", "target": "backend_app_budgeting_router_categorydefinitionpatchbody", @@ -64522,7 +66708,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L182", + "source_location": "L202", "weight": 1.0 }, { @@ -64533,18 +66719,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L189", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_create_category", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L222", + "source_location": "L209", "weight": 1.0 }, { @@ -64558,6 +66733,17 @@ "source_location": "L23", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_create_category", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L242", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router", "target": "backend_app_budgeting_router_update_plan", @@ -64566,18 +66752,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L246", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_fund_category", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L262", + "source_location": "L266", "weight": 1.0 }, { @@ -64591,6 +66766,17 @@ "source_location": "L28", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_fund_category", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L282", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router", "target": "backend_app_budgeting_router_assignments", @@ -64599,7 +66785,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L284", + "source_location": "L304", "weight": 1.0 }, { @@ -64610,18 +66796,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L299", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_expected_income", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L312", + "source_location": "L319", "weight": 1.0 }, { @@ -64637,51 +66812,40 @@ }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_close", + "target": "backend_app_budgeting_router_expected_income_item", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L332", + "source_location": "L331", "weight": 1.0 }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_reopen", + "target": "backend_app_budgeting_router_expected_incomes", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L338", + "source_location": "L337", "weight": 1.0 }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_copy_previous", + "target": "backend_app_budgeting_router_create_expected_income", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L347", + "source_location": "L344", "weight": 1.0 }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_close_frontend", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/router.py", - "source_location": "L355", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_reopen_frontend", + "target": "backend_app_budgeting_router_patch_expected_income", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -64692,13 +66856,13 @@ }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_copy_frontend", + "target": "backend_app_budgeting_router_delete_expected_income", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L373", + "source_location": "L386", "weight": 1.0 }, { @@ -64712,6 +66876,116 @@ "source_location": "L39", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_match_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L402", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_unmatch_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L425", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_close", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L447", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_reopen", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L453", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_copy_previous", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L462", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_close_frontend", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L470", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_reopen_frontend", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L479", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_expectedincomepatchbody", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L48", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_copy_frontend", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L488", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router", + "target": "backend_app_budgeting_router_expectedincomematchbody", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L57", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router", "target": "backend_app_budgeting_router_period_for", @@ -64720,7 +66994,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L46", + "source_location": "L64", "weight": 1.0 }, { @@ -64731,7 +67005,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L50", + "source_location": "L68", "weight": 1.0 }, { @@ -64742,7 +67016,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L54", + "source_location": "L72", "weight": 1.0 }, { @@ -64753,7 +67027,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L58", + "source_location": "L76", "weight": 1.0 }, { @@ -64764,18 +67038,40 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L62", + "source_location": "L80", "weight": 1.0 }, { "source": "backend_app_budgeting_router", - "target": "backend_app_budgeting_router_frontend_summary", + "target": "backend_app_budgeting_router_expected_income_json", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L74", + "source_location": "L92", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_reopen_period", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L1052", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_copy_previous_month", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L1084", "weight": 1.0 }, { @@ -64841,7 +67137,40 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L498", + "source_location": "L480", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_require_open", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L532", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_get_category", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L539", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_create_category", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L546", "weight": 1.0 }, { @@ -64855,39 +67184,6 @@ "source_location": "L55", "weight": 1.0 }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_require_open", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L550", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_get_category", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L557", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_create_category", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L564", - "weight": 1.0 - }, { "source": "backend_app_budgeting_service", "target": "backend_app_budgeting_service_ensure_credit_reserve_category", @@ -64896,7 +67192,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L590", + "source_location": "L572", "weight": 1.0 }, { @@ -64907,7 +67203,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L610", + "source_location": "L592", "weight": 1.0 }, { @@ -64918,7 +67214,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L619", + "source_location": "L601", "weight": 1.0 }, { @@ -64929,7 +67225,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L636", + "source_location": "L618", "weight": 1.0 }, { @@ -64940,7 +67236,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L674", + "source_location": "L656", "weight": 1.0 }, { @@ -64954,6 +67250,50 @@ "source_location": "L69", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_get_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L702", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L711", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_ensure_expected_date_in_period", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L721", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L730", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service", "target": "backend_app_budgeting_service_add_expected_income", @@ -64962,18 +67302,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L720", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_match_expected_income", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L747", + "source_location": "L761", "weight": 1.0 }, { @@ -64989,13 +67318,13 @@ }, { "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_fund", + "target": "backend_app_budgeting_service_match_expected_income", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L788", + "source_location": "L796", "weight": 1.0 }, { @@ -65009,6 +67338,50 @@ "source_location": "L82", "weight": 1.0 }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_unmatch_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L847", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_update_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L880", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_delete_expected_income", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L927", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service", + "target": "backend_app_budgeting_service_fund", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L949", + "weight": 1.0 + }, { "source": "backend_app_budgeting_service", "target": "backend_app_budgeting_service_close_period", @@ -65017,29 +67390,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L823", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_reopen_period", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L891", - "weight": 1.0 - }, - { - "source": "backend_app_budgeting_service", - "target": "backend_app_budgeting_service_copy_previous_month", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/budgeting/service.py", - "source_location": "L923", + "source_location": "L984", "weight": 1.0 }, { @@ -67250,7 +69601,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L134", + "source_location": "L132", "weight": 1.0 }, { @@ -67261,7 +69612,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L168", + "source_location": "L166", "weight": 1.0 }, { @@ -67283,7 +69634,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L58", + "source_location": "L56", "weight": 1.0 }, { @@ -67528,17 +69879,6 @@ "source_location": "L94", "weight": 1.0 }, - { - "source": "backend_app_ledger_savings", - "target": "backend_app_ledger_savings_transfer_category_for_accounts", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/app/ledger/savings.py", - "source_location": "L102", - "weight": 1.0 - }, { "source": "backend_app_ledger_savings", "target": "backend_app_ledger_savings_adjust_balance", @@ -67547,7 +69887,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L112", + "source_location": "L108", "weight": 1.0 }, { @@ -67558,7 +69898,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L196", + "source_location": "L190", "weight": 1.0 }, { @@ -67580,7 +69920,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L288", + "source_location": "L280", "weight": 1.0 }, { @@ -67591,7 +69931,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L31", + "source_location": "L29", "weight": 1.0 }, { @@ -67602,7 +69942,18 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L39", + "source_location": "L35", + "weight": 1.0 + }, + { + "source": "backend_app_ledger_savings", + "target": "backend_app_ledger_savings_transfer_category_for_accounts", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/ledger/savings.py", + "source_location": "L98", "weight": 1.0 }, { @@ -68185,7 +70536,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L136", + "source_location": "L137", "weight": 1.0 }, { @@ -68196,7 +70547,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L151", + "source_location": "L152", "weight": 1.0 }, { @@ -68207,7 +70558,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L161", + "source_location": "L162", "weight": 1.0 }, { @@ -68218,7 +70569,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L329", + "source_location": "L330", "weight": 1.0 }, { @@ -68229,7 +70580,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L41", + "source_location": "L42", "weight": 1.0 }, { @@ -68240,7 +70591,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L479", + "source_location": "L480", "weight": 1.0 }, { @@ -68251,7 +70602,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L58", + "source_location": "L59", "weight": 1.0 }, { @@ -68262,7 +70613,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L595", + "source_location": "L607", "weight": 1.0 }, { @@ -68273,7 +70624,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L651", + "source_location": "L663", "weight": 1.0 }, { @@ -68284,7 +70635,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L721", + "source_location": "L733", "weight": 1.0 }, { @@ -68295,7 +70646,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L740", + "source_location": "L752", "weight": 1.0 }, { @@ -68306,7 +70657,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L76", + "source_location": "L77", "weight": 1.0 }, { @@ -68317,7 +70668,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L773", + "source_location": "L785", "weight": 1.0 }, { @@ -68328,7 +70679,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L886", + "source_location": "L898", "weight": 1.0 }, { @@ -68339,7 +70690,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L890", + "source_location": "L902", "weight": 1.0 }, { @@ -68372,7 +70723,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_budget.py", - "source_location": "L109", + "source_location": "L115", "weight": 1.0 }, { @@ -68383,7 +70734,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_budget.py", - "source_location": "L138", + "source_location": "L144", "weight": 1.0 }, { @@ -68394,7 +70745,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_budget.py", - "source_location": "L147", + "source_location": "L153", "weight": 1.0 }, { @@ -68617,6 +70968,72 @@ "source_location": "L74", "weight": 1.0 }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L104", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L202", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_seed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L23", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_login", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L230", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_test_expected_income_month_api_crud_and_summary", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "backend_tests_test_expected_income", + "target": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L30", + "weight": 1.0 + }, { "source": "backend_tests_test_import_holds", "target": "backend_tests_test_import_holds_hold_document", @@ -69010,7 +71427,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L112", + "source_location": "L114", "weight": 1.0 }, { @@ -69021,7 +71438,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L119", + "source_location": "L121", "weight": 1.0 }, { @@ -69032,7 +71449,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L154", + "source_location": "L157", "weight": 1.0 }, { @@ -69043,7 +71460,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L173", + "source_location": "L174", "weight": 1.0 }, { @@ -69054,7 +71471,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L193", + "source_location": "L194", "weight": 1.0 }, { @@ -69065,7 +71482,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L211", + "source_location": "L212", "weight": 1.0 }, { @@ -69076,7 +71493,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L234", + "source_location": "L235", "weight": 1.0 }, { @@ -69087,7 +71504,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L251", + "source_location": "L253", "weight": 1.0 }, { @@ -69098,7 +71515,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L302", + "source_location": "L304", "weight": 1.0 }, { @@ -69109,7 +71526,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L314", + "source_location": "L316", "weight": 1.0 }, { @@ -69120,7 +71537,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L33", + "source_location": "L35", "weight": 1.0 }, { @@ -69131,7 +71548,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L378", + "source_location": "L380", "weight": 1.0 }, { @@ -69142,7 +71559,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L49", + "source_location": "L51", "weight": 1.0 }, { @@ -69153,7 +71570,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L75", + "source_location": "L77", "weight": 1.0 }, { @@ -69164,7 +71581,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L120", + "source_location": "L122", "weight": 1.0 }, { @@ -69175,7 +71592,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L135", + "source_location": "L139", "weight": 1.0 }, { @@ -69186,7 +71603,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L143", + "source_location": "L147", "weight": 1.0 }, { @@ -69197,7 +71614,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L151", + "source_location": "L155", "weight": 1.0 }, { @@ -69208,7 +71625,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L173", + "source_location": "L177", "weight": 1.0 }, { @@ -69219,18 +71636,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L205", - "weight": 1.0 - }, - { - "source": "backend_tests_test_imports", - "target": "backend_tests_test_imports_seed", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/tests/test_imports.py", - "source_location": "L26", + "source_location": "L209", "weight": 1.0 }, { @@ -69241,7 +71647,18 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L261", + "source_location": "L265", + "weight": 1.0 + }, + { + "source": "backend_tests_test_imports", + "target": "backend_tests_test_imports_seed", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_imports.py", + "source_location": "L28", "weight": 1.0 }, { @@ -69252,7 +71669,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L294", + "source_location": "L298", "weight": 1.0 }, { @@ -69263,7 +71680,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L368", + "source_location": "L372", "weight": 1.0 }, { @@ -69274,7 +71691,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L412", + "source_location": "L416", "weight": 1.0 }, { @@ -69285,7 +71702,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L42", + "source_location": "L44", "weight": 1.0 }, { @@ -69296,7 +71713,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L457", + "source_location": "L461", "weight": 1.0 }, { @@ -69307,7 +71724,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L492", + "source_location": "L498", "weight": 1.0 }, { @@ -69318,7 +71735,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L512", + "source_location": "L518", "weight": 1.0 }, { @@ -69329,7 +71746,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L81", + "source_location": "L83", "weight": 1.0 }, { @@ -69340,7 +71757,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_imports.py", - "source_location": "L96", + "source_location": "L98", "weight": 1.0 }, { @@ -69428,7 +71845,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L114", + "source_location": "L115", "weight": 1.0 }, { @@ -69439,7 +71856,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L124", + "source_location": "L125", "weight": 1.0 }, { @@ -69450,7 +71867,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L144", + "source_location": "L145", "weight": 1.0 }, { @@ -69461,7 +71878,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L155", + "source_location": "L156", "weight": 1.0 }, { @@ -69472,7 +71889,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L161", + "source_location": "L162", "weight": 1.0 }, { @@ -69483,7 +71900,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L180", + "source_location": "L181", "weight": 1.0 }, { @@ -69494,7 +71911,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L194", + "source_location": "L195", "weight": 1.0 }, { @@ -69505,7 +71922,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L214", + "source_location": "L215", "weight": 1.0 }, { @@ -69516,7 +71933,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -69527,7 +71944,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L74", + "source_location": "L75", "weight": 1.0 }, { @@ -69538,7 +71955,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L78", + "source_location": "L79", "weight": 1.0 }, { @@ -69549,7 +71966,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L86", + "source_location": "L87", "weight": 1.0 }, { @@ -69560,7 +71977,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L104", + "source_location": "L102", "weight": 1.0 }, { @@ -69571,7 +71988,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L146", + "source_location": "L144", "weight": 1.0 }, { @@ -69582,7 +71999,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L170", + "source_location": "L168", "weight": 1.0 }, { @@ -69637,7 +72054,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L67", + "source_location": "L65", "weight": 1.0 }, { @@ -69648,7 +72065,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_review_queue_batch.py", - "source_location": "L73", + "source_location": "L71", "weight": 1.0 }, { @@ -69659,7 +72076,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L108", + "source_location": "L107", "weight": 1.0 }, { @@ -69670,7 +72087,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L125", + "source_location": "L124", "weight": 1.0 }, { @@ -69681,7 +72098,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L149", + "source_location": "L148", "weight": 1.0 }, { @@ -69692,7 +72109,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L188", + "source_location": "L187", "weight": 1.0 }, { @@ -69703,7 +72120,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L205", + "source_location": "L204", "weight": 1.0 }, { @@ -69714,7 +72131,18 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L253", + "source_location": "L250", + "weight": 1.0 + }, + { + "source": "backend_tests_test_savings", + "target": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/tests/test_savings.py", + "source_location": "L315", "weight": 1.0 }, { @@ -69728,17 +72156,6 @@ "source_location": "L32", "weight": 1.0 }, - { - "source": "backend_tests_test_savings", - "target": "backend_tests_test_savings_test_convert_rejects_expense_with_confirmed_refund", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/tests/test_savings.py", - "source_location": "L324", - "weight": 1.0 - }, { "source": "backend_tests_test_savings", "target": "backend_tests_test_savings_test_convert_rejects_closed_period_and_cross_space_operation", @@ -69747,7 +72164,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L350", + "source_location": "L339", "weight": 1.0 }, { @@ -69758,7 +72175,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L379", + "source_location": "L364", "weight": 1.0 }, { @@ -69769,7 +72186,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L399", + "source_location": "L384", "weight": 1.0 }, { @@ -69780,7 +72197,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L425", + "source_location": "L410", "weight": 1.0 }, { @@ -69791,7 +72208,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L468", + "source_location": "L453", "weight": 1.0 }, { @@ -69802,7 +72219,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_savings.py", - "source_location": "L481", + "source_location": "L466", "weight": 1.0 }, { @@ -69871,17 +72288,6 @@ "source_location": "L2", "weight": 1.0 }, - { - "source": "frontend_package", - "target": "frontend_package_devdependencies", - "relation": "contains", - "_origin": "ast", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "frontend/package.json", - "source_location": "L29", - "weight": 1.0 - }, { "source": "frontend_package", "target": "frontend_package_private", @@ -69893,6 +72299,17 @@ "source_location": "L3", "weight": 1.0 }, + { + "source": "frontend_package", + "target": "frontend_package_devdependencies", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "frontend/package.json", + "source_location": "L30", + "weight": 1.0 + }, { "source": "frontend_package", "target": "frontend_package_version", @@ -69950,7 +72367,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_hookform_resolvers", + "target": "frontend_package_dependencies_fontsource_onest", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -69961,7 +72378,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_tanstack_react_query", + "target": "frontend_package_dependencies_hookform_resolvers", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -69972,7 +72389,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_i18next", + "target": "frontend_package_dependencies_tanstack_react_query", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -69983,7 +72400,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_react", + "target": "frontend_package_dependencies_i18next", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -69994,7 +72411,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_react_dom", + "target": "frontend_package_dependencies_react", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -70005,7 +72422,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_react_hook_form", + "target": "frontend_package_dependencies_react_dom", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -70016,7 +72433,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_react_i18next", + "target": "frontend_package_dependencies_react_hook_form", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -70027,7 +72444,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_react_router_dom", + "target": "frontend_package_dependencies_react_i18next", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -70038,7 +72455,7 @@ }, { "source": "frontend_package_dependencies", - "target": "frontend_package_dependencies_zod", + "target": "frontend_package_dependencies_react_router_dom", "relation": "contains", "_origin": "ast", "confidence": "EXTRACTED", @@ -70047,6 +72464,17 @@ "source_location": "L27", "weight": 1.0 }, + { + "source": "frontend_package_dependencies", + "target": "frontend_package_dependencies_zod", + "relation": "contains", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "frontend/package.json", + "source_location": "L28", + "weight": 1.0 + }, { "source": "frontend_package_devdependencies", "target": "frontend_package_devdependencies_eslint_js", @@ -70055,7 +72483,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L30", + "source_location": "L31", "weight": 1.0 }, { @@ -70066,7 +72494,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L31", + "source_location": "L32", "weight": 1.0 }, { @@ -70077,7 +72505,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L32", + "source_location": "L33", "weight": 1.0 }, { @@ -70088,7 +72516,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L33", + "source_location": "L34", "weight": 1.0 }, { @@ -70099,7 +72527,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L34", + "source_location": "L35", "weight": 1.0 }, { @@ -70110,7 +72538,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L35", + "source_location": "L36", "weight": 1.0 }, { @@ -70121,7 +72549,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L36", + "source_location": "L37", "weight": 1.0 }, { @@ -70132,7 +72560,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L37", + "source_location": "L38", "weight": 1.0 }, { @@ -70143,7 +72571,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L38", + "source_location": "L39", "weight": 1.0 }, { @@ -70154,7 +72582,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L39", + "source_location": "L40", "weight": 1.0 }, { @@ -70165,7 +72593,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L40", + "source_location": "L41", "weight": 1.0 }, { @@ -70176,7 +72604,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L41", + "source_location": "L42", "weight": 1.0 }, { @@ -70187,7 +72615,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L42", + "source_location": "L43", "weight": 1.0 }, { @@ -70198,7 +72626,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L43", + "source_location": "L44", "weight": 1.0 }, { @@ -70209,7 +72637,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L44", + "source_location": "L45", "weight": 1.0 }, { @@ -70220,7 +72648,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L45", + "source_location": "L46", "weight": 1.0 }, { @@ -70231,7 +72659,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L46", + "source_location": "L47", "weight": 1.0 }, { @@ -70242,7 +72670,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "frontend/package.json", - "source_location": "L47", + "source_location": "L48", "weight": 1.0 }, { @@ -75756,7 +78184,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L182", + "source_location": "L202", "weight": 1.0 }, { @@ -75767,7 +78195,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L58", + "source_location": "L76", "weight": 1.0 }, { @@ -75781,6 +78209,28 @@ "source_location": "L39", "weight": 1.0 }, + { + "source": "backend_app_budgeting_router_expectedincomematchbody", + "target": "backend_app_budgeting_router_py_basemodel", + "relation": "inherits", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L57", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_router_expectedincomepatchbody", + "target": "backend_app_budgeting_router_py_basemodel", + "relation": "inherits", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/router.py", + "source_location": "L48", + "weight": 1.0 + }, { "source": "backend_app_budgeting_router_fundingbody", "target": "backend_app_budgeting_router_py_basemodel", @@ -75800,7 +78250,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L50", + "source_location": "L68", "weight": 1.0 }, { @@ -75811,7 +78261,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/router.py", - "source_location": "L54", + "source_location": "L72", "weight": 1.0 }, { @@ -76658,7 +79108,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L168", + "source_location": "L166", "weight": 1.0 }, { @@ -76669,7 +79119,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L168", + "source_location": "L166", "weight": 1.0 }, { @@ -76680,7 +79130,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L168", + "source_location": "L166", "weight": 1.0 }, { @@ -76691,7 +79141,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L58", + "source_location": "L56", "weight": 1.0 }, { @@ -76702,7 +79152,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L58", + "source_location": "L56", "weight": 1.0 }, { @@ -76713,7 +79163,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L58", + "source_location": "L56", "weight": 1.0 }, { @@ -76724,7 +79174,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L134", + "source_location": "L132", "weight": 1.0 }, { @@ -76735,7 +79185,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L134", + "source_location": "L132", "weight": 1.0 }, { @@ -76746,7 +79196,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L134", + "source_location": "L132", "weight": 1.0 }, { @@ -77329,7 +79779,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L330", + "source_location": "L331", "weight": 1.0 }, { @@ -77340,7 +79790,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L334", + "source_location": "L335", "weight": 1.0 }, { @@ -77351,7 +79801,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L337", + "source_location": "L338", "weight": 1.0 }, { @@ -77362,7 +79812,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L341", + "source_location": "L342", "weight": 1.0 }, { @@ -77373,7 +79823,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L359", + "source_location": "L360", "weight": 1.0 }, { @@ -77384,7 +79834,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L366", + "source_location": "L367", "weight": 1.0 }, { @@ -77395,7 +79845,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L387", + "source_location": "L388", "weight": 1.0 }, { @@ -77406,7 +79856,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L406", + "source_location": "L407", "weight": 1.0 }, { @@ -77417,7 +79867,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L416", + "source_location": "L417", "weight": 1.0 }, { @@ -77428,7 +79878,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L426", + "source_location": "L427", "weight": 1.0 }, { @@ -77439,7 +79889,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L431", + "source_location": "L432", "weight": 1.0 }, { @@ -77450,7 +79900,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L434", + "source_location": "L435", "weight": 1.0 }, { @@ -77461,7 +79911,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L441", + "source_location": "L442", "weight": 1.0 }, { @@ -77472,7 +79922,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L452", + "source_location": "L453", "weight": 1.0 }, { @@ -77483,7 +79933,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L459", + "source_location": "L460", "weight": 1.0 }, { @@ -77494,7 +79944,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L466", + "source_location": "L467", "weight": 1.0 }, { @@ -77505,7 +79955,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L472", + "source_location": "L473", "weight": 1.0 }, { @@ -77516,7 +79966,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L490", + "source_location": "L491", "weight": 1.0 }, { @@ -77527,7 +79977,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L505", + "source_location": "L506", "weight": 1.0 }, { @@ -77538,7 +79988,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L510", + "source_location": "L511", "weight": 1.0 }, { @@ -77549,7 +79999,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L517", + "source_location": "L518", "weight": 1.0 }, { @@ -77560,7 +80010,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L522", + "source_location": "L523", "weight": 1.0 }, { @@ -77571,7 +80021,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L528", + "source_location": "L529", "weight": 1.0 }, { @@ -77582,7 +80032,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L534", + "source_location": "L535", "weight": 1.0 }, { @@ -77593,7 +80043,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L540", + "source_location": "L541", "weight": 1.0 }, { @@ -77604,7 +80054,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L546", + "source_location": "L547", "weight": 1.0 }, { @@ -77615,7 +80065,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L571", + "source_location": "L583", "weight": 1.0 }, { @@ -77626,7 +80076,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L589", + "source_location": "L601", "weight": 1.0 }, { @@ -77637,7 +80087,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L103", + "source_location": "L104", "weight": 1.0 }, { @@ -77648,7 +80098,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L110", + "source_location": "L111", "weight": 1.0 }, { @@ -77659,7 +80109,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L118", + "source_location": "L119", "weight": 1.0 }, { @@ -77670,7 +80120,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L126", + "source_location": "L127", "weight": 1.0 }, { @@ -77681,7 +80131,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L130", + "source_location": "L131", "weight": 1.0 }, { @@ -77692,7 +80142,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L77", + "source_location": "L78", "weight": 1.0 }, { @@ -77703,7 +80153,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L80", + "source_location": "L81", "weight": 1.0 }, { @@ -77714,7 +80164,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L84", + "source_location": "L85", "weight": 1.0 }, { @@ -77725,7 +80175,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L88", + "source_location": "L89", "weight": 1.0 }, { @@ -77736,7 +80186,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L94", + "source_location": "L95", "weight": 1.0 }, { @@ -77747,7 +80197,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L137", + "source_location": "L138", "weight": 1.0 }, { @@ -77758,7 +80208,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L144", + "source_location": "L145", "weight": 1.0 }, { @@ -77769,7 +80219,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L652", + "source_location": "L664", "weight": 1.0 }, { @@ -77780,7 +80230,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L656", + "source_location": "L668", "weight": 1.0 }, { @@ -77791,7 +80241,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L670", + "source_location": "L682", "weight": 1.0 }, { @@ -77802,7 +80252,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L682", + "source_location": "L694", "weight": 1.0 }, { @@ -77813,7 +80263,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L688", + "source_location": "L700", "weight": 1.0 }, { @@ -77824,7 +80274,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L694", + "source_location": "L706", "weight": 1.0 }, { @@ -77835,7 +80285,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L699", + "source_location": "L711", "weight": 1.0 }, { @@ -77846,7 +80296,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L705", + "source_location": "L717", "weight": 1.0 }, { @@ -77857,7 +80307,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L712", + "source_location": "L724", "weight": 1.0 }, { @@ -77868,7 +80318,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L774", + "source_location": "L786", "weight": 1.0 }, { @@ -77879,7 +80329,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L777", + "source_location": "L789", "weight": 1.0 }, { @@ -77890,7 +80340,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L784", + "source_location": "L796", "weight": 1.0 }, { @@ -77901,7 +80351,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L794", + "source_location": "L806", "weight": 1.0 }, { @@ -77912,7 +80362,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L810", + "source_location": "L822", "weight": 1.0 }, { @@ -77923,7 +80373,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L827", + "source_location": "L839", "weight": 1.0 }, { @@ -77934,7 +80384,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L834", + "source_location": "L846", "weight": 1.0 }, { @@ -77945,7 +80395,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L839", + "source_location": "L851", "weight": 1.0 }, { @@ -77956,7 +80406,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L848", + "source_location": "L860", "weight": 1.0 }, { @@ -77967,7 +80417,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L858", + "source_location": "L870", "weight": 1.0 }, { @@ -77978,7 +80428,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L864", + "source_location": "L876", "weight": 1.0 }, { @@ -77989,7 +80439,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L870", + "source_location": "L882", "weight": 1.0 }, { @@ -78000,7 +80450,7 @@ "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L877", + "source_location": "L889", "weight": 1.0 }, { @@ -78026,14 +80476,14 @@ "weight": 1.0 }, { - "source": "backend_alembic_versions_20260922_0003_savings_system_rationale_42", + "source": "backend_alembic_versions_20260922_0003_savings_system_rationale_40", "target": "backend_alembic_versions_20260922_0003_savings_system_replace_check_constraint", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L42", + "source_location": "L40", "weight": 1.0 }, { @@ -78103,14 +80553,47 @@ "weight": 1.0 }, { - "source": "backend_app_budgeting_service_rationale_645", + "source": "backend_app_budgeting_service_rationale_627", "target": "backend_app_budgeting_service_update_category_definition", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/budgeting/service.py", - "source_location": "L645", + "source_location": "L627", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_rationale_714", + "target": "backend_app_budgeting_service_get_period_expected_income", + "relation": "rationale_for", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L714", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_rationale_733", + "target": "backend_app_budgeting_service_expected_income_items", + "relation": "rationale_for", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L733", + "weight": 1.0 + }, + { + "source": "backend_app_budgeting_service_rationale_889", + "target": "backend_app_budgeting_service_update_expected_income", + "relation": "rationale_for", + "_origin": "ast", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/app/budgeting/service.py", + "source_location": "L889", "weight": 1.0 }, { @@ -78532,25 +81015,25 @@ "weight": 1.0 }, { - "source": "backend_app_ledger_models_rationale_135", + "source": "backend_app_ledger_models_rationale_133", "target": "backend_app_ledger_models_posting", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L135", + "source_location": "L133", "weight": 1.0 }, { - "source": "backend_app_ledger_models_rationale_169", + "source": "backend_app_ledger_models_rationale_167", "target": "backend_app_ledger_models_category", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L169", + "source_location": "L167", "weight": 1.0 }, { @@ -78565,14 +81048,14 @@ "weight": 1.0 }, { - "source": "backend_app_ledger_models_rationale_59", + "source": "backend_app_ledger_models_rationale_57", "target": "backend_app_ledger_models_operation", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/models.py", - "source_location": "L59", + "source_location": "L57", "weight": 1.0 }, { @@ -78587,58 +81070,58 @@ "weight": 1.0 }, { - "source": "backend_app_ledger_savings_rationale_105", + "source": "backend_app_ledger_savings_rationale_101", "target": "backend_app_ledger_savings_transfer_category_for_accounts", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L105", + "source_location": "L101", "weight": 1.0 }, { - "source": "backend_app_ledger_savings_rationale_122", + "source": "backend_app_ledger_savings_rationale_118", "target": "backend_app_ledger_savings_adjust_balance", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L122", + "source_location": "L118", "weight": 1.0 }, { - "source": "backend_app_ledger_savings_rationale_199", + "source": "backend_app_ledger_savings_rationale_193", "target": "backend_app_ledger_savings_convert_expense_to_savings", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L199", + "source_location": "L193", "weight": 1.0 }, { - "source": "backend_app_ledger_savings_rationale_291", + "source": "backend_app_ledger_savings_rationale_283", "target": "backend_app_ledger_savings_revert_savings_conversion", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L291", + "source_location": "L283", "weight": 1.0 }, { - "source": "backend_app_ledger_savings_rationale_40", + "source": "backend_app_ledger_savings_rationale_36", "target": "backend_app_ledger_savings_ensure_savings_resources", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/app/ledger/savings.py", - "source_location": "L40", + "source_location": "L36", "weight": 1.0 }, { @@ -78708,25 +81191,25 @@ "weight": 1.0 }, { - "source": "backend_tests_test_adapter_contracts_rationale_480", + "source": "backend_tests_test_adapter_contracts_rationale_481", "target": "backend_tests_test_adapter_contracts_testalfasavingsrule", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L480", + "source_location": "L481", "weight": 1.0 }, { - "source": "backend_tests_test_adapter_contracts_rationale_891", + "source": "backend_tests_test_adapter_contracts_rationale_903", "target": "backend_tests_test_adapter_contracts_minimal_pdf", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L891", + "source_location": "L903", "weight": 1.0 }, { @@ -78785,14 +81268,14 @@ "weight": 1.0 }, { - "source": "backend_tests_test_private_fixtures_rationale_35", + "source": "backend_tests_test_private_fixtures_rationale_36", "target": "backend_tests_test_private_fixtures_load_entries", "relation": "rationale_for", "_origin": "ast", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "backend/tests/test_private_fixtures.py", - "source_location": "L35", + "source_location": "L36", "weight": 1.0 }, { @@ -78875,7 +81358,7 @@ "confidence_score": 0.85, "context": "call", "source_file": "backend/alembic/versions/20260922_0003_savings_system.py", - "source_location": "L118", + "source_location": "L114", "weight": 1.0 }, { @@ -78899,7 +81382,7 @@ "confidence_score": 0.85, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L153", + "source_location": "L154", "weight": 1.0 }, { @@ -78911,7 +81394,7 @@ "confidence_score": 0.85, "context": "call", "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L120", + "source_location": "L121", "weight": 1.0 }, { @@ -79144,7 +81627,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L331", + "source_location": "L332", "weight": 0.8 }, { @@ -79155,51 +81638,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L572", - "weight": 0.8 - }, - { - "source": "backend_tests_test_adapter_contracts_testbasecontract", - "target": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter", - "relation": "uses", - "_origin": "ast", - "confidence": "INFERRED", - "confidence_score": 0.95, - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L100", - "weight": 0.8 - }, - { - "source": "backend_tests_test_adapter_contracts_testbasecontract", - "target": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter", - "relation": "uses", - "_origin": "ast", - "confidence": "INFERRED", - "confidence_score": 0.95, - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L101", - "weight": 0.8 - }, - { - "source": "backend_tests_test_adapter_contracts_testbasecontract", - "target": "backend_app_imports_adapters_alfa_xlsx_alfacreditxlsxadapter", - "relation": "uses", - "_origin": "ast", - "confidence": "INFERRED", - "confidence_score": 0.95, - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L111", - "weight": 0.8 - }, - { - "source": "backend_tests_test_adapter_contracts_testbasecontract", - "target": "backend_app_imports_adapters_ozon_pdf_ozoncreditpdfadapter", - "relation": "uses", - "_origin": "ast", - "confidence": "INFERRED", - "confidence_score": 0.95, - "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L112", + "source_location": "L584", "weight": 0.8 }, { @@ -79210,7 +81649,51 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L99", + "source_location": "L100", + "weight": 0.8 + }, + { + "source": "backend_tests_test_adapter_contracts_testbasecontract", + "target": "backend_app_imports_adapters_ozon_pdf_ozondebitpdfadapter", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L101", + "weight": 0.8 + }, + { + "source": "backend_tests_test_adapter_contracts_testbasecontract", + "target": "backend_app_imports_adapters_rocketbank_pdf_rocketbankdebitpdfadapter", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L102", + "weight": 0.8 + }, + { + "source": "backend_tests_test_adapter_contracts_testbasecontract", + "target": "backend_app_imports_adapters_alfa_xlsx_alfacreditxlsxadapter", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L112", + "weight": 0.8 + }, + { + "source": "backend_tests_test_adapter_contracts_testbasecontract", + "target": "backend_app_imports_adapters_ozon_pdf_ozoncreditpdfadapter", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_adapter_contracts.py", + "source_location": "L113", "weight": 0.8 }, { @@ -79221,7 +81704,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L653", + "source_location": "L665", "weight": 0.8 }, { @@ -79232,7 +81715,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L716", + "source_location": "L728", "weight": 0.8 }, { @@ -79243,7 +81726,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L775", + "source_location": "L787", "weight": 0.8 }, { @@ -79254,7 +81737,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_adapter_contracts.py", - "source_location": "L881", + "source_location": "L893", "weight": 0.8 }, { @@ -79298,7 +81781,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_budget.py", - "source_location": "L102", + "source_location": "L108", "weight": 0.8 }, { @@ -79309,7 +81792,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_budget.py", - "source_location": "L151", + "source_location": "L157", "weight": 0.8 }, { @@ -79323,6 +81806,39 @@ "source_location": "L51", "weight": 0.8 }, + { + "source": "backend_tests_test_expected_income_test_expected_income_crud_and_validation", + "target": "backend_app_errors_apperror", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L33", + "weight": 0.8 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_match_unmatch_and_delete_cascade", + "target": "backend_app_errors_apperror", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L132", + "weight": 0.8 + }, + { + "source": "backend_tests_test_expected_income_test_expected_income_mutations_guard_closed_period", + "target": "backend_app_errors_apperror", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_expected_income.py", + "source_location": "L215", + "weight": 0.8 + }, { "source": "backend_tests_test_import_holds_test_hold_cannot_be_resolved_before_document_confirmation", "target": "backend_app_errors_apperror", @@ -79397,7 +81913,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L384", + "source_location": "L387", "weight": 0.8 }, { @@ -79408,7 +81924,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L221", + "source_location": "L222", "weight": 0.8 }, { @@ -79419,7 +81935,18 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L239", + "source_location": "L241", + "weight": 0.8 + }, + { + "source": "backend_tests_test_import_savings_test_unresolved_hold_counts_and_month_filter", + "target": "backend_app_dependencies_requestcontext", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_import_savings.py", + "source_location": "L365", "weight": 0.8 }, { @@ -79430,7 +81957,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_import_savings.py", - "source_location": "L373", + "source_location": "L375", "weight": 0.8 }, { @@ -79441,7 +81968,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_imports.py", - "source_location": "L138", + "source_location": "L142", "weight": 0.8 }, { @@ -79452,7 +81979,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_imports.py", - "source_location": "L506", + "source_location": "L512", "weight": 0.8 }, { @@ -79463,7 +81990,18 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_imports.py", - "source_location": "L146", + "source_location": "L150", + "weight": 0.8 + }, + { + "source": "backend_tests_test_imports_test_import_detail_exposes_pending_candidate_and_blocker", + "target": "backend_app_dependencies_requestcontext", + "relation": "uses", + "_origin": "ast", + "confidence": "INFERRED", + "confidence_score": 0.95, + "source_file": "backend/tests/test_imports.py", + "source_location": "L475", "weight": 0.8 }, { @@ -79496,7 +82034,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L101", + "source_location": "L100", "weight": 0.8 }, { @@ -79507,7 +82045,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L192", + "source_location": "L191", "weight": 0.8 }, { @@ -79518,7 +82056,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L136", + "source_location": "L135", "weight": 0.8 }, { @@ -79529,7 +82067,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L153", + "source_location": "L152", "weight": 0.8 }, { @@ -79540,7 +82078,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L367", + "source_location": "L356", "weight": 0.8 }, { @@ -79551,7 +82089,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L343", + "source_location": "L334", "weight": 0.8 }, { @@ -79562,7 +82100,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L265", + "source_location": "L262", "weight": 0.8 }, { @@ -79573,7 +82111,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L391", + "source_location": "L376", "weight": 0.8 }, { @@ -79584,7 +82122,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L473", + "source_location": "L458", "weight": 0.8 }, { @@ -79595,7 +82133,7 @@ "confidence": "INFERRED", "confidence_score": 0.95, "source_file": "backend/tests/test_savings.py", - "source_location": "L402", + "source_location": "L387", "weight": 0.8 }, { @@ -80648,5 +83186,5 @@ "source_file": "docs/adr/0003-versioned-statement-imports.md" } ], - "built_at_commit": "63d065011b91bc99763427a81d613d7ce3f5428d" + "built_at_commit": "970fe9dacff90afec8f7e805a0bbb28401547ecc" } \ No newline at end of file diff --git a/graphify-out/2026-09-23/manifest.json b/graphify-out/2026-09-23/manifest.json index a136907..f14d85b 100644 --- a/graphify-out/2026-09-23/manifest.json +++ b/graphify-out/2026-09-23/manifest.json @@ -30,9 +30,9 @@ "semantic_hash": "" }, "backend/app/analytics/service.py": { - "mtime": 1790061159.3943744, - "seen": 1790096479.536424, - "ast_hash": "58ac24a62b4cf8a986527f79d456127d", + "mtime": 1790158886.5589485, + "seen": 1790164233.4191206, + "ast_hash": "3d87f3a80dc16a7781b5b802a0a66039", "semantic_hash": "" }, "backend/app/audit/__init__.py": { @@ -66,15 +66,15 @@ "semantic_hash": "039081cab3d91704e8f8a7152a981304" }, "backend/app/budgeting/router.py": { - "mtime": 1790140570.7235522, - "seen": 1790140596.4645138, - "ast_hash": "5c8ea9e79dbe5450c2891c40931f0f4d", + "mtime": 1790164219.7100794, + "seen": 1790164233.4191263, + "ast_hash": "e4c01ff67e84d606da20520c634aada1", "semantic_hash": "" }, "backend/app/budgeting/service.py": { - "mtime": 1790139967.779716, - "seen": 1790140596.4645145, - "ast_hash": "8b936c8c80b35123143fcc6bed627172", + "mtime": 1790164039.9056563, + "seen": 1790164233.4191272, + "ast_hash": "9856f61057a9ddc569b2d8ae5d78f688", "semantic_hash": "" }, "backend/app/categorization/__init__.py": { @@ -222,9 +222,9 @@ "semantic_hash": "" }, "backend/app/imports/adapters/ozon_pdf.py": { - "mtime": 1789733868.836172, - "seen": 1789735433.158129, - "ast_hash": "dfa6dc9ccf2c655e6c2eeaceea0cf06a", + "mtime": 1790163956.5875351, + "seen": 1790164233.4191487, + "ast_hash": "a0aa31d71ab7a45a479178cd630d8b05", "semantic_hash": "" }, "backend/app/imports/adapters/rocketbank_pdf.py": { @@ -288,15 +288,15 @@ "semantic_hash": "d41d8cd98f00b204e9800998ecf8427e" }, "backend/app/ledger/models.py": { - "mtime": 1790060833.8770478, - "seen": 1790096479.5364609, - "ast_hash": "86891c404082d8d2c84214f31d8616ff", + "mtime": 1790158886.5589485, + "seen": 1790164233.4191582, + "ast_hash": "38e4db3531f1672e57e86ec36d7b1ed7", "semantic_hash": "" }, "backend/app/ledger/router.py": { - "mtime": 1790155278.0175776, - "seen": 1790155776.860304, - "ast_hash": "24b2565478f257f38561fabff646130a", + "mtime": 1790158886.5589485, + "seen": 1790164233.419159, + "ast_hash": "37c07d8487d317af02a3762099bce24b", "semantic_hash": "" }, "backend/app/ledger/service.py": { @@ -372,15 +372,15 @@ "semantic_hash": "bfec0778131788a91a0bc5c9ec2ad8ba" }, "backend/tests/test_budget.py": { - "mtime": 1790141279.1849978, - "seen": 1790141340.361456, - "ast_hash": "81578f618d0758c7f9e2f00c921f2594", + "mtime": 1790164269.4717507, + "seen": 1790164324.1326215, + "ast_hash": "6d01ee3dd3fdc66f65ba85ba6a3909fc", "semantic_hash": "" }, "backend/tests/test_imports.py": { - "mtime": 1790140440.029933, - "seen": 1790140596.4645612, - "ast_hash": "9e568b07fa4d77eb55c36ef748fb0f9b", + "mtime": 1790164055.474866, + "seen": 1790164233.4191756, + "ast_hash": "580d49a52a4cfc72ce23b21cc983f833", "semantic_hash": "" }, "backend/tests/test_ledger_properties.py": { @@ -402,9 +402,9 @@ "semantic_hash": "ed54799a921d10394f826893acb46876" }, "frontend/package.json": { - "mtime": 1790055350.366911, - "seen": 1790096479.5364823, - "ast_hash": "172e2880b6084c1fc423ea759b99280a", + "mtime": 1790164273.1148, + "seen": 1790164324.1326368, + "ast_hash": "6e94a9e65d8bbac0083b73acea30af23", "semantic_hash": "" }, "frontend/scripts/generate-api.mjs": { @@ -672,9 +672,9 @@ "semantic_hash": "53e014a77ff3070820a83458af08a5fd" }, "frontend/src/pages/OperationsPage.tsx": { - "mtime": 1790155897.8159056, - "seen": 1790156681.728144, - "ast_hash": "5fd3db4e96df49497a42d9040b02ff58", + "mtime": 1790157347.0632977, + "seen": 1790157380.8711965, + "ast_hash": "79e817d97de60b1c3aa88a69312089c4", "semantic_hash": "" }, "frontend/src/pages/ResetPasswordPage.tsx": { @@ -888,9 +888,9 @@ "semantic_hash": "" }, "backend/tests/test_adapter_contracts.py": { - "mtime": 1790061478.1675427, - "seen": 1790096479.5364716, - "ast_hash": "9d446a10c953a14c8d4962eff50f5b97", + "mtime": 1790164118.1117096, + "seen": 1790164233.419169, + "ast_hash": "a9bc17e60e6795f552aba5dee534c9ba", "semantic_hash": "" }, "backend/tests/test_import_holds.py": { @@ -900,9 +900,9 @@ "semantic_hash": "" }, "backend/tests/test_private_fixtures.py": { - "mtime": 1789737822.4871244, - "seen": 1789737916.7915628, - "ast_hash": "f14cd118f1e8d6b5088536d50d2b965a", + "mtime": 1790164067.7670314, + "seen": 1790164233.419178, + "ast_hash": "268632b4cd05c2538fac5f22b28480ba", "semantic_hash": "" }, ".gitea/workflows/ci.yml": { @@ -948,15 +948,15 @@ "semantic_hash": "" }, "backend/alembic/versions/20260922_0003_savings_system.py": { - "mtime": 1790078031.6120079, - "seen": 1790096479.536419, - "ast_hash": "12acc1a6c82583b06da88974500498a7", + "mtime": 1790158886.5589485, + "seen": 1790164233.4191144, + "ast_hash": "94f0fec8f2edfdefd3d00ece470867c2", "semantic_hash": "" }, "backend/app/ledger/savings.py": { - "mtime": 1790097195.1310222, - "seen": 1790129548.0529978, - "ast_hash": "5367de3a6184c6df07170721a6a0fcf8", + "mtime": 1790158886.5589485, + "seen": 1790164233.4191597, + "ast_hash": "8b17828223421e8062069382024a7ae3", "semantic_hash": "" }, "backend/tests/test_budget_savings.py": { @@ -972,15 +972,15 @@ "semantic_hash": "" }, "backend/tests/test_import_savings.py": { - "mtime": 1790129378.2103765, - "seen": 1790129548.0530114, - "ast_hash": "7bf7f4500852520a2a975a452911af1c", + "mtime": 1790164033.0365639, + "seen": 1790164233.419175, + "ast_hash": "aee4dbfbada3e53720c7c5dd64014c26", "semantic_hash": "" }, "backend/tests/test_savings.py": { - "mtime": 1790097195.1310337, - "seen": 1790129548.053015, - "ast_hash": "c5eb8af5219e2f5cc153d09c0c4a37a1", + "mtime": 1790164079.4361887, + "seen": 1790164233.4191797, + "ast_hash": "db9a0c71ac67e3c104a4fcd9ecb83062", "semantic_hash": "" }, "frontend/src/components/budget/BudgetBlockers.tsx": { @@ -1122,9 +1122,9 @@ "semantic_hash": "" }, "backend/tests/test_review_queue_batch.py": { - "mtime": 1790155761.6000907, - "seen": 1790155776.860325, - "ast_hash": "ca92b0417d73b849012c90803a4a6885", + "mtime": 1790158886.5589485, + "seen": 1790164233.419179, + "ast_hash": "0074192ea42734bcc988792b5de3624b", "semantic_hash": "" }, "frontend/src/test/review-queue-save.test.tsx": { @@ -1146,9 +1146,27 @@ "semantic_hash": "" }, "frontend/src/test/ledger-view.test.tsx": { - "mtime": 1790156126.5019412, - "seen": 1790156681.7281582, - "ast_hash": "dbd335027673613bbee4cb47aa4b6983", + "mtime": 1790157401.4480782, + "seen": 1790157424.7858286, + "ast_hash": "325d3bc51b743c4fdde3c00733ce9c99", + "semantic_hash": "" + }, + "backend/tests/test_expected_income.py": { + "mtime": 1790164281.3358464, + "seen": 1790164324.132625, + "ast_hash": "459ccb83896076b6acdeb11870bf344c", + "semantic_hash": "" + }, + "docs/questions/\u043f\u0435\u0440\u0435\u0432\u043e\u0434_\u043c\u0435\u0436\u0434\u0443_\u0441\u0432\u043e\u0438\u043c\u0438.md": { + "mtime": 1790159262.1681526, + "seen": 1790164233.4192622, + "ast_hash": "25245974c220fc36138fda26f8202e38", + "semantic_hash": "" + }, + "docs/tasks/0002-fixes.md": { + "mtime": 1790159106.0020006, + "seen": 1790164233.4192643, + "ast_hash": "772e67f454e325d9bd207036e190d511", "semantic_hash": "" } } \ No newline at end of file diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index b06042c..aaebdc8 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,49 +1,49 @@ # Graph Report - finance (2026-09-23) ## Corpus Check -- 187 files · ~90,166 words +- 191 files · ~92,817 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 1667 nodes · 5182 edges · 95 communities (72 shown, 16 thin omitted) -- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 91 edges (avg confidence: 0.93) +- 1708 nodes · 5406 edges · 102 communities (78 shown, 15 thin omitted) +- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 96 edges (avg confidence: 0.93) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `63d06501` +- Built from commit: `970fe9da` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). ## Community Hubs (Navigation) -- Category -- budgeting/router.py -- db/models.py -- AppError - imports/router.py +- budgeting/router.py +- Base +- main.py +- test_import_savings.py - alfa_xlsx.py - system-account-picker.test.tsx - types.ts -- router.tsx +- LoginPage.tsx - ledger/router.py - @testing-library/jest-dom - compilerOptions -- ReviewQueuePage.tsx -- @testing-library/user-event +- AnalyticsPage.tsx +- mcc.py - devDependencies - ledger/service.py - dependencies -- ImportDetailPage.tsx +- useOperations.ts - OperationsPage.tsx -- Base +- analytics/service.py - apiErrors.ts -- adapters/base.py +- test_adapter_contracts.py - BudgetPage.tsx - client.ts -- fields.tsx +- imports/service.py - Docker Compose Development Stack - Financial Space - scripts -- @types/react +- router.tsx - General Pool - TestBaseContract - Per-File Envelope Encryption @@ -53,68 +53,73 @@ - Closed Beta Launch Gates - package.json - Financial Tracker MVP -- test_adapter_contracts.py +- TestRocketbankDebitContract - generate-api.mjs - schema.d.ts - test_api.py - i18n-parity.test.ts - Expected Income -- helpers.tsx -- ledger/models.py +- api +- AccountsPage.tsx - category-manager.test.tsx - graphify -- @types/react-dom +- index.ts - typescript-eslint - Ближайший край: накопления, категории и блокировки бюджета -- vitest +- RocketbankDebitPdfAdapter - Favicon SVG (ledger lines icon) - init-app-role.sh - Payee - test_private_fixtures.py - finance-backend - LocalDirectoryBlobStore -- OzonDebitPdfAdapter +- TestOzonDebitContract - Gitea CI and real statement imports - 20260918_0002_hold_lifecycle.py - eslint-plugin-react-hooks - import-hold-resolution.test.tsx - budgeting/service.py - TestAlfaDebitContract -- vite -- mcc.py -- TestAlfaSavingsRule +- AppLayout.tsx +- 20260922_0003_savings_system.py +- jsdom - savings-convert-revert.test.tsx - get_settings - ColumnChart.tsx - dependencies.py - AGENTS.md -- test_savings.py +- Session - test_category_definitions.py - budget-plan.test.tsx -- imports/service.py +- TestAlfaSavingsRule - exports/service.py -- test_imports.py +- @testing-library/react - identity/service.py -- Session +- test_import_holds.py - get_or_create_period - 20260923_0005_optional_hold_reason.py -- test_import_savings.py -- conftest.py +- typescript +- useAuth.ts - test_review_queue_batch.py +- @vitejs/plugin-react +- useImports.ts +- describeApiError +- app_error_handler - review-queue-save.test.tsx -- account-adjustment.test.tsx +- detect_adapter +- review-queue-month.test.tsx ## God Nodes (most connected - your core abstractions) -1. `Session` - 211 edges -2. `AppError` - 72 edges +1. `Session` - 221 edges +2. `AppError` - 76 edges 3. `Base` - 48 edges -4. `conflict()` - 43 edges -5. `get_settings()` - 40 edges -6. `PkMixin` - 40 edges -7. `record()` - 39 edges -8. `TimestampMixin` - 38 edges -9. `StatementDocument` - 36 edges -10. `create_expense()` - 36 edges +4. `record()` - 44 edges +5. `conflict()` - 43 edges +6. `get_settings()` - 40 edges +7. `PkMixin` - 40 edges +8. `get_or_create_period()` - 39 edges +9. `TimestampMixin` - 38 edges +10. `bad_request()` - 36 edges ## Surprising Connections (you probably didn't know these) - `Typed Same-Origin API Client` --conceptually_related_to--> `Same-Origin Reverse Proxy` [INFERRED] @@ -136,43 +141,43 @@ - **Financial Space Tenancy Boundary** — context_financial_space, context_membership, docs_adr_0001_financial_space_ownership_and_rls_defense_in_depth_authorization, docs_adr_0001_financial_space_ownership_and_rls_transaction_local_rls, docs_adr_0001_financial_space_ownership_and_rls_cross_space_integrity [EXTRACTED 1.00] - **Safe Statement Import Flow** — context_statement_import, context_parse_run, context_source_record, docs_adr_0003_versioned_statement_imports_immutable_statement_document, docs_adr_0003_versioned_statement_imports_conservative_deduplication, docs_adr_0003_versioned_statement_imports_atomic_confirm_revert [EXTRACTED 1.00] -## Communities (95 total, 16 thin omitted) +## Communities (102 total, 15 thin omitted) -### Community 0 - "Category" -Cohesion: 0.20 -Nodes (15): balances(), cash_flow(), category_spend(), plan_fact(), date, UUID, category_for_mcc(), Category owning the MCC code, else the system «Остальное» fallback. (+7 more) +### Community 0 - "imports/router.py" +Cohesion: 0.15 +Nodes (35): confirm(), ConfirmBody, decide_row(), DecisionBody, delete_source(), detail(), HoldResolveBody, imports() (+27 more) ### Community 1 - "budgeting/router.py" -Cohesion: 0.11 -Nodes (52): balances(), cash_flow(), category_spend(), plan_fact(), Context, date, Db, get (+44 more) +Cohesion: 0.15 +Nodes (51): AssignmentItem, assignments(), AssignmentsBody, categories(), category_definition_json(), category_definitions(), CategoryBody, CategoryDefinitionPatchBody (+43 more) -### Community 2 - "db/models.py" -Cohesion: 0.17 -Nodes (23): AuditEvent, Append-only domain/security event. Never stores raw financial payloads., ExpectedIncome, ExpectedIncomeMatch, FundingMovement, PeriodClosure, PlanAssignment, Links one actual income operation to one expected income (1:1 per operation). (+15 more) +### Community 2 - "Base" +Cohesion: 0.09 +Nodes (49): downgrade(), upgrade(), AuditEvent, Append-only domain/security event. Never stores raw financial payloads., ExpectedIncome, ExpectedIncomeMatch, FundingMovement, PeriodClosure (+41 more) -### Community 3 - "AppError" -Cohesion: 0.19 -Nodes (11): AppError, Any, Domain error rendered as a machine-readable JSON error payload., unprocessable(), decrypt_file(), encrypt_file(), EncryptedFile, Per-file random DEK; DEK wrapped with the KEK from the secret manager. (+3 more) +### Community 3 - "main.py" +Cohesion: 0.20 +Nodes (15): get_db(), get_engine(), get_session_factory(), sessionmaker, health(), healthz(), get, readiness() (+7 more) -### Community 4 - "imports/router.py" -Cohesion: 0.05 -Nodes (79): _check_constraints(), downgrade(), _has_column(), _has_row(), _has_unique_constraint(), _normalized_sqltext(), Savings system resources, adjustments and reversible conversions., Swap a check constraint for a new value list, dialect-safely. Fresh databases… (+71 more) +### Community 4 - "test_import_savings.py" +Cohesion: 0.13 +Nodes (41): RequestContext, ParseRun, Immutable extracted bank fact with document origin coordinates., SourceRecord, StatementDocument, _build_candidates(), add_record(), make_document() (+33 more) ### Community 5 - "alfa_xlsx.py" -Cohesion: 0.12 -Nodes (32): AlfaCreditXlsxAdapter, AlfaDebitXlsxAdapter, _AlfaHeaderMeta, AlfaXlsxAdapterBase, _cell_str(), _debit_find_header(), _debit_header_metadata(), _debit_header_value() (+24 more) +Cohesion: 0.15 +Nodes (26): AlfaDebitXlsxAdapter, _AlfaHeaderMeta, AlfaXlsxAdapterBase, _cell_str(), _debit_find_header(), _debit_header_metadata(), _debit_header_value(), _debit_norm() (+18 more) ### Community 6 - "system-account-picker.test.tsx" -Cohesion: 0.11 -Nodes (15): AdjustBalanceResult, BudgetCategory, Operation, Page, budgetCategoriesMock, listAccountsMock, listOperationsMock, categoriesMock (+7 more) +Cohesion: 0.12 +Nodes (13): Account, AdjustBalanceResult, BudgetCategory, Operation, adjustBalanceMock, listMock, budgetCategoriesMock, listAccountsMock (+5 more) ### Community 7 - "types.ts" -Cohesion: 0.08 -Nodes (35): AccountStatus, AccountType, AdjustBalancePayload, BalanceItem, BalancesReport, BudgetStatus, BudgetWarning, CashFlowMonth (+27 more) - -### Community 8 - "router.tsx" Cohesion: 0.07 -Nodes (43): AcceptInvitePayload, LoginPayload, PasswordResetPayload, AcceptInvitePage, AccountsPage, AnalyticsPage, BudgetPage, ImportDetailPage (+35 more) +Nodes (38): AcceptInvitePayload, AccountStatus, AccountType, BalanceItem, BalancesReport, BudgetStatus, BudgetWarning, CashFlowMonth (+30 more) + +### Community 8 - "LoginPage.tsx" +Cohesion: 0.21 +Nodes (11): AcceptInvitePage, LoginPage, RequireAuth(), AuthLayout(), AuthLayoutProps, TextField(), useMe(), AcceptInvitePage() (+3 more) ### Community 9 - "ledger/router.py" Cohesion: 0.15 @@ -182,53 +187,57 @@ Nodes (38): account_json(), AccountBody, accounts(), adjust_balance(), AdjustBal Cohesion: 0.07 Nodes (28): compilerOptions, baseUrl, esModuleInterop, forceConsistentCasingInFileNames, isolatedModules, jsx, lib, module (+20 more) -### Community 12 - "ReviewQueuePage.tsx" -Cohesion: 0.09 -Nodes (43): NotFoundPage, PlanFactBars(), PlanFactBarsProps, PlanFactRow, EmptyState(), EmptyStateProps, MonthSwitcher(), MonthSwitcherProps (+35 more) +### Community 12 - "AnalyticsPage.tsx" +Cohesion: 0.13 +Nodes (24): PlanFactBars(), PlanFactBarsProps, PlanFactRow, MonthSwitcher(), MonthSwitcherProps, useAnalyticsBalances(), useAnalyticsCashFlow(), useAnalyticsCategorySpend() (+16 more) + +### Community 13 - "mcc.py" +Cohesion: 0.14 +Nodes (23): _create_tenant_policy(), _default_keys(), downgrade(), _has_table(), _space_ids(), upgrade(), _default_categories(), default_category_system_keys() (+15 more) ### Community 14 - "devDependencies" -Cohesion: 0.10 -Nodes (21): eslint, @eslint/js, eslint-plugin-jsx-a11y, devDependencies, eslint, @eslint/js, eslint-plugin-jsx-a11y, globals (+13 more) +Cohesion: 0.09 +Nodes (23): eslint, @eslint/js, eslint-plugin-jsx-a11y, devDependencies, eslint, @eslint/js, eslint-plugin-jsx-a11y, globals (+15 more) ### Community 15 - "ledger/service.py" -Cohesion: 0.13 -Nodes (48): ensure_others_category(), The system «Остальное» fallback category, created on first use., Operation, Posting, Signed balance change of one account within one operation. Sign convention…, User financial fact. amount_kopecks is always positive; direction lives in…, account_balance(), _apply_suggestion() (+40 more) +Cohesion: 0.14 +Nodes (47): ensure_others_category(), The system «Остальное» fallback category, created on first use., Operation, Posting, Signed balance change of one account within one operation. Sign convention…, User financial fact. amount_kopecks is always positive; direction lives in…, account_balance(), _apply_suggestion() (+39 more) ### Community 16 - "dependencies" -Cohesion: 0.09 -Nodes (23): @fontsource/funnel-sans, @fontsource/geist-mono, dependencies, @fontsource/funnel-sans, @fontsource/geist-mono, @hookform/resolvers, i18next, react (+15 more) - -### Community 17 - "ImportDetailPage.tsx" Cohesion: 0.08 -Nodes (45): api, invalidationRoots, queryKeys, SESSION_ROOT, sessionInvalidationRoot, SPACE_ROOT, spaceInvalidationRoot, HoldResolutionAction (+37 more) +Nodes (25): @fontsource/funnel-sans, @fontsource/geist-mono, @fontsource/onest, dependencies, @fontsource/funnel-sans, @fontsource/geist-mono, @fontsource/onest, @hookform/resolvers (+17 more) + +### Community 17 - "useOperations.ts" +Cohesion: 0.15 +Nodes (17): invalidationRoots, queryKeys, SESSION_ROOT, sessionInvalidationRoot, SPACE_ROOT, spaceInvalidationRoot, CategorizeBatchPayload, CreateOperationPayload (+9 more) ### Community 18 - "OperationsPage.tsx" Cohesion: 0.11 -Nodes (46): CategorizeBatchPayload, CreateOperationPayload, isSystemAccount(), Locale, useAccounts(), useActiveAccounts(), useUserAccounts(), useCategorizeBatch() (+38 more) +Nodes (42): AdjustBalancePayload, CreateAccountPayload, isSystemAccount(), Locale, useAccounts(), useActiveAccounts(), useAdjustBalance(), useArchiveAccount() (+34 more) -### Community 19 - "Base" -Cohesion: 0.15 -Nodes (22): downgrade(), upgrade(), BankCategoryMapping, CategorizationRule, CategoryMcc, IncomeSource, MccCode, Payee (+14 more) +### Community 19 - "analytics/service.py" +Cohesion: 0.20 +Nodes (18): balances(), cash_flow(), category_spend(), plan_fact(), Context, date, Db, get (+10 more) ### Community 20 - "apiErrors.ts" -Cohesion: 0.09 -Nodes (24): isApiError(), BudgetBlocker, App(), queryClient, AppRoutes(), blockerCta(), blockerText(), BudgetBlockers() (+16 more) +Cohesion: 0.33 +Nodes (6): isApiError(), App(), queryClient, AppRoutes(), apiErrorCode(), container -### Community 21 - "adapters/base.py" -Cohesion: 0.12 -Nodes (20): account_fingerprint(), _mask_digits(), money_to_kopecks(), normalize_description(), date, Parse statement money strings like '-1 234,56 RUR', '+ 500.00 ₽', '12 345'.…, record_fingerprint(), StatementDraft (+12 more) +### Community 21 - "test_adapter_contracts.py" +Cohesion: 0.13 +Nodes (21): AlfaCreditXlsxAdapter, account_fingerprint(), amount_to_kopecks(), _mask_digits(), money_to_kopecks(), Parse statement money strings like '-1 234,56 RUR', '+ 500.00 ₽', '12 345'.…, SourceRow, StatementDraft (+13 more) ### Community 22 - "BudgetPage.tsx" -Cohesion: 0.14 -Nodes (27): CreatableCategoryKind, CategoryManagerModal(), CREATE_KINDS, CreateCategoryForm(), MccCodesModal(), parseMccCodes(), RenameModal(), Badge() (+19 more) +Cohesion: 0.17 +Nodes (28): CreatableCategoryKind, CategoryManagerModal(), CREATE_KINDS, CreateCategoryForm(), MccCodesModal(), parseMccCodes(), RenameModal(), useBudgetCategories() (+20 more) ### Community 23 - "client.ts" Cohesion: 0.26 Nodes (10): apiClient, ApiError, buildUrl(), ErrorEnvelope, parseErrorEnvelope(), QueryValue, readCsrfToken(), request() (+2 more) -### Community 24 - "fields.tsx" -Cohesion: 0.21 -Nodes (11): FieldChrome, InputProps, MoneyField(), MoneyFieldProps, SelectField(), SelectFieldProps, SelectProps, TextareaField() (+3 more) +### Community 24 - "imports/service.py" +Cohesion: 0.15 +Nodes (33): Any, record(), get_income_source(), Replace the category's MCC code set; codes are unique per space., set_category_mcc_codes(), conflict(), not_found(), Any (+25 more) ### Community 25 - "Docker Compose Development Stack" Cohesion: 0.29 @@ -242,6 +251,10 @@ Nodes (12): Credit Reserve, Financial Account, Financial Space, Membership, User Cohesion: 0.22 Nodes (9): scripts, api:generate, build, dev, lint, preview, test, test:watch (+1 more) +### Community 28 - "router.tsx" +Cohesion: 0.15 +Nodes (11): AccountsPage, AnalyticsPage, BudgetPage, ImportDetailPage, ImportsPage, NotFoundPage, OperationsPage, OverviewPage (+3 more) + ### Community 29 - "General Pool" Cohesion: 0.29 Nodes (8): Budget Period, Funding, General Pool, Monthly Category, Plan Assignment, Savings Envelope, Immutable Closure Snapshots, Plan and Funding Separation @@ -278,9 +291,9 @@ Nodes (4): name, private, type, version Cohesion: 0.18 Nodes (11): Audited Break-Glass Access, Cross-Space Referential Integrity, Defense-in-Depth Authorization, Financial Space Ownership, Transaction-Local RLS Context, Budget Invariants, Critical User Path, Financial Tracker MVP (+3 more) -### Community 38 - "test_adapter_contracts.py" -Cohesion: 0.13 -Nodes (8): minimal_pdf(), _QuotaSettings, Sanitized synthetic contract tests for the evidenced statement adapters. These…, Build a small valid single-font PDF with empty or ASCII-only pages., same_page_rocket_lines(), synthetic_rocket_lines(), TestRocketbankDebitContract, MonkeyPatch +### Community 38 - "TestRocketbankDebitContract" +Cohesion: 0.24 +Nodes (3): same_page_rocket_lines(), synthetic_rocket_lines(), TestRocketbankDebitContract ### Community 39 - "generate-api.mjs" Cohesion: 0.40 @@ -294,13 +307,13 @@ Nodes (5): components, $defs, operations, paths, webhooks Cohesion: 0.67 Nodes (3): TestClient, test_invite_login_and_authenticated_space(), test_openapi_contains_critical_paths() -### Community 44 - "helpers.tsx" -Cohesion: 0.18 -Nodes (11): User, DESKTOP_NAV, meMock, MOBILE_NAV, user, createTestQueryClient(), renderWithProviders(), loginMock (+3 more) +### Community 44 - "api" +Cohesion: 0.14 +Nodes (14): api, User, createMock, listMock, DESKTOP_NAV, meMock, MOBILE_NAV, user (+6 more) -### Community 45 - "ledger/models.py" -Cohesion: 0.26 -Nodes (11): HoldResolution, Append-only, tenant-scoped settlement of one HOLD source record. The extracted…, Account, Financial account. Balance is always derived: opening + confirmed postings., FinancialSpace, Membership, test_postgres_rls_requires_matching_transaction_context(), test_s3_blob_round_trip() (+3 more) +### Community 45 - "AccountsPage.tsx" +Cohesion: 0.10 +Nodes (37): Badge(), BadgeTone, Button(), ButtonProps, Variant, ConfirmDialog(), ConfirmDialogProps, EmptyState() (+29 more) ### Community 46 - "category-manager.test.tsx" Cohesion: 0.14 @@ -310,21 +323,29 @@ Nodes (12): CategoryDefinition, categoriesMock, createCategoryMock, definitions, Cohesion: 0.17 Nodes (11): command, enabled, timeout, type, mcp, graphify, plugin, $schema (+3 more) +### Community 48 - "index.ts" +Cohesion: 0.22 +Nodes (10): BudgetBlocker, blockerCta(), blockerText(), BudgetBlockers(), BudgetBlockersProps, Cta, createI18n(), detectLocale() (+2 more) + ### Community 50 - "Ближайший край: накопления, категории и блокировки бюджета" Cohesion: 0.10 Nodes (20): 1. Доменная основа накоплений, 2. Альфа debit: «Копилка для сдачи», 3. Управление категориями, 4. Понятные и устранимые блокировки, Backend-контракт, Frontend, Ближайший край: накопления, категории и блокировки бюджета, Бюджетная семантика (+12 more) +### Community 51 - "RocketbankDebitPdfAdapter" +Cohesion: 0.22 +Nodes (7): _date_from(), _PendingRecord, date, Rocketbank debit statement contract, evidenced against the real document.…, RocketbankDebitPdfAdapter, open_pdf(), _quota_error() + ### Community 58 - "test_private_fixtures.py" -Cohesion: 0.10 -Nodes (24): Protocol, StatementAdapter, detect_adapter(), Any, Reconcile parsed rows against declared bank controls with stable diagnostics.…, _reconciliation_summary(), _check(), _fail() (+16 more) +Cohesion: 0.12 +Nodes (22): _draft_json(), Any, Reconcile parsed rows against declared bank controls with stable diagnostics.…, _reconciliation_summary(), _check(), _fail(), _load_entries(), parsed() (+14 more) ### Community 62 - "LocalDirectoryBlobStore" Cohesion: 0.39 Nodes (3): LocalDirectoryBlobStore, Path, S3-neutral local store; production swaps in an S3-compatible client. -### Community 63 - "OzonDebitPdfAdapter" -Cohesion: 0.18 -Nodes (6): _ozon_normalize(), OzonDebitPdfAdapter, Ozon debit statement contract, evidenced against the real document. A 'Справка…, ozon_extracted(), TestOzonDebitContract, Pattern +### Community 63 - "TestOzonDebitContract" +Cohesion: 0.15 +Nodes (6): minimal_pdf(), ozon_extracted(), _QuotaSettings, Build a small valid single-font PDF with empty or ASCII-only pages., TestOzonDebitContract, MonkeyPatch ### Community 64 - "Gitea CI and real statement imports" Cohesion: 0.29 @@ -339,16 +360,20 @@ Cohesion: 0.15 Nodes (11): ImportDetail, ImportRow, ImportSummary, confirmMock, detailFixture(), getImportMock, postedRow(), getImportMock (+3 more) ### Community 68 - "budgeting/service.py" -Cohesion: 0.16 -Nodes (39): BudgetPeriod, Calendar month budget period in the space timezone (month granularity)., add_expected_income(), archive_category(), _balance_until(), _close_blockers(), close_period(), _closure_snapshot() (+31 more) +Cohesion: 0.13 +Nodes (50): BudgetPeriod, Calendar month budget period in the space timezone (month granularity)., add_expected_income(), archive_category(), _balance_until(), _close_blockers(), close_period(), _closure_snapshot() (+42 more) ### Community 69 - "TestAlfaDebitContract" Cohesion: 0.18 Nodes (3): alfa_workbook_bytes(), synthetic_alfa_rows(), TestAlfaDebitContract -### Community 71 - "mcc.py" -Cohesion: 0.14 -Nodes (23): _create_tenant_policy(), _default_keys(), downgrade(), _has_table(), _space_ids(), upgrade(), _default_categories(), default_category_system_keys() (+15 more) +### Community 70 - "AppLayout.tsx" +Cohesion: 0.19 +Nodes (10): AppLayout(), MOBILE_NAV_ITEMS, MOBILE_NAV_ROUTES, NAV_ICONS, NAV_ITEMS, NavIconName, LangSwitcher(), useLogout() (+2 more) + +### Community 71 - "20260922_0003_savings_system.py" +Cohesion: 0.32 +Nodes (11): _check_constraints(), downgrade(), _has_column(), _has_row(), _has_unique_constraint(), _normalized_sqltext(), Savings system resources, adjustments and reversible conversions., Swap a check constraint for a new value list, dialect-safely. Fresh databases… (+3 more) ### Community 73 - "savings-convert-revert.test.tsx" Cohesion: 0.20 @@ -363,88 +388,92 @@ Cohesion: 0.24 Nodes (7): CashFlowColumn, ColumnChart(), ColumnChartProps, BarRow, HorizontalBars(), HorizontalBarsProps, rows ### Community 76 - "dependencies.py" -Cohesion: 0.09 -Nodes (39): current_context(), current_session(), alias, Context, CurrentSession, Db, Header, User (+31 more) +Cohesion: 0.10 +Nodes (39): current_context(), Context, CurrentSession, Db, Header, require_csrf(), forbidden(), cancel_deletion() (+31 more) -### Community 79 - "test_savings.py" +### Community 79 - "Session" Cohesion: 0.14 -Nodes (33): adjust_balance(), convert_expense_to_savings(), ensure_savings_resources(), Account, date, Operation, User, UUID (+25 more) +Nodes (43): AppError, Domain error rendered as a machine-readable JSON error payload., Session, Category, Budget category. Kept in ledger module to avoid circular imports., adjust_balance(), convert_expense_to_savings(), ensure_savings_resources() (+35 more) ### Community 80 - "test_category_definitions.py" Cohesion: 0.50 Nodes (8): bootstrap(), TestClient, HTTP contract for category definitions, system protections and CSRF., test_adjust_and_savings_conversion_http_contracts(), test_categories_expose_and_update_multiple_mcc_codes(), test_category_lifecycle_create_rename_archive_restore(), test_openapi_contains_new_contracts(), test_space_has_protected_savings_pair() ### Community 81 - "budget-plan.test.tsx" -Cohesion: 0.25 -Nodes (7): BudgetSummary, categories, categoriesMock, month, summary, summaryMock, updatePlanMock - -### Community 82 - "imports/service.py" -Cohesion: 0.18 -Nodes (29): Any, record(), utcnow(), conflict(), not_found(), magic_kind(), _apply_hold_matches(), _category_id_for_source() (+21 more) +Cohesion: 0.15 +Nodes (11): BudgetSummary, ExpectedIncome, categories, categoriesMock, month, summary, summaryMock, updatePlanMock (+3 more) ### Community 83 - "exports/service.py" -Cohesion: 0.13 -Nodes (19): DataExport, build_export(), consume_export(), _csv_bytes(), get_export(), _json_rows(), purge_due_spaces(), datetime (+11 more) - -### Community 84 - "test_imports.py" -Cohesion: 0.17 -Nodes (29): DedupCandidate, ParseRun, Immutable extracted bank fact with document origin coordinates., SourceRecord, SourceRecordLink, StatementDocument, _build_candidates(), _match_hold_resolutions() (+21 more) +Cohesion: 0.07 +Nodes (45): Any, Transaction-local RLS context. No-op on SQLite (tests); fail-closed on…, Transactional scope for workers/endpoints that own the transaction lifecycle., session_scope(), set_space_context(), download(), export_status(), Context (+37 more) ### Community 85 - "identity/service.py" -Cohesion: 0.26 -Nodes (20): bad_request(), unauthorized(), accept_invitation(), authenticate(), create_invitation(), create_password_reset(), create_session(), get_active_session() (+12 more) +Cohesion: 0.19 +Nodes (24): current_session(), alias, User, unauthorized(), accept_invitation(), authenticate(), create_invitation(), create_password_reset() (+16 more) -### Community 86 - "Session" -Cohesion: 0.16 -Nodes (41): Session, add_record(), _draft(), hold_document(), make_document(), date, Path, TestClient (+33 more) +### Community 86 - "test_import_holds.py" +Cohesion: 0.13 +Nodes (42): normalize_description(), date, record_fingerprint(), add_record(), _draft(), hold_document(), make_document(), date (+34 more) ### Community 87 - "get_or_create_period" -Cohesion: 0.34 -Nodes (14): get_or_create_period(), validate_year_month(), Budget semantics for savings transfers, adjustments and archived history., savings_row(), seed(), test_adjustment_changes_only_envelope_available_not_pool(), test_adjustment_on_regular_account_keeps_pool_and_totals(), test_archived_category_history_stays_in_totals() (+6 more) +Cohesion: 0.18 +Nodes (27): compute_period_state(), create_category(), get_or_create_period(), Deterministic budget state. Resource model: - income lands in the general pool;…, category_for_mcc(), get_category_mcc_codes(), UUID, Category owning the MCC code, else the system «Остальное» fallback. (+19 more) ### Community 88 - "20260923_0005_optional_hold_reason.py" Cohesion: 0.83 Nodes (3): downgrade(), _reason_constraint_name(), upgrade() -### Community 89 - "test_import_savings.py" -Cohesion: 0.32 -Nodes (17): get_savings_account(), add_record(), make_document(), date, User, Import contract for the «Копилка для сдачи» savings_transfer decision., seed(), test_confirm_creates_savings_transfer_with_system_category() (+9 more) - -### Community 90 - "conftest.py" -Cohesion: 0.27 -Nodes (6): client(), db(), db_factory(), fixture, sessionmaker, TestClient +### Community 90 - "useAuth.ts" +Cohesion: 0.36 +Nodes (8): ResetPasswordPage, useAcceptInvite(), useConfirmPasswordReset(), useLogin(), useRequestPasswordReset(), useSessionMutation(), ResetPasswordPage(), ResetValues ### Community 91 - "test_review_queue_batch.py" Cohesion: 0.60 Nodes (10): bootstrap(), category_ids(), create_account(), create_expense(), operations_by_id(), TestClient, test_batch_assigns_picked_categories_and_moves_leftovers_to_others(), test_batch_is_atomic_when_one_category_is_unknown() (+2 more) -### Community 92 - "review-queue-save.test.tsx" +### Community 93 - "useImports.ts" +Cohesion: 0.13 +Nodes (24): ImportStatus, ToastApi, ToastContext, ToastItem, ToastKind, ToastProvider(), useToast(), useConfirmImport() (+16 more) + +### Community 94 - "describeApiError" +Cohesion: 0.44 +Nodes (8): useCancelDeletion(), useRequestDeletion(), useRequestExport(), useSpaceDeletion(), describeApiError(), DeletionForm(), DeletionFormValues, SettingsPage() + +### Community 95 - "app_error_handler" +Cohesion: 0.32 +Nodes (8): app_error_handler(), Request, security_headers(), stale_data_handler(), exception_handler, JSONResponse, middleware, StaleDataError + +### Community 96 - "review-queue-save.test.tsx" Cohesion: 0.25 Nodes (6): categories, categoriesMock, categorizeBatchMock, categorizeMock, importsListMock, operationsListMock -### Community 94 - "account-adjustment.test.tsx" -Cohesion: 0.20 -Nodes (5): Account, adjustBalanceMock, listMock, createMock, listMock +### Community 100 - "detect_adapter" +Cohesion: 0.29 +Nodes (4): Protocol, StatementAdapter, detect_adapter(), Workbook + +### Community 101 - "review-queue-month.test.tsx" +Cohesion: 0.33 +Nodes (5): Page, categoriesMock, importsListMock, importSummary, operationsListMock ## Knowledge Gaps -- **267 isolated node(s):** `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type`, `/home/k1nq/.local/bin/graphify-mcp`, `/home/k1nq/repos/finance/graphify-out/graph.json` (+262 more) - These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 468 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) -- **16 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **270 isolated node(s):** `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type`, `/home/k1nq/.local/bin/graphify-mcp`, `/home/k1nq/repos/finance/graphify-out/graph.json` (+265 more) + These have ≤1 connection - possible missing edges or undocumented components. (Counts symbols only; 477 node(s) total have ≤1 connection when file, concept and rationale nodes are included.) +- **15 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Session` connect `Session` to `Category`, `budgeting/router.py`, `db/models.py`, `imports/router.py`, `alfa_xlsx.py`, `ledger/service.py`, `Base`, `ledger/models.py`, `budgeting/service.py`, `mcc.py`, `dependencies.py`, `test_savings.py`, `imports/service.py`, `exports/service.py`, `test_imports.py`, `identity/service.py`, `get_or_create_period`, `test_import_savings.py`, `conftest.py`?** - _High betweenness centrality (0.067) - this node is a cross-community bridge._ -- **Why does `AppError` connect `AppError` to `imports/router.py`, `alfa_xlsx.py`, `test_adapter_contracts.py`, `budgeting/service.py`, `get_settings`, `dependencies.py`, `ledger/service.py`, `test_savings.py`, `imports/service.py`, `test_imports.py`, `identity/service.py`, `adapters/base.py`, `get_or_create_period`, `Session`, `test_import_savings.py`, `OzonDebitPdfAdapter`?** - _High betweenness centrality (0.049) - this node is a cross-community bridge._ -- **Why does `TestRocketbankDebitContract` connect `test_adapter_contracts.py` to `AppError`, `adapters/base.py`?** +- **Why does `Session` connect `Session` to `Base`, `main.py`, `budgeting/service.py`, `test_import_savings.py`, `20260922_0003_savings_system.py`, `dependencies.py`, `mcc.py`, `ledger/service.py`, `analytics/service.py`, `exports/service.py`, `identity/service.py`, `test_import_holds.py`, `get_or_create_period`, `imports/service.py`?** + _High betweenness centrality (0.071) - this node is a cross-community bridge._ +- **Why does `AppError` connect `Session` to `imports/router.py`, `main.py`, `budgeting/service.py`, `alfa_xlsx.py`, `TestRocketbankDebitContract`, `test_import_savings.py`, `get_settings`, `dependencies.py`, `ledger/service.py`, `exports/service.py`, `RocketbankDebitPdfAdapter`, `identity/service.py`, `test_adapter_contracts.py`, `get_or_create_period`, `imports/service.py`, `test_import_holds.py`, `TestOzonDebitContract`, `app_error_handler`?** + _High betweenness centrality (0.047) - this node is a cross-community bridge._ +- **Why does `get_settings()` connect `get_settings` to `imports/router.py`, `Base`, `main.py`, `alfa_xlsx.py`, `dependencies.py`, `exports/service.py`, `RocketbankDebitPdfAdapter`, `identity/service.py`, `test_import_holds.py`, `imports/service.py`?** _High betweenness centrality (0.019) - this node is a cross-community bridge._ - **Are the 4 inferred relationships involving `Session` (e.g. with `upgrade()` and `upgrade()`) actually correct?** _`Session` has 4 INFERRED edges - model-reasoned connections that need verification._ -- **Are the 39 inferred relationships involving `AppError` (e.g. with `request_export()` and `login()`) actually correct?** - _`AppError` has 39 INFERRED edges - model-reasoned connections that need verification._ +- **Are the 42 inferred relationships involving `AppError` (e.g. with `request_export()` and `login()`) actually correct?** + _`AppError` has 42 INFERRED edges - model-reasoned connections that need verification._ - **Are the 3 inferred relationships involving `Base` (e.g. with `downgrade()` and `upgrade()`) actually correct?** _`Base` has 3 INFERRED edges - model-reasoned connections that need verification._ - **What connects `$schema`, `file:///home/k1nq/repos/finance/.kilo/plugins/graphify.js`, `type` to the rest of the system?** - _267 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file + _270 weakly-connected nodes found - possible documentation gaps or missing edges._ \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html index a2e89ad..7b3cd15 100644 --- a/graphify-out/graph.html +++ b/graphify-out/graph.html @@ -63,12 +63,12 @@
-
1667 nodes · 5182 edges · 95 communities
+
1708 nodes · 5406 edges · 102 communities