SPEC_LWOPAN_MIGRATION.md

Lwopan migration into apps.siao.ai — spec

⚠️ Built, and partly superseded by SPEC_ACCOUNTS.md. The migration shipped. But everything here about accounts is now wrong: user stories 1–4 (register with email/password, a password for this site, magic-login links) and 21 (leave NextAuth's session as-is) describe features that were built and have since been removed. AnswerHub has no credential store — identity comes from accounts.siao.ai, and its User row is a profile keyed by logtoSub. The Prisma models named below for accounts (Account, Session, VerificationToken, TwoFactorToken, TwoFactorConfirmation) no longer exist. Everything about submissions, blog, comments, likes and admin moderation still holds.

Status: built (Lwopan migration complete; later renamed to AnswerHub). Originally drafted from a /grill-me session. Lives in the apps-siao-ai repo (~/siao-ai/apps-siao-ai/), which currently has a working nav homepage (see SPEC_APPS.md) with a lwopan card linking to /lwopan (currently 404s). No issue tracker exists yet for this project — this file is the spec until one does. Full decision trail: NOTES_APPS.md ch.4 (grill session), source app explored at ~/Lwopan/learning-platform.

Naming note: "Lwopan" (羅盤) is a placeholder — the app will be renamed later, deliberately deferred so it doesn't block this work. This spec uses "Lwopan"/"lwopan" throughout to match the current code and directory names; treat every occurrence as "whatever it ends up being called."

Problem Statement

~/Lwopan/learning-platform is a fully-featured, never-deployed Next.js learning platform (帳號系統, 作業分享/submissions, 技術博客/blog, 知識庫/knowledge base, admin review) sitting outside the siao.ai project family as its own standalone repo with its own Tailwind design system built around a Liquid Glass aesthetic the owner has since decided to abandon. It isn't reachable at any siao.ai subdomain, has no path into the apps.siao.ai nav homepage's /lwopan card (which currently 404s by design), and its frontend doesn't match the direction the owner wants going forward.

Solution

Merge learning-platform's backend logic — Prisma schema, NextAuth setup, API routes, business logic — into the apps-siao-ai Next.js app as-is, under a /lwopan route namespace (pages and API routes both prefixed, e.g. app/lwopan/..., app/lwopan/api/...), so future apps mounted the same way don't collide on route names. Rebuild the frontend from scratch against this backend: Liquid Glass is dropped entirely, and the migration is the trigger for apps-siao-ai adopting Tailwind CSS + Radix UI (overturning the nav homepage's earlier "plain CSS, no Tailwind" decision — see Implementation Decisions). Ship this as one single migration covering every existing feature area, not a phased rollout, with the same high testing bar the nav homepage got — but stop at "builds and tests pass locally"; going live on apps.siao.ai is a separately-decided, deliberately deferred step (same posture the owner already took for the nav homepage itself, see NOTES_APPS.md ch.2–3).

User Stories

Account system (foundation for everything else)

  1. As a visitor, I want to register an account with email/password, so that I can participate in the platform.
  2. As a visitor, I want to sign in with Google, so that I don't need a separate password for this site.
  3. As a user, I want to receive and use a magic-login email link, so that I can sign in without typing a password.
  4. As a user, I want email verification before my account is fully active, so that the platform can trust the email I registered with.
  5. As a user, I want to optionally enable two-factor authentication, so that my account has an extra layer of protection.
  6. As a user, I want to edit my profile (avatar, bio, social links), so that other users can learn about me.
  7. As a user, I want to upload a profile avatar image, so that my profile isn't a blank placeholder.
  8. As a user, I want to view another user's public profile, so that I can see their submissions and posts.
  9. As an admin, I want a role-based permission system (USER vs admin roles), so that moderation actions are restricted to the right people.
  10. As an admin, I want to ban a user account, so that abusive accounts stop being able to upload content.

Submissions (作業分享)

  1. As a user, I want to upload a submission (an assignment/solution), so that I can share it with other learners.
  2. As a user, I want to bulk-upload multiple submissions at once, so that I don't have to repeat the single-upload flow for each one.
  3. As a visitor, I want to browse and open individual submissions by their slug, so that I can read the content.
  4. As a user, I want to like and comment on a submission, so that I can engage with other users' work.
  5. As an admin, I want to review submissions before or after they're public, so that I can moderate content quality.

Blog (技術博客)

  1. As a visitor, I want to read blog posts written in MDX with syntax highlighting and math rendering, so that technical content displays correctly.
  2. As a user (author), I want to write and publish blog posts, so that I can share technical knowledge.

Knowledge base (知識庫)

  1. As a visitor, I want to browse the knowledge base's structured content, so that I can learn systematically rather than searching ad hoc.
  1. As a visitor, I want to search across submissions/posts/knowledge content, so that I can find relevant material quickly. (Search backend — Algolia — is not configured this round; the UI and query logic port over, but live search results depend on a future session wiring up real Algolia credentials.)

Platform integration

  1. As the owner, I want /lwopan's pages and API routes fully namespaced under that prefix, so that a second app mounted onto apps.siao.ai later can't collide with Lwopan's routes.
  2. As the owner, I want Lwopan's NextAuth session left exactly as it is today (its own session/cookie, not integrated with any other siao.ai login), so that a future platform-wide shared-login design isn't accidentally foreclosed or half-implemented by this migration.
  3. As the owner, I want the whole migration to build and pass its test suite locally, so that I know the port is correct — without it needing to be live on apps.siao.ai yet.
  4. As the owner, I want uploaded files (avatars, submission uploads) to keep working exactly as they do today (local disk under public/uploads/), so that this migration doesn't quietly break a working feature by trying to also swap storage backends in the same pass.

Implementation Decisions

Testing Decisions

Out of Scope

Further Notes