diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..5d2bf43 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,10 @@ +language: "en-US" +reviews: + auto_review: true + # Instruct the AI to evaluate complexity and apply labels + system_prompt: > + You are an expert open-source maintainer. Analyze the code changes and the PR description. + Based on the complexity, automatically apply ONE of the following labels to the PR: + - 'complexity: basic' (for small UI tweaks, typos, simple bug fixes) + - 'complexity: intermediate' (for standard feature additions, new endpoints) + - 'complexity: high' (for major architecture changes, ML pipeline updates, complex logic) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index dbf4bd7..0491aac 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,7 +5,14 @@ body: - type: markdown attributes: value: | + > ⚠️ **Is this a security vulnerability?** + > Do NOT use this form. Read [SECURITY.md](https://github.com/jpdevhub/FreshScanAi/blob/main/SECURITY.md) and report it privately via email instead. + > Public disclosure of a security issue before a fix is shipped puts every user at risk. + + --- + Before submitting, search open issues to avoid duplicates. + Vague reports without reproduction steps will be closed. - type: textarea id: description diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 9f6b55f..17950f0 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,16 @@ name: Feature Request description: Suggest a new feature or enhancement -labels: [feature] +labels: [feature, needs-discussion] body: + - type: markdown + attributes: + value: | + > ⚠️ **Is this a security concern?** Use [SECURITY.md](https://github.com/jpdevhub/FreshScanAi/blob/main/SECURITY.md) instead. + + **Read before opening:** + - Features require maintainer approval before implementation work begins. + - A PR opened for a feature without a linked, approved issue will be closed. + - Check the [Roadmap in DOCUMENTATION.md](https://github.com/jpdevhub/FreshScanAi/blob/main/DOCUMENTATION.md#14-future-roadmap) first — if your idea is already planned, comment on the existing tracking issue instead. - type: textarea id: problem attributes: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9f91d26..c40443e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,15 @@ -## Summary - + -## Motivation - +## Description -## Implementation Notes - - -## Screenshots (if applicable) - + ## Checklist -- [ ] `npm run lint` passes -- [ ] Backend tests pass (`python -m pytest backend/`) -- [ ] No `.env` files or credentials committed -- [ ] Branch is up to date with `main` -- [ ] PR description is complete + +- [ ] `npm run lint` passes with no errors +- [ ] `npm run build` compiles without TypeScript errors +- [ ] `python -m pytest` passes (including new tests I added) +- [ ] No `.env` files, API keys, secrets, model weights, or `__pycache__` in this diff +- [ ] Branch is rebased on `main`, not merged diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..522fb54 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + # Maintain NPM dependencies (Frontend) + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + labels: + - "dependencies" + + # Maintain Python dependencies (Backend) + - package-ecosystem: "pip" + directory: "/backend" + schedule: + interval: "weekly" + labels: + - "dependencies" + + # Maintain GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + labels: + - "dependencies" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22c815b..458d1df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,14 +60,10 @@ jobs: cache: pip - name: Install dependencies - run: | - pip install fastapi uvicorn supabase Pillow numpy \ - python-dotenv python-multipart httpx pytest + run: pip install -r requirements-ci.txt - name: Lint with Ruff - run: | - pip install ruff - ruff check . --config ruff.toml + run: ruff check . --config ruff.toml - name: Run tests run: python -m pytest tests/test_ci.py -v diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 0000000..b600bc4 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,31 @@ +name: Greetings + +on: + pull_request_target: + types: [opened] + issues: + types: [opened] + +jobs: + greeting: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: | + 👋 Welcome to FreshScan AI! Thank you for opening an issue. + + Our maintainers will review this shortly. In the meantime, please ensure your report includes all necessary context and reproduction steps (if it's a bug). If this is a security issue, please close this and follow the `SECURITY.md` protocol. + pr-message: | + 🎉 Thank you for your Pull Request! We're thrilled to have your contribution to FreshScan AI. + + Before we review, please make sure you have: + - Followed the `CONTRIBUTING.md` guidelines. + - Ensured all automated CI checks (linting, tests) are passing. + - Checked that your commit messages follow the Conventional Commits format. + + A maintainer will review your code as soon as possible! diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..98380ea --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,24 @@ +name: Stale Issue/PR Management + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove the stale label or comment, otherwise this will be closed in 7 days.' + stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove the stale label or comment, otherwise this will be closed in 7 days.' + close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' + close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' + days-before-stale: 30 + days-before-close: 7 + exempt-issue-labels: 'bug,help wanted,needs-discussion' + exempt-pr-labels: 'dependencies' diff --git a/.gitignore b/.gitignore index fed1209..96ca793 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ __pycache__ *.pyo *.pyd *.egg-info +._* # Vite internals .vite diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4141d2..38f90fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,176 +1,239 @@ # Contributing to FreshScan AI -Thank you for your interest in contributing. Please read this document before opening an issue or pull request. +Thank you for your interest in contributing. + +> [!CAUTION] +> **Security issues must NOT be reported here.** Read [SECURITY.md](SECURITY.md) and email the maintainer privately instead. --- ## Table of Contents -- [Getting Started](#getting-started) +- [Before You Start](#before-you-start) +- [Understanding the Codebase](#understanding-the-codebase) - [Branch Naming](#branch-naming) - [Commit Message Conventions](#commit-message-conventions) -- [Pull Request Guidelines](#pull-request-guidelines) -- [Code Style](#code-style) -- [Testing](#testing) +- [Pull Request Requirements](#pull-request-requirements) +- [Code Standards](#code-standards) +- [Testing Requirements](#testing-requirements) +- [What Will Be Rejected](#what-will-be-rejected) - [Review Timeline](#review-timeline) - [Issue Labels](#issue-labels) -- [Contact](#contact) --- -## Getting Started +## Before You Start -Follow the setup steps in [README.md](README.md) to get your local environment running before contributing. +1. Set up your local environment fully by following [README.md](README.md). If your environment is not running correctly, do not open a PR. +2. Search open issues and open PRs before starting work. Duplicate work will be closed. +3. For any change that is **not** a clear bug fix or a `good first issue` task, **open an issue first** and get explicit approval from a maintainer before writing code. PRs submitted without prior discussion on non-trivial changes will be closed. +4. Do not begin working on an issue until it is assigned to you. Comment to request assignment; do not self-assign. + +--- + +## Understanding the Codebase + +Read [DOCUMENTATION.md](DOCUMENTATION.md) before touching any of the following areas. A PR that contradicts the documented architecture will be rejected regardless of code quality. + +| Area | Entry point | What to understand first | +|------|-------------|--------------------------| +| AI inference pipeline | `backend/inference.py`, `backend/fusion.py` | Dual-stream architecture (Stream A + Stream B), temperature scaling, fusion formula | +| Scan endpoints | `backend/main.py` → `/api/v1/scan`, `/api/v1/scan-auto` | Demo mode vs. real inference path, image routing via `router.py` | +| Frontend scan flow | `src/pages/ScannerPage.tsx` | `ScanPhase` state machine: `idle → capturing → processing → done/error` | +| Analysis display | `src/pages/AnalysisDashboard.tsx` | Score loading priority: `?id=` param → sessionStorage → latest scan | +| API client | `src/lib/api.ts` | All backend calls go through this single wrapper | +| Design system | `src/index.css` | Color tokens, typography, utility classes — do not introduce inline styles | +| Database schema | `backend/migrations/` | All schema changes require a new migration file | --- ## Branch Naming -Use the following conventions when creating branches: +Branches must follow this exact pattern. PRs from branches that do not match will not be reviewed. | Type | Pattern | Example | -|---|---|---| -| New feature | `feat/` | `feat/scan-history-export` | +|------|---------|---------| +| Feature | `feat/` | `feat/scan-history-export` | | Bug fix | `fix/` | `fix/map-marker-overlap` | | Documentation | `docs/` | `docs/update-setup-guide` | | Refactor | `refactor/` | `refactor/inference-pipeline` | -| Chore | `chore/` | `chore/update-dependencies` | +| Tests | `test/` | `test/auth-endpoint-coverage` | +| Chore | `chore/` | `chore/update-fastapi` | + +Rules: +- Use lowercase letters and hyphens only. No underscores, no slashes within the description. +- Keep the description under 40 characters. +- Never push directly to `main` or `dev`. Force pushes to `main` are disabled. --- ## Commit Message Conventions -Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. +Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification exactly. -``` -(): +```text +(): ``` -Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` +**Allowed types:** `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore` -**Examples:** +**Scopes map to the codebase:** -``` -feat(scanner): add confidence threshold display -fix(auth): handle OAuth redirect on mobile -docs: update backend setup instructions -chore: upgrade fastapi to 0.111 -``` +| Scope | What it covers | +|-------|---------------| +| `scanner` | `ScannerPage.tsx`, camera/upload logic | +| `dashboard` | `AnalysisDashboard.tsx` | +| `map` | `MarketMapPage.tsx`, Leaflet layer | +| `auth` | `auth.py`, `AuthPage.tsx`, OAuth flow | +| `inference` | `inference.py`, `fusion.py`, `router.py` | +| `api` | `main.py` endpoints | +| `db` | `backend/migrations/`, schema changes | +| `ci` | `.github/workflows/` | +| `deps` | Dependency updates | -Rules: -- Use the imperative mood in the summary ("add" not "added", "fix" not "fixed") -- Keep the summary line under 72 characters -- Do not end the summary line with a period +**Rules:** +- Use the imperative mood: `add`, `fix`, `remove` — not `added`, `fixed`, `removed`. +- Keep the summary line under 72 characters. +- Do not end the summary line with a period. +- Do not write vague summaries (`update files`, `fix stuff`, `changes`). These commits will be asked to be reworded before the PR is reviewed. ---- +**Examples:** -## Pull Request Guidelines +```text +feat(scanner): add live confidence threshold display +fix(auth): handle OAuth redirect loop on mobile Safari +test(inference): add unit tests for temperature scaling edge cases +chore(deps): upgrade fastapi to 0.115 +``` -Before opening a pull request: +--- -- Ensure your branch is up to date with `main` -- Run `npm run lint` and fix all errors -- Run the backend tests with `python -m pytest backend/` and ensure they pass -- Keep each PR focused on a single change +## Pull Request Requirements -**PR description must include:** +Every PR must pass **all** of the following before a review will begin. The CI pipeline (`ci.yml`) enforces the automated checks automatically on every PR opened against `main`. -1. **What** — a clear summary of the change -2. **Why** — the motivation or problem being solved -3. **How** — a brief description of the implementation approach -4. **Screenshots** — if the change affects the UI +### Automated gates (must be green) -Use this template when opening a PR: +| Check | Command | Failure means | +|-------|---------|---------------| +| Frontend lint | `npm run lint` | ESLint errors in TypeScript/React code | +| Frontend build | `npm run build` | TypeScript compile error or Vite build failure | +| Backend lint | `ruff check . --config ruff.toml` | PEP 8 / style violations in Python code | +| Backend tests | `python -m pytest tests/test_ci.py -v` | Regression in a CI-covered endpoint | -```markdown -## Summary - +Do not open a PR if any of these are failing locally. Fix them first. -## Motivation - +### Manual requirements (checked during review) -## Implementation Notes - +- [ ] Branch is up to date with `main` — rebase, do not merge +- [ ] No `.env` files, credentials, secrets, or API keys are present anywhere in the diff +- [ ] No model weight files (`.pth`, `.pt`, `.onnx`, `.bin`) are committed +- [ ] No `__pycache__/` directories, `.pyc` files, or macOS `._*` metadata files are committed +- [ ] New endpoints include corresponding tests in `backend/tests/` or `backend/test_*.py` +- [ ] New utility functions in the frontend include a test file (Vitest) +- [ ] UI changes include before/after screenshots in the PR description +- [ ] Schema changes include a new migration file under `backend/migrations/` -## Screenshots (if applicable) - +### PR description template -## Checklist -- [ ] `npm run lint` passes -- [ ] Backend tests pass (`python -m pytest backend/`) -- [ ] No `.env` files or credentials committed -- [ ] Branch is up to date with `main` -``` +Use the template that loads automatically from `.github/PULL_REQUEST_TEMPLATE.md`. Every section must be filled in. Placeholder text left in the description ("What does this PR do?", "Why is this change needed?") means the PR is not ready for review and it will be marked as **Draft** until it is. --- -## Code Style +## Code Standards -**Frontend (TypeScript / React):** +### Python / FastAPI -- Follow the existing TypeScript strict mode configuration in `tsconfig.app.json` -- Use functional components and hooks; no class components -- Keep components in `src/components/` and pages in `src/pages/` -- Use Tailwind utility classes consistent with the existing design system in `src/index.css` -- Do not introduce new dependencies without discussion in an issue first +- Type-annotate every function signature. Unannotated functions will not be merged. +- Keep route handlers thin. Business logic belongs in dedicated modules (`inference.py`, `fusion.py`, `router.py`, `auth.py`), not in `main.py` route bodies. +- All secrets and configuration must come from environment variables via `os.environ.get(...)`. No hardcoded fallback values for credentials. +- Follow the existing pattern for error handling: raise `HTTPException` with a precise `status_code` and `detail`. Do not swallow exceptions silently. +- Do not add a dependency to `requirements.txt` without a prior issue discussion. Add a comment next to it explaining why it is needed. +- Run `ruff check . --config ruff.toml` before pushing. Ruff is enforced in CI. -**Backend (Python / FastAPI):** +### TypeScript / React -- Follow PEP 8 -- Type-annotate all function signatures -- Keep route handlers thin; move business logic to dedicated modules -- Do not add dependencies to `requirements.txt` without discussion in an issue first +- Strict TypeScript mode is enabled in `tsconfig.app.json`. No `any` types without an explicit `// eslint-disable` comment that explains why. +- Use functional components and hooks only. Class components will not be accepted. +- Components go in `src/components/`. Pages go in `src/pages/`. Do not create new top-level directories without maintainer approval. +- All backend calls must go through `src/lib/api.ts`. Do not call `fetch()` directly from a component. +- Use the existing CSS design tokens defined in `src/index.css`. Do not introduce arbitrary color values, font sizes, or spacing that are not part of the design system. +- Do not add a new npm dependency without a prior issue discussion and maintainer approval. -**General:** +### General -- Do not commit `__pycache__/`, `.pyc` files, macOS `._*` metadata files, or build artifacts -- Do not commit `.env` or any file containing credentials or secrets +- Do not commit generated files, build artifacts (`dist/`), or editor configuration (`.vscode/`, `.idea/`) except for files already tracked. +- Do not modify `vercel.json`, `Dockerfile`, or `backend/startup.sh` without explicit maintainer approval — these affect production deployments. --- -## Testing +## Testing Requirements -**Frontend:** - -There are currently no frontend unit tests. If you add a utility function or a complex hook, include a test file alongside it (Vitest is available). - -**Backend:** +### Backend ```bash cd backend -python -m pytest +python -m pytest tests/test_ci.py -v ``` -Tests live in `backend/test_auth.py`, `backend/auto_test.py`, and `backend/test_pipeline.py`. Add tests for any new endpoint or inference logic you introduce. +- All new API endpoints must have at least one test in `backend/tests/` or as a new `test_*.py` file. +- All new inference or fusion logic must have unit tests covering the normal path and at least one edge case (e.g., zero confidence, boundary score values). +- Tests must pass with `DEV_BYPASS_AUTH=false`. Do not write tests that only work in bypass mode. + +### Frontend + +Vitest is configured. There are currently no component tests; if you add a utility function or a custom hook, include a co-located `.test.ts` or `.test.tsx` file. + +--- + +## What Will Be Rejected + +PRs will be closed without review if they: + +- Are submitted without a prior issue or maintainer approval for non-trivial changes +- Fail any automated CI gate +- Contain `.env` files, secrets, model weights, or binary artifacts +- Touch the deployment configuration (`vercel.json`, `Dockerfile`, `startup.sh`) without approval +- Introduce a new dependency (npm or PyPI) without prior discussion +- Rewrite existing, working logic without a documented reason +- Have vague commit messages (`fix`, `update`, `wip`, `changes`) +- Do not include tests for new logic +- Leave placeholder text in the PR description template +- Add UI that deviates from the design system tokens in `src/index.css` --- ## Review Timeline -- Assignment requests on issues: responded to within **24 hours** -- Pull request reviews: within **48 hours** of submission +| Action | Target | +|--------|--------| +| Assignment confirmation on issues | Within **24 hours** | +| First review on submitted PR | Within **48 hours** | +| Re-review after requested changes | Within **48 hours** | -If you have not received a response after 48 hours, tag the maintainer in a comment or reach out via Discord. +If you have not received a response after 48 hours, tag the maintainer (`@jpdevhub`) in a comment. --- ## Issue Labels | Label | When to use | -|---|---| -| `good first issue` | Self-contained tasks suitable for new contributors | -| `bug` | Something is broken or behaves incorrectly | -| `feature` | A new capability or enhancement | +|-------|-------------| +| `good first issue` | Self-contained tasks with clear acceptance criteria, no deep codebase knowledge required | +| `bug` | A confirmed deviation from documented behavior | +| `feature` | A new capability not yet described in the roadmap | | `help wanted` | Maintainer is actively seeking external input | | `documentation` | Changes or additions to docs only | +| `needs-discussion` | Opened issue requires design or architecture discussion before work can begin | -When opening an issue, apply the most relevant label and provide enough context for someone to start working without asking for clarification. +When opening an issue, apply the most relevant label and provide enough detail for a contributor to start work without asking for clarification. Vague issues will be closed with a request for more information. --- ## Contact | Channel | Handle / Address | -|---|---| +|---------|-----------------| | Discord | `Razen04` | -| Email | karanrathore23@zohomail.in | +| Email (non-security) | karanrathore23@zohomail.in | +| Security issues | See [SECURITY.md](SECURITY.md) | diff --git a/README.md b/README.md index 7ede9a3..948ec2d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
Report Bug · - Request Feature + Request Feature

diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..33ac7f5 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,67 @@ +# Security Policy + +## Supported Versions + +Only the latest commit on `main` receives security fixes. + +## Reporting a Vulnerability + +**Do NOT open a GitHub issue, pull request, or discussion for a security vulnerability.** Public disclosure before a fix is in place puts every user of this project at risk. + +### Private Disclosure + +Report vulnerabilities by **email only**: + +```text +karanrathore23@zohomail.in +``` + +Subject line: `[SECURITY] FreshScan AI — ` + +Include in your report: + +1. **Description** — what the vulnerability is and which component is affected. +2. **Steps to reproduce** — exact, minimal steps that demonstrate the issue. +3. **Impact** — what an attacker could achieve by exploiting it. +4. **Affected versions/commits** — commit SHA or version string if known. +5. **Suggested fix** (optional) — if you have a patch or mitigation in mind. + +Do not attach screenshots of credentials, keys, or personal data. + +### Response Timeline + +| Action | Target | +|--------|--------| +| Acknowledgement of receipt | Within **48 hours** | +| Initial triage / severity assessment | Within **5 days** | +| Fix or mitigation shipped | Within **14 days** for critical; **30 days** for others | +| Public disclosure | After the fix is merged and deployed | + +### What Qualifies + +Report issues such as: + +- Authentication bypass or token leakage in the FastAPI auth layer (`auth.py`) +- Exposure of `SUPABASE_SERVICE_KEY` or other secrets through any code path +- SQL injection or insecure direct object reference in Supabase queries +- Arbitrary file upload or path traversal in the scan endpoints +- Cross-origin resource sharing (CORS) misconfiguration that exposes authenticated endpoints +- Any condition where `DEV_BYPASS_AUTH=true` or `DEV_MODE=true` is reachable in production + +### What Does Not Qualify + +- Bugs that affect only local development environments with `DEV_BYPASS_AUTH=true` +- Issues requiring physical access to the device +- Theoretical vulnerabilities with no demonstrated exploit path + +### Coordinated Disclosure + +We follow a **coordinated disclosure** model. Once a fix is in place: + +1. A security advisory will be published in the GitHub Security tab. +2. The commit message will reference the CVE number if one has been assigned. +3. The reporter will be credited in the advisory unless they prefer anonymity. + +--- + +Thank you for helping keep FreshScan AI and its users safe. diff --git a/backend/requirements-base.txt b/backend/requirements-base.txt new file mode 100644 index 0000000..083eb70 --- /dev/null +++ b/backend/requirements-base.txt @@ -0,0 +1,8 @@ +fastapi>=0.111.0 +uvicorn[standard]>=0.29.0 +supabase>=2.4.0 +Pillow>=10.3.0 +numpy>=1.26.0 +python-dotenv>=1.0.0 +python-multipart>=0.0.9 +httpx>=0.27.0 diff --git a/backend/requirements-ci.txt b/backend/requirements-ci.txt new file mode 100644 index 0000000..bff7da2 --- /dev/null +++ b/backend/requirements-ci.txt @@ -0,0 +1,3 @@ +-r requirements-base.txt +pytest>=8.0.0 +ruff>=0.4.0 diff --git a/backend/requirements.txt b/backend/requirements.txt index 7a050b4..c8107e7 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,30 +1,13 @@ # FreshScan AI — Backend Dependencies # Install with: pip install -r requirements.txt -# ── Web Framework ───────────────────────────────────────────────────────────── -fastapi>=0.111.0 -uvicorn[standard]>=0.29.0 +-r requirements-base.txt -# ── Database / Auth ─────────────────────────────────────────────────────────── -supabase>=2.4.0 - -# ── Image Processing ────────────────────────────────────────────────────────── -Pillow>=10.3.0 +# ── Testing ─────────────────────────────────────────────────────────────────── +# Used for running test_auth.py scripts locally (CI test deps are in requirements-ci.txt) +pytest>=8.0.0 # ── ML / Inference (optional — server starts without them in demo mode) ─────── # Comment these out if you don't have GPU/model files and just want demo mode. torch>=2.2.0 torchvision>=0.17.0 - -# ── Numerics ────────────────────────────────────────────────────────────────── -numpy>=1.26.0 - -# ── Environment ─────────────────────────────────────────────────────────────── -python-dotenv>=1.0.0 - -# ── HTTP / Multipart ────────────────────────────────────────────────────────── -python-multipart>=0.0.9 -httpx>=0.27.0 - -# ── Testing ─────────────────────────────────────────────────────────────────── -pytest>=8.0.0 diff --git a/public/._manifest.json b/public/._manifest.json deleted file mode 100644 index ef371c7..0000000 Binary files a/public/._manifest.json and /dev/null differ diff --git a/src/pages/ScannerPage.tsx b/src/pages/ScannerPage.tsx index 3b9eb75..f357e5e 100644 --- a/src/pages/ScannerPage.tsx +++ b/src/pages/ScannerPage.tsx @@ -27,13 +27,14 @@ export default function ScannerPage() { if (!cameraActive || uploadPreviewUrl) return; let cancelled = false; + const currentVideo = videoRef.current; async function startCamera() { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode } }); if (cancelled) { stream.getTracks().forEach(t => t.stop()); return; } streamRef.current = stream; - if (videoRef.current) videoRef.current.srcObject = stream; + if (currentVideo) currentVideo.srcObject = stream; } catch (err) { if (!cancelled) console.error('Camera error:', err); } @@ -44,7 +45,7 @@ export default function ScannerPage() { cancelled = true; streamRef.current?.getTracks().forEach(t => t.stop()); streamRef.current = null; - if (videoRef.current) videoRef.current.srcObject = null; + if (currentVideo) currentVideo.srcObject = null; }; }, [facingMode, cameraActive, uploadPreviewUrl]);