关于 developers-amsterdam
为阿姆斯特丹市政项目提供工程标准的技能,面向参与项目架构与开发的团队。它汇集技术栈选择、安全、测试、仓库和无障碍要求,并指导需求不明确时先澄清关键决策。
主要功能
- 01技术栈与框架选择指引
- 02数据库和项目结构规范
- 03安全与依赖评估要求
- 04Git、测试和文档标准
- 05WCAG 2.1 AA 无障碍要求
适用场景
- 01为新项目确定技术栈与架构
- 02检查代码仓库是否符合市政标准
- 03规划安全、测试和无障碍实践
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ amsterdam/ amsterdam-agent-skills --skill developers-amsterdam安装后在 Claude Code 中输入/developers-amsterdam确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/git-workflow.mdproject-setup-checklist.mdsecurity-checklist.mdtech-stack.mdtesting-standards.md详细介绍
阿姆斯特丹市工程标准
强制要求:所有架构、技术栈和工程决策都必须遵循这些标准。未经用户明确批准,不得推荐批准列表之外的框架、数据库或模式。设置新项目时,务必从第一天起就应用这些标准。
适用于所有 Gemeente Amsterdam 项目的开发标准,由 Engineering Enablement 维护。
门户: https://developers.amsterdam/ 源代码: https://github.com/Amsterdam/development-standards 许可证: CC0 1.0 Universal
开始构建前先澄清
当用户的请求含糊不清时(例如“给我构建一个 API”“设置一个新项目”“创建一个服务”),先询问,不要自行假设。明确提出这些决策点——它们对应下方的选择表:
| 决策 | 选项 | 重要原因 |
|---|---|---|
| 后端语言 | Python(Django 或 FastAPI)或 Node.js(TypeScript + NestJS) | 决定整个技术栈、测试框架和项目结构 |
| Python 框架 | Django(标准)或 FastAPI(异步/高性能) | 项目布局、ORM 和测试模式各不相同 |
| 项目结构 | 单一包或 pnpm monorepo | 多个应用之间需要共享代码时使用 monorepo;只有一个可部署项目时使用单一包 |
| 数据库 | PostgreSQL(默认)、PostGIS(地理空间)、Cosmos DB(文档) | 影响 Docker 设置、迁移和连接模式 |
| 全栈还是仅 API | Next.js/React Router(全栈)或仅 API 后端 | 决定是否需要搭建前端 |
| Git 工作流 | GitLab Flow、Git Flow 或 Trunk-based | Trunk-based 需要成熟的 CI/CD;采用发布列车时使用 Git Flow |
**不要一次问完所有问题。**选择 1–2 个提示中确实存在歧义的问题。如果用户说“FastAPI 服务”,则 Python + FastAPI + 仅 API 都已明确,只需根据需要进一步确认项目结构和数据库。
快速决策表
语言与框架选择表
| 需求 | 选择 | 说明 |
|---|---|---|
| 后端 API(标准) | Python + Django | 大多数项目的默认选择 |
| 后端 API(高性能/异步) | Python + FastAPI | 异步或性能至关重要时使用 |
| 后端 API(JS 生态系统) | Node.js + TypeScript + NestJS | 团队主要具备 JS 方面的专业能力时使用 |
| 前端应用 | TypeScript + React | 新项目始终使用 TypeScript |
| 全栈应用 | Next.js 或 React Router | 搭配 Amsterdam Design System |
| 移动应用 | React Native | 集成到 Amsterdam App 平台 |
| 低代码 | Mendix | 用于面向市民的简单应用 |
| 地图 | Leaflet | 参见 maps.developers.amsterdam |
| 包管理器 | pnpm | 所有 Node.js/TypeScript 项目的默认选择 |
数据库选择表
| 需求 | 选择 |
|---|---|
| 标准 RDBMS | PostgreSQL |
| 地理空间数据 | PostgreSQL + PostGIS |
| 文档存储 | Azure Cosmos DB 或 MongoDB |
| 遗留系统/迁移 | Microsoft SQL Server |
仓库要求清单
| 要求 | 强制要求 |
|---|---|
| 托管在 City of Amsterdam GitHub 组织中 | 是 |
| 公开仓库 | 是(IaC 除外,须为私有) |
| 包含团队名称的 CODEOWNERS 文件 | 是 |
| 包含模板章节的 README | 是 |
| EU-PL v1.2 许可证 | 是 |
对 develop 和 main 启用分支保护 | 是 |
| 提交签名(GPG 或 SSH) | 是 |
| CI/CD 流水线 | 是 |
| 为架构决策编写 ADR | 是 |
| 更新日志 | 是 |
测试框架选择表
| 场景 | 框架 | 覆盖率目标 |
|---|---|---|
| 前端单元/集成测试 | Jest 或 Vitest + React Testing Library | 70% |
| 前端快照测试 | Jest 或 Vitest + react-test-renderer | — |
| 前端 E2E/回归测试 | Playwright 或 Cypress | — |
| 前端 API 模拟 | MSW 或 Mirage JS | — |
| 后端(Django) | Django 测试框架 | 80% |
| 后端(FastAPI) | pytest | 80% |
Git 工作流
分支模型
main— 稳定、可用于生产环境的代码develop— 集成分支,设为默认分支- 推荐使用:GitLab Flow、Git Flow 或主干开发(后者需要 CI/CD)
分支命名
模式:<type>/<ticket>-<description>
| 前缀 | 用途 |
|---|---|
feature/ | 新功能 |
chore/ | 维护、重构 |
bugfix/ | 缺陷修复 |
hotfix/ | 生产环境紧急修复 |
docs/ | 文档变更 |
示例:
feature/PROJ-123-add-user-authbugfix/PROJ-456-fix-login-redirecthotfix/fix-critical-payment-error
提交格式
使用 Conventional Commits。标题 = 变更内容,描述 = 变更原因。
feat(auth): add SSO integration for employees
Implements SAML-based SSO to replace legacy password login.
Reduces onboarding friction and improves security posture.
Refs: PROJ-789
规则:
- 提交应保持原子性(每次提交只包含一个逻辑变更)
- 使用 GPG 或 SSH 密钥为提交签名(推荐使用 SSH)
- 切勿提交:机密、凭据、PII、生成文件、
node_modules、本地配置
分支保护(必需)
- 合并到
develop和main前必须经过 PR 审查 - 至少需要一项批准
- 不得为图方便而禁用
完整的分支策略、签名设置和 PR 工作流:请参阅
references/git-workflow.md
安全规则(摘要)
| # | 规则 |
|---|---|
| 1 | 在需求、设计和架构中主动集成安全措施 |
| 2 | 最小权限原则 |
| 3 | 深度防御(多层安全防护) |
| 4 | 故障安全默认值(故障期间保持安全状态) |
| 5 | 尽量缩小攻击面 |
| 6 | 不信任服务(验证并清理所有外部数据) |
| 7 | 开放设计(安全性不依赖于保密) |
| 8 | 默认安全 |
| 9 | 职责分离 |
| 10 | 保持安全机制简单 |
必需实践:
- 启用分支保护规则
- 公开源代码(IaC 除外)
- 部署前测试代码
- 评估第三方依赖项
- 符合城市标准的身份验证和监控/日志记录
- 按 RFC9068 验证 JWT(验证 typ、发行方、受众、签名和过期时间)
- 所有传输中的数据均使用 HTTPS
- 为获取的资源设置 CSP 标头和 SRI
包含代码示例的完整安全检查清单:请参阅
references/security-checklist.md
依赖项评估
| 标准 | 检查项 |
|---|---|
| 文档 | 质量、学习曲线、示例 |
| 许可证 | 是否兼容?(MIT、Apache 2.0、BSD、EUPL = 安全) |
| 性能 | 对软件包体积的影响(尤其是前端) |
| 安全性 | 已知漏洞、补丁响应时间 |
| 成熟度 | 项目年限、路线图、发布频率 |
| 维护情况 | 活跃维护者、提交频率 |
| 采用情况 | 下载趋势(npm trends、PePy、Packagist) |
拒绝在大多数标准上得分较低的软件包。结果不一时 = 咨询团队。
前端的附加要求:
- 定期更新并应用补丁
- 每年评估质量、可靠性和必要性
- 安全扫描:GitHub Dependabot、NPM audit、Snyk
无障碍访问
必须符合 WCAG 2.1 AA,遵循《数字政府法》。
适用于所有政府网站、应用、内联网、外联网、云应用和移动应用。
主要要求:
- 支持 200% 缩放
- 使用描述性链接文本
- 兼容屏幕阅读器
- 页面和焦点顺序合乎逻辑,并显示焦点环
- 为多媒体添加字幕
- 按 WCAG 1.4.12 设置 CSS 间距
- 支持从右到左的语言
测试工具:WebAIM WAVE、W3C Markup Validation、Google Lighthouse、VoiceOver、JAWS、TalkBack。
数据库标准
- 所有新项目默认使用 PostgreSQL 作为 RDBMS
- 地理空间数据使用 PostGIS 扩展
- 本地开发使用官方 Docker 镜像(
postgres、postgis/postgis) - 版本与 Azure PostgreSQL Flexible Server 保持一致
Docker 标准
- 在开发、测试和生产环境中使用 Docker 进行容器化
- 基础镜像:维护良好,并指定确切版本(绝不使用
latest标签) - 常见的批准镜像:Alpine、NGINX、Node.js、PHP、Postgres、Python、Ubuntu
- 仅安装必要的软件包
- 明确指定所有依赖项的版本
- Dockerfile 存放在应用的 GitHub 仓库中
- 编译后的镜像存放在 Azure Container Registry (ACR) 中
- 定期更新(至少每月或每季度一次)
- 不为不同的 DTAP/OTAP 环境分别创建镜像
- 不使用非官方或未经认证的 Docker 镜像
- 使用环境变量存储敏感数据(绝不硬编码)
包管理器与项目结构
- pnpm 是所有新 Node.js/TypeScript 项目的默认包管理器。使用 npm 或 yarn 需要明确说明理由(例如,工具不兼容或客户要求)
- 使用
corepack enable通过package.json中的packageManager字段固定 pnpm 版本
何时使用 Monorepo
| 信号 | 结构 |
|---|---|
| 单个可部署应用,没有共享库 | 单个包 |
| 多个应用共享代码(例如,前端 + API + 共享类型) | pnpm monorepo |
| 团队间共享设计令牌、UI 库或配置 | pnpm monorepo |
| 没有共享代码的独立微服务 | 独立仓库 |
Monorepo 设置
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
标准目录结构:
├── apps/
│ ├── web/ # Next.js frontend
│ └── api/ # Backend service
├── packages/
│ ├── shared/ # Shared types, utils
│ └── config/ # Shared ESLint, TSConfig
├── pnpm-workspace.yaml
├── package.json # Root with "packageManager" field
└── pnpm-lock.yaml
跨包引用
// apps/web/package.json
{
"dependencies": {
"@project/shared": "workspace:*"
}
}
跨包运行命令:pnpm -r build、pnpm --filter web dev。
文档要求
所有新仓库必须满足以下要求(自 2024 年 5 月起):
- 应用概览(用途)
- 许可证:EU-PL v1.2
- README(使用标准模板)
- 架构决策记录(ADR)
- 包含审查日期的变更日志
- 数据处理信息
- API 文档(端点、参数、身份验证、请求/响应)
- 列明用途的功能清单
README 模板和 ADR 模板:参阅
references/project-setup-checklist.md
应做 / 不应做
| 应做 | 不应做 |
|---|---|
| 所有新的前端项目都使用 TypeScript | 使用没有类型的 JavaScript |
| 默认使用 PostgreSQL 作为数据库 | 在没有理由的情况下选择其他数据库 |
| 使用 GPG 或 SSH 签名提交 | 推送未经签名的提交 |
| 合并前要求 PR 审查 | 未经审查就合并 |
| 使用 EU-PL v1.2 许可证 | 未经批准使用其他许可证 |
| 符合 WCAG 2.1 AA | 发布无法无障碍使用的功能 |
| 使用公共仓库(IaC 除外) | 在没有理由的情况下使用私有仓库 |
| 根据标准评估依赖项 | 未经评估就添加软件包 |
| 使用固定版本标签的 Docker 镜像 | 使用 latest 标签或未经认证的镜像 |
| 从第一天起就将安全纳入设计 | 事后才补充安全措施 |
| 使用 Conventional Commits 格式 | 提交消息缺少上下文 |
| 前端覆盖率达到 70% / 后端覆盖率达到 80% | 跳过生产代码的测试 |
| 将机密存储在 Key Vault / 环境变量中 | 将机密硬编码或提交凭据 |
| 使用 README、ADR、变更日志编写文档 | 让仓库缺少文档 |
| Node.js/TypeScript 项目使用 pnpm | 未经说明理由就使用 npm 或 yarn |
共享组件
| 组件 | 仓库 |
|---|---|
| Amsterdam Design System | github.com/Amsterdam/design-system |
| BMI DMS Upload | github.com/Amsterdam/bmi-dms-upload |
| Wonen UI | github.com/Amsterdam/wonen-ui |
| Maps | maps.developers.amsterdam |
技能边界
| 关注事项 | 本技能 | 其他技能 |
|---|---|---|
| 选择哪种框架/语言 | developers-amsterdam | — |
| 如何构建 UI 组件 | — | amsterdam-design-system |
| 文本内容和语气 | — | amsterdam-stijl |
参考文件
| 文件 | 阅读时机…… |
|---|---|
references/tech-stack.md | 选择语言、框架或共享组件;说明偏离既定方案的理由 |
references/git-workflow.md | 设置分支、提交签名、PR 工作流,或审查 Git 实践 |
references/testing-standards.md | 搭建测试基础设施、选择框架、定义覆盖率目标 |
references/security-checklist.md | 实现身份验证、JWT 验证、CSP、Docker 安全,或审查安全性 |
references/project-setup-checklist.md | 创建新仓库、编写 README/ADR、设置许可证 |