---
title: "软件交接清单：项目结束时你应该拿到什么"
canonical: https://wavect.io/zh/software-development-guide/software-handover-checklist/
language: zh
description: "一次干净的交接，意味着你可以运行、修改并把软件交给任何人，而不必去找最初的构建者。这需要代码及其完整历史、文档、测试、可用的 CI/CD、你自己的密钥与凭据，以及对每一处基础设施的管理员权限。如果其中任何一项还留在供应商那里，那你不是拥有你的软件，你是在租它。用下面的清单，在你宣布构建完成之前，确认你确实拿到了一切。"
image: "https://wavect.io/img/general/bak/open_graph_preview.jpg"
---

当一次构建结束时

# 软件交接清单：构建结束时你应该拿到什么

一次干净的交接，意味着你可以运行、修改并把软件交给任何人，而不必去找最初的构建者。这需要代码及其完整历史、文档、测试、可用的 CI/CD、你自己的密钥与凭据，以及对每一处基础设施的管理员权限。如果其中任何一项还留在供应商那里，那你不是拥有你的软件，你是在租它。用下面的清单，在你宣布构建完成之前，确认你确实拿到了一切。

简短回答

一次干净的交接把代码、历史、文档、测试、CI/CD、密钥和完整的基础设施权限都交给你，让任何称职的团队都能脱离最初的构建者接手。

适合

- 正在结束与一家公司或自由职业者合作的创始人
- 要把项目转到内部的团队
- 想避免被供应商绑死的买家
- 任何在为尽职调查或审计做准备的人
- 必须比第一支构建团队活得更久的产品

不适合

- 你从没打算维护的一次性原型
- 你刻意要终身留用同一家供应商的构建
- 没有生产足迹的内部脚本
- 还没达到可交付状态的工作

// 01

## 比较各个选项

如何分辨一次干净的交接和一个绑死陷阱。

| 维度 | 干净的交接 | 供应商绑死的危险信号 |
| --- | --- | --- |
| 代码所有权 | 仓库在你的组织里，带完整 git 历史。 | 代码在供应商账户里，或一个没有历史的压缩包。 |
| 凭据 | 所有密钥和账户都归你并已轮换。 | 密钥和登录信息留在供应商手里。 |
| 基础设施 | 你持有托管、DNS 和可观测性的管理员权限。 | 供应商是生产环境唯一的管理员。 |
| 文档 | 架构、搭建步骤和运行手册都写了下来。 | 知识只存在原始开发者的脑子里。 |
| 测试与 CI/CD | 自动化测试和一条你能自己跑的流水线。 | 没有测试，或只有供应商能触发部署。 |
| 绑死 | 任何称职的团队都能接手。 | 只有最初的构建者能改任何东西。 |

// 02

## Wavect 的立场

你应该能炒掉我们，软件却照常运行。如果做不到，那次交接就不干净。

我们把代码交付到你自己的仓库里，带完整历史；交付运行它所需的文档和运行手册；交付发布它所需的测试和流水线；并交付它运行所依赖的每一个账户和服务器的管理员权限。密钥归你并已轮换，而不是归我们。

无供应商绑死是默认配置，不是付费附加项。一次交接的目标，是让任何称职的团队，包括你自己的，都能脱离我们把工作往前推。这才是真正拥有你的软件的意思。

// 03

## 成本、风险与周期

成本 构建的一部分 一次干净的交接是包含在内的，不是最后才加的增项。

风险 跳过就会被绑死 漏掉一项，就会让你依赖最初的构建者。

时间 在交付时核验 在你签字确认前就跑这份清单，而不是几周之后。

// 04

## 这里通常会出什么问题

- 收到一个没有 git 历史的代码压缩包，于是你失去了每个决策背后的缘由。
- 发现生产密钥和账户仍归供应商所有。
- 发现供应商是托管、DNS 或数据库唯一的管理员。
- 接手一套没有测试、也没有可运行流水线的代码库。
- 依赖只存在原始开发者脑子里的知识。
- 在没人核验过交接项之前，就宣布构建完成。

// 05

## 检查清单

在你接受交接之前，确认以下每一项。

- 源代码在你拥有的仓库里，且 git 历史完整无缺。
- 书面文档：架构概览、本地搭建步骤和部署步骤。
- 一套你能运行的自动化测试，并有当前结果的书面记录。
- 一条你能自己触发、而不只有供应商能触发的可用 CI/CD 流水线。
- 所有密钥和凭据都转交给你，并已从供应商账户轮换出来。
- 对每一处基础设施的管理员权限：托管、DNS、数据库和可观测性。
- 常见操作的运行手册：部署、回滚、恢复和处理事故。
- 确认无供应商绑死，让任何称职的团队都能脱离最初的构建者接手。

