Files
MeetPaprika/working/02-项目程序开发详细步骤.md

671 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 02-项目程序开发详细步骤
## 1. 开发原则
1. 先完整对标 `doc/index.html`,再做工程化拆分。
2. 每一轮开发只领取 `04-任务矩阵.md` 中明确编号的任务,避免重复做。
3. 每一轮必须同步更新:
- `03-推进台账.md`
- `04-任务矩阵.md`
- `05-验收证据.md`
- 必要时更新 `06-决策记录.md`
4. 涉及移民、法律、隐私、退款、attorney referral、表单收集的内容必须留有验收证据和确认记录。
5. 不把明文服务器密码写入长期文档;部署凭据用 SSH key、环境变量或受控密钥库。
## 2. 当前基线复现
目标:确认 `doc/index.html` 当前 mockup 可回溯、可打开、可作为工程化基准。
步骤:
1. 进入项目目录:
```bash
cd /home/mes123456/MeetPaprika
```
2. 确认文件存在:
```bash
test -f doc/index.html && wc -l doc/index.html
```
3. 检查当前页面路由和脚本入口:
```bash
rg -n "pageData|URLSearchParams|data-page|page=start|page=ask|page=terms|page=privacy|page=disclaimer" doc/index.html
```
4. 浏览器打开以下页面并记录截图:
- `doc/index.html?page=home`
- `doc/index.html?page=press`
- `doc/index.html?page=judging`
- `doc/index.html?page=scholarly`
- `doc/index.html?page=services`
- `doc/index.html?page=why`
- `doc/index.html?page=resources`
- `doc/index.html?page=faq`
- `doc/index.html?page=start`
- `doc/index.html?page=ask`
- `doc/index.html?page=terms`
- `doc/index.html?page=privacy`
- `doc/index.html?page=disclaimer`
验收标准:
- 所有公开路由能渲染。
- 未识别 `?page=unknown` 回退 `home`。
- 顶部导航 active 状态正确。
- Resources 下拉可见且链接正确。
- 证据记录写入 `05-验收证据.md`。
## 3. 阶段 A静态 mockup 修复
目标:不引入构建系统,先修复当前单文件中影响体验和转化的明确问题。
任务:
1. 修复 Services 页面 04/05/06 卡片 CTA。
- 已由 `contact` 改为 `start`。
2. 明确 `blog` 和 `about` 是否保留。
- 若保留,加入导航或 footer。
- 若不保留,记录为隐藏路由。
3. 检查 legal 页面日期。
- 已由 `July 10, 2026` 改为 `July 6, 2026`。
- 当前工作日期为 `2026-07-06`。
4. 检查首页、Press、Judging、Services、FAQ、Legal 移动端布局。
5. 补充基础 SEO
- description
- canonical
- Open Graph
- favicon 占位或正式资源
6. 将 mockup 表单明确标注为占位,或进入阶段 B 改为真实表单。
验收标准:
- 无明显死链。
- 所有 CTA 指向存在页面。
- 法务日期有明确确认。
- 桌面和移动端核心页面无明显重叠。
- 变更写入台账和证据。
## 4. 阶段 B真实表单与线索收集
目标Start Here 和 Ask a Question 从视觉 mockup 变成真实可提交入口。
### 推荐字段
Start Here
- name required
- email required
- linkedin
- company_website
- current_role_company
- field_or_industry
- resume_cv optional upload
- reason required
- existing_recognition
- timeline
- consent/disclaimer acknowledgement
Ask a Question
- name required
- email required
- linkedin optional
- resume_cv optional upload
- question required
- consent/disclaimer acknowledgement
### 实现路径选项
| 方案 | 适用 | 优点 | 风险 |
| --- | --- | --- | --- |
| 第三方表单服务 | 快速上线 | 开发少,有后台记录 | 文件上传和隐私策略受限 |
| 自建轻量 API | 需要控制数据 | 可控、可扩展 | 需要安全、日志、备份 |
| CRM 直连 | 销售流程明确 | 直接进入业务系统 | 依赖第三方 API 和权限 |
建议优先级:
1. 若目标是快速 HTTPS 上线:先接第三方表单或 webhook。
2. 若会收 CV/敏感信息:优先自建 API加上传限制和访问控制。
3. 若已有 CRM按 CRM 字段建映射并保留 submission id。
### 表单验收标准
- 必填字段缺失时不能提交。
- email 格式错误时提示。
- 文件上传明确限制类型和大小。
- 成功后有 submission id 或后台记录 id。
- 失败时显示错误状态,不静默跳转。
- disclaimer 可见:提交不创建 attorney-client relationship。
- 验收证据包含页面截图、提交记录、job_id/report_id/submission id。
## 5. 阶段 CNext.js + React + PostgreSQL 工程化
目标:把单文件 mockup 迁移为 Next.js + React 应用,并接入 PostgreSQL形成可维护、可部署、可验收的正式工程。
### 5.1 技术架构
- 前端和服务端框架Next.js + React
- 语言TypeScript
- 样式:先使用全局 CSS / CSS Modules 迁移 `doc/index.html` 视觉;不强行引入 UI 框架
- 数据库PostgreSQL
- ORMPrisma
- 表单校验Zod 或等价 schema 校验
- 部署Node.js 进程监听 `8082`Nginx/Caddy 提供 HTTPS 反向代理
- 验收Playwright 页面截图 + API/数据库写入验证
### 5.2 初始化工程
当前已完成初始化。保留建议命令供复建参考:
```bash
npx create-next-app@latest paprika-site --ts --eslint --app --src-dir=false
cd paprika-site
npm install prisma @prisma/client zod
npx prisma init
```
本项目已直接在当前根目录工程化,并保留 `doc/index.html` 为对标基线。
### 5.3 页面迁移
从 `doc/index.html` 迁移为真实路由:
| 旧路由 | Next.js 路由 |
| --- | --- |
| `?page=home` | `/` |
| `?page=press` | `/press` |
| `?page=judging` | `/judging` |
| `?page=scholarly` | `/scholarly` |
| `?page=services` | `/services` |
| `?page=why` | `/why` |
| `?page=resources` | `/resources` |
| `?page=faq` | `/faq` |
| `?page=start` | `/start` |
| `?page=ask` | `/ask` |
| `?page=thanks` | `/thanks` |
| `?page=terms` | `/terms` |
| `?page=privacy` | `/privacy` |
| `?page=disclaimer` | `/disclaimer` |
隐藏路由 `blog`、`about` 先不要公开,除非产品确认。
### 5.4 PostgreSQL 数据模型初稿
建议最小表:
```prisma
model Submission {
id String @id @default(cuid())
type String
name String
email String
linkedin String?
companyWebsite String?
currentRoleCompany String?
fieldOrIndustry String?
reason String?
existingRecognition String?
timeline String?
question String?
consentAccepted Boolean @default(false)
sourcePath String?
status String @default("new")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
files SubmissionFile[]
}
model SubmissionFile {
id String @id @default(cuid())
submissionId String
fileName String
mimeType String
byteSize Int
storageKey String
createdAt DateTime @default(now())
submission Submission @relation(fields: [submissionId], references: [id])
}
```
字段说明:
- `type``start` 或 `ask`
- `sourcePath`:提交来源,如 `/start`、`/ask`
- `status``new`、`reviewed`、`spam`、`archived`
- 文件上传未落地前,可以先不创建 `SubmissionFile` 或禁用上传。
### 5.5 表单 API
建议 API
```text
POST /api/submissions
```
请求类型:
- `type=start`
- `type=ask`
验收:
- 必填字段缺失返回 400。
- 邮箱格式错误返回 400。
- 成功写入 PostgreSQL 并返回 `submission_id`。
- 前端成功后跳转 `/thanks?submission_id=...` 或展示成功状态。
- 失败时显示明确错误。
### 5.6 环境变量
`.env` 至少包含:
```bash
DATABASE_URL="postgresql://USER:PASSWORD@HOST:5432/paprika"
NEXT_PUBLIC_SITE_URL="https://paprikalaw.com"
```
规则:
- `.env` 不提交。
- 服务器凭据和数据库密码不写入 `working` 文档。
- 生产数据库用户只授予应用所需权限。
### 5.7 服务器 PostgreSQL 验证
用户已确认 PostgreSQL 在服务器 `170.106.192.152` 安装完成。正式接入前需要在服务器上验证:
```bash
ssh ubuntu@170.106.192.152
systemctl status postgresql --no-pager
psql --version
sudo -u postgres psql -c '\l'
```
建议创建应用数据库和受限应用用户:
```sql
CREATE DATABASE paprika;
CREATE USER paprika_app WITH ENCRYPTED PASSWORD 'REPLACE_WITH_SECURE_PASSWORD';
GRANT CONNECT ON DATABASE paprika TO paprika_app;
```
进入数据库后授予 schema 权限:
```sql
\c paprika
GRANT USAGE, CREATE ON SCHEMA public TO paprika_app;
```
生产 `DATABASE_URL` 示例:
```bash
DATABASE_URL="postgresql://paprika_app:REPLACE_WITH_SECURE_PASSWORD@127.0.0.1:5432/paprika"
```
注意:
- 不使用 SSH 登录密码作为数据库密码。
- 不把数据库密码写入仓库、`working` 文档或聊天后的可复制文档。
- 如果 PostgreSQL 仅供本机 Next.js 使用,优先监听 `127.0.0.1`,不要对公网开放 5432。
### 5.8 构建和本地验证
```bash
npm install
npm run generate:legacy
npm run prisma:generate
npm run lint
npx tsc --noEmit
npm run build
npm run start -- -p 8082
```
本地生产服务冒烟:
```bash
for p in / /press /judging /scholarly /services /why /resources /faq /start /ask /thanks /terms /privacy /disclaimer /robots.txt /sitemap.xml; do
code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8082$p)
printf '%s %s\n' "$code" "$p"
done
```
生产数据库迁移:
```bash
npx prisma migrate deploy
```
验收标准:
- `npm run dev` 可本地启动。
- `npm run build` 通过。
- `npm run start -- -p 8082` 可在 8082 启动。
- `npx prisma migrate deploy` 可在生产环境执行。
- 核心页面内容、视觉和 CTA 与 `doc/index.html` 对标。
- Start/Ask 提交能写入 PostgreSQL。当前本地未配置 `DATABASE_URL` 时只能验证 400 校验路径和 500 失败路径,不能关闭入库验收。
## 6. 阶段 D部署到云服务器
目标:让 `https://paprikalaw.com/` 访问目标站点,内部服务端口使用 `8082`。
### 服务器信息
- Host`170.106.192.152`
- User`ubuntu`
- 端口范围:`8080-8099` 已开放
- 本项目端口:`8082`
- 密码:不写入文档;使用用户交接的临时凭据登录后立即配置 SSH key
### 建议部署结构
```text
/opt/paprika/
current/
releases/
shared/
.env
logs/
```
### 基础命令模板
```bash
ssh ubuntu@170.106.192.152
sudo mkdir -p /opt/paprika/releases /opt/paprika/shared/logs
sudo chown -R ubuntu:ubuntu /opt/paprika
```
### Next.js 服务示例
构建并启动:
```bash
npm ci
npm run build
npm run start -- -p 8082
```
生产建议用 systemd
```ini
[Unit]
Description=Paprika static site
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/paprika/current
Environment=NODE_ENV=production
EnvironmentFile=/opt/paprika/shared/.env
ExecStart=/usr/bin/npm run start -- -p 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
### Nginx 反向代理示例
```nginx
server {
listen 80;
server_name paprikalaw.com www.paprikalaw.com;
location / {
proxy_pass http://127.0.0.1:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
HTTPS
```bash
sudo certbot --nginx -d paprikalaw.com -d www.paprikalaw.com
```
验收标准:
- `curl -I http://127.0.0.1:8082` 在服务器上返回 200。
- `curl -I https://paprikalaw.com/` 返回 200。
- `https://paprikalaw.com/`、`/start`、`/faq` 可访问。
- `POST /api/submissions` 能写入 PostgreSQL 并返回 `submission_id`。
- systemd 服务 `active (running)`。
- Nginx 配置通过 `sudo nginx -t`。
- HTTPS 证书有效。
## 7. 阶段 E回归验收
目标:上线前后能证明页面、表单、合规、部署都可用。
### 页面回归
必测页面:
- home
- press
- judging
- scholarly
- services
- why
- resources
- faq
- start
- ask
- thanks
- terms
- privacy
- disclaimer
### 设备尺寸
- Desktop1440x900
- Tablet768x1024
- Mobile390x844
### 验收内容
- 页面可访问。
- 首屏品牌和 CTA 可见。
- Header 不遮挡内容。
- 文本无明显重叠。
- CTA 链接可达。
- 表单可提交或明确是 mockup。
- Footer legal 链接可达。
- Legal disclaimer 可见。
### 证据格式
每次验收写入 `05-验收证据.md`
```text
EV-YYYYMMDD-序号
时间:
任务:
命令/页面:
结果:
证据文件:
job_id/report_id/submission_id
结论:
```
## 8. 阶段 F后续产品增强
可选任务:
- 增加真实 Contact 页面。
- 增加 Blog/Resources 内容系统。
- 增加案例或证据包示例,但必须避免误导和隐私泄露。
- 增加 analytics并同步 Privacy Policy。
- 增加 sitemap、robots、structured data。
- 增加 Playwright screenshot regression。
- 增加后台 leads 管理或 CRM 同步。
## 9. 阶段 G邮箱系统配置与验证
目标:确认 `mail.paprikalaw.com` 邮件系统可用,管理员和普通公司邮箱能登录、收发和承接网站通知。
### 9.1 邮箱入口
- 普通用户网页登录:`https://mail.paprikalaw.com/webmail/`
- 管理员网页登录:`https://mail.paprikalaw.com/admin/`
- 管理员邮箱:`admin@paprikalaw.com`
### 9.2 需要创建或确认的普通邮箱
```text
info@paprikalaw.com
contact@paprikalaw.com
support@paprikalaw.com
sales@paprikalaw.com
marketing@paprikalaw.com
hr@paprikalaw.com
finance@paprikalaw.com
billing@paprikalaw.com
legal@paprikalaw.com
service@paprikalaw.com
```
凭据规则:
- 用户已提供统一初始密码,但不写入长期文档。
- 建议创建后立即为每个邮箱设置独立强密码。
- 如果邮件系统支持启用首次登录改密、2FA、登录审计和反垃圾策略。
### 9.3 DNS 和投递验证
需要确认:
- `mail.paprikalaw.com` A/AAAA 记录正确。
- `paprikalaw.com` MX 记录指向邮件服务器。
- SPF 记录包含授权发件源。
- DKIM 已生成并加入 DNS。
- DMARC 已配置,至少先从 `p=none` 观察。
- 反向 DNS/PTR 与邮件服务器发信域名匹配。
建议验证:
```bash
dig MX paprikalaw.com
dig TXT paprikalaw.com
dig TXT default._domainkey.paprikalaw.com
dig TXT _dmarc.paprikalaw.com
```
### 9.4 网站表单通知接入
Next.js 表单写入 PostgreSQL 后,可选邮件通知:
- 发件邮箱:建议 `support@paprikalaw.com` 或专用 `no-reply@paprikalaw.com`
- 收件邮箱:建议 `support@paprikalaw.com`、`contact@paprikalaw.com`
- 表单类型:
- `/start` 提交通知
- `/ask` 提交通知
- 邮件内容不得包含完整敏感 CV 文件,只发送 submission id 和后台查看提示。
环境变量示例:
```bash
SMTP_HOST="mail.paprikalaw.com"
SMTP_PORT="587"
SMTP_USER="support@paprikalaw.com"
SMTP_PASSWORD="REPLACE_WITH_SECURE_PASSWORD"
LEADS_NOTIFY_TO="support@paprikalaw.com,contact@paprikalaw.com"
```
验收标准:
- 管理员能登录 admin。
- 10 个普通邮箱能登录 webmail。
- 至少完成一封内部互发、一封外部收信、一封外部发信测试。
- SPF/DKIM/DMARC 检查通过或有明确待处理项。
- 表单邮件通知如启用,必须记录 message id 或测试截图。
## 10. 每轮工作固定流程
1. 查看 `04-任务矩阵.md`,领取一个或一组任务。
2. 查看相关决策:`06-决策记录.md`。
3. 修改代码或文档。
4. 执行对应验证。
5. 将证据写入 `05-验收证据.md`。
6. 更新任务状态。
7. 在 `03-推进台账.md` 记录:
- 本轮做了什么
- 改了哪些文件
- 验证了什么
- 下一步是什么
## 11. 完全对标核验清单
每次声称“已完全对标 `doc/index.html`”时,至少执行以下核验。
### 10.1 源文件结构核验
```bash
wc -l doc/index.html
rg -n 'function [A-Za-z0-9_]+\(|const [A-Za-z0-9_]+ =|href="\?page=|Last updated|Packages start|@media|--[a-z-]+:' doc/index.html
```
验收:
- 记录 `doc/index.html` 行数。
- 记录 CSS token、断点、路由、CTA、函数、法务日期、价格文案。
### 10.2 页面和函数映射核验
```bash
rg -n 'pageData|home:|press:|judging:|scholarly:|services:|why:|resources:|faq:|blog:|start:|ask:|thanks:|about:|terms:|privacy:|disclaimer:' doc/index.html
rg -n 'function (hero|heroWithKicker|servicesCta|card|pressPage|judgingPage|scholarlyPage|o1CriteriaPage|faqPage|legalTermsPage|legalPrivacyPage|legalDisclaimerPage)' doc/index.html
```
验收:
- `01-项目功能内容.md` 中的路由清单与 `pageData` 保持一致。
- 使用中函数、未调用函数都有记录。
- 隐藏路由 `blog`、`about` 不被误删。
### 10.3 链接和 CTA 核验
```bash
rg -n 'href="\?page=|card\("' doc/index.html
```
验收:
- Header、footer、hero、services CTA、form mockup、thanks、service card 链接全部登记。
- 不存在的 `contact` 路由历史缺陷必须保留在风险和任务矩阵中;修复后记录验收证据。
### 10.4 Legal 和 FAQ 核验
```bash
sed -n '2870,3035p' doc/index.html
sed -n '3070,3228p' doc/index.html
```
验收:
- FAQ 4 组 20 个问题记录完整。
- Terms、Privacy、Disclaimer section 数量和标题记录完整。
- Terms 缺少 17、legal 日期晚于当前日期、原文语法风险均进入任务矩阵。
### 10.5 视觉样式核验
```bash
rg -n '^\\s*\\.[A-Za-z0-9_-]+|@media|grid-template-columns|width: min|border-radius|background:' doc/index.html
```
验收:
- CSS token、布局宽度、卡片、表单、Press、Judging、FAQ、Legal、响应式断点在文档中有对应说明。
- 后续工程化拆分不能只迁移内容,必须迁移视觉规则。