ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
An enterprise-grade, bilingual (Khmer & English) digital academic repository and AI-assisted research library purpose-built for the Phnom Penh Teacher Education College (PTEC).
PTEC e-Library is a free, public digital library and academic repository engineered to serve teacher educators, pre-service teacher trainees, and educational researchers across Cambodia. It bridges the accessibility gap for higher education by cataloging textbooks, curriculum guides, teacher training manuals, monographs, and student action-research theses into a unified, lightning-fast digital portal.README 전문 보기 ↗PTEC e-Library is a free, public digital library and academic repository engineered to serve teacher educators, pre-service teacher trainees, and educational researchers across Cambodia. It bridges the accessibility gap for higher education by cataloging textbooks, curriculum guides, teacher training manuals, monographs, and student action-research theses into a unified, lightning-fast digital portal.
The platform operates across dual deployment targets:
sin1), achieving single-digit millisecond latency to our Supabase database.flowchart TB
subgraph Clients["Clients & Edge Gateway"]
Browser["Desktop & Mobile Browsers<br/>(Bilingual Khmer/EN · PWA Offline Shell)"]
CF["Cloudflare Edge<br/>(Turnstile CAPTCHA · DDoS Shield · TLS 1.3)"]
CFTunnel["Cloudflare Tunnel Connector<br/>(Zero Open Ports on Self-Hosted Hardware)"]
end
subgraph AppHost["Application Host (Next.js 16 App Router)"]
Middleware["Next.js Middleware (Edge)<br/>- Canonical Host 308 Collapse<br/>- Split Content Security Policy<br/>- Fast-Path Auth Verification"]
subgraph RouteGroups["Route Architecture"]
PublicTree["app/[locale]/(public)/<br/>- Prerendered ISR Pages (revalidate=60)<br/>- Deep Native Search (/search)<br/>- Virtualized PDF.js Reader"]
AuthTree["app/(auth)/<br/>- Turnstile Protected Login/Signup<br/>- Gmail Custom SMTP Tokens"]
AdminTree["app/(admin)/admin/<br/>- AAL2 MFA (TOTP) Enforced<br/>- Central Route Policy Registry"]
end
UploadStaging[("Durable Staging Volume<br/>/app/.upload-staging<br/>(Atomic Chunk Assembly)")]
end
subgraph StorageTier["Resilient Object Storage Tier"]
Zima["Zima Storage Appliance<br/>- Primary HTTP REST Storage<br/>- Segment Budget: 64/80 chars<br/>- Multi-File Batch (120/hr)"]
R2["Cloudflare R2 (Legacy Fallback)<br/>- Presigned S3 GET URLs"]
end
subgraph DataTier["Data & Knowledge Engine (Supabase / Postgres 17)"]
Postgres[("PostgreSQL 17 Database<br/>- 100% Row Level Security (RLS)<br/>- 5 RBAC System Roles<br/>- 93 CI-Managed Migrations")]
PgVector[("pgvector Engine<br/>- book_chunks (768 dims)<br/>- HNSW Cosine Index<br/>- Scoped match_record_chunks()")]
LexicalIndex[("Lexical Search Engine<br/>- book_pages Extracted Text<br/>- GIN Trigram (pg_trgm)")]
end
subgraph AIEngine["AI Brain 2.1 Research Engine"]
AILogic["lib/ai/ Core Pipeline<br/>- Corpus Spellcheck (16,314 words)<br/>- Deterministic Intent Router (85% non-LLM)<br/>- Reciprocal Rank Fusion (RRF)<br/>- Structural Furniture Filter (TOC/Index)<br/>- Anti-Hallucination Citation Guard"]
Gemini["Google Gemini 3.5 Flash<br/>- Cloud Generation & Embeddings<br/>- Gemini Vision OCR Pipeline"]
Ollama["Local Ollama Service (ZimaOS)<br/>- Qwen2.5 Chat & BGE-M3 Embeddings<br/>- Automatic Circuit Breaker Fallback"]
end
Browser --> CF --> CFTunnel --> Middleware
Middleware --> PublicTree & AuthTree & AdminTree
AdminTree --> UploadStaging --> Zima
PublicTree -.-> R2
PublicTree & AdminTree --> Postgres
Postgres --> PgVector & LexicalIndex
PublicTree --> AILogic
AILogic --> Postgres
AILogic --> Gemini
AILogic --> Ollama
disableAutoFetch: true, disableStream: true): Instead of downloading entire 100+ MB PDFs, the reader requests only visible pages via HTTP 206 Byte-Range requests (reducing initial payload from ~178 MB to ~7 MB).pageColors API (#151B26 background, #E6EAF0 foreground) rather than naive CSS invert() filters, preserving diagram clarity and typography contrast.page.cleanup(), enforcing strict canvas budgets by device tier (Mobile, Tablet, Desktop) to prevent browser tab crashes.reading_progress.last_page) and bookmarks are stamped with the authenticated user's ID, preventing session collisions on shared campus workstations.app/sw.ts): Fine-grained caching policies separating hashed app assets, PDF.js workers, and dynamic API responses.lib/offline.ts): Binary PDF bytes are stored exclusively in the browser's Cache Storage under an isolated offline-books cache, verified via read-back assertions before marking titles as available offline./offline-books shelf and /offline-reader client viewer that function without an active internet connection.book_pages via pg_trgm) and semantic vector scans (book_chunks via pgvector(768) HNSW), fusing candidates through RRF.lib/ai/page-quality.ts): Heuristically detects and eliminates non-evidence sections (Tables of Contents, Indices) using sentence density and locator density signals, preventing TOC hits from dominating results.qwen2.5) on edge hardware, falling back to Gemini 3.5 Flash if the local instance experiences high latency or downtime.(Title, p. N), verifies them against retrieved passage metadata, and aggressively scrubs ungrounded claims.lib/admin/access-policy.ts): Declarative permissions registry. Every admin route and server mutation checks policies via await requireRouteAccess("books.upload").reader, staff, librarian, admin, and super_admin./admin/(protected).forbidden.tsx) and HTTP 401 (unauthorized.tsx) status codes rather than generic masked React errors./api/cron/security-scan), identifying credential stuffing, brute-force attempts, and malware uploads, instantly alerting via Telegram.init, chunk, finalize, GET, DELETE): Upload files up to 100 MiB with zero risk of HTTP timeouts.UPLOAD_STAGING_DIR), preventing "Missing chunk 0" errors during container redeployments.zimaUploadStream): Uploads directly to Zima Storage within a 1 MB memory window with an exact byte-calculated multipart boundary.POST /api/v1/files request, unlocking 120 books/hour (a 4× increase over single-file paths) while staying within storage API quotas.| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16.3.4 (App Router) | React Server Components, standalone output, --webpack build for PWA worker |
| UI Library | React 19.2.6 | Server Actions, optimistic state, Suspense streaming |
| Styling | Tailwind CSS v4 | Modern CSS-first engine, OKLCH color design tokens |
| Database | Supabase / PostgreSQL 17 | 100% RLS enforcement, PostgREST, GoTrue auth, connection pooling |
| Vector Engine | pgvector | 768-dimensional HNSW cosine index for semantic literature chunks |
| Lexical Engine | PostgreSQL pg_trgm | Trigram subword indexing across unsegmented Khmer script |
| Object Storage | Zima Storage & Cloudflare R2 | HTTP REST storage with atomic chunk assembly; legacy presigned R2 fallback |
| AI / LLM | Google Gemini 3.5 & Ollama | Hybrid RAG, Gemini Vision OCR, text-embedding-001, local Qwen2.5 |
| PDF Engine | PDF.js 6.2 & React-PDF 10.4 |
npm install -g supabase)git clone https://github.com/raksmeyron97-design/ptec-elibrary.git
cd ptec-elibrary
# Install dependencies and trigger postinstall (copies PDF.js assets)
npm install
Copy .env.example to .env.local:
cp .env.example .env.local
Fill in the required variables (see Environment Variable Registry).
supabase start
This boots PostgreSQL, PostgREST, GoTrue Auth, Storage, and automatically replays all 93 migrations from supabase/migrations/ plus supabase/seed.sql.
npm run dev
Open http://localhost:3000 in your browser.
[!TIP] If dev server renders become slow, clear Next.js Turbopack caches with:
npm run dev:clean
The project enforces strict automated quality gates before any code merges to main:
# Type check (allocates 4 GB heap to prevent OOM)
npx tsc --noEmit
# Lint code quality
npm run lint
# Run Vitest unit & invariant tests
npm test # Watch mode
npx vitest run # Single-pass CI execution
# Run Playwright End-to-End tests (boots local Supabase stack)
npm run test:e2e
# Run AI & Retrieval benchmarks
npm run ai:answer-benchmark -- --live-suite smoke --gate
npm run retrieval:benchmark
npm run search:benchmark
# Verify local Ollama AI connectivity (Khmer support & fallback)
npm run ai:local-check
# Verify PWA and hero image assets
npm run check:hero
npm run pwa:assets
Our automated test suite continuously asserts structural engineering invariants:
| Invariant Test Suite | Enforced Architectural Rule |
|---|---|
lib/cache/cache-safety.test.ts | Disallows cookies() or headers() in public route trees to maintain full static ISR prerenderability. |
lib/storage/folder-name.test.ts | Validates all storage folder path segments against Zima's 80-char regex and enforces 100% ASCII compliance. |
lib/uploads/state.test.ts | Guarantees upload state machine safety: sessions cannot reach COMPLETED without reaching STORED. |
lib/admin/authorization-boundary.test.ts | Asserts that every Server Action enforces permission guards before opening service-role database clients. |
lib/ai/live-contract.test.ts | Enforces that reasoning token budgets never consume output quotas and verified citations match ground truth. |
lib/ai/page-quality.test.ts | Proves that structural book furniture (TOC, Index) is excluded from AI evidence while substantive text is retained. |
lib/pdf-worker-tracing.test.ts | Guarantees that pdf.worker.mjs is correctly bundled into standalone output builds, preventing PDF indexing crashes. |
| Variable Name | Scope | Required | Description |
|---|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Client | Yes | Supabase API Gateway URL (Cloud or Self-Hosted Kong). |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Client | Yes | Public anonymous JWT key used for browser queries. |
SUPABASE_SERVICE_ROLE_KEY | Server | Yes | Elevated key bypassing RLS. Never expose to the client! |
ZIMA_API_URL | Server | Yes | Base URL of the primary Zima Storage appliance. |
ZIMA_API_KEY | Server | Yes | Secret API key for Zima file mutations. |
GEMINI_API_KEY | Server | Yes | Google Cloud API key for Gemini 3.5 Flash and text embeddings. |
AI_PROVIDER | Server | Optional | Default generation engine (gemini or ollama). Defaults to gemini. |
AI_EMBED_PROVIDER | Server | Optional | Embedding engine (gemini). Must match vector database dimensions (768). |
OLLAMA_BASE_URL | Server | Optional | Local Ollama endpoint on self-hosted hardware (http://127.0.0.1:11434). |
UPLOAD_STAGING_DIR | Server | Yes | Persistent directory for chunked upload staging (/app/.upload-staging). |
NEXT_PUBLIC_SITE_URL | Client | Yes | Canonical production origin (https://library.ptec.edu.kh). |
NEXT_PUBLIC_TURNSTILE_SITE_KEY |
sin1) in vercel.json.The repository ships with a multi-stage, hardened Docker setup:
# 1. Build and run using the production docker-compose
docker compose up -d --build
# 2. View container logs
docker compose logs -f ptec-elibrary
nextjs (UID 1001) on Alpine Linux.upload-staging to preserve chunked uploads across updates.web Docker bridge to a cloudflared sidecar container—requiring zero open inbound ports on your local network firewall.Ron Raksmey (រ៉ុន រស្មី)
Educator, Mathematics Scholar & Full-Stack Product Builder
Phnom Penh, Cambodia 🇰🇭
[email protected]| Range-request streaming viewer with canvas budgeting and dark recoloring |
| PWA & Offline | Serwist 9.5 & Web Push | Service worker caching, offline document shell, VAPID push notifications |
| i18n | next-intl 4.13 | Prerendered locale routing (/ for English, /km for Khmer) |
| Testing | Vitest 4.1 & Playwright 1.60 | Unit testing, local Supabase container replay, end-to-end browser tests |
| Client |
| Yes |
| Cloudflare Turnstile public site key. |
TURNSTILE_SECRET_KEY | Server | Yes | Cloudflare Turnstile server verification secret. |
CRON_SECRET | Server | Yes | Bearer token protecting automated /api/cron/* endpoints. |
TELEGRAM_BOT_TOKEN | Server | Yes | Telegram bot token for real-time Sev 1/2/3 security and system alerts. |
TELEGRAM_CHAT_ID | Server | Yes | Target Telegram channel/group ID for notifications. |
SMTP_USER / SMTP_PASS | Server | Yes | Gmail custom SMTP credentials for transactional authentication emails. |