// 06

## 在我们的工作中是什么样子

已交付到生产、并由客户拥有的构建。

### [LivLive](/zh/case-studies/livlive/)
- **Status:** 上线
- **Outcome:** 1000+ - 并发用户
- **Summary:** AR-RWA 平台：通过产品募集 200 万美元+、1000+ 并发用户，整整六周。
- **Stack:** Solidity, Typescript, React

### [PromptID](/zh/case-studies/promptid/)
- **Status:** 上线
- **Outcome:** 6周 - 从零到生产
- **Summary:** AI 原生评估平台，在压缩的市场压力下 6 周内从零到生产。
- **Stack:** NestJS, NextJS, LangChain

这些是精选项目，并非我们的全部作品。自 2018 年以来我们已交付 75+ 款产品。

// 07

## 什么时候适用，什么时候不适用

// 01

### 什么时候 Wavect 是合适之选

- 你想彻底拥有你的软件，而不是向供应商租用它。
- 你日后可能把项目转到内部或交给另一支团队。
- 你把文档、测试和权限当成默认配置来期待。
- 你想要一个从第一天就规划交接的构建者。

// 02

### 什么时候我们并不合适

- 你想要一个你永远离不开的供应商。
- 你把文档和测试看成可选的额外项。
- 你在做一个没有前途的一次性原型。
- 你不愿接管你自己的凭据和基础设施。

如果离开构建它的人你就跑不起来自己的软件，那你还没拥有它。

// 08

## 相关服务与阅读

- [服务 软件开发](/zh/services/software-development/)
- [服务 软件质量保障](/zh/services/software-quality-assurance/)
- [服务 分时 CTO](/zh/services/fractional-cto/)
- [指南 上线前的软件质量保障清单](/zh/software-development-guide/software-qa-checklist-before-launch/)
- [指南 如何挑选软件开发公司](/zh/software-development-guide/how-to-choose-a-software-agency/)
- [指南 从 vibe coding 原型到生产](/zh/software-development-guide/vibe-coded-prototype-to-production/)
- [案例研究 LivLive：链上构建交付到上线](/zh/case-studies/livlive/)
- [案例研究 PromptID：从 0 到生产用了 6 weeks](/zh/case-studies/promptid/)

// 09

## 常见问题

### 交接里最重要的那一件事是什么？

在你拥有的仓库里、带完整 git 历史的代码。历史承载着每一次改动背后的推理，而一个没有它的压缩包把这些都丢掉了。其他一切都建立在这之上。

### 凭据为什么那么重要？

如果生产密钥和账户留在供应商那里，他们就掌控着你的软件能不能继续运行。凭据应当转交给你并轮换，让一切都不再依赖最初构建者的登录信息。

### 什么算供应商绑死？

任何意味着只有最初的构建者能改动、部署或运维软件的情况。代码在他们的账户里、没有文档的系统，或他们不肯交出的管理员权限，全都是绑死。

### 交接时我真的需要测试和 CI/CD 吗？

需要。没有一套自动化测试和一条你能自己跑的流水线，未来每一次改动都既有风险又缓慢。正是它们让一支新团队在你接手后能安全前进。

### 我该在什么时候核验交接？

在你为构建签字确认之前，而不是几周之后。趁最初的团队还在合作时跑这份清单，这样任何缺口都能立刻补上。

### Wavect 会为一次干净的交接额外收费吗？

不会。无供应商绑死是默认配置。交接项是构建的一部分，不是最后的增项。

