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

17 KiB
Raw Permalink Blame History

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. 进入项目目录:

    cd /home/mes123456/MeetPaprika
    
  2. 确认文件存在:

    test -f doc/index.html && wc -l doc/index.html
    
  3. 检查当前页面路由和脚本入口:

    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. 明确 blogabout 是否保留。
    • 若保留,加入导航或 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 进程监听 8082Nginx/Caddy 提供 HTTPS 反向代理
  • 验收Playwright 页面截图 + API/数据库写入验证

5.2 初始化工程

当前已完成初始化。保留建议命令供复建参考:

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

隐藏路由 blogabout 先不要公开,除非产品确认。

5.4 PostgreSQL 数据模型初稿

建议最小表:

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])
}

字段说明:

  • typestartask
  • sourcePath:提交来源,如 /start/ask
  • statusnewreviewedspamarchived
  • 文件上传未落地前,可以先不创建 SubmissionFile 或禁用上传。

5.5 表单 API

建议 API

POST /api/submissions

请求类型:

  • type=start
  • type=ask

验收:

  • 必填字段缺失返回 400。
  • 邮箱格式错误返回 400。
  • 成功写入 PostgreSQL 并返回 submission_id
  • 前端成功后跳转 /thanks?submission_id=... 或展示成功状态。
  • 失败时显示明确错误。

5.6 环境变量

.env 至少包含:

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 安装完成。正式接入前需要在服务器上验证:

ssh ubuntu@170.106.192.152
systemctl status postgresql --no-pager
psql --version
sudo -u postgres psql -c '\l'

建议创建应用数据库和受限应用用户:

CREATE DATABASE paprika;
CREATE USER paprika_app WITH ENCRYPTED PASSWORD 'REPLACE_WITH_SECURE_PASSWORD';
GRANT CONNECT ON DATABASE paprika TO paprika_app;

进入数据库后授予 schema 权限:

\c paprika
GRANT USAGE, CREATE ON SCHEMA public TO paprika_app;

生产 DATABASE_URL 示例:

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 构建和本地验证

npm install
npm run generate:legacy
npm run prisma:generate
npm run lint
npx tsc --noEmit
npm run build
npm run start -- -p 8082

本地生产服务冒烟:

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

生产数据库迁移:

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

服务器信息

  • Host170.106.192.152
  • Userubuntu
  • 端口范围:8080-8099 已开放
  • 本项目端口:8082
  • 密码:不写入文档;使用用户交接的临时凭据登录后立即配置 SSH key

建议部署结构

/opt/paprika/
  current/
  releases/
  shared/
    .env
    logs/

基础命令模板

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 服务示例

构建并启动:

npm ci
npm run build
npm run start -- -p 8082

生产建议用 systemd

[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 反向代理示例

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

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

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 需要创建或确认的普通邮箱

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 与邮件服务器发信域名匹配。

建议验证:

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.comcontact@paprikalaw.com
  • 表单类型:
    • /start 提交通知
    • /ask 提交通知
  • 邮件内容不得包含完整敏感 CV 文件,只发送 submission id 和后台查看提示。

环境变量示例:

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 源文件结构核验

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 页面和函数映射核验

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 保持一致。
  • 使用中函数、未调用函数都有记录。
  • 隐藏路由 blogabout 不被误删。

10.3 链接和 CTA 核验

rg -n 'href="\?page=|card\("' doc/index.html

验收:

  • Header、footer、hero、services CTA、form mockup、thanks、service card 链接全部登记。
  • 不存在的 contact 路由历史缺陷必须保留在风险和任务矩阵中;修复后记录验收证据。
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 视觉样式核验

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、响应式断点在文档中有对应说明。
  • 后续工程化拆分不能只迁移内容,必须迁移视觉规则。