Docuask / PROJECT_SPEC.md
Claude
Point live demo at the working Railway deployment
1874e21 unverified
|
Raw
History Blame Contribute Delete
5.42 kB
# DocuAsk β€” Full-Stack Document Q&A Web App
## Purpose (read first)
A customer-facing web app where a user uploads a PDF (or pastes text), asks
questions in a chat box, and gets answers with the source passage shown. The
retrieval backend is intentionally lightweight β€” the point of this project is
the front-end product loop and user-facing data collection, not the RAG. Spend
effort on the UI, error handling, and the feedback/telemetry layer.
Target reviewer: general software-engineering apprenticeship (React front-end,
REST API, CI/CD, deployed live URL, product metrics).
## Stack (fixed β€” do not substitute)
- **Frontend:** React + Vite + Tailwind CSS
- **Backend:** FastAPI (Python)
- **Retrieval:** BM25 + FAISS (keep minimal; a single in-memory index is fine)
- **Persistence:** SQLite (question/answer/latency/feedback log)
- **Tests:** pytest (backend)
- **CI:** GitHub Actions running pytest on every push
- **Deploy:** Docker Compose locally; frontend to Vercel/Netlify, backend to
Render/Railway
## Repository setup (Session 0)
Public GitHub repo named `docuask` under github.com/Sriyansh-28.
- `git init`, add a Python + Node `.gitignore`, MIT license, `README.md`.
- Structure:
```
docuask/
backend/ # FastAPI app, retrieval, db, tests
frontend/ # Vite React app
docker-compose.yml
.github/workflows/ci.yml
README.md
PROJECT_SPEC.md
```
- First commit: skeleton only. Push to the new remote before writing features.
## Session 1 β€” Skeleton end to end
Goal: browser shows data fetched from the API.
- FastAPI app with `GET /health` returning `{"status":"ok"}`.
- Vite React app with one page that calls `/health` and renders the status.
- Docker Compose brings both up with one `docker compose up`.
- CORS configured so frontend can call backend in dev.
**Acceptance criteria**
- [x] `docker compose up` starts both services with no errors.
- [x] Opening the frontend URL shows "API status: ok" pulled live from the backend.
- [x] Repo pushed; README has a one-line run instruction.
## Session 2 β€” Upload & parse flow
Goal: user uploads a PDF; backend extracts and chunks the text.
- `POST /documents` accepts a PDF or raw text, extracts text (pypdf), splits
into chunks, builds/stores the index in memory keyed by a document id.
- Frontend: drag-and-drop upload widget with loading and success states.
- Handle failures visibly: encrypted PDF, non-PDF file, empty/huge file β†’ clear
error message in the UI, no crash.
**Acceptance criteria**
- [x] Uploading a normal PDF returns a document id and shows "ready" in the UI.
- [x] Uploading a broken/encrypted PDF shows a friendly error, backend logs it.
- [x] A pytest test covers the parse-failure path.
## Session 3 β€” Retrieval + chat loop
Goal: the core question→answer experience.
- `POST /ask` takes `{document_id, question}`, runs BM25 + FAISS retrieval,
returns the answer text plus the top source passage.
- Frontend: chat interface β€” question input, message history, each answer shows
the source passage underneath.
- Show a loading indicator while `/ask` is in flight.
**Acceptance criteria**
- [x] Asking a question about an uploaded doc returns a relevant passage.
- [x] The source passage is visibly shown under each answer.
- [x] Empty question or unknown document id is handled gracefully.
## Session 4 β€” Data-collection & feedback layer (the score-lifting part)
Goal: turn this into a web-enabled system for data collection with product
metrics.
- SQLite table
`interactions(id, document_id, question, answer, latency_ms, feedback, created_at)`.
- Every `/ask` call logs the row with measured `latency_ms`.
- πŸ‘ / πŸ‘Ž buttons on each answer β†’ `POST /feedback` updates the row.
- `GET /stats` returns: total questions, median latency, thumbs-up rate.
- A small `/dashboard` page in the frontend reads `/stats` and shows 3 numbers +
a simple bar of questions-over-time.
**Acceptance criteria**
- [x] Each question persists with its real latency.
- [x] Feedback buttons update the record and reflect in `/stats`.
- [x] Dashboard page renders the three metrics live from the DB.
## Session 5 β€” Polish, test, deploy
Goal: live URL + green CI + a README a recruiter can skim.
- Backend pytest suite covers `/health`, upload success + failure, `/ask`,
`/feedback`.
- `.github/workflows/ci.yml` runs pytest on every push; badge in README.
- Deploy backend (Render/Railway) and frontend (Vercel/Netlify); wire the live
API URL.
- README: one-paragraph description, screenshot/GIF of the chat + dashboard,
live demo link, run instructions, tech stack.
> Deployed as the single-image combined app (`Dockerfile` + `app/server.py`) on
> **Railway** β€” one container serving the React frontend and the FastAPI API
> under `/api` from one origin. (A Hugging Face Static Space + separate API is
> also supported; see the README.)
**Acceptance criteria**
- [x] CI badge is green on the default branch.
- [x] Live demo URL works end to end (upload β†’ ask β†’ feedback β†’ dashboard) β€”
verified against https://docuask-production-c732.up.railway.app.
- [x] README has a screenshot and the live link.
## Guardrails
- Keep retrieval simple; do not over-engineer the RAG. If a session is running
long, cut retrieval sophistication, never the front-end or telemetry.
- Only report metrics you actually measured. No invented user counts.