1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
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.
|