# Elements Directory

Every element on the periodic table, its route, backend mount, and auth model, in one table. "Public reads" means unauthenticated GETs; writes always need a token unless noted.

This table is generated from the site's element registry, so it lists every tile that actually renders on the homepage, including the ones that are external links or not built yet.

| Element | Route | Backend mount | Auth model | What it is |
| --- | --- | --- | --- | --- |
| Journal | /journal | /api/journal | invite-only: membership on every route, scoped writes | collaborative wiki-journal, see [Journal API](/docs/journal-api) |
| RNG Capitalist | /rng-capitalist | /api/rng | authed (any PAT), no scope; Plaid bank linking is browser-session only | AI purchase-decision roulette; evaluate costs an LLM call, 10/min |
| Knowledge | /knowledge | /api/knowledge | public reads; scoped writes | AI-classified knowledge base, see [Knowledge API](/docs/knowledge-api) |
| Trips | /trips | /api/trips | public reads AND anonymous create | trip itinerary pastebin, see [Trips API](/docs/trips-api) |
| Who Owes Me | /who-owes-me | /api/loans | browser session only (PATs 403) | personal loan ledger; non-owner mutations 403 |
| Practice | /practice | /api/practice | authed, practice:write writes | training sessions, vocab SRS, and [training plans](/docs/training-plans-api) |
| Vocabulary | /vocabulary | /api/vocabulary | public reads; knowledge:write writes | narrower view of the same data, see [Vocabulary API](/docs/vocabulary-api) |
| Skincare | /skincare | /api/skincare | authed only, owner-scoped | AM/PM routine tracker |
| Scoreboard | /scoreboard | /api/scoreboard | public reads; entries:write writes | IRL game scoreboard, see [Scoreboard API](/docs/scoreboard-api) |
| Courses | /courses | /api/courses | public reads; scoped writes | course catalog: linked slide decks and interactive lessons anyone can write or upload, see [Courses API](/docs/courses-api) |
| Documentation | /docs | (frontend only) | fully public | these docs; /llms.txt, /llms-full.txt |
| Blog | /blog | /api/blog | public reads; author-only scoped writes | public long-form posts, slug-keyed with versioned history, see [Blog API](/docs/blog-api) |
| Hardcore | (no route yet) | (not built yet) | n/a, placeholder tile | Minecraft Hardcore World |
| Inventory | (no route yet) | (not built yet) | n/a, placeholder tile | Wardrobe & item tracker |
| GitHub | github.com/shane1595042264 (external, new tab) | (external link, no API) | n/a, leaves the site | GitHub profile & repos |
| YouTube | www.youtube.com/@mr.doubleplus8206 (external, new tab) | (external link, no API) | n/a, leaves the site | YouTube channel |
| Bilibili | space.bilibili.com/453338854?spm_id_from=333.1007.0.0 (external, new tab) | (external link, no API) | n/a, leaves the site | Bilibili channel |
| LinkedIn | www.linkedin.com/in/shane-juntao-li/ (external, new tab) | (external link, no API) | n/a, leaves the site | LinkedIn profile |
| Nibbler | nibbook.com (external, new tab) | (external link, no API) | n/a, leaves the site | AI-powered book reader. Reading captures vocab into the knowledge base. |
| Wattpad | www.wattpad.com/user/JuntaoLi (external, new tab) | (external link, no API) | n/a, leaves the site | Wattpad profile & stories |
| Tea | /journal/tea | /api/tea-entries | authed author (PATs need entries:write, reads included); PIN-gated shares | private entries unlocked per-entry via the X-Tea-Pin header |
| Slot assignments | (homepage) | /api/slot-assignments | browser session only (PATs 403) | periodic-table layout persistence; PUT replaces the whole map |
| Activities | (journal sidebar) | /api/activities/:date | invite-only: journal membership to read | daily activity feed (calendar, commits, chat, location); ingest is cron/admin only |

## Cross-element gotchas

- Tea PIN flow: GET /api/tea-entries/:id returns 401 `PIN required` without a valid 4-digit `X-Tea-Pin` header, 403 on a wrong PIN, 429 after 10 failures per entry per minute. When the author has a universal PIN, a miss also counts against a per-author bucket (10 per minute across all their entries) and a 429 from it refuses the universal PIN, though the right entry PIN still opens its entry. Distinguish the three.
- Skincare reorder is `POST /api/skincare/reorder` (declared before /:id) and requires the COMPLETE ordered id list for that routine. It is all or nothing: a partial list, or a stale or foreign id, is a 400 and changes no positions.
- Scoreboard `GET /icons/search` requires auth because it spends GitHub API quota; deleting a player with match history is a 409.
- RNG evaluate auto-bans a denied category for 30 days; there is no unban endpoint.
- Admin-gated or machine-only surfaces (practice settings PATCH, activity ingest, wechat ingest, calendar connect, slot assignments, RNG Plaid bank linking) are not usable with PATs; skip them.
