Skip to content

fix: missing error handlers (ImportError on startup), IBPS SO → all-g… - #23

Merged
KafKafrnZ merged 13 commits into
mainfrom
claude/pc-file-access-mnxju
Jun 9, 2026
Merged

KafKafrnZ merged 13 commits into
mainfrom
claude/pc-file-access-mnxju

Conversation

@KafKafrnZ

Copy link
Copy Markdown
Owner

…ov-exams, loading/error pages

  • error_handler.py: add http_exception_handler + rate_limit_exception_handler (were imported in main.py but never defined — caused ImportError, backend would not start)
  • data_analyzer.py: replace hardcoded 'IBPS SO exam strategist' with broad all-gov-exams prompt covering UPSC, SSC, IBPS PO/SO/Clerk, RRB, State PSC, SBI, RBI, SEBI, NABARD
  • main.py: rename logger 'ibps_so' → 'ascend_ai'
  • Add loading.tsx skeleton screens for all 6 routes (dashboard, tutor, practice, mock-tests, progress, error-log)
  • Add app/error.tsx global error boundary + app/not-found.tsx 404 page
  • Add tutor/error.tsx route-level error page for SSE failures

claude and others added 13 commits June 9, 2026 09:57
…ov-exams, loading/error pages

- error_handler.py: add http_exception_handler + rate_limit_exception_handler (were
  imported in main.py but never defined — caused ImportError, backend would not start)
- data_analyzer.py: replace hardcoded 'IBPS SO exam strategist' with broad all-gov-exams
  prompt covering UPSC, SSC, IBPS PO/SO/Clerk, RRB, State PSC, SBI, RBI, SEBI, NABARD
- main.py: rename logger 'ibps_so' → 'ascend_ai'
- Add loading.tsx skeleton screens for all 6 routes (dashboard, tutor, practice,
  mock-tests, progress, error-log)
- Add app/error.tsx global error boundary + app/not-found.tsx 404 page
- Add tutor/error.tsx route-level error page for SSE failures
…for all 5 LLMs

Full 7-phase execution plan with Goal/Step/Deliverable format prompts
covering all 46 actionable tasks derived from the 117-flaw audit.
Includes global rules, phase ordering, starter briefs per LLM, and
key file reference table.

https://claude.ai/code/session_0187VmZN4QmeBgzDk7HP8c3c
C-2 CSRF:
- Add ALLOWED_ORIGINS to config.py (JSON env var, defaults to localhost)
- Add csrf_protection middleware to main.py — rejects POST/PUT/DELETE from
  unknown origins; safe methods and requests with no Origin header pass through
- Fix cookie_security_options() to always use SameSite=Lax (Vercel/Railway
  are different domains; Strict silently blocks cross-domain cookie sends)
- Document ALLOWED_ORIGINS in .env.example

C-3 Refresh tokens:
- Reduce access token TTL: 240 min → 60 min (env-overridable)
- Add REFRESH_TOKEN_EXPIRE_DAYS=30 to config (env-overridable)
- Add refresh_token / refresh_expires_at columns to AuthToken model
- Alembic migration c1d2e3f4a5b6 adds both columns + index
- auth.py: create_refresh_token() and verify_refresh_token() helpers
- /login: issue hashed refresh token stored in DB; raw token in HttpOnly cookie
  scoped to path=/auth
- /auth/refresh: verify raw token against stored hash, rotate both tokens
- /logout + /auth/logout: null out refresh_token in DB, delete both cookies
- frontend/lib/api.ts: fetchWithRefresh() auto-retries on 401 after refresh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- App and pytest start without sentry-sdk installed in dev/test
- Update MEMORY.md with GK-1 through GK-11 completion status
…ns tests

G2 — Rate limit enforcement:
- real_limiter fixture in conftest swaps in MovingWindowRateLimiter(MemoryStorage())
  so the global mock is bypassed for specific tests; restored on teardown
- TestRateLimitBehavior: 6th login within 1 minute returns 429 RATE_LIMITED

