Give your agent a wallet you control.
에이전트가 일회용 카드나 기계 결제 프로토콜로 온라인 결제하고, 모든 요청을 직접 승인
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Practice portfolio: add practice trades and see them in AED. Built with Claude Code.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A small web app where a first-time investor adds a few practice trades and sees how they are doing, all in AED.
Live: https://practice-portfolio.7mxd.me/
e2e/motion.mjs).Money never passes through a floating-point number. Prices are parsed from text into whole cents, converted into micro-AED (millionths of a dirham) with BigInt, and only rounded to fils (half away from zero) when shown. 1 cent × 3.6725 is exactly 36,725 micro-AED, so the USD conversion is exact. For example, 230.00 USD is 844.675 AED and displays as AED 844.68.
The portfolio total is calculated from the exact values and rounded once, so in rare cases it can differ by 0.01 from the sum of the rounded rows. That is the more accurate choice.
npm install
npm run dev # local app
npm test # unit tests (Vitest)
npm run build # type-check and build
npm run e2e # browser smoke test; run `npx vite preview --port 4173` first
node e2e/a11y.mjs # accessibility audit (WCAG 2.2 AA + touch targets), same server
node e2e/motion.mjs # animations run, and none run with reduced motion, same server
Every push to main runs the unit tests, the build, the browser test, the accessibility audit and the motion check, and deploys to GitHub Pages only if all of them pass (.github/workflows/deploy.yml).
| File | What it does |
|---|---|
src/money.ts | Parsing prices, USD → AED, rounding and formatting. Pure functions. |
src/portfolio.ts | The five instruments, trade validation, merging trades into positions, each trade's own result, totals, the portfolio mix, the cost preview. |
src/storage.ts | Saving and loading trades (BigInt as strings), tolerant of bad data. |
src/main.ts | The page only: reads the form, shows errors, draws the summary, the mix bar, the holdings and each trade, confirmations and Undo. |
src/stock-select.ts | The stock drop-down with logos (ARIA select-only combobox, since a native <select> cannot show images). |
src/*.test.ts | Unit tests, including encoding.test.ts, which guards against garbled text. |
e2e/smoke.mjs | Browser test: errors, drop-down by mouse and keyboard, logos, totals, portfolio mix, each trade, Undo, reload. |
e2e/a11y.mjs | Accessibility audit with axe-core (after animations settle), plus the 44 px touch-target check. |
e2e/motion.mjs | Checks the animations run, and that none run with reduced motion on. |
docs/PRODUCT.md | Short product brief (users, tone, constraints) that guided the design decisions. |
docs/prompt-history.md, .pdf | Every prompt I gave Claude Code for this build, in order; the PDF is the same log, formatted. |
e2e/make-icons.mjs, e2e/shots.mjs | Helpers: the home-screen icon, and screenshots for visual checks. |
In the order I would build them:
On my phone, a holding read "Emaar Properties  · AED": a stray "Â" in front of the "·". Some quick edits had been made with Windows PowerShell, which read the UTF-8 files as Windows-1252 and saved them back, garbling every "·" (and "—" and "→" broke the same way). The 28 tests all passed, because they check numbers, not text. The browser test hadn't caught it either.
How I fixed it, test first:
.gitattributes fixes the line endings.Both checks run in CI before every deploy, so this cannot ship again unnoticed. The test proved its worth later: one more PowerShell edit slipped in and garbled the README, and the encoding test failed straight away, before anything was committed.
Earlier, the same cause showed up as a quieter problem: a find-and-replace matched nothing because of Windows vs Unix line endings. It was caught because each edit is searched for afterwards.
Company logos come from Wikimedia Commons and are cropped to their symbol (public/logos/). They belong to their owners and are used only to identify each company. ADNOC Gas is shown with the ADNOC parent logo.
The app's own mark (rising bars with a seedling) started as a Gemini concept, from a prompt that Claude Code wrote for me (it is in the prompt history). It was redrawn by hand as a small SVG (public/favicon.svg) in the app's palette, so it stays sharp from the 16 px browser tab to the 180 px home-screen icon (e2e/make-icons.mjs).
The prompts are in docs/prompt-history.md, also as a formatted PDF: docs/prompt-history.pdf. The money maths, the cost preview, each trade's result and the portfolio mix were written test-first: each test was run and seen to fail before the code existed. Most design changes came from me testing the live app on my phone and sending screenshots back. Claude checked each request against the brief before building it.