Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b9d950
fix: align FE/BE paths for AI-config reveal and rate endpoints
Sagargupta16 Jul 4, 2026
09368b4
docs: comprehensive hardening plan from Wave 1 research
Sagargupta16 Jul 4, 2026
2ed0c19
chore(ci): align on Python 3.13 everywhere; add job timeouts
Sagargupta16 Jul 4, 2026
f484c0e
feat(security): split BYOK encryption key from JWT secret; use HKDF f…
Sagargupta16 Jul 4, 2026
8ab75f5
feat(security): refresh token rotation via User.token_version
Sagargupta16 Jul 4, 2026
e91a3f2
feat(security): per-authenticated-user rate limits on upload + ai chat
Sagargupta16 Jul 4, 2026
7a205cc
feat(db): DB-level ondelete=CASCADE on every user_id FK
Sagargupta16 Jul 4, 2026
1b491ac
feat(analytics): robust anomaly detection with median+MAD and rolling…
Sagargupta16 Jul 4, 2026
f3137d2
chore: broaden tax detection regex; delete stale Makefile + dead reno…
Sagargupta16 Jul 4, 2026
029291e
feat(analytics): 50/30/20 budget-rule aggregation endpoint
Sagargupta16 Jul 4, 2026
3ef1990
feat(budget): replace /budgets with 50/30/20 Budget Rule page
Sagargupta16 Jul 4, 2026
ff6b07c
fix: cascade migration duplicated SQLite FKs; harden /budgets against…
Sagargupta16 Jul 4, 2026
d970431
fix(budget): remove dead capForBar ternary (SonarCloud typescript:S3923)
Sagargupta16 Jul 4, 2026
30ed499
feat(budget): three-column layout, top-10 rollup, expanded period opt…
Sagargupta16 Jul 4, 2026
f5606ae
feat(budget): relabel generic 'Transfer' rows on Savings column
Sagargupta16 Jul 4, 2026
07e5642
feat(budget): collapse rows by category with top-3 subs inline
Sagargupta16 Jul 4, 2026
ad8d0dd
fix(budget): relabel 'Transfer: X → Y' rows + kill horizontal scroll
Sagargupta16 Jul 4, 2026
48ba415
fix(budget): design-system consistency + Education classifier
Sagargupta16 Jul 4, 2026
8ee8793
fix(budget): rewrite CategoryTable with hand-rolled rows (no more tru…
Sagargupta16 Jul 4, 2026
a6c9d24
refactor(frontend): extract Money primitive + migrate 5 pages to Page…
Sagargupta16 Jul 4, 2026
9f34b28
fix(frontend): cap historical chart data at today
Sagargupta16 Jul 4, 2026
6062ac1
docs: changelog Unreleased + CLAUDE.md guidance for Money / chart cap
Sagargupta16 Jul 4, 2026
d761cf3
refactor: fix all 18 SonarCloud issues on PR #202
Sagargupta16 Jul 4, 2026
fc6702a
chore: retrigger CI on latest sonar-fix HEAD
Sagargupta16 Jul 4, 2026
3f86652
Merge remote-tracking branch 'origin/main' into feat/comprehensive-ha…
Sagargupta16 Jul 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions .github/renovate.json

This file was deleted.

1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
# fails the build on lint/type/test errors.
backend:
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: backend
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/deploy-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ concurrency:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
defaults:
Expand Down Expand Up @@ -66,6 +67,7 @@ jobs:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
timeout-minutes: 10
needs: build
steps:
- name: Deploy to GitHub Pages
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/keepalive.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ permissions:
jobs:
ping:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Wake backend
run: |
# The /api/health endpoint is unauthenticated and returns instantly.
# We don't fail the workflow on non-200 — the goal is only to keep
# The /health endpoint is unauthenticated and returns instantly.
# (App-level route in main.py -- no /api/ prefix, unlike domain routers.)
# We don't fail the workflow on non-200 -- the goal is only to keep
# the branch warm; a transient 5xx during deploy is fine.
curl --silent --max-time 30 \
"https://ledger-sync-api.vercel.app/health" \
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/migrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@ on:
- 'backend/alembic/**'
- 'backend/src/ledger_sync/db/migrations/**'
- 'backend/src/ledger_sync/db/models.py'
- 'backend/src/ledger_sync/db/_models/**'

workflow_dispatch: # Allow manual trigger

jobs:
migrate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.14'
python-version: '3.13'

- uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8

Expand Down
63 changes: 0 additions & 63 deletions backend/Makefile

This file was deleted.

4 changes: 2 additions & 2 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "2.17.0"
description = "Personal finance dashboard backend -- Excel import, financial analytics, multi-currency exchange rates"
authors = [{ name = "Sagar Gupta" }]
readme = "README.md"
requires-python = ">=3.11"
requires-python = ">=3.13"
dependencies = [
"sqlalchemy>=2.0.51",
"alembic>=1.18.4",
Expand Down Expand Up @@ -94,7 +94,7 @@ select = ["E", "F", "I", "N", "W", "UP"]
"src/ledger_sync/core/analytics_engine.py" = ["PERF401"]

[tool.mypy]
python_version = "3.12"
python_version = "3.13"
strict = true
warn_return_any = true
warn_unused_configs = true
Expand Down
8 changes: 6 additions & 2 deletions backend/src/ledger_sync/api/ai_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
record_usage,
)
from ledger_sync.api.deps import CurrentUser, DatabaseSession
from ledger_sync.api.rate_limit import limiter
from ledger_sync.api.rate_limit import limiter, user_limiter
from ledger_sync.config.settings import settings
from ledger_sync.db.models import UserPreferences

Expand Down Expand Up @@ -188,7 +188,11 @@ def _from_bedrock_blocks(blocks: list[dict[str, Any]]) -> list[dict[str, Any]]:
503: {"description": "Bedrock is not configured on the server"},
},
)
@limiter.limit("30/minute")
# Two-layer rate limit. Per-user (30/min) is the primary throttle; IP-keyed
# (60/min) protects the auth path against unauthenticated floods and gives a
# safety net when a token is missing/malformed.
@user_limiter.limit("30/minute")
@limiter.limit("60/minute")
def bedrock_chat_proxy(
request: Request, # slowapi requires a `request: Request` parameter # noqa: ARG001
current_user: CurrentUser,
Expand Down
2 changes: 2 additions & 0 deletions backend/src/ledger_sync/api/analytics_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from ledger_sync.api.analytics_v2_impl import (
networth_misc_router,
recurring_router,
spending_rule_router,
summaries_router,
)
from ledger_sync.api.deps import CurrentUser
Expand All @@ -27,6 +28,7 @@
# Mount the split sub-routers under the same prefix.
router.include_router(summaries_router)
router.include_router(recurring_router)
router.include_router(spending_rule_router)
router.include_router(networth_misc_router)


Expand Down
8 changes: 7 additions & 1 deletion backend/src/ledger_sync/api/analytics_v2_impl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

from .networth_misc import router as networth_misc_router
from .recurring import router as recurring_router
from .spending_rule import router as spending_rule_router
from .summaries import router as summaries_router

__all__ = ["networth_misc_router", "recurring_router", "summaries_router"]
__all__ = [
"networth_misc_router",
"recurring_router",
"spending_rule_router",
"summaries_router",
]
Loading
Loading