# AI Study Room — Full Content (English) Generated: 2026-05-09 Total articles: 226 --- ## Git Commands Cheat Sheet: The Only Reference You Need URL: https://dingjiu1989-hue.github.io/en/tech/git-cheatsheet.html Date: 2026-05-07 | Board: tech Description: A comprehensive Git cheat sheet covering branches, undo operations, staging, commits, and remote collaboration. Bookmark this for quick lookups. Git is the backbone of modern software development. This cheat sheet covers every command you'll need in daily work — from basic commits to hairy rebase scenarios. ## Setup & Configuration git config --global user.name "Your Name" git config --global user.email "you@example.com" git config --global init.defaultBranch main git config --list # show all settings ## Starting a Repository git init # create a new repo git clone # clone an existing repo git clone -b # clone a specific branch ## Staging & Committing git status # what changed? git add # stage a file git add -p # stage interactively (hunks) git commit -m "message" # commit staged changes git commit -am "message" # add tracked files AND commit git commit --amend # fix the last commit message ## Branching git branch # list local branches git branch # create a branch git checkout # switch to a branch git checkout -b # create AND switch git switch # modern way to switch git switch -c # modern create + switch git merge # merge branch into current git branch -d # delete a branch (safe) git branch -D # force delete ## Undoing Things git restore # discard working changes git restore --staged # unstage a file git reset --soft HEAD~1 # undo last commit, keep changes staged git reset --hard HEAD~1 # undo last commit, discard changes (DANGER) git revert # safe undo — creates a new commit git stash # save uncommitted changes git stash pop # restore stashed changes ## Remote Repositories git remote -v # list remotes git remote add origin # add a remote git push origin main # push to remote git push -u origin main # push and set upstream git pull origin main # fetch + merge git fetch origin # fetch without merging git push origin --delete # delete remote branch ## Log & History git log --oneline --graph --all # pretty history graph git log -p # see changes to a file git blame # who changed what line git diff # unstaged changes git diff --staged # staged changes git show # details of a commit ## Advanced: Interactive Rebase git rebase -i HEAD~3 # squash/reword last 3 commits git rebase -i --autosquash # auto-squash fixup commits git rebase --continue | --abort | --skip ## Quick Reference Card Task| Command ---|--- Create branch| `git checkout -b feature/x` Save work| `git stash` Undo last commit| `git reset --soft HEAD~1` Discard file changes| `git restore file.txt` See what you did| `git log --oneline -10` Sync with remote| `git pull --rebase` Bookmark this page. You'll be back. --- ## Python Tutorial: From Zero to Your First Program URL: https://dingjiu1989-hue.github.io/en/tech/python-tutorial.html Date: 2026-05-07 | Board: tech Description: A beginner-friendly Python tutorial. Master variables, conditionals, loops, and functions in 30 minutes and write your first working program. Python is the most approachable programming language in the world — and also one of the most powerful. In this tutorial, you'll go from zero to a working program in 30 minutes. ## Installing Python Download from [python.org](). During installation on Windows, check **"Add Python to PATH"**. On macOS, `brew install python` works too. Verify with: python3 --version # should print "Python 3.x.x" ## Your First Program print("Hello, world!") Save as `hello.py` and run with `python3 hello.py`. That's it — you're a programmer now. ## Variables and Types name = "Alice" # string age = 30 # integer height = 1.68 # float is_student = False # boolean print(f"{name} is {age} years old") # f-strings! ## Conditionals score = 85 if score >= 90: print("A") elif score >= 80: print("B") elif score >= 70: print("C") else: print("Need improvement") ## Lists and Loops fruits = ["apple", "banana", "cherry"] fruits.append("date") print(fruits[0]) # "apple" for fruit in fruits: print(fruit.upper()) # List comprehension (Python's superpower) squares = [x**2 for x in range(10)] # → [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ## Dictionaries user = { "name": "Alice", "email": "alice@example.com", "age": 30 } print(user["name"]) user["city"] = "New York" # add a key for key, value in user.items(): print(f"{key}: {value}") ## Functions def greet(name, greeting="Hello"): return f"{greeting}, {name}!" print(greet("Alice")) # "Hello, Alice!" print(greet("Bob", "Howdy")) # "Howdy, Bob!" ## Working with Files # Read a file with open("data.txt", "r") as f: content = f.read() # Write a file with open("output.txt", "w") as f: f.write("Hello, file!") ## Error Handling try: result = 10 / 0 except ZeroDivisionError: print("Can't divide by zero!") finally: print("This always runs") ## A Complete Mini-Program import json def load_todos(): try: with open("todos.json") as f: return json.load(f) except FileNotFoundError: return [] def save_todos(todos): with open("todos.json", "w") as f: json.dump(todos, f, indent=2) def main(): todos = load_todos() while True: cmd = input("add/show/quit: ").lower() if cmd == "add": todos.append(input("Task: ")) save_todos(todos) elif cmd == "show": for i, t in enumerate(todos, 1): print(f"{i}. {t}") elif cmd == "quit": break main() ## Where to Go Next * **Automate the Boring Stuff** — free Python book, perfect for practical learners * **Real Python** — excellent tutorials from beginner to advanced * **Build something** — a CLI tool, a simple web scraper, a TODO app. Anything. The secret to learning Python: start building things immediately. Don't get stuck in tutorial hell. --- ## Docker in 30 Minutes: From Install to First Container URL: https://dingjiu1989-hue.github.io/en/tech/docker-quickstart.html Date: 2026-05-08 | Board: tech Description: A hands-on Docker tutorial for absolute beginners. Learn images, containers, and Dockerfiles by building and running your first containerized app. Docker lets you package your application with everything it needs into a lightweight container that runs anywhere. No more "it works on my machine." Let's get you from zero to a running container in 30 minutes. ## What Problem Does Docker Solve? Before Docker: you install Python 3.11, your teammate uses 3.10, the server runs 3.9. Your app uses PostgreSQL 15, but production is on 14. Dependency hell. Docker wraps your app AND its exact environment into one portable unit — a container. ## Installation Download **Docker Desktop** from [docker.com](). It includes Docker Engine, CLI, Docker Compose, and a GUI dashboard. Verify: docker --version docker run hello-world # should print a welcome message ## Core Concepts Concept| What It Is| Analogy ---|---|--- **Image**| A blueprint — the files, dependencies, and config| A recipe **Container**| A running instance of an image| The dish you cooked **Dockerfile**| Instructions to build an image| The recipe card **Docker Hub**| Public registry of images| GitHub for container images **Volume**| Persistent storage outside the container| An external hard drive ## Your First Container # Run nginx web server in a container docker run -d -p 8080:80 --name my-nginx nginx # Visit http://localhost:8080 — you'll see the nginx welcome page! # What's running? docker ps # Stop it docker stop my-nginx # Remove it docker rm my-nginx ## Writing a Dockerfile Create a simple Python app: # app.py from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello from Docker!' if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) # Dockerfile FROM python:3.12-slim # start from a Python image WORKDIR /app # set working directory COPY requirements.txt . # copy dependency list RUN pip install -r requirements.txt COPY . . # copy everything else EXPOSE 5000 # document what port we use CMD ["python", "app.py"] # what to run on start # requirements.txt flask==3.1.0 # Build and run docker build -t my-python-app . docker run -d -p 5000:5000 my-python-app ## Essential Commands docker ps # list running containers docker ps -a # list ALL containers docker images # list images docker logs # view logs docker exec -it bash # shell into a running container docker rm # remove a container docker rmi # remove an image docker system prune -a # clean up everything unused ## Docker Compose (Multi-Container Apps) # docker-compose.yml version: '3.8' services: web: build: . ports: - "5000:5000" depends_on: - db db: image: postgres:16 environment: POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data volumes: pgdata: docker compose up -d # start everything docker compose down # stop everything ## Docker vs VM Containers share the host OS kernel, so they start in milliseconds and use minimal RAM. VMs each need their own OS, taking gigabytes. For most web apps, Docker is the clear winner. --- ## 10 Must-Have VS Code Extensions to Double Your Productivity URL: https://dingjiu1989-hue.github.io/en/tech/vscode-extensions.html Date: 2026-05-07 | Board: tech Description: Handpicked VS Code extensions for AI completion, Git visualization, code formatting, and remote development. Install these first on any new editor. A freshly installed VS Code is a blank canvas. The right extensions turn it into the most powerful editor on the planet. Here are the 10 you should install first. ## 1\. GitHub Copilot / Supermaven AI code completion that actually works. Copilot understands your project context and suggests entire functions, not just single lines. If you're looking for a free alternative, **Supermaven** is surprisingly good for tab completions. Install at least one — coding without AI assistance in 2026 feels like coding without autocomplete. ## 2\. GitLens Git superpowers inside VS Code. Hover over any line to see who changed it and when. Inline blame annotations, rich commit history, branch comparison, and an interactive rebase UI. It makes the built-in Git support feel like a demo. Free for individual use. ## 3\. Prettier The formatter that ended all formatting arguments. Set it as your default formatter, enable "Format on Save," and never think about indentation or line wrapping again. Supports JavaScript, TypeScript, HTML, CSS, JSON, Markdown, and a dozen more languages. ## 4\. ESLint Catches bugs before they happen. It's not just about style — ESLint flags unused variables, missing await, unreachable code, and security patterns. Pair with Prettier for the ultimate code quality setup. ## 5\. Error Lens Shows errors and warnings inline, right in your code — not in a separate panel. The error message appears next to the offending line, color-coded. It sounds small, but seeing errors immediately as you type changes everything. Once you try it, you can't go back. ## 6\. Thunder Client A lightweight API client built into VS Code's sidebar. Think Postman, but it lives in your editor, doesn't require an account, and is much faster for quick API testing. Supports collections, environments, and scriptless testing. ## 7\. Dev Containers Define your development environment in a Dockerfile or docker-compose.yml, and VS Code runs inside the container. Every team member gets the exact same tools and versions — no more "works on my machine." Essential for projects with complex dependencies. ## 8\. Better Comments Color-codes your comments: orange for TODOs, red for FIXMEs, green for notes, blue for info. It makes important comments visually scannable instead of blending into a sea of gray. Simple idea, outsized impact. ## 9\. Path Intellisense Autocompletes file paths as you type imports and requires. Saves you from the "wait, was it `../../components/Button` or `../components/Button`?" dance. ## 10\. Project Manager Fast switching between projects. Save your favorite repos, assign tags, and jump between them with Ctrl+Shift+P → "Project Manager: Open." If you bounce between multiple codebases, this is a lifesaver. ## Bonus: Color Theme Pick one good theme and stick with it. **Catppuccin** , **Dracula** , and **One Dark Pro** are community favorites with excellent language coverage. A theme you enjoy looking at for 8 hours a day is worth the 30 seconds to install. --- ## Linux Commands Cheat Sheet: 50 Commands Every Developer Should Know URL: https://dingjiu1989-hue.github.io/en/tech/linux-commands.html Date: 2026-05-07 | Board: tech Description: A practical Linux command reference organized by task — file operations, process management, networking, permissions, and text processing. Bookmark this. A good Linux command-line reference isn't nice to have — it's essential. This cheatsheet covers 50 commands organized by what you're actually trying to do, from file navigation to process management to networking. ## File Navigation pwd # print working directory ls -la # list all files with details cd /path/to/dir # change directory cd .. # go up one level cd - # go back to previous directory find . -name "*.py" # find files by name pattern locate filename # find file quickly (uses indexed db) ## File Operations cp source dest # copy file cp -r source dest # copy directory recursively mv source dest # move or rename rm file # remove file rm -rf dir # remove directory (DANGER — no undo) mkdir -p a/b/c # create nested directories touch file # create empty file or update timestamp ln -s target link # create symbolic link ## Viewing and Editing Files cat file # print entire file less file # scroll through file (q to quit) head -20 file # first 20 lines tail -f file # follow file as it grows (logs) wc -l file # count lines grep "pattern" file # search for pattern grep -r "pattern" dir # search recursively nano file # simple terminal editor vim file # advanced editor (:q! to quit) ## Permissions chmod 755 script.sh # rwxr-xr-x (owner full, others read+execute) chmod +x script.sh # make executable chown user:group file # change owner and group umask 022 # set default permissions mask ## Process Management ps aux # list all running processes ps aux | grep nginx # find specific process top # real-time process monitor (q to quit) htop # prettier top (install separately) kill 1234 # terminate process by PID kill -9 1234 # force kill (SIGKILL) pkill -f pattern # kill by name pattern bg # resume suspended job in background fg # bring background job to foreground jobs # list background jobs ## Disk and Storage df -h # disk free (human-readable) du -sh dir # directory size summary du -sh * | sort -h # size of each item, sorted mount # show mounted filesystems lsblk # list block devices ## Networking ping host # test connectivity curl -I url # fetch headers only curl -s url | jq # fetch JSON and pretty-print wget url # download file ssh user@host # connect to remote server scp file user@host:path # copy file to remote netstat -tlnp # listening ports ss -tlnp # modern alternative to netstat lsof -i :3000 # what's using port 3000 ## Text Processing sed 's/old/new/g' file # replace all occurrences awk '{{print $1}}' file # print first column sort file # sort lines sort -u file # sort and deduplicate uniq -c file # count occurrences cut -d',' -f1 file # extract column 1 from CSV tr '[:lower:]' '[:upper:]' # convert case ## Compression and Archives tar -czf archive.tar.gz dir # create gzipped tarball tar -xzf archive.tar.gz # extract gzipped tarball gzip file # compress single file gunzip file.gz # decompress zip -r archive.zip dir # create zip ## System Info uname -a # kernel info whoami # current user who # who is logged in uptime # how long system has been up free -h # memory usage date # current date/time history # command history !! # re-run last command !$ # last argument of previous command ## Quick Reference by Task Task| Command ---|--- Find large files| `find . -type f -size +100M` Search in files| `grep -rn "TODO" .` Count files in directory| `ls -1 | wc -l` See disk usage of all mounts| `df -h` Check if a port is open| `nc -zv host 443` Watch command output every 2s| `watch -n 2 command` Create alias permanently| `echo 'alias ll="ls -la"' >> ~/.bashrc` --- ## REST API Best Practices: The Complete Guide for 2026 URL: https://dingjiu1989-hue.github.io/en/tech/rest-api-best-practices.html Date: 2026-05-07 | Board: tech Description: Design production-ready REST APIs with proper naming, versioning, pagination, error handling, and security. Includes OpenAPI documentation standards. REST APIs power the modern web, but most APIs are designed with subtle flaws that cause pain months later. This guide covers the conventions, patterns, and anti-patterns that separate production APIs from weekend projects. ## 1\. Use Nouns, Not Verbs, for Resources # Good GET /users GET /users/42 POST /users PUT /users/42 DELETE /users/42 # Bad GET /getUsers POST /createUser GET /users/42/getProfile ## 2\. Version Your API from Day One Use URL prefix versioning (`/v1/users`) or header-based versioning (`Accept: application/vnd.api.v2+json`). URL versioning is simpler for public APIs. Choose one and stick with it everywhere — mixing strategies is worse than either alone. ## 3\. Consistent Naming Conventions // JSON: camelCase for properties {{"userId": 42, "createdAt": "2026-05-07"}} // URL paths: kebab-case GET /user-orders/42 // Query parameters: snake_case GET /users?sort_by=name&page;_size=20 ## 4\. Use Proper HTTP Status Codes Code| When to Use ---|--- 200 OK| Successful GET, PUT, PATCH 201 Created| Successful POST — always include Location header 204 No Content| Successful DELETE (no body returned) 400 Bad Request| Malformed input, validation failure 401 Unauthorized| Missing or expired auth token 403 Forbidden| Authenticated but not permitted 404 Not Found| Resource doesn't exist 409 Conflict| Duplicate or state conflict 422 Unprocessable| Valid syntax but semantic error 429 Too Many| Rate limit exceeded — include Retry-After header 500 Internal Error| Unexpected server failure (never expose stack traces) ## 5\. Error Response Format Always return errors in a consistent structure: {{ "error": {{ "code": "VALIDATION_ERROR", "message": "Email is required", "details": [ {{"field": "email", "reason": "must not be empty"}}, {{"field": "age", "reason": "must be positive"}} ], "requestId": "req_abc123" }} }} ## 6\. Pagination, Filtering, and Sorting # Pagination with cursor (preferred for large datasets) GET /users?cursor=eyJpZCI6NDJ9&limit;=20 Response: {{"data": [...], "nextCursor": "eyJpZCI6NjJ9", "hasMore": true}} # Or offset-based for simpler use cases GET /users?offset=0&limit;=20 # Filtering GET /users?status=active&role;=admin # Sorting GET /users?sort=-createdAt # descending GET /users?sort=+name # ascending ## 7\. Security Checklist * **Always use HTTPS.** No exceptions. * **Set rate limits.** At minimum: 60 req/min per IP for unauthenticated, 1000 req/min per user for authenticated. * **Validate Content-Type.** Reject requests with wrong Content-Type headers. * **Set CORS explicitly.** Never use `Access-Control-Allow-Origin: *` with credentials. * **Use API keys or OAuth2.** Never roll your own auth protocol. * **Keep secrets out of responses.** Password hashes, internal IDs, stack traces, server versions. ## 8\. API Documentation Use OpenAPI 3.1 (Swagger). It's the industry standard and generates interactive docs automatically. Tools like Stoplight, Redoc, and Swagger UI render beautiful docs from a single spec file. If your API doesn't have an OpenAPI spec, it's not ready for production. --- ## Git Advanced: Interactive Rebase, Cherry-Pick, Bisect, and More URL: https://dingjiu1989-hue.github.io/en/tech/git-advanced.html Date: 2026-05-07 | Board: tech Description: Master the Git commands that separate senior developers from juniors. Interactive rebase, cherry-pick, bisect, reflog recovery, and custom Git hooks. Most developers stop at `add`, `commit`, `push`, and `pull`. But Git has a set of advanced commands that can save hours of frustration and make your commit history something you're actually proud of. Here's your guide to interactive rebase, cherry-pick, bisect, reflog, and hooks. ## Interactive Rebase: Rewrite History Cleanly The most powerful Git feature most developers never learn. Interactive rebase lets you reorder, squash, split, and edit commits before pushing. # Squash last 4 commits into 1 clean commit git rebase -i HEAD~4 # In the editor, mark commits: # pick abc1234 First commit message (keep as-is) # squash def5678 Fix typo (merge into previous) # squash ghi9012 Format code (merge into previous) # squash jkl3456 Update tests (merge into previous) # Then write a single commit message ### When to Use Interactive Rebase * **Before pushing to main:** Squash "WIP" and "fix typo" commits into meaningful units * **Before opening a PR:** Reorder commits so they tell a logical story * **Never:** On shared branches or commits that have been pushed. Rewriting public history causes chaos. ## Cherry-Pick: Apply a Specific Commit Anywhere When you need one specific commit from another branch without merging everything: # Apply a single commit to the current branch git cherry-pick abc1234 # Apply a range of commits git cherry-pick abc1234..def5678 # Cherry-pick without committing (stage changes only) git cherry-pick -n abc1234 Common use: a bug fix on a release branch that you need on main, but main has diverged significantly. Cherry-pick the fix commit. ## Git Bisect: Find the Commit That Broke Everything Binary search through your commit history to find exactly which commit introduced a bug: # Start bisect session git bisect start git bisect bad HEAD # current commit is broken git bisect good v2.5.0 # this tag was working # Git checks out a commit halfway between. Test it. # If broken: git bisect bad # If working: git bisect good # Repeat until Git identifies the culprit commit. # Then end the session: git bisect reset For automated bisecting, provide a test script: git bisect run npm test # Git runs the test on each step # If the test exits with code 0 → good, non-zero → bad # Git finds the breaking commit automatically ## Git Reflog: The Ultimate Undo Reflog records every movement of HEAD — commits, checkouts, rebases, resets. When you think you've lost work, reflog is your safety net: git reflog # Shows: abc1234 HEAD@{{0}}: commit: Add login feature # def5678 HEAD@{{1}}: rebase (finish): returning to refs/heads/main # ghi9012 HEAD@{{2}}: reset: moving to HEAD~3 # Recover that "lost" commit git checkout HEAD@{{2}} # go back to before the reset git branch recovered-branch # save it to a branch Scenario| Recovery Command ---|--- Undo a bad rebase| `git reset --hard HEAD@{{1}}` Recover deleted branch| `git checkout -b recovered HEAD@{{3}}` Undo amend on wrong commit| `git reset --soft HEAD@{{1}}` ## Git Hooks: Automate Your Workflow Hooks are scripts that run automatically on Git events. They live in `.git/hooks/` and can be written in any language. Use them to prevent mistakes before they happen: #!/bin/bash # .git/hooks/pre-commit — run linter before every commit npm run lint if [ $? -ne 0 ]; then echo "Linting failed. Commit aborted." exit 1 fi #!/bin/bash # .git/hooks/commit-msg — enforce conventional commits MSG=$(cat "$1") if ! echo "$MSG" | grep -qE "^(feat|fix|refactor|test|docs|chore)(\(.+\))?: "; then echo "Commit message must follow conventional commits format" echo " feat: add feature" echo " fix: resolve bug" exit 1 fi Hook| When It Runs| Use For ---|---|--- pre-commit| Before commit is created| Linting, formatting, unit tests commit-msg| After message is entered| Enforce message format pre-push| Before push to remote| Integration tests, security scans post-checkout| After checkout/switching branches| Install dependencies if changed --- ## Advanced TypeScript Patterns: Generics, Mapped Types, and Template Literals URL: https://dingjiu1989-hue.github.io/en/tech/typescript-advanced-patterns.html Date: 2026-05-08 | Board: tech Description: Go beyond basic TypeScript with advanced patterns: conditional types, mapped types, template literal types, infer, and brand types. Real examples that make your code safer. TypeScript's type system is a programming language in its own right. Once you go beyond basic annotations, you can encode invariants into types that make entire categories of bugs impossible. Here are the advanced patterns that level up your TypeScript in 2026. ## 1\. Conditional Types Conditional types select types based on a condition — like a ternary operator at the type level. type IsString = T extends string ? true : false; type A = IsString<"hello">; // true type B = IsString; // false // Real example: extract the array element type type ArrayElement = T extends (infer U)[] ? U : never; type Item = ArrayElement; // string ## 2\. Mapped Types Mapped types transform existing types by iterating over their keys. // Make all properties optional type Partial = { [K in keyof T]?: T[K] }; // Make all properties readonly type Readonly = { readonly [K in keyof T]: T[K] }; // Real example: pick nullable fields type Nullable = { [K in keyof T]: T[K] | null }; ## 3\. Template Literal Types Construct types from string patterns — powerful for typed routing and event systems. type EventName = "click" | "focus" | "blur"; type Handler = `on${Capitalize}`; // "onClick" | "onFocus" | "onBlur" // Real example: typed API routes type Route = `/api/${string}`; type UserRoute = `/api/users/${number}`; const route: UserRoute = "/api/users/42"; // OK const bad: UserRoute = "/api/users/abc"; // Error ## 4\. The infer Keyword Extract and capture types from other types during conditional type checks. // Extract return type of a function type ReturnType = T extends (...args: any[]) => infer R ? R : never; // Extract the promise resolved type type Awaited = T extends Promise ? U : T; // Real example: extract component props type Props = C extends React.ComponentType ? P : never; ## 5\. Branded Types (Nominal Typing) TypeScript uses structural typing, but sometimes you want nominal types — two strings that are not interchangeable. type UserId = string & { readonly __brand: "UserId" }; type OrderId = string & { readonly __brand: "OrderId" }; function createUserId(id: string): UserId { return id as UserId; } function getUser(id: UserId) { /* ... */ } getUser(createUserId("abc")); // OK getUser("abc"); // Error — plain string is not a UserId ## 6\. Discriminated Unions The most useful pattern in TypeScript. Model states exhaustively with a discriminator field. type RequestState = | { status: "idle" } | { status: "loading" } | { status: "success"; data: T } | { status: "error"; error: Error }; function render(state: RequestState) { switch (state.status) { case "idle": return "Ready"; case "loading": return "Loading..."; case "success": return state.data; // T — narrowed! case "error": return state.error.message; // Error — narrowed! } } ## 7\. Builder Pattern with Type Safety class QueryBuilder< T extends Record, Selected extends keyof T | "*" = "*", WhereClause extends Partial = {} > { select(...cols: K[]): QueryBuilder { return this as any; } where(conditions: Partial): QueryBuilder> { return this as any; } } ## Quick Reference: When to Use What Pattern| Use Case ---|--- Conditional Types| Transform types based on conditions Mapped Types| Bulk-modify object property types Template Literal Types| String-pattern-based types (routes, events) infer| Extract embedded types Branded Types| Distinguish same-shape types semantically Discriminated Unions| Exhaustive state modeling (async, forms) **Bottom line:** Advanced TypeScript patterns let you catch bugs at compile time instead of runtime. Discriminated unions and branded types alone will eliminate entire categories of bugs. See also: [TypeScript ORM comparison]() and [tRPC for end-to-end types](). --- ## Testing Strategies for Web Apps: Unit, Integration, E2E, and When to Use Each URL: https://dingjiu1989-hue.github.io/en/tech/testing-strategies-web-apps.html Date: 2026-05-08 | Board: tech Description: Stop guessing which tests to write. A practical guide to the testing trophy model — unit, integration, and e2e test strategies with real code examples. Testing is easy to get wrong. Too many unit tests give false confidence. Too few integration tests miss real bugs. Too many E2E tests make CI slow. Here's a practical guide to the Testing Trophy — the modern testing strategy that actually works. ## The Testing Trophy (Not the Testing Pyramid) The classic testing pyramid said "lots of unit, some integration, few E2E." The Testing Trophy inverts this: integration tests provide the most confidence per dollar, so write more of them. | Unit Tests| Integration Tests| E2E Tests ---|---|---|--- **Tests**| Single function/component| Multiple modules together| Full user flow in browser **Speed**| Fastest (ms)| Fast (10-100ms)| Slow (seconds) **Confidence**| Low (isolated)| High (integration is the risk)| Highest (real UX) **Flakiness**| None| Low| High (network, timing) **Debugging**| Easiest| Moderate| Hardest **Recommended ratio**| 20%| 60%| 20% ## Unit Tests — Test Pure Logic Exhaustively Unit tests shine for pure functions: validation logic, data transformation, utility functions, and business rules. Don't unit test React components in isolation — that's what integration tests are for. Don't test implementation details (test behavior, not methods). // Good unit test: pure business logic describe("calculateDiscount", () => { it("gives 20% off orders over $100", () => { expect(calculateDiscount({ total: 150, coupon: null })).toBe(30); }); it("stacks with coupon, max 50%", () => { expect(calculateDiscount({ total: 100, coupon: "SAVE30" })).toBe(40); }); }); ## Integration Tests — The Confidence Backbone Integration tests verify that multiple units work together. For frontend: render a component with real state, click something, assert the DOM. For backend: hit an endpoint, verify the database state. These catch the bugs unit tests miss. // Frontend integration test: render + interact + assert test("submits form and shows success", async () => { render(); await user.type(screen.getByLabel("Email"), "test@example.com"); await user.click(screen.getByText("Sign Up")); expect(await screen.findByText("Check your email")).toBeVisible(); }); // Backend integration test: request → response test("POST /api/users creates user in DB", async () => { const res = await request(app) .post("/api/users") .send({ email: "test@example.com", name: "Test" }); expect(res.status).toBe(201); const user = await db.query("SELECT * FROM users WHERE email = $1", ["test@example.com"]); expect(user.rows[0].name).toBe("Test"); }); ## E2E Tests — Validate Critical User Flows E2E tests drive a real browser through your most important flows: signup, login, purchase, onboarding. Keep these to critical paths only — they're slow and can be flaky. Playwright is the best E2E tool in 2026. // E2E: only critical paths test("user can complete purchase", async ({ page }) => { await page.goto("/products/widget"); await page.click("text=Add to Cart"); await page.click("text=Checkout"); await page.fill("[name=card]", "4242424242424242"); await page.click("text=Pay $29.00"); await expect(page.locator(".confirmation")).toContainText("Thank you"); }); ## Testing Stack Recommendations Layer| Tool| When ---|---|--- Unit| Vitest| Pure functions, utils, business logic Component Integration| Vitest + Testing Library| Any component with user interaction Backend Integration| Vitest + Supertest| API endpoints, DB writes E2E| Playwright| Signup, login, purchase, onboarding Visual Regression| Chromatic / Percy| Design system components **Bottom line:** Write mostly integration tests. They provide the best confidence-to-effort ratio. Unit test pure logic. E2E test only critical flows (max 20 scenarios). A slow CI pipeline is a broken one — keep E2E count low. See also: [build tools]() (Vitest is built on Vite) and [CI/CD tools comparison](). --- ## Web Security Basics: CORS, CSP, XSS, CSRF — What Every Developer Must Know URL: https://dingjiu1989-hue.github.io/en/tech/web-security-basics.html Date: 2026-05-08 | Board: tech Description: Practical web security guide covering Cross-Site Scripting, CORS headers, Content Security Policy, SQL injection, and CSRF attacks. Includes code examples and prevention strategies. Security isn't optional — it's part of your job as a developer. Most breaches exploit well-known vulnerabilities that have been understood for years. Here are the five web security threats every developer must understand, with prevention strategies and code examples. ## The Threat Landscape Attack| Severity| OWASP Rank| What It Does ---|---|---|--- XSS (Cross-Site Scripting)| Critical| #2| Injects malicious scripts into your pages SQL Injection| Critical| #3| Executes arbitrary SQL on your database CSRF (Cross-Site Request Forgery)| High| Dropped| Tricks users into performing unwanted actions CORS Misconfiguration| High| #5| Allows unauthorized cross-origin access Insecure Authentication| Critical| #1| Weak auth allows account takeover ## 1\. Cross-Site Scripting (XSS) XSS happens when user input is rendered as HTML without sanitization. An attacker who can inject