summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBertrand Yuan <189593334+bertyuan@users.noreply.github.com>2026-04-06 18:18:01 +0800
committerBertrand Yuan <189593334+bertyuan@users.noreply.github.com>2026-04-06 18:18:01 +0800
commit100c23ac1ae1a3c762ed400b916c931548f80c85 (patch)
treecb562a3146445b3fa80e8f2c66674061a816701d
parentf247a8c4a863ec430f4a705b5c493d652c8429bd (diff)
add technical research and UI design documents
Signed-off-by: Bertrand Yuan <189593334+bertyuan@users.noreply.github.com>
-rw-r--r--docs/tech-research-documents.md205
-rw-r--r--docs/ui-design-documents.md195
2 files changed, 400 insertions, 0 deletions
diff --git a/docs/tech-research-documents.md b/docs/tech-research-documents.md
new file mode 100644
index 0000000..93ab875
--- /dev/null
+++ b/docs/tech-research-documents.md
@@ -0,0 +1,205 @@
+# Tech Research Documents
+
+> Last Updated: 2026-04-06
+> Scope: Current implementation in this repository (frontend, APIs, CMS, database, auth, comments, email, and engineering workflow)
+
+## 1. Research Objective
+
+This document summarizes the current technical architecture, key implementation decisions, risks, and evolution paths for planning and technical review.
+
+## 2. System Positioning
+
+This project is a full-stack blog platform with these core capabilities:
+
+- Content publishing and management (Payload CMS)
+- Reading-first frontend experience (Next.js App Router)
+- User interaction (OAuth login, comments, share, subscribe)
+- Distribution and SEO (RSS, OG image generation, JSON-LD, sitemap)
+
+## 3. Current Tech Stack
+
+| Layer | Selection | Current Role |
+| --- | --- | --- |
+| Web framework | Next.js 15 + React 19 | Routing, server rendering, client interactions |
+| Language | TypeScript 5.7 | End-to-end type safety |
+| UI and styling | Tailwind CSS v4 + shadcn/ui + fumadocs-ui + motion | Design system, layout, interaction effects |
+| CMS | Payload CMS v3 + Lexical | Content modeling, admin panel, rich text editing |
+| Database | PostgreSQL + Drizzle ORM | Persistence for auth/comments and related data |
+| Auth | better-auth | OAuth (Google/GitHub) and session handling |
+| Comments | @fuma-comment/react + @fuma-comment/server | Comment display, write, and interaction |
+| Email | Resend + React Email | Newsletter subscription and email templates |
+| Validation | zod + @t3-oss/env-nextjs | Environment and input validation |
+| Engineering quality | Vitest + Testing Library + Biome | Tests, lint, and formatting |
+
+## 4. Architecture Overview
+
+### 4.1 Module Layers
+
+1. Presentation layer: `src/app/(main)` and `src/components`
+2. Content access layer: `src/lib/payload-posts.ts` (query and DTO normalization)
+3. Auth/comment layer: `src/server/auth`, `src/server/comments/config.ts`, and comment API routes
+4. Data layer: `src/server/db` (Drizzle schema + DB connection)
+5. CMS admin layer: `src/app/(payload)` + `payload.config.ts`
+
+### 4.2 Typical Read Flow (Posts)
+
+1. A server component calls `getPublishedPosts` or `getPostBySlug`.
+2. Payload reads from PostgreSQL `payload` schema.
+3. `transformPost` normalizes documents into `BlogPost`.
+4. The page renders and mounts client interactions (share/comments).
+
+### 4.3 Typical Write Flow (Comments)
+
+1. Post page comment component calls `/api/comments/[...comment]`.
+2. API route delegates handling to `NextComment`.
+3. Session is validated via better-auth adapter.
+4. Drizzle adapter writes to `blog_comments`, `blog_rates`, and `blog_roles`.
+
+## 5. Key Implementation Findings
+
+### 5.1 Content Modeling (Payload)
+
+Defined collections:
+
+- `posts`: title, slug, description, content, featured image, author, tags, status, publish time
+- `users`: auth-enabled user collection
+- `media`: image uploads (`public/media`)
+
+Config highlights:
+
+- Payload uses PostgreSQL `payload` schema.
+- Lexical is used as the editor.
+- Generated type file is `payload-types.ts`.
+
+### 5.2 Data Access Strategy
+
+`src/lib/payload-posts.ts` centralizes:
+
+- Published post pagination
+- Post lookup by slug
+- Slug list for static params
+- Tag-based filtering
+- Tag statistics
+
+Benefits:
+
+- UI layer is decoupled from raw CMS document shape.
+- Frontend consistently consumes normalized `BlogPost`.
+
+### 5.3 Auth Implementation
+
+- better-auth + Drizzle adapter (PostgreSQL)
+- OAuth providers: Google and GitHub
+- Extended user field: `role` (default `user`)
+- Session retrieval: `auth.api.getSession({ headers })`
+
+### 5.4 Comment Implementation
+
+- Frontend component: `@fuma-comment/react`
+- Backend entry: `NextComment` route handlers
+- Tables: `comments`, `rates`, `roles`
+- Existing TODO indicates role governance is not fully completed
+
+### 5.5 SEO and Distribution
+
+Implemented:
+
+- Page metadata generation
+- JSON-LD for posts/tags
+- RSS/Atom output (`/rss.xml`)
+- Dynamic OG image routes (`/banner.png`, `/og/[...slug]`)
+- `next-sitemap` sitemap generation
+
+### 5.6 Newsletter and Email
+
+- Form flow: `next-safe-action` + `react-hook-form` + zod
+- Subscription flow: Resend audience contact create/update
+- Template system: React Email (`emails/newsletter-welcome.tsx`)
+
+Current state: welcome email send logic exists but is currently commented out in action flow.
+
+### 5.7 Testing and Quality
+
+- Tests mainly cover `components/hooks/lib`
+- Test stack: Vitest + jsdom
+- Static checks: Biome
+- Content link validation script: `scripts/lint.mts`
+
+## 6. Data Model Findings
+
+### 6.1 Auth-related Tables (`blog_*`)
+
+- `blog_users`
+- `blog_sessions`
+- `blog_accounts`
+- `blog_verifications`
+
+### 6.2 Comment-related Tables (`blog_*`)
+
+- `blog_comments`
+- `blog_rates`
+- `blog_roles`
+
+### 6.3 Schema Separation Strategy
+
+- CMS content: `payload` schema
+- App auth/comments: `blog_*` tables
+
+Advantage: clear boundary between CMS-managed structures and application-owned business tables.
+
+## 7. Runtime and Operations
+
+### 7.1 Environment Governance
+
+`src/env.js` enforces validation for DB, Resend, OAuth, and analytics variables. `SKIP_ENV_VALIDATION` is supported for specific local workflows.
+
+### 7.2 Local Database Bootstrap
+
+`start-database.sh` supports Docker/Podman and includes:
+
+- Port conflict checks
+- Existing container reuse
+- Default password replacement prompt
+
+### 7.3 Common Scripts
+
+- Run: `dev`, `build`, `preview`, `start`
+- Data: `db:*`, `payload:*`
+- Quality: `lint`, `check`, `test`, `test:coverage`
+
+## 8. Risk and Technical Debt Assessment
+
+| Priority | Finding | Evidence | Impact | Recommendation |
+| --- | --- | --- | --- | --- |
+| P0 | Potential missing type dependency in email utility | `src/lib/resend.ts` imports type from `./source`, but `src/lib/source.ts` is absent | Type-check/build instability risk | Replace with explicit local type or add the missing module |
+| P0 | Payload secret has a default fallback | `payload.config.ts` uses `process.env.PAYLOAD_SECRET || 'your-secret-key'` | Production misconfiguration security risk | Enforce required secret in production and fail fast |
+| P1 | RSS path inconsistency risk | Actual route is `/rss.xml`, while some references use `/api/rss.xml` | Feed discovery may fail in clients | Unify RSS canonical path and all references |
+| P1 | In-memory aggregation bottleneck at scale | Search/RSS/tag stats read up to 1000 posts and aggregate in memory | Performance degradation as content grows | Move to DB-side aggregation/pagination and incremental indexing |
+| P1 | Base URL tied to one deployment variable | `baseUrl` mainly depends on `VERCEL_PROJECT_PRODUCTION_URL` | Wrong canonical/OG URLs in non-Vercel production | Add explicit `NEXT_PUBLIC_SITE_URL` and enforce in production |
+| P2 | Comment role governance is incomplete | Role TODO exists in comment config | Future moderation/delete policy gaps | Complete role policy and add policy tests |
+| P2 | Mixed language usage in code/comments | English and Chinese are mixed in labels/comments | Collaboration and consistency friction | Define and enforce a language policy |
+
+## 9. Suggested Evolution Roadmap
+
+### Phase 1: Stability and Correctness
+
+1. Fix `resend.ts` type dependency issue.
+2. Harden production config checks (Payload secret, site URL).
+3. Align all RSS path references.
+
+### Phase 2: Scalability
+
+1. Move tag statistics to DB aggregation.
+2. Introduce incremental search indexing.
+3. Add caching/revalidation boundaries for high-traffic pages.
+
+### Phase 3: Governance and Developer Efficiency
+
+1. Establish ADR (Architecture Decision Record) practice.
+2. Add route-level integration tests (auth/comments/rss/search).
+3. Add CI gates: `typecheck + test + lint + link validation`.
+
+## 10. Summary
+
+The project has a solid modern baseline (Next.js + Payload + Drizzle + better-auth), clear module boundaries, and strong extensibility. In the short term, focus on configuration hardening and correctness. In the mid term, focus on scaling and governance.
+
diff --git a/docs/ui-design-documents.md b/docs/ui-design-documents.md
new file mode 100644
index 0000000..1b0cc73
--- /dev/null
+++ b/docs/ui-design-documents.md
@@ -0,0 +1,195 @@
+# UI Design Documents
+
+> Last Updated: 2026-04-06
+> Scope: Current implementation in this repository (Next.js frontend + Payload content system)
+
+## 1. Document Purpose
+
+This document captures the UI design of the current implementation and serves as a baseline for future iterations. It covers:
+
+- Information architecture and page structure
+- Visual language and component conventions
+- Interaction behavior, responsiveness, and accessibility baseline
+- Actionable UI improvements for the current codebase
+
+## 2. Product Positioning and Design Principles
+
+The site is currently positioned as a content-first technical blog. The UI follows these principles:
+
+1. Reading first: prioritize hierarchy, contrast, and low visual noise.
+2. Lightweight navigation: keep access to posts, tags, and login straightforward.
+3. Consistent style: use dashed borders, corner crosses, and subtle motion as a recognizable theme.
+4. Low learning cost: both anonymous and authenticated flows should be intuitive.
+5. Cross-device consistency: preserve the same visual language across desktop and mobile.
+
+## 3. User Roles and Core Journeys
+
+| Role | Primary Goal | Core Routes |
+| --- | --- | --- |
+| Visitor | Browse and read content quickly | `/`, `/posts`, `/posts/[slug]`, `/tags` |
+| Returning reader | Filter by topic and engage | `/tags/[tag]`, `/posts/[slug]` (comments) |
+| Authenticated user | Comment, share, subscribe | `/login` -> `/posts/[slug]` |
+| Content admin | Publish and maintain content | `/admin` (Payload admin) |
+
+## 4. Information Architecture
+
+### 4.1 Route and Page Responsibilities
+
+| Route | Responsibility | Main File |
+| --- | --- | --- |
+| `/` | Hero + latest posts + newsletter CTA | `src/app/(main)/(home)/page.tsx` |
+| `/posts` | Paginated post list | `src/app/(main)/(home)/posts/page.tsx` |
+| `/posts/[slug]` | Post detail + share + comments | `src/app/(main)/(home)/posts/[slug]/page.tsx` |
+| `/tags` | Tag index | `src/app/(main)/(home)/tags/page.tsx` |
+| `/tags/[tag]` | Tag-filtered posts + pagination | `src/app/(main)/(home)/tags/[...slug]/page.tsx` |
+| `/about` | MDX content page (profile) | `src/app/(main)/(home)/(mdx)/about/page.mdx` |
+| `/login` | OAuth login page | `src/app/(main)/(auth)/login/page.tsx` |
+| `404` | Not found page | `src/app/(main)/not-found.tsx` |
+
+### 4.2 Global Layout Structure
+
+- The main shell is based on `HomeLayout`, with custom `Header` and `Footer`.
+- Content sections consistently use the `Section` wrapper for border/corner styling.
+- Vertical rhythm is maintained using dashed separators between major blocks.
+
+Related files:
+
+- `src/app/(main)/(home)/layout.tsx`
+- `src/components/sections/header/index.tsx`
+- `src/components/sections/footer.tsx`
+- `src/components/section.tsx`
+
+## 5. Visual Design Guidelines
+
+### 5.1 Typography and Layout
+
+- Primary font: `Geist`; monospace font: `Geist Mono`.
+- Home and detail pages use strong heading hierarchy (`text-3xl` to `text-6xl`).
+- Secondary information uses muted color tokens to improve reading focus.
+
+### 5.2 Color and Theme
+
+- Color tokens are mapped to `fumadocs` variables (`src/styles/globals.css`).
+- Supports `light`, `dark`, and `system` theme modes.
+- Cards use translucent backgrounds (`bg-card/50`) with hover transitions.
+
+### 5.3 Shape and Decoration
+
+- Signature visual elements: dashed borders + corner cross markers.
+- Hero and separators use textured pattern backgrounds (`bg-dashed`).
+- Footer uses a grid + gradient overlay to create depth.
+
+### 5.4 Icon System
+
+- Base icons come from `lucide-react`; brand icons are wrapped in `Icons`.
+- Icons are used for navigation, status communication, and interaction feedback.
+
+## 6. Page-Level Design Notes
+
+### 6.1 Home `/`
+
+Structure:
+
+1. Hero (personal positioning + CTA + social links)
+2. Posts section heading
+3. Latest 3 posts
+4. Newsletter subscription block
+
+Notes:
+
+- Hero uses background imagery and fade-in motion for first-screen identity.
+- The messaging is personal-brand oriented rather than marketing oriented.
+
+### 6.2 Posts List `/posts`
+
+- Shows total count and current range (for example `1-5`).
+- Uses horizontal information cards for fast scanning.
+- Pagination supports numbered jumps and ellipsis.
+
+### 6.3 Post Detail `/posts/[slug]`
+
+- Top area includes title, description, and tags.
+- Main area renders rich text content.
+- Desktop includes a sticky side panel for author/date/share.
+- Bottom includes comments (posting requires login).
+
+### 6.4 Tags `/tags` and `/tags/[tag]`
+
+- `/tags`: tag grid with counts.
+- `/tags/[tag]`: reuses the posts-list visual pattern for consistency.
+
+### 6.5 Login `/login`
+
+- Centered card layout aligned with global style (dashed borders + corner markers).
+- Currently supports Google/GitHub OAuth only.
+
+## 7. Core Component Interaction Guidelines
+
+| Component | Current Behavior | Design Intent |
+| --- | --- | --- |
+| `Header` | Sticky nav, search, theme toggle, mobile menu | Keep global actions always reachable |
+| `PostCard` | Fully clickable card with title/summary/meta/image | Improve list browsing efficiency |
+| `TagCard` | Tag chip with optional count | Encourage topic discovery |
+| `NewsletterForm` | Validation + success/error feedback | Reduce subscription friction |
+| `ThemeToggle` | Theme switch with transition effect | Keep switching smooth and perceptible |
+| `UserButton` | Session-aware menu (sign in/sign out) | Minimize account operation complexity |
+
+## 8. Motion and Feedback
+
+Implemented interaction feedback:
+
+- Hero background fade-in (`motion`)
+- Hover transforms on icons and buttons
+- Theme transition via `startViewTransition`
+- Share action success toast after copy
+
+Guideline:
+
+- Keep motion short, lightweight, and functional; avoid distracting animation.
+
+## 9. Responsive and Accessibility Baseline
+
+### 9.1 Responsive Behavior
+
+- Uses Tailwind breakpoint system (`sm` to `2xl`).
+- Header collapses into a menu on smaller screens.
+- Post detail layout falls back from dual-column to single-column on small screens.
+
+### 9.2 Accessibility
+
+Current baseline:
+
+- Core semantic structure is in place (`main`, `section`, `article`).
+- Key icon buttons include accessible labels.
+
+Recommended improvements:
+
+1. Improve visible keyboard focus states for custom controls.
+2. Audit all icon-only links to ensure explicit accessible naming.
+
+## 10. Current Issues and Priority Improvements
+
+### P0 (high priority)
+
+1. Mixed language tone across content should be standardized.
+2. Missing explicit empty states for posts/tags views.
+3. Newsletter flow can further improve repeated-submit protection messaging.
+
+### P1 (medium priority)
+
+1. Add reusable skeletons for list views (future-proof for client data loading).
+2. Extract a shared page-header component to reduce repeated patterns.
+3. Add design token documentation (spacing, radius, border rules).
+
+### P2 (low priority)
+
+1. Add visual regression screenshot baseline for key pages.
+2. Add a component snapshot guide under `docs/`.
+
+## 11. Next Iteration Design Checklist
+
+- [ ] Extract a shared page-header component
+- [ ] Add reusable empty-state modules
+- [ ] Run an accessibility-focused pass
+- [ ] Define and enforce copy language policy
+- [ ] Build component visual reference documentation