AutoTranscribe
Overview
- Secure upload and transcription web app with encryption, virus scanning, and S3-compatible storage (Akamai Linode Object Storage).
- Stack: React (Vite) client, Node/Express API, MongoDB, OpenAI Whisper (with optional Deepgram and AssemblyAI providers), ClamAV, Docker Compose.
Prerequisites
- A VM with Docker Engine and Docker Compose installed.
- Linode Object Storage bucket and access keys.
- OpenAI API key for Whisper (or set SKIP_TRANSCRIPTION=true), or a Deepgram API key, or an AssemblyAI API key.
Setup
- Copy
.env.exampleto.envand fill values:JWT_SECRETa long random stringS3_ENDPOINTfor your Linode regionLINODE_ACCESS_KEY,LINODE_SECRET_KEY,LINODE_BUCKETOPENAI_API_KEY(orSKIP_TRANSCRIPTION=true)WHISPER_MODEL(defaults towhisper-1)- Optional:
WHISPER_MAX_MB(defaults to 25) - Optional Deepgram provider: set
DEEPGRAM_API_KEY(and optionallyDEEPGRAM_MODEL) - Optional AssemblyAI provider: set
ASSEMBLYAI_API_KEY(and optionallyASSEMBLYAI_MODEL)
Build and Run (on your VM)
docker compose up -d --build- Open client at
http://<vm-host>:3000and API health athttp://<vm-host>:8080/api/health.
Services
mongo: MongoDB 6 with persistedmongo-datavolume.clamd: ClamAV daemon on port 3310.server: Express API at:8080.client: Nginx serving SPA at:3000and proxying/apitoserver.
API Notes
- Registration:
POST /api/auth/registerwith{ email, password }(min 8 chars).- Registration now requires a code:
{ email, password, code }. - Codes are single-use, auto-generated at server startup and topped up automatically in the background.
- Admin endpoints (set
ADMIN_API_KEYin.env):- List available codes:
GET /api/admin/registration-codeswith headerX-Admin-Key: <key> - List used codes:
GET /api/admin/registration-codes?status=usedwith headerX-Admin-Key: <key> - Generate codes:
POST /api/admin/registration-codes/generatebody{ n: 50 }with headerX-Admin-Key - Top up now:
POST /api/admin/registration-codes/topupwith headerX-Admin-Key
- List available codes:
- Registration now requires a code:
- Login:
POST /api/auth/loginreturns{ token }; sendAuthorization: Bearer <token>. - Upload:
POST /api/uploadmultipart fieldsfile,hasPII,hasPCI, optionalprovider=auto|openai|deepgram(defaultauto).
Security/Compliance
- AES-256-CBC encryption is applied when either PII or PCI flag is true. Keys/IV are stored in the
Filerecord for demo purposes; use a KMS in production. - Virus scanning via ClamAV; set
SKIP_VIRUS_SCAN=truefor development.
Troubleshooting
- Ensure
LINODE_*vars and bucket exist; API returns 500 if not configured. - If ClamAV takes time to update defs, first run may be slower; increase
CLAMD_STARTUP_TIMEOUTif needed. - For cross-origin local dev without Docker, API enables CORS; set client axios base to
http://localhost:8080/apior run via Docker where Nginx proxies/api.
Transcription Providers
- Primary: OpenAI Whisper (
OPENAI_API_KEY). - Fallback: Deepgram (
DEEPGRAM_API_KEY) and/or AssemblyAI (ASSEMBLYAI_API_KEY). Inprovider=auto, the server tries Whisper first (within size), then Deepgram, then AssemblyAI. - Force provider: Set
provider=openaito only use Whisper (no fallback). Setprovider=deepgramto only use Deepgram. Setprovider=assemblyaito only use AssemblyAI. - To force-skip transcription entirely, set
SKIP_TRANSCRIPTION=true. Stripe - Optional subscriptions integration is stubbed and ready.
- Configure in
.env(server reads secret; client uses VITE_ vars if you wire them):STRIPE_SECRET_KEY,STRIPE_PUBLIC_KEY- Price IDs (set at least the ones you will use):
STRIPE_PRICE_HOBBY_MONTHLY,STRIPE_PRICE_CREATOR_MONTHLY,STRIPE_PRICE_BUSINESS_MONTHLYSTRIPE_PRICE_HOBBY_ANNUAL,STRIPE_PRICE_CREATOR_ANNUAL,STRIPE_PRICE_BUSINESS_ANNUAL
- Redirects:
STRIPE_SUCCESS_URL,STRIPE_CANCEL_URL
- Endpoint:
POST /api/billing/checkoutwith{ priceId }and user JWT returns{ url }to redirect to Stripe Checkout. - If Stripe is not configured, the endpoint returns a stub checkout URL for testing navigation.