Plan: Transitioning to Forward Deployed Engineer / AI Engineer
一份分階段路線圖,供後端工程師轉向 FDE 與 AI Engineer 角色——解讀頭銜混亂、應用型 LLM 技術棧與面試循環。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Real one
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗The study planner that learns how you study, with a kodama that plans each day around you. For university students: deadlines, tasks and a calendar, planned around how long things really take you and when you focus best.
npm install
npx vercel dev # runs the app and /api locally (load .env.local first: set -a; . ./.env.local; set +a)
Look (tasteskill v2, editorial greeting): white ground, tonal pale-blue panels (#f3f6fc), Instrument Serif for the greeting and Instrument Sans for everything else, ink #14213d, calm pastel blue #b4caf0 for primary actions and active states, deep #35599a for links. Shadows only on floating things (menus). Colours and radii live in the @theme block of src/index.css; shared classes in src/ui.js; icons in src/icons.jsx. Check changes with node .agents/skills/design-taste-frontend/scripts/lint.mjs --app src.
Routes: /today, /tasks, /goals, /projects, /calendar (/ and /do-now go to Today). vercel.json rewrites them to index.html.
Layout:
Sections (Today opens first): Today (greeting, key numbers, "Right now" with ways to choose, coming up, your tasks, weekly review), Tasks (add, Eisenhower matrix or list, AI prioritise), Projects (something bigger than a task: an investment, exam or test; it owns tasks via projectId, shows progress, and the AI breaks it into tasks), Goals (pyramid, happiness goals, hobbies), Calendar. Every page opens with a Notion-style head (cover art, an icon on its edge, a big serif title). On the Tasks board each card has cover art and tag chips (box, due date, hours, steps, repeat). Screens live in src/screens/, shared pieces in src/components/ and src/shared.jsx. The previous UI is kept in legacy/.
Env vars (see .env.example): ANTHROPIC_API_KEY, DATABASE_URL (Neon Postgres), ADMIN_EMAILS (who may open the owner dashboard at /dsb; everyone else gets a 404). Accounts use Better Auth (api/_auth.js): set BETTER_AUTH_SECRET (openssl rand -base64 32), BETTER_AUTH_URL (the site origin), and RESEND_API_KEY + EMAIL_FROM for verification and reset mails (without a key, mails print in the server log and verification is skipped).
Database (db/schema.sql): users, goals, hobbies, projects, deadlines, tasks and ai_calls, linked by real foreign keys (a task's project, deadline and goal; deleting a project unlinks its tasks, deleting a user removes everything of theirs). A visitor only gets a users row once they have content or use the AI. users.email and users.auth_id are ready for accounts. api/_store.js maps the app's one document to these tables, unknown fields land in each row's extra jsonb. Apply or re-run with set -a; . ./.env.local; set +a; node scripts/migrate.mjs (also copies the old workspaces / usage tables, which are kept as a backup).
Tasks: done section with undo and weekly count, drag between boxes (or "Move to" in Details), steps, repeats. Calendar has month, week and day views; give a task a start time to see it as a block. Settings (gear): reminders (browser notifications, only while a tab is open) and JSON backup export/import.
npm test # unit checks for the pure logic in src/
Also: Replan my week (Calendar, the AI agent, or the banner when planned tasks slip) shows what moves and what is at risk before you apply it; a weekly goal-alignment card on Goals; energy check-ins in Today that teach the planner your best hours; a Pomodoro focus timer that logs real time on tasks; syllabus import in Deadlines.
Public API (/api/v1/tasks): Authorization: Bearer <API key> (Settings > API key). GET lists, POST {title, important, urgent, due, when, start, hours, readiness} creates, PATCH|DELETE ?id=<id> edits or removes. 300 requests/hour per key. Reload an open tab to see API changes.
Account API (for scripts and other clients; the app itself uses /api/auth/*): POST /api/signup, POST /api/login ({identifier, password}, email or username), POST /api/logout, GET /api/me, POST /api/forgot-password, POST /api/reset-password, DELETE /api/account. They are aliases for the Better Auth routes (api/auth/[...all].js), so the same checks and rate limits apply. Other methods get 405.
Rate limits (api/_rate.js, per id per hour, 4x per IP): AI 60, state 600, API 300. Over the limit: 429 with Retry-After; X-RateLimit-Limit/Remaining on every response. If the counter is down the request is refused (503).
Deadlines live in Tasks. A dated task is a deadline. "Check with AI" in a task's panel decides if it is one task (kept as is) or several (you choose to split; it then becomes a deadline card that owns the new tasks, and you can add your own tasks to it). Syllabus import is on the Tasks page. /deadlines opens Tasks.
Accounts: email + password. Passwords are salted scrypt hashes (never stored or logged in plain text) and are checked against the Have I Been Pwned breach list; 10 to 128 characters. Sessions are httpOnly cookies. Sign-up verifies the email, "Forgot password?" mails a one-hour link and signs out other devices. Every row in users, goals, tasks, ... belongs to the account id ("user".id = users.id). Data a browser saved before accounts existed is moved into the account on first sign-in. Auth rate limits, three layers: Vercel Firewall (edge), per IP per route ("rateLimit": sign-in 5/min, sign-up 5/h, reset and verification mails 3/h, social 10/min, all else 100/min), and per email across all IPs (auth_hit: 10 failed sign-ins per 15 min locks that account for the window, 3 sign-up / reset / verification mails an hour). Google and GitHub sign-in switch on when their *_CLIENT_ID / *_CLIENT_SECRET are set. Settings > Delete account mails a confirmation link (opened while signed in); it removes the login and every row of the user's data. /api/state and every AI endpoint answer 401 without a session.
Sign-in screens: split layout, a pixel-art high-rise skyline seen from an observation deck on the left (a different one per step: a night skyline with lit windows for sign-in, dawn for sign-up, a rainy night for password reset, snow for check-your-inbox, afternoon for the welcome questions) and the form on the right. The art is drawn by art/authoring/gen_city.py (npm run pixel:city) into public/pixel/city/ as separate layers (sky, clouds, three tiers of towers with haze between, the street, traffic lights, flickering windows, rain or snow, the ledge and mug steam) that src/Wallpaper.jsx moves with CSS steps; it also draws the header of the emails. Sign-up asks for name, username, email and a confirmed password (Show / Hide on each); sign-in takes email or username. The first sign-in asks two quick questions ("Who is Desker for?", "What do you want from it?"), saved as onboarding on the account. Emails (api/_mail.js) are HTML with a plain-text twin.
The kodama (Phase 5): the companion and the AI agent are one character. Its name is the user's (data.kodama.name, default "Kodama"); its voice and wellbeing rules live in src/persona.js and are also the opening of the chat prompt in api/chat.js. src/kodama.js decides how it feels, what it says, which ritual is due and how it grows (growth replaced XP, levels, quests and badges; the old XP total became starting growth once).
Rhythm data: the rhythm engine (src/rhythm.js) stores in the account document (rhythm, energyLog). db/migrations/001_rhythm.sql holds the tables for it; they are not applied automatically. Run it by hand on a branch database first.
Notifications (web push, optional): set VITE_VAPID_PUBLIC_KEY, VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT and CRON_SECRET (npx web-push generate-vapid-keys makes the pair). Then call GET /api/state?push=1 with Authorization: Bearer <CRON_SECRET> once an hour. A Vercel cron on a paid plan works; the free plan only allows daily crons, so use an external scheduler such as cron-job.org or a GitHub Action. Without the five variables the Settings toggle is hidden and the endpoint answers 503. What may be sent is src/pushPlan.js: a morning note at 08:00 and an evening one at 19:00 in the user's time zone, never in quiet hours, never after 5+ days away.
Analytics and beta health (optional, off by default): set ANALYTICS=on and VITE_ANALYTICS=on and apply db/migrations/002_events.sql to log first-party product events (the allow-list is src/analytics.js; a test checks that no property can carry free text). Events go to /api/state?events=1 and live in an events table tied to the account and deleted with it. The owner dashboard (/dsb) has a "Beta health" section: sign-ups and active people per week, D1 / D7 / W4 retention, tasks done per active user, how many finished tasks have a real duration, estimate error against Desker's plan error by weeks since sign-up, and companion rates. Most of it is computed from data the app already stores and works without the events table; the notification rate needs it and says so when it is missing.