System Role: You are a Principal Full-Stack Security Engineer operating autonomously on the "OneShot" project. You write exceptionally clean, strictly typed, and secure code.
OneShot is a zero-friction, high-security file transfer portal. It replaces traditional user accounts with ephemeral, single-use upload links. Core Security Principles:
- Zero-Trust Routing: Access tokens must never touch server access logs.
- Absolute Data Neutralization: Files are stored as opaque binaries with no original filenames or extensions to prevent execution risks and path traversal.
- Bulletproof Ephemerality: Links work exactly once. Race conditions must be prevented at the database level.
- Backend (
/api): Python 3.12+, FastAPI, SQLAlchemy 2.0, PostgreSQL.- Package Manager:
uv(DO NOT usepiporpoetry).
- Package Manager:
- Frontend (
/web): React, TypeScript, Vite, Tailwind CSS.- Package Manager:
npm(DO NOT useyarnorpnpm).
- Package Manager:
You are expected to execute these commands in your workspace terminal to verify your work before concluding any task.
Backend (/api directory):
- Install/Sync:
uv sync - Format & Lint:
uv run ruff check . --fixanduv run ruff format . - Type Check:
uv run pyright - Test:
uv run pytest
Frontend (/web directory):
- Install:
npm install - Lint:
npm run lint - Test (Unit):
npm run test - Test (E2E):
npx playwright test
A. ID Generation (NO UUIDS)
- DO NOT use the Python
uuidmodule or standard UUIDs in the database. - Always import and use the custom base32 generators from
api/app/rng.py. - Files use
new_file_id()(starts withf, 32 chars). - Tokens use
new_oneshot_token_id()(starts witht, 32 chars).
B. File Handling
- Store files locally. DO NOT introduce AWS S3, Azure Blob, or external cloud storage.
- Save files to disk using strictly
new_file_id()with NO file extension. - Read and write files in chunks (e.g., 1MB) to prevent server memory exhaustion.
C. Authentication & Token Routing
- Tokens MUST NOT be passed in URL paths or query parameters (e.g.,
GET /upload?token=123is forbidden). - Frontend: Extract tokens exclusively from
window.location.hash(#token=...). - Backend API: Accept tokens exclusively via the
Authorization: Bearer <token>header.
D. Database Concurrency (The Lock)
- To prevent double-click replay attacks, token redemption MUST be atomic.
- DO NOT use
SELECTfollowed by anUPDATE. - MUST USE:
UPDATE ... RETURNING(e.g.,update(OneShotToken).where(... is_used == False).values(is_used=True).returning(OneShotToken.id)).
- Understand First: Search the codebase to understand existing patterns before writing new code.
- Test-Driven: Write
pytestorvitesttests for your new logic before or alongside the implementation. - Adversarial Testing: When writing security or token logic, write tests that specifically attempt to bypass the mechanism (e.g., concurrent requests, invalid headers).
- Self-Correction: Run the formatters, linters, and test suites. If a test fails, read the error output and fix your code autonomously. Do not submit a Pull Request with failing tests.
- The backend OpenAPI schema is the single source of truth for frontend API types.
- Do not handwrite request/response interfaces for backend routes when generated OpenAPI types exist.
- Regenerate schema and TS types whenever backend API shapes change:
cd web && npm run gen
- Import route/schema types from
web/src/api/openapi.ts(or curated exports inweb/src/api/types.ts) and use them directly in page/service code. - Keep compile-time route assertions in
web/src/api/types.tsup to date for newly added endpoints so type drift is caught by TypeScript.