You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
3.8 KiB
Markdown
62 lines
3.8 KiB
Markdown
# Architect Assessment
|
|
|
|
## Flaws identified by order of priority
|
|
[P0] Backend/Frontend contract is still broken for GET /syntheses.
|
|
Backend returns { items: [...] } in backend/src/handlers/syntheses.rs:38, but frontend expects a raw array in frontend/src/api/syntheses.ts:63 and uses it directly in frontend/src/pages/Home.tsx:37.
|
|
|
|
[P0] List item shape mismatch remains (sections vs preview fields).
|
|
Backend list item exposes preview fields in backend/src/models/synthesis.rs:77, while frontend type requires sections in frontend/src/types.ts:122 and renders from it in frontend/src/pages/Home.tsx:181.
|
|
|
|
[P0] Admin rate-limit update path mismatch is still present.
|
|
Backend route expects provider_name in backend/src/router.rs:73 and backend/src/handlers/admin.rs:227, but frontend sends id in frontend/src/api/admin.ts:38 and frontend/src/pages/admin/RateLimits.tsx:70.
|
|
|
|
[P0] Scraper SSRF hardening is incomplete (inference).
|
|
SSRF check is pre-request only in backend/src/services/scraper.rs:84 / backend/src/services/scraper.rs:184, then request executes in backend/src/services/scraper.rs:87. The hardened scraper client exists in backend/src/services/scraper.rs:57 but app boot still uses generic client in backend/src/main.rs:53.
|
|
|
|
[P1] Scraper body-size protection is post-download.
|
|
Body is fully read first in backend/src/services/scraper.rs:111, then checked in backend/src/services/scraper.rs:116, which weakens memory/DoS protection.
|
|
|
|
[P1] User-level rate-limit override appears per-job, not persistent across jobs.
|
|
Limiter is built in-run in backend/src/services/synthesis.rs:292, created from settings in backend/src/services/synthesis.rs:386, and keyed at check in backend/src/services/synthesis.rs:410.
|
|
|
|
[P1] Runtime state is not multi-instance safe.
|
|
Generation jobs and provider buckets are in-memory (backend/src/app_state.rs:21, backend/src/app_state.rs:24, backend/src/services/synthesis.rs:82, backend/src/services/rate_limiter.rs:113).
|
|
|
|
[P2] Magic-link quota can still be consumed before email send success.
|
|
Token creation occurs before delivery in backend/src/handlers/auth.rs:100 and backend/src/handlers/auth.rs:153, with active-token cap in backend/src/services/auth.rs:21.
|
|
|
|
[P2] Frontend test strategy still masks backend contract drift.
|
|
Home tests mock sections list items in frontend/src/tests/pages/home.test.tsx:24, which does not match backend list payload.
|
|
|
|
[P2] Frontend unit tests still cannot run in this environment.
|
|
npm run test -- --run fails on missing optional Rollup native module (@rollup/rollup-darwin-x64), so current frontend unit-test signal is unavailable locally.
|
|
|
|
[P3] sqlx compile-time query guarantees are still not implemented.
|
|
Runtime query usage is explicit in backend/src/db/users.rs:35, despite offline mode setup in backend/Dockerfile:21.
|
|
|
|
[P3] Postgres is still published on host by default.
|
|
Port mapping is open in docker-compose.yml:38.
|
|
|
|
|
|
## Remediation Order
|
|
|
|
### Summary
|
|
- Fix API contract breaks first.
|
|
- Then close scraper/network security gaps.
|
|
- Then harden runtime architecture for scale/reliability.
|
|
|
|
### Key Changes
|
|
- Align `/syntheses` and admin rate-limit contracts end-to-end (backend + frontend + tests).
|
|
- Wire dedicated hardened HTTP clients and enforce SSRF checks per hop with streaming body limits.
|
|
- Move job/rate-limit state to shared backing (Redis/DB) if multi-instance is in scope.
|
|
- Add contract tests so frontend mocks cannot drift from backend payloads.
|
|
|
|
### Test Plan
|
|
- Backend integration tests for `/syntheses` list shape and `/admin/rate-limits/{provider_name}` update path.
|
|
- Security tests for scraper redirect/private-IP/rebinding cases and oversized responses.
|
|
- Frontend tests consuming real API fixtures (or generated schema fixtures), not hand-crafted mismatched types.
|
|
|
|
### Assumptions
|
|
- Backend is the API source of truth.
|
|
- You want production-safe defaults even for self-hosted single-tenant deployments.
|