chore: sync port references and docs to 4000s infra

This commit is contained in:
asepharyana
2026-08-02 16:19:30 +07:00
parent ad7747bfd4
commit 62021397e0
21 changed files with 123 additions and 70 deletions
+4 -4
View File
@@ -1,13 +1,13 @@
BOT_TOKENS=isi_token_bot_1,isi_token_bot_2,isi_token_bot_3
STORAGE_CHANNEL_ID=-1001234567890
BASE_URL=https://tele.asepharyana.my.id
DATABASE_URL=postgresql://user:password@localhost:5432/telegram_uploader
PORT=3000
BASE_URL=https://upload.asepharyana.my.id
DATABASE_URL=postgresql://asephs:***@100.121.180.82:6432/uploader
PORT=4000
NODE_ENV=production
LOG_LEVEL=info
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=30
# TRUST_PROXY=true # Uncomment when behind reverse proxy (Traefik, Nginx) for correct client IP detection
# TRUST_PROXY=true # Uncomment when behind reverse proxy (Caddy, Nginx) for correct client IP detection
# S3-compatible API credentials
# S3_ACCESS_KEY=filedrop-admin
+6 -2
View File
@@ -1,3 +1,7 @@
# ⚠️ LEGACY — pembangunan & deploy sekarang DISARANKAN memakai Nix + systemd
# (lihat flake.nix + .github/workflows/deploy.yml + Caddy reverse proxy di orangevps).
# Dockerfile ini hanya dipertahankan untuk konteks historis / fallback, bukan deploy produksi.
# Stage 1: Builder
FROM oven/bun:alpine AS builder
@@ -26,7 +30,7 @@ COPY schema.sql ./
COPY package.json ./
# Expose port
EXPOSE 3000
EXPOSE 4000
# Start server
CMD ["bun", "dist/index.js"]
CMD ["bun", "dist/index.js"]
+20 -7
View File
@@ -4,12 +4,11 @@ Backend production-ready untuk upload file ke Telegram yang tersimpan di private
## Setup
1. Install PostgreSQL database
2. Buat database: `createdb telegram_uploader`
3. Setup environment: `cp .env.example .env`
4. Edit `.env` dengan nilai yang sesuai
5. Create table: `bun run db:migrate`
6. Install dependencies: `bun install`
1. Siapkan PostgreSQL database (produksi: database `uploader` via PgBouncer pool di `100.121.180.82:6432`)
2. Setup environment: `cp .env.example .env`
3. Edit `.env` dengan nilai yang sesuai (lihat `DATABASE_URL`, `PORT=4000`)
4. Create table: `bun run db:migrate`
5. Install dependencies: `bun install`
## Telegram Private Channel Setup
@@ -24,6 +23,20 @@ bun run dev # Development mode
bun run start # Production mode
```
## Deployment (Produksi — Nix + systemd)
> Infra lama berbasis Docker + Traefik sudah dihapus dari orangevps (2026-08-02).
- **Host**: orangevps
- **Service**: systemd unit `teleuploader` (env via `/etc/teleuploader/env` / BWS secrets)
- **Build**: Nix flake (`flake.nix`) — `nix build .#teleuploader``nix copy``systemctl restart teleuploader`
- **CI**: `.github/workflows/deploy.yml` (Gitea Actions / GitHub Actions)
- **Port**: `4000` (`PORT` env)
- **Domain**: `https://upload.asepharyana.my.id`
- **Reverse proxy**: Caddy (bukan Traefik/Docker)
- **Database**: `postgresql://asephs:***@100.121.180.82:6432/uploader` (PgBouncer pool di imrnes, **bukan** 5432/localhost)
- `deploy.sh` & `Dockerfile` & `docker-compose.yml` bersifat **legacy** — jangan dipakai untuk deploy produksi.
## API Endpoints
- `POST /api/upload` - Upload file
@@ -34,7 +47,7 @@ bun run start # Production mode
## FAQ
**URL permanen maksudnya apa?**
URL backend tetap permanen: `https://tele.asepharyana.my.id/f/{public_id}`
URL backend tetap permanen: `https://upload.asepharyana.my.id/f/{public_id}`
Ini berarti URL service Anda fix, bukan jaminan file Telegram abadi.
## Testing
+5
View File
@@ -1,4 +1,9 @@
#!/bin/bash
# ⚠️ LEGACY — Script deploy lama berbasis Docker. Sejak 2026-08-02 Docker dihapus
# dari orangevps; produksi kini memakai Nix + systemd (lihat flake.nix, dan CI
# .github/workflows/deploy.yml yang menjalankan `nix build` → `nix copy` →
# `systemctl restart teleuploader`). Berkas ini hanya dipertahankan sebagai
# referensi historis — JANGAN dipakai untuk deploy produksi.
# ─── FileDrop Deploy Script ──────────────────────────────────────────────────
# Builds the Bun app locally and deploys to the VPS via Docker.
#
+3
View File
@@ -1,3 +1,6 @@
# ⚠️ LEGACY — Docker/Traefik sudah DIHAPUS dari VPS produksi (orangevps).
# Deploy sekarang Nix + systemd (flake.nix + .github/workflows/deploy.yml) dengan
# Caddy reverse proxy. Berkas ini hanya dipertahankan sebagai referensi historis.
services:
app:
build: .
@@ -1,5 +1,10 @@
# Telegram Bot Uploader Backend Implementation Plan
> ⚠️ **LEGACY** — Dokumen historis (2026-05-17). Port & infrastruktur sudah berubah:
> produksi kini berjalan di port `4000` (Nix + systemd + Caddy, domain `upload.asepharyana.my.id`)
> dan database via PgBouncer pool `100.121.180.82:6432` (bukan port 5432, bukan localhost).
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Production-ready backend for Telegram file uploader with dual upload methods (bot + HTTP API), PostgreSQL storage, and redirect-based downloads.
@@ -75,9 +80,9 @@ schema.sql
```bash
BOT_TOKEN=isi_token_bot_telegram
STORAGE_CHANNEL_ID=-1001234567890
BASE_URL=https://tele.asepharyana.my.id
DATABASE_URL=postgresql://user:password@localhost:5432/telegram_uploader
PORT=3000
BASE_URL=https://upload.asepharyana.my.id
DATABASE_URL=postgresql://asephs:***@100.121.180.82:6432/uploader
PORT=4000
NODE_ENV=production
LOG_LEVEL=info
RATE_LIMIT_WINDOW_MS=60000
@@ -148,7 +153,7 @@ bun run start # Production mode
## FAQ
**URL permanen maksudnya apa?**
URL backend tetap permanen: `https://tele.asepharyana.my.id/f/{public_id}`
URL backend tetap permanen: `https://upload.asepharyana.my.id/f/{public_id}`
Ini berarti URL service Anda fix, bukan jaminan file Telegram abadi.
## Testing
@@ -250,7 +255,7 @@ export const config = {
storageChatId: parseInt(process.env.STORAGE_CHANNEL_ID, 10),
baseUrl: process.env.BASE_URL,
databaseUrl: process.env.DATABASE_URL,
port: parseInt(process.env.PORT, 10) || 3000,
port: parseInt(process.env.PORT, 10) || 4000,
nodeEnv: process.env.NODE_ENV || 'development',
logLevel: process.env.LOG_LEVEL || 'info',
rateLimitWindowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 60000,
@@ -1009,14 +1014,14 @@ bun run dev
- [ ] **Step 2: Test health endpoint**
```bash
curl http://localhost:3000/health
curl http://localhost:4000/health
# Expected: {"status":"ok"}
```
- [ ] **Step 3: Upload test file via HTTP API (multipart)**
```bash
curl -X POST http://localhost:3000/api/upload \
curl -X POST http://localhost:4000/api/upload \
-F "file=@/path/to/testfile.txt" \
-F "fileName=test.txt"
```
@@ -1024,14 +1029,14 @@ curl -X POST http://localhost:3000/api/upload \
- [ ] **Step 4: Check file info endpoint**
```bash
curl http://localhost:3000/file/{public_id}/info
curl http://localhost:4000/file/{public_id}/info
# Expected: JSON with file metadata
```
- [ ] **Step 5: Download redirect**
```bash
curl -I http://localhost:3000/f/{public_id}
curl -I http://localhost:4000/f/{public_id}
# Expected: HTTP 302 with Location header to Telegram CDN
```
@@ -1047,7 +1052,7 @@ curl -I http://localhost:3000/f/{public_id}
- [ ] **Step 7: Test error handling (file too large)**
```bash
curl -X POST http://localhost:3000/api/upload \
curl -X POST http://localhost:4000/api/upload \
-F "file=@/dev/null" \
-H "Content-Length: 10000000000"
# Expected: HTTP 400 with error message
@@ -1057,7 +1062,7 @@ curl -X POST http://localhost:3000/api/upload \
```bash
# Send 31 requests within 1 minute
for i in {1..31}; do curl http://localhost:3000/f/{public_id} & done
for i in {1..31}; do curl http://localhost:4000/f/{public_id} & done
wait
# Expected: First 30 succeed, last one returns 429
```
@@ -1066,7 +1071,7 @@ wait
```bash
# In terminal 1: bun run dev
# In terminal 2: curl http://localhost:3000/health && sleep 0.1 && curl http://localhost:3000/health
# In terminal 2: curl http://localhost:4000/health && sleep 0.1 && curl http://localhost:4000/health
# Send SIGINT to server (Ctrl+C in terminal 1)
# Check if server stops cleanly, logs show shutdown sequence
```
@@ -1,5 +1,11 @@
# Docker, Traefik, and GitHub Actions Deployment Plan
> ⚠️ **LEGACY** — Dokumen historis (2026-05-18). Arsitektur Docker + Traefik +
> GitHub Actions sudah digantikan (2026-08-02) oleh Nix + systemd + Caddy di
> orangevps: port `4000`, domain `upload.asepharyana.my.id`, database via
> PgBouncer pool `100.121.180.82:6432` (bukan 5432/localhost).
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Containerize TeleUploader using Bun, configure Traefik labels for routing `upload.asepharyana.my.id`, and set up full GitHub Actions CI/CD to VPS `45.127.35.244`.
@@ -57,7 +63,7 @@ WORKDIR /usr/src/app
# Set production environment variables
ENV NODE_ENV=production
ENV PORT=3000
ENV PORT=4000
# Copy necessary files from builder and repo
COPY --from=builder /usr/src/app/dist/index.js ./dist/index.js
@@ -65,7 +71,7 @@ COPY --from=builder /usr/src/app/package.json ./package.json
COPY schema.sql ./schema.sql
# Expose server port
EXPOSE 3000
EXPOSE 4000
# Start server
CMD ["bun", "dist/index.js"]
@@ -104,7 +110,7 @@ services:
- STORAGE_CHANNEL_ID=${STORAGE_CHANNEL_ID}
- BASE_URL=${BASE_URL}
- DATABASE_URL=${DATABASE_URL}
- PORT=3000
- PORT=4000
- NODE_ENV=production
- LOG_LEVEL=info
networks:
@@ -115,7 +121,7 @@ services:
- "traefik.http.routers.teleuploader.entrypoints=websecure"
- "traefik.http.routers.teleuploader.tls=true"
- "traefik.http.routers.teleuploader.tls.certresolver=letsencrypt"
- "traefik.http.services.teleuploader.loadbalancer.server.port=3000"
- "traefik.http.services.teleuploader.loadbalancer.server.port=4000"
networks:
app-shared-net:
@@ -166,9 +172,9 @@ jobs:
env:
BOT_TOKEN: "mock_token"
STORAGE_CHANNEL_ID: "123456"
BASE_URL: "http://localhost:3000"
DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/postgres"
PORT: "3000"
BASE_URL: "http://localhost:4000"
DATABASE_URL: "postgresql://asephs:***@100.121.180.82:6432/postgres"
PORT: "4000"
run: bun run test
build-and-push:
@@ -223,7 +229,7 @@ jobs:
- STORAGE_CHANNEL_ID=${STORAGE_CHANNEL_ID}
- BASE_URL=${BASE_URL}
- DATABASE_URL=${DATABASE_URL}
- PORT=3000
- PORT=4000
- NODE_ENV=production
- LOG_LEVEL=info
networks:
@@ -234,7 +240,7 @@ jobs:
- "traefik.http.routers.teleuploader.entrypoints=websecure"
- "traefik.http.routers.teleuploader.tls=true"
- "traefik.http.routers.teleuploader.tls.certresolver=letsencrypt"
- "traefik.http.services.teleuploader.loadbalancer.server.port=3000"
- "traefik.http.services.teleuploader.loadbalancer.server.port=4000"
networks:
app-shared-net:
@@ -248,7 +254,7 @@ jobs:
STORAGE_CHANNEL_ID=${{ secrets.STORAGE_CHANNEL_ID }}
BASE_URL=${{ secrets.BASE_URL }}
DATABASE_URL=${{ secrets.DATABASE_URL }}
PORT=3000
PORT=4000
EOF
# Pull latest docker image
@@ -1,5 +1,11 @@
# S3-Compatible TeleUploader Implementation Plan
> ⚠️ **LEGACY** — Dokumen historis (2026-07-06). Port & infrastruktur sudah berubah:
> produksi kini berjalan di port `4000` (Nix + systemd + Caddy, domain
> `upload.asepharyana.my.id`), database via PgBouncer pool `100.121.180.82:6432`
> (bukan 5432/localhost). Contoh kode di bawah memakai `localhost:4000` untuk dev.
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Transform TeleUploader into an S3-compatible storage server (Telegram-backed) with a web file manager UI.
@@ -2675,7 +2681,7 @@ describe('S3 Bucket Operations', () => {
process.env.S3_DEFAULT_REGION = 'us-east-1';
process.env.BOT_TOKEN = '123456:ABC-DEF';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'http://localhost:3000';
process.env.BASE_URL = 'http://localhost:4000';
process.env.DATABASE_URL = 'postgresql://localhost/test';
});
@@ -2684,7 +2690,7 @@ describe('S3 Bucket Operations', () => {
});
it('should return 403 for unauthorized requests', async () => {
const req = new Request('http://localhost:3000/', {
const req = new Request('http://localhost:4000/', {
method: 'GET',
headers: { authorization: 'Invalid' },
});
@@ -2849,7 +2855,7 @@ describe('Web API v1', () => {
mockDbExecute.mockClear();
process.env.BOT_TOKEN = '123456:ABC-DEF';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'http://localhost:3000';
process.env.BASE_URL = 'http://localhost:4000';
process.env.DATABASE_URL = 'postgresql://localhost/test';
});
@@ -2858,7 +2864,7 @@ describe('Web API v1', () => {
});
it('should list buckets via GET /api/v1/buckets', async () => {
const req = new Request('http://localhost:3000/api/v1/buckets');
const req = new Request('http://localhost:4000/api/v1/buckets');
const res = await handleWebApiV1(req);
expect(res.status).toBe(200);
const data = await res.json();
@@ -2867,7 +2873,7 @@ describe('Web API v1', () => {
});
it('should return 404 for unknown API path', async () => {
const req = new Request('http://localhost:3000/api/v1/unknown');
const req = new Request('http://localhost:4000/api/v1/unknown');
const res = await handleWebApiV1(req);
expect(res.status).toBe(404);
const data = await res.json();
@@ -2875,7 +2881,7 @@ describe('Web API v1', () => {
});
it('should return bucket object listing', async () => {
const req = new Request('http://localhost:3000/api/v1/buckets/test-bucket/objects?prefix=');
const req = new Request('http://localhost:4000/api/v1/buckets/test-bucket/objects?prefix=');
const res = await handleWebApiV1(req);
// Should return 200 even with empty results
expect(res.status).toBe(200);
@@ -2885,7 +2891,7 @@ describe('Web API v1', () => {
});
it('should reject invalid bucket name on create', async () => {
const req = new Request('http://localhost:3000/api/v1/buckets', {
const req = new Request('http://localhost:4000/api/v1/buckets', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ name: 'INVALID_NAME!' }),
@@ -1,5 +1,10 @@
# Telegram Bot Uploader Backend Design
> ⚠️ **LEGACY** — Dokumen historis (2026-05-17). Port & infrastruktur sudah berubah:
> produksi kini berjalan di port `4000` (Nix + systemd + Caddy, domain `upload.asepharyana.my.id`)
> dan database via PgBouncer pool `100.121.180.82:6432` (bukan port 5432, bukan localhost).
**Date:** 2026-05-17
**Status:** Approved
**Stack:** Bun, Telegraf, PostgreSQL, Drizzle ORM, Winston, nanoid
@@ -35,7 +40,7 @@ Production-ready backend untuk Telegram file uploader dengan dual upload methods
4. Bot extracts `telegram_file_id`, `telegram_file_unique_id`, `storage_message_id`
5. Bot generates `public_id` using nanoid
6. Bot saves metadata to PostgreSQL
7. Bot replies with download link: `https://tele.asepharyana.my.id/f/{public_id}`
7. Bot replies with download link: `https://upload.asepharyana.my.id/f/{public_id}`
#### Upload via HTTP API
1. Client POSTs to `/api/upload` with file (multipart or base64)
@@ -115,7 +120,7 @@ fileName: optional_filename.ext
"size_bytes": 1024000,
"file_type": "document",
"created_at": "2026-05-17T23:42:19Z",
"download_url": "https://tele.asepharyana.my.id/f/abc123xyz"
"download_url": "https://upload.asepharyana.my.id/f/abc123xyz"
}
```
@@ -212,9 +217,9 @@ schema.sql
```
BOT_TOKEN=<telegram_bot_token>
STORAGE_CHANNEL_ID=<private_channel_id>
BASE_URL=https://tele.asepharyana.my.id
DATABASE_URL=postgresql://user:password@localhost:5432/telegram_uploader
PORT=3000
BASE_URL=https://upload.asepharyana.my.id
DATABASE_URL=postgresql://asephs:***@100.121.180.82:6432/uploader
PORT=4000
NODE_ENV=production
LOG_LEVEL=info
RATE_LIMIT_WINDOW_MS=60000
@@ -7,6 +7,12 @@ metadata:
# Design: TeleUploader Deployment & CI/CD Setup
> ⚠️ **LEGACY** — Dokumen historis (2026-05-18) untuk arsitektur Docker + Traefik +
> GitHub Actions. Docker & Traefik sudah dihapus dari VPS produksi (2026-08-02):
> deploy sekarang Nix + systemd + Caddy di orangevps, port `4000`, domain
> `upload.asepharyana.my.id`, database via PgBouncer pool `100.121.180.82:6432`.
We are setting up production deployment for TeleUploader on VPS `45.127.35.244` behind Traefik utilizing GitHub Actions.
## 1. System Architecture
@@ -22,7 +28,7 @@ TeleUploader is a Bun-based service.
### `Dockerfile`
- Multi-stage build.
- **Stage 1 (Build)**: Install dependencies, copy source files, run Biome lint/format checks, compile TS build to `dist/index.js` using `bun build`.
- **Stage 2 (Run)**: Use minimal `oven/bun:1.1-slim` runtime. Copy `dist/index.js`, `schema.sql`, and `package.json`. Expose port `3000`.
- **Stage 2 (Run)**: Use minimal `oven/bun:1.1-slim` runtime. Copy `dist/index.js`, `schema.sql`, and `package.json`. Expose port `4000`.
### `docker-compose.yml`
```yaml
@@ -38,7 +44,7 @@ services:
- STORAGE_CHANNEL_ID=${STORAGE_CHANNEL_ID}
- BASE_URL=${BASE_URL}
- DATABASE_URL=${DATABASE_URL}
- PORT=3000
- PORT=4000
- NODE_ENV=production
- LOG_LEVEL=info
networks:
@@ -49,7 +55,7 @@ services:
- "traefik.http.routers.teleuploader.entrypoints=websecure"
- "traefik.http.routers.teleuploader.tls=true"
- "traefik.http.routers.teleuploader.tls.certresolver=letsencrypt"
- "traefik.http.services.teleuploader.loadbalancer.server.port=3000"
- "traefik.http.services.teleuploader.loadbalancer.server.port=4000"
networks:
app-shared-net:
+1 -1
View File
@@ -137,7 +137,7 @@ export const config: AppConfig = {
storageChatId: parseInt(process.env.STORAGE_CHANNEL_ID!, 10),
baseUrl: process.env.BASE_URL!,
databaseUrl: process.env.DATABASE_URL!,
port: parseInt(process.env.PORT!, 10) || 3000,
port: parseInt(process.env.PORT!, 10) || 4000,
nodeEnv: process.env.NODE_ENV || 'development',
logLevel: process.env.LOG_LEVEL || 'info',
rateLimitWindowMs: parseNumber(process.env.RATE_LIMIT_WINDOW_MS, 60000),
+1 -1
View File
@@ -1,5 +1,5 @@
const stripPort = (host: string): string => {
// Handle IPv6: [::1]:8080 -> [::1]
// Handle IPv6: [::1]:4321 -> [::1]
if (host.startsWith('[')) {
const closeBracket = host.indexOf(']');
return host.slice(0, closeBracket + 1).toLowerCase();
+2 -2
View File
@@ -10,8 +10,8 @@ const setEnv = (key: string, value: string) => {
defaultEnv('BOT_TOKEN', '123456:ABC-DEF');
defaultEnv('STORAGE_CHANNEL_ID', '-1001234567890');
defaultEnv('BASE_URL', 'https://example.com');
defaultEnv('DATABASE_URL', 'postgresql://user:pass@localhost:5432/test');
defaultEnv('PORT', '3000');
defaultEnv('DATABASE_URL', 'postgresql://asephs:***@100.121.180.82:6432/test');
defaultEnv('PORT', '4000');
defaultEnv('NODE_ENV', 'test');
setEnv('ADMIN_API_TOKEN', 'route-secret-token');
setEnv('SESSION_COOKIE_NAME', 'route_session');
+2 -2
View File
@@ -10,8 +10,8 @@ const setEnv = (key: string, value: string) => {
defaultEnv('BOT_TOKEN', '123456:ABC-DEF');
defaultEnv('STORAGE_CHANNEL_ID', '-1001234567890');
defaultEnv('BASE_URL', 'https://example.com');
defaultEnv('DATABASE_URL', 'postgresql://user:pass@localhost:5432/test');
defaultEnv('PORT', '3000');
defaultEnv('DATABASE_URL', 'postgresql://asephs:***@100.121.180.82:6432/test');
defaultEnv('PORT', '4000');
defaultEnv('NODE_ENV', 'test');
setEnv('ADMIN_API_TOKEN', 'route-secret-token');
setEnv('SESSION_COOKIE_NAME', 'route_session');
+1 -1
View File
@@ -4,7 +4,7 @@ process.env.BOT_TOKENS = 'bot1:token,bot2:token,bot3:token';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'https://example.com';
process.env.DATABASE_URL = 'sqlite://test.db';
process.env.PORT = '3000';
process.env.PORT = '4000';
// Track mock queue instances for per-bot assertions
const queueInstances: Array<{
+1 -1
View File
@@ -5,7 +5,7 @@ import type { TelegramMediaMessage } from '../src/shared/utils/file';
// Mock environment
process.env.BOT_TOKEN = process.env.BOT_TOKEN || '123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ';
process.env.STORAGE_CHANNEL_ID = process.env.STORAGE_CHANNEL_ID || '-1001234567890';
process.env.BASE_URL = process.env.BASE_URL || 'https://tele.asepharyana.my.id';
process.env.BASE_URL = process.env.BASE_URL || 'https://upload.asepharyana.my.id';
type BotTestContext = {
message: TelegramMediaMessage;
+5 -5
View File
@@ -28,7 +28,7 @@ describe('Environment Variables Validation', () => {
expect(config.storageChatId).toBe(parseInt(process.env.STORAGE_CHANNEL_ID || '0', 10));
});
it('config.port should default to 3000 when not specified', () => {
it('config.port should default to 4000 when not specified', () => {
expect(typeof config.port).toBe('number');
});
@@ -108,8 +108,8 @@ describe('Telegram chunk size validation', () => {
BOT_TOKENS: '123456:ABC-DEF',
STORAGE_CHANNEL_ID: '-1001234567890',
BASE_URL: 'https://example.com',
DATABASE_URL: 'postgresql://user:***@localhost:5432/test',
PORT: '3000',
DATABASE_URL: 'postgresql://asephs:***@100.121.180.82:6432/test',
PORT: '4000',
TELEGRAM_CHUNK_SIZE_BYTES: String(48 * 1024 * 1024),
},
stdout: 'pipe',
@@ -131,8 +131,8 @@ describe('Telegram chunk size validation', () => {
BOT_TOKENS: '123456:ABC-DEF',
STORAGE_CHANNEL_ID: '-1001234567890',
BASE_URL: 'https://example.com',
DATABASE_URL: 'postgresql://user:***@localhost:5432/test',
PORT: '3000',
DATABASE_URL: 'postgresql://asephs:***@100.121.180.82:6432/test',
PORT: '4000',
TELEGRAM_CHUNK_SIZE_BYTES: String(TELEGRAM_CHUNK_SIZE_MAX_BYTES),
},
stdout: 'pipe',
+2 -2
View File
@@ -13,8 +13,8 @@
process.env.BOT_TOKENS ||= '123456:ABC-DEF,789012:GHI-JKL,345678:MNO-PQR';
process.env.STORAGE_CHANNEL_ID ||= '-1001234567890';
process.env.BASE_URL ||= 'https://example.com';
process.env.DATABASE_URL ||= 'postgresql://user:pass@localhost:5432/test';
process.env.PORT ||= '3000';
process.env.DATABASE_URL ||= 'postgresql://asephs:***@100.121.180.82:6432/test';
process.env.PORT ||= '4000';
process.env.NODE_ENV = 'test';
// Pin the chunk size to the safe 19 MB value UNCONDITIONALLY. Bun auto-loads
+2 -2
View File
@@ -10,8 +10,8 @@ const setEnv = (key: string, value: string) => {
defaultEnv('BOT_TOKENS', '123456:ABC-DEF');
defaultEnv('STORAGE_CHANNEL_ID', '-1001234567890');
defaultEnv('BASE_URL', 'https://example.com');
defaultEnv('DATABASE_URL', 'postgresql://user:***@localhost:5432/test');
defaultEnv('PORT', '3000');
defaultEnv('DATABASE_URL', 'postgresql://asephs:***@100.121.180.82:6432/test');
defaultEnv('PORT', '4000');
defaultEnv('NODE_ENV', 'test');
setEnv('ADMIN_API_TOKEN', 'route-secret-token');
setEnv('SESSION_COOKIE_NAME', 'route_session');
+2 -2
View File
@@ -4,8 +4,8 @@ process.env.NODE_ENV = 'test';
process.env.BOT_TOKEN = '123456:ABC-DEF';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'http://localhost:4000';
process.env.DATABASE_URL = 'postgresql://localhost/test';
process.env.PORT = '3000';
process.env.DATABASE_URL = 'postgresql://asephs:***@100.121.180.82:6432/test';
process.env.PORT = '4000';
process.env.S3_ACCESS_KEY = 'filedrop-admin';
process.env.S3_SECRET_KEY = 'unit-test-secret';
+1 -1
View File
@@ -59,7 +59,7 @@ describe('Web API v1', () => {
process.env.BOT_TOKEN = '123456:ABC-DEF';
process.env.STORAGE_CHANNEL_ID = '-1001234567890';
process.env.BASE_URL = 'http://localhost:4000';
process.env.DATABASE_URL = 'postgresql://localhost/test';
process.env.DATABASE_URL = 'postgresql://asephs:***@100.121.180.82:6432/test';
const webApi = await import('../src/interfaces/http/controllers/web-api-controller');
handleWebApiV1 = webApi.handleWebApiV1;
});