最近审阅: 2026-06-26 审阅人 [Kevin Riedl](/zh/team/kevin-riedl/) [wiki ↗](https://www.wikidata.org/wiki/Q139796365)

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/#organization",
      "@type": [
        "Organization",
        "ProfessionalService",
        "LocalBusiness"
      ],
      "employee": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "founder": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "legalRepresentative": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "name": "Wavect GmbH",
      "subjectOf": {
        "@id": "https://wavect.io/verified-claims.json#dataset",
        "@type": "Dataset",
        "creator": {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        "description": "A machine-readable registry of quantitative and qualitative claims published by Wavect, with review dates, localized page appearances and public third-party citations where available.",
        "inLanguage": "en",
        "isAccessibleForFree": true,
        "license": "https://creativecommons.org/licenses/by/4.0/",
        "name": "Wavect verified publication claims",
        "url": "https://wavect.io/verified-claims.json"
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/team/kevin-riedl/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Kevin Riedl",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796365",
        "https://www.linkedin.com/in/wsdt",
        "https://github.com/wsdt"
      ],
      "url": "https://wavect.io/team/kevin-riedl/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/team/christof-jori/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Christof Jori",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796367",
        "https://www.linkedin.com/in/jocr77/",
        "https://github.com/jo-chris"
      ],
      "url": "https://wavect.io/team/christof-jori/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/#website",
      "@type": "WebSite",
      "inLanguage": [
        "en",
        "de",
        "es",
        "zh"
      ],
      "name": "Wavect",
      "potentialAction": {
        "@type": "SearchAction",
        "query-input": "required name=search_term_string",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://wavect.io/search/?q={search_term_string}"
        }
      },
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/zh/software-development-guide/software-handover-checklist/#webpage",
      "@type": "WebPage",
      "dateModified": "2026-06-26",
      "inLanguage": "zh",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-06-26",
      "url": "https://wavect.io/zh/software-development-guide/software-handover-checklist/"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/zh/software-development-guide/software-handover-checklist/#article",
      "@type": "Article",
      "about": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "author": {
        "@id": "https://wavect.io/team/kevin-riedl/#person",
        "@type": "Person",
        "name": "Kevin Riedl",
        "url": "https://wavect.io/team/kevin-riedl/"
      },
      "dateModified": "2026-06-26",
      "datePublished": "2026-06-26",
      "description": "一次干净的交接，意味着你可以运行、修改并把软件交给任何人，而不必去找最初的构建者。这需要代码及其完整历史、文档、测试、可用的 CI/CD、你自己的密钥与凭据，以及对每一处基础设施的管理员权限。如果其中任何一项还留在供应商那里，那你不是拥有你的软件，你是在租它。用下面的清单，在你宣布构建完成之前，确认你确实拿到了一切。",
      "headline": "软件交接清单：构建结束时你应该拿到什么",
      "inLanguage": "zh",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-06-26",
      "mainEntityOfPage": "https://wavect.io/zh/software-development-guide/software-handover-checklist/#webpage",
      "mentions": [
        {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        {
          "@type": "Service",
          "name": "软件开发",
          "url": "https://wavect.io/zh/services/software-development/"
        },
        {
          "@type": "Service",
          "name": "软件质量保障",
          "url": "https://wavect.io/zh/services/software-quality-assurance/"
        },
        {
          "@type": "Service",
          "name": "分时 CTO",
          "url": "https://wavect.io/zh/services/fractional-cto/"
        }
      ],
      "name": "软件交接清单：构建结束时你应该拿到什么",
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "reviewedBy": {
        "@id": "https://wavect.io/team/kevin-riedl/#person",
        "@type": "Person",
        "name": "Kevin Riedl",
        "url": "https://wavect.io/team/kevin-riedl/"
      },
      "speakable": {
        "@type": "SpeakableSpecification",
        "cssSelector": [
          ".cmp-hero__headline",
          ".cmp-hero__lead"
        ]
      },
      "url": "https://wavect.io/zh/software-development-guide/software-handover-checklist/"
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "item": "https://wavect.io/zh/",
          "name": "首页",
          "position": 1
        },
        {
          "@type": "ListItem",
          "item": "https://wavect.io/zh/software-development-guide/",
          "name": "软件开发指南",
          "position": 2
        },
        {
          "@type": "ListItem",
          "item": "https://wavect.io/zh/software-development-guide/software-handover-checklist/",
          "name": "软件交接清单：构建结束时你应该拿到什么",
          "position": 3
        }
      ]
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "在你拥有的仓库里、带完整 git 历史的代码。历史承载着每一次改动背后的推理，而一个没有它的压缩包把这些都丢掉了。其他一切都建立在这之上。"
      },
      "name": "交接里最重要的那一件事是什么？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "如果生产密钥和账户留在供应商那里，他们就掌控着你的软件能不能继续运行。凭据应当转交给你并轮换，让一切都不再依赖最初构建者的登录信息。"
      },
      "name": "凭据为什么那么重要？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "任何意味着只有最初的构建者能改动、部署或运维软件的情况。代码在他们的账户里、没有文档的系统，或他们不肯交出的管理员权限，全都是绑死。"
      },
      "name": "什么算供应商绑死？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "需要。没有一套自动化测试和一条你能自己跑的流水线，未来每一次改动都既有风险又缓慢。正是它们让一支新团队在你接手后能安全前进。"
      },
      "name": "交接时我真的需要测试和 CI/CD 吗？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "在你为构建签字确认之前，而不是几周之后。趁最初的团队还在合作时跑这份清单，这样任何缺口都能立刻补上。"
      },
      "name": "我该在什么时候核验交接？"
    },
    {
      "@type": "Question",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "不会。无供应商绑死是默认配置。交接项是构建的一部分，不是最后的增项。"
      },
      "name": "Wavect 会为一次干净的交接额外收费吗？"
    }
  ],
  "speakable": {
    "@type": "SpeakableSpecification",
    "cssSelector": [
      ".faq-question",
      ".faq-answer"
    ]
  }
}
```
