ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
一個針對金融與經濟課程的教室模擬投資風險。學生從手機將自己的財富分配於安全資產與高風險資產,市場於投影機上結算,並
AI 翻譯
A classroom simulation of investment risk, for finance and economics courses. Students divide their wealth between a safe and a risky asset from their phones, the market resolves on the projector, and
教育TypeScript · PLpgSQLGitHub @Water6446上線中營運者未確認
試用過了嗎? 點一下就好,不需要登入。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證The Risk Game 為課堂教學而設計的金融模擬,供學生使用。
AI 翻譯
Finance simulation built for in class learning with students
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A live, in-class simulation where a professor hosts a session and students join
from their phones/laptops to split their wealth between a safe and a
risky asset each round. Built on Next.js (App Router) + TypeScript,
Supabase (Postgres / Auth / Realtime), Tailwind, Recharts, and
qrcode.react. Replaces a manual spreadsheet.
Security is a first-class requirement. The threat model is a curious CS
student with browser dev tools and the public anon key. See
Security model and the hardening checklist.檢視完整 README ↗A live, in-class simulation where a professor hosts a session and students join
from their phones/laptops to split their wealth between a safe and a
risky asset each round. Built on Next.js (App Router) + TypeScript,
Supabase (Postgres / Auth / Realtime), Tailwind, Recharts, and
qrcode.react. Replaces a manual spreadsheet.
Security is a first-class requirement. The threat model is a curious CS student with browser dev tools and the public anon key. See Security model and the hardening checklist.
Three games share one engine — lobby, rounds, lock/reveal, leaderboard, present mode and CSV export. Hosts have accounts (a dashboard of past and live sessions); students join anonymously with a code or QR and may optionally keep their results in an account.
| Doc | What's in it |
|---|---|
| DESIGN.md | The "Academy Arcade" design system every screen follows |
| MECHANICS.md | How every game number works (luck, Sharpe, returns, ρ, fees, the index fund) |
| docs/DEPLOYMENT.md | Supabase CLI workflow, dashboard setup, the launch checklist |
| docs/ACCOUNTS.md | How accounts work, the security rules behind them, hosting limits |
| CLAUDE.md | Working notes for AI-assisted changes (read before editing) |
| Basic | Portfolio | Manager | |
|---|---|---|---|
| Risky side | one risky bet | N risky assets | 5 fund managers + an index fund |
| Outcome | good / bad | good / bad per asset | continuous normal returns |
| Round = | a round | a round | a year (25 by default) |
| Extra | — | correlation ρ | fees, leverage to 2×, a secret alpha |
The manager game teaches active vs. passive: skill is real but tiny and statistically invisible over a career, fees compound against you regardless, and a 0.05% index fund is always on the menu as the passive alternative. Its maths, the fee order of operations and the secrecy model are in MECHANICS.md § Manager game.
$100).25).safe = current − risky.p = 0.6) or Bad.new = safe + risky·(1.1|0.9)new = safe + risky·(2|0)market_mode = auto|manual,
market_scope = shared|independent (manual implies shared).Worked examples (all verified by tests, in both TS and SQL):
| mode | wealth | risky | outcome | result |
|---|---|---|---|---|
| moderate | 100 | 50 | good | 105 |
| moderate | 100 | 50 | bad | 95 |
| extreme | 100 | 50 | good | 150 |
| extreme | 100 | 50 | bad | 50 |
app/ Next.js routes: / (marketing), /host, /join, /play,
/login, /account, /auth, /privacy, /terms
components/ UI — ui.tsx primitives, icons.tsx, and one folder per
surface (host/, student/, account/, auth/, marketing/)
lib/game/ Pure, unit-tested game maths — the TypeScript mirror of
the SQL (types, math, portfolio, manager, results, format)
lib/auth/ Who may host, sign-in validation, open-redirect guard
supabase/migrations/ SQL migrations, applied in order (`npm run db:push`)
0001–0005 Schema, RLS + grants + Realtime, host RPCs + round loop,
delete_session, submit_allocation
0006–0013 Market odds, bots, the portfolio game, correlation
0008 TEMPORARY testing bypass: guests may host (see CLAUDE.md)
0014–0015 The manager game (session_secrets holds the true alpha:
RLS on, NO policies, NO grants — deny-all)
0016–0025 The account layer (see docs/ACCOUNTS.md)
0026 The manager game's index fund
0027–0030 Security fixes: throttle counts up front, player names +
host moderation, hidden odds in session_secrets,
helper grants + size limits
scripts/
db-selftest.mjs `npm run test:db` — applies every migration to a
throwaway in-process Postgres and runs both suites below
db_selftest.sql The game: security model + wealth math + manager secrecy
accounts_selftest.sql The account layer
_supabase_mock.sql Local stand-in for Supabase's auth surface (test only)
security-check.ts `npm run security-check` — the same denials, live
Copy .env.example to .env.local and fill in. The comments there explain
each one.
| var | exposure | purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | public | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | public | publishable key (safe; protected by RLS) |
NEXT_PUBLIC_SITE_URL | public | canonical URL for join link/QR, auth redirects, metadata; Production only (https://www.sharpesim.com) |
NEXT_PUBLIC_ALLOW_ANON_HOST | public | the testing bypass; on until launch |
NEXT_PUBLIC_EMAIL_DELIVERY | public | show email-dependent flows; off until custom SMTP |
USERNAME_LOOKUP_SECRET | server only | enables username sign-in; unset = email only |
SUPABASE_SERVICE_ROLE_KEY | server only | not used by the app; only the live security check |
The service_role key is never shipped to the client and is not needed to run the app — every privileged action is a host-only RPC.
npm run db:push).npm install
npm run dev # Next.js dev server on http://localhost:3000
npm run test # game-maths unit tests (Vitest)
npm run test:db # the database self-tests (no Docker, no cloud)
npm run test:db builds a throwaway Postgres in-process (PGlite), applies a
tiny mock of Supabase's auth.uid() / role surface plus every migration,
and runs two suites as attacker identities — aborting on any failure. Run one
with npm run test:db -- game or -- accounts. Among what they prove:
current_wealth, write
any allocation directly, or put more than their wealth at risk (the submit
RPC clamps it);sessions.config leaks no alpha, beta or
tracking_error; a student cannot read session_secrets or call
get_manager_truth before the game finishes; the leverage cap is enforced
server-side; the index fund stays out of the skill shuffle and tracks the
market exactly, less its fee;profiles, quotas and the player
cap hold, guest purges sever rather than delete results, username lookup
fails closed, the login throttle locks.While the testing bypass is live the game suite also prints a NOTE: that a
guest can host — a reminder, not a failure.
NEXT_PUBLIC_* variables above (and USERNAME_LOOKUP_SECRET if you
want username sign-in) as Vercel env vars. Do not set the service_role
key in Vercel.student-game-5.vercel.app both redirect there). Set it as the Supabase
Auth → URL Configuration Site URL, with https://www.sharpesim.com/** in
the redirect URLs, so Google and email sign-in return to your app.The full pre-class launch checklist — including closing the testing bypass — dashboard steps, smoke test and rollback plan live in docs/DEPLOYMENT.md.
anon/authenticated roles, so every direct query is subject to policy.resolve_round, a SECURITY DEFINER
function that asserts the caller is the session's host, refuses unless the
round is locked, and is the only writer of players.current_wealth.submit_allocation (and its
portfolio/manager siblings): SECURITY DEFINER RPCs that tie the row to
auth.uid(), accept only while the round is open, validate the amounts
(the basic game clamps 0 ≤ risky ≤ wealth; the manager game rejects anything
past the leverage cap) and derive safe server-side. Students hold no direct
insert/update grant on allocations at all (players: display_name only).0008 plus
NEXT_PUBLIC_ALLOW_ANON_HOST; both are reverted at launch
(docs/DEPLOYMENT.md Part C.1).0024) —
Supabase grants every new function to anon directly, so this is enforced
explicitly and asserted by the self-test.get_my_rank() (returns rank + total, never the list).session_secrets, readable
only through get_manager_truth() (the host any time, students once the game
finishes).supabase_realtime publication (done by 0002_rls.sql).npm run test:db passes, and npm run security-check against the live
project.