Giới Thiệu
Việc thêm một kế hoạch Nhóm (chúng tôi gọi là "Crew") là một trong những yếu tố có ảnh hưởng lớn nhất giúp sản phẩm chuyển mình từ người dùng cá nhân sang sự hợp tác thực sự. Điều này không chỉ thay đổi mô hình giá cả mà còn thúc đẩy vòng tăng trưởng, loại bỏ các rào cản tiềm ẩn cho người mua và—nếu thực hiện đúng—không yêu cầu phải viết lại.
Trong bài viết này, chúng tôi sẽ chia sẻ cách tiếp cận của Indie10k, những gì chúng tôi đã học được và cách bạn có thể triển khai nó mà không làm gián đoạn lộ trình của mình.
Tại Sao Kế Hoạch Nhóm Quan Trọng
- Động lực lan tỏa trong nhóm: Khi các cộng tác viên thấy tiến độ của nhau, họ sẽ giữ nhịp.
- Doanh thu mở rộng vượt trội hơn việc thu hút mới: Các nhóm gia tăng ARPU và mở khóa nâng cấp cấp tài khoản.
- Loại bỏ phản đối “nhưng đồng sáng lập của tôi cần truy cập” khi bạn hỗ trợ các vai trò cơ bản.
Mô Hình Giá: Từ Người Dùng Cá Nhân Đến Ghế Tài Khoản
Chúng tôi định giá Nhóm dựa trên một nhóm ghế cấp tài khoản, không phải theo lời mời dự án.
- Ghế tài khoản đại diện cho những cộng tác viên duy nhất trên tất cả các dự án mà họ sở hữu.
- Các lời mời đang chờ sẽ tiêu tốn ghế; việc thu hồi sẽ giải phóng ngay lập tức.
- Chủ sở hữu không tính vào nhóm, và cùng một cộng tác viên trên nhiều dự án chỉ tính một lần.
Điều này tạo ra sự cân bằng giữa doanh thu dự đoán và linh hoạt cho các nhóm nhỏ hoặc tập thể. Đối với Indie10k:
- Miễn phí/Builder/Hacker: sử dụng cá nhân hoặc hợp tác hạn chế (0 ghế mặc định)
- Crew: bao gồm một hạn ngạch ghế nhóm (ví dụ: 3 ghế)
Ví dụ về môi trường:
ENABLE_TEAM=true
TEAM_DEFAULT_SEAT_POOL=0
TEAM_CREW_SEAT_POOL=3
TEAM_INVITE_EXPIRES_DAYS=7
Mẹo: Gán ghế cho các cấp độ trả phí qua bảng định giá của bạn thay vì mã hóa giá vào trong mã.
Tác Động Tăng Trưởng: ARPU, Vòng Lặp Viral, Giữ Chân Khách Hàng
- ARPU cao hơn: Các tài khoản nâng cấp để mở khóa nhiều cộng tác viên hơn; giới hạn ghế tạo ra những cơ hội bán thêm tự nhiên.
- Lời mời do sản phẩm dẫn dắt: Mỗi lời mời là một điểm tiếp cận thu hút có độ ma sát thấp; việc chấp nhận sẽ dẫn dắt người dùng mới vào sản phẩm của bạn.
- Giữ chân qua trách nhiệm: Các nhóm quay lại để hoàn thành các vòng lặp cùng nhau (kiểm tra trạng thái, chia sẻ bằng chứng và đánh giá).
Ý tưởng đo lường:
- Theo dõi các sự kiện đạt giới hạn ghế như một tín hiệu bán thêm.
- Đo lường tỷ lệ chấp nhận lời mời và thời gian đến hành động đầu tiên sau khi chấp nhận.
- Phân đoạn giữ chân theo “cá nhân so với nhóm” để định lượng tác động.
Vấn Đề Nó Giải Quyết (Trích dẫn Thực tế Chúng Tôi Nghe)
- “Tôi không thể thêm đồng sáng lập của mình mà không chia sẻ đăng nhập.”
- “Chúng tôi phân chia dự án giữa các tài khoản cá nhân—bây giờ mọi thứ bị phân tán.”
- “Chúng tôi cần quyền đọc cho cố vấn và quyền chỉnh sửa cho lập trình viên.”
Giải pháp: các vai trò (đọc, viết, quản trị, chủ sở hữu) với hành vi dự đoán và một giao diện người dùng đơn giản cho các thành viên.
Cách Triển Khai (Nhanh, An Toàn)
Con đường mà chúng tôi sử dụng—tối thiểu, có thể đảo ngược và được đánh dấu tính năng.
1) Bắt Đầu Với PRD Chặt Chẽ
Giữ phạm vi ngắn gọn: lời mời qua email, vai trò, bảng thành viên, thực thi ghế và token an toàn. PRD đầy đủ của chúng tôi có trong docs/team-prd.md
và bao gồm:
- Ma trận vai trò và các mục không phải là mục tiêu cho v1.
- Quy tắc nhóm ghế cấp tài khoản.
- An ninh (token đã mã hóa, hết hạn, sử dụng một lần; không phân loại email).
2) Schema + Dịch Vụ (Server-Trước)
Thêm hai bảng:
project_members(project_id, user_id, role, status, …)
project_invites(project_id, email, role, token_hash, expires_at, status, …)
Các hàm trợ giúp dịch vụ (chỉ phía máy chủ):
requireRole(projectId, userId, minRole)
createInvite(projectId, email, role, invitedBy)
acceptInvite(token, userId)
changeMemberRole(...)
,removeMember(...)
,revokeInvite(inviteId)
- Tính toán ghế:
getSeatPoolSize(ownerId)
+getSeatsUsed(ownerId)
(người dùng khác nhau + email đang chờ trên tất cả các dự án của chủ sở hữu)
3) APIs Phản Ánh Mô Hình Tư Duy
POST /api/projects/:id/invites
→ tạo lời mời (quản trị+)POST /api/team/invites/accept
→ chấp nhận lời mời (xác thực)PATCH /api/projects/:id/members/:userId
→ thay đổi vai trò (quản trị+)DELETE /api/projects/:id/members/:userId
→ xóa (quản trị+)DELETE /api/projects/:id/invites/:inviteId
→ thu hồi (quản trị+)POST /api/projects/:id/invites/:inviteId/resend
→ xoay token + gửi lại (quản trị+, giới hạn tần suất)GET /api/projects/:id/members
→ liệt kê thành viên + lời mời đang chờ + sử dụng ghế
Bảo vệ mọi tuyến đường bằng kiểm tra vai trò phía máy chủ. Giữ cho phản hồi dự đoán được: NextResponse.json({ ... }, { status })
.
4) Email + Luồng Chấp Nhận
- Email lời mời bao gồm một URL chấp nhận:
/invite/accept?token=...
. - Trang này gọi
POST /api/team/invites/accept
và chuyển hướng đến dự án. - Trong phát triển:
RESEND_API_KEY=STDOUT
để xem trước email an toàn trong nhật ký.
5) Giao Diện Thành Viên Không Quá Đà
- Danh sách thành viên với vai trò và một biểu mẫu mời đơn giản.
- Một đồng hồ ghế đọc “X trong Y ghế đã sử dụng (trên toàn bộ tài khoản)”.
- Các lời mời đang chờ với “Gửi lại” và “Thu hồi”.
- Hiển thị tên/email thay vì ID thô để rõ ràng.
6) Các Biện Pháp, Không Phản Kháng
Sử dụng giới hạn tỷ lệ nơi mà lạm dụng có khả năng xảy ra (tạo/gửi lại lời mời). Fail-open khi thiếu cơ sở hạ tầng trong phát triển.
// Ví dụ về khóa
invite:create:user:{userId}
invite:resend:user:{userId}
invite:resend:project:{projectId}
7) Bảo Mật Mặc Định
- Mã hóa token (sha256 với salt) và chỉ lưu trữ hash.
- Thực thi hết hạn khi chấp nhận; xem các khóa thiếu như 500 trong sản xuất.
- Tránh phân loại email; luôn phản hồi với một thông báo tổng quát “Lời mời đã được gửi”.
Ví Dụ PRD (Tóm Tắt)
Vai trò: người đọc, người viết, quản trị, chủ sở hữu. Người đọc xem; người viết chỉnh sửa và thực hiện hành động; quản trị viên quản lý thành viên; chủ sở hữu là không thể thay đổi và có thể xóa dự án.
Pool Ghế: cộng tác viên duy nhất trên các dự án của chủ sở hữu; các lời mời đang chờ tính; việc thu hồi giải phóng ghế ngay lập tức.
Giao diện: Danh sách thành viên, biểu mẫu mời, đồng hồ ghế và trạng thái lỗi rõ ràng.
Tham khảo: xem docs/team-prd.md
để biết ma trận và các ràng buộc đầy đủ.
Hướng Dẫn Triển Khai (Tóm Tắt)
Chúng tôi đã tài liệu hóa các bước chính xác tương ứng với công nghệ (Drizzle schema, App Router routes, Zod validators, Resend emails, Stack Auth checks) trong docs/team-impl.md
.
Điểm nổi bật:
- Cờ tính năng:
ENABLE_TEAM
ẩn mọi thứ cho đến khi bạn sẵn sàng. - Kiểm tra vai trò: tập trung lại với
requireRole()
và tái sử dụng trên các tuyến đường. - Phạm vi truy cập: mở rộng danh sách và truy vấn dự án để bao gồm các thành viên tích cực (không chỉ chủ sở hữu), trong khi khóa các thay đổi cho người viết/quản trị.
Ghi Chú Cuối
Nếu bạn có ngay cả một số ít người dùng hỏi “Tôi có thể mời đồng sáng lập của mình không?”, một kế hoạch Nhóm không chỉ mở khóa sự hợp tác—mà còn một con đường mô hình kinh doanh hoàn chỉnh: doanh thu mở rộng, sử dụng bền vững hơn và tăng trưởng đáng tin cậy hơn.
Hãy triển khai nó một cách nhỏ gọn. Khóa nó lại. Tiến hành từ đó.