G3 — SSE stream coverage:
- TestSSEStream: mocks ask_tutor_stream, verifies Content-Type: text/event-stream
  and that at least one data: line is emitted; also verifies auth guard on stream

G5 — Expired session rejection:
- TestExpiredSession: inserts MockTestSession 5 minutes in the past, verifies
  POST /mock-tests/1/submit returns 400 SESSION_EXPIRED
- Bonus: missing session returns 404 SESSION_NOT_FOUND

G6 — Conversations roundtrip:
- TestConversations: saves question+answer, verifies both role=user and
  role=assistant messages appear in GET /conversations (correct response shape)
- Auth guard coverage on both GET and POST conversations endpoints

All 69 tests pass (was 61).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… fixes

P-D1  Wire fetchWithRefresh into all 5 authenticated pages + tutor streaming
      inline 401 → refresh → retry. Dead code eliminated.
P-D9  DB pool: env-configurable DB_POOL_SIZE/DB_MAX_OVERFLOW, pool_pre_ping
      and pool_recycle=1800 now documented in .env.example
P-D3  Add DEPLOY.md — complete Railway + Vercel step-by-step deploy guide
P-D2  Fix README — remove false LangChain/LlamaIndex claims, accurate stack
P-D4  Fix SECURITY.md — replace placeholder email with GitHub advisory link
P-D10 Add frontend/vercel.json (security headers + microphone permission)
      Bump railway.toml healthcheckTimeout 10→30s for fastembed warmup
P-D6  PWA manifest — replace SVG icons with 192/512px PNGs (proper installability)
P-D5  Add OpenGraph + Twitter Card metadata + 1200×630 og-image.png
      microphone=(self) added to Permissions-Policy for Voice Input
P-D8  Sentry frontend: guard init on DSN presence, add instrumentation.ts
      for App Router, fix Permissions-Policy to include microphone=(self)
P-D7  Frontend tests 13→34: api.test.ts (fetchWithRefresh 5 cases),
      auth-redirect.test.ts (11 proxy guard cases), + 6 edge-case extensions
      Fix TestDeadDependenciesRemoved path resolution (relative to __file__)

Backend: 69/69 passing. Frontend: 34/34 passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- frontend/app/api/[...path]/route.ts: add "expect" to HOP_BY_HOP_HEADERS
  — Node.js undici does not support forwarding Expect: 100-continue,
  causing all POST requests to 502 when run locally
- backend/app/core/config.py: load .env.local before .env so the
  gitignored local dev file takes precedence (matches Docker Compose convention)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…#21

- backend: kept router-based main.py (94 lines), our auth.py (hashlib refresh tokens),
  our config.py (.env.local precedence), merged error_handler.py (structured errors +
  client IP logging), our railway.toml (healthcheckTimeout=30 for fastembed warmup)
- frontend: merged vercel.json (combined security + cache headers), our proxy.ts
  (/explore in PROTECTED_ROUTES + isTokenExpired), our 8 loading/error skeleton pages
- tests: fixed proxy-auth and auth-redirect tests to use valid JWT-format tokens
  (isTokenExpired now parses token as JWT; plain strings always returned expired=true)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ngth

- tutor/page.tsx: add rehype-sanitize to ReactMarkdown (prevents XSS from AI output)
- AuthCard.tsx: 4-rule password strength meter (length/upper/digit/special char),
  per-rule indicator bars, first-unmet-rule hint, onFocus/onBlur for show/hide,
  aria-live="polite" on error alert
- AppLayout.tsx: htmlFor/id on profile-name and profile-email inputs
- forgot-password/page.tsx: htmlFor/id on email input, role="alert" on success msg
- reset-password/page.tsx: htmlFor/id on password inputs, role="alert" on messages
- next.config.ts: Content-Security-Policy header
- package.json: add rehype-sanitize dependency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@KafKafrnZ
KafKafrnZ merged commit 887de31 into main Jun 9, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants