writing-server-code

โดย bitwarden

Bitwarden มาตรฐานโค้ดเซิร์ฟเวอร์สำหรับ C# และ .NET ใช้เมื่อทำงานในเซิร์ฟเวอร์ repo การสร้างคำสั่ง คำค้นหา บริการ หรือ API endpoints และใช้เมื่อ...

npx skills add https://github.com/bitwarden/server --skill writing-server-code

Architectural Rationale

Command Query Separation (CQS)

New features should use the CQS pattern — discrete action classes instead of large entity-focused services. See ADR-0008.

Why CQS matters at Bitwarden: The codebase historically grew around entity-focused services (e.g., CipherService) that accumulated hundreds of methods. CQS breaks these into single-responsibility classes (CreateCipherCommand, GetOrganizationApiKeyQuery), making code easier to test, reason about, and modify without unintended side effects.

Commands = write operations. Change state, may return result. Named after the action: RotateOrganizationApiKeyCommand.

Queries = read operations. Return data, never change state.

When NOT to use CQS: When modifying existing service-based code, follow the patterns already in the file. Don't refactor to CQS unless explicitly asked. If asked to refactor, apply the pattern only to the scope requested.

Caching

When caching is needed, follow the conventions in CACHING.md. Use IFusionCache instead of IDistributedCache.

Don't implement caching unless requested. If a user describes a performance problem where caching might help, suggest it — but don't implement without confirmation.

GUID Generation

Always use CoreHelpers.GenerateComb() for entity IDs — never Guid.NewGuid(). Sequential COMBs prevent SQL Server index fragmentation that random GUIDs cause on clustered indexes, which is critical for Bitwarden's database performance at scale.

Library shape

When creating or modifying code under src/Libraries/, read src/Libraries/LIBRARY.md — it is the canonical shape and covers public surface, settings, endpoints, repositories, and cross-library dependencies.

Comment discipline

Write comments for the non-obvious why, not the what. Code that speaks for itself gets no comment; a non-doc comment earns its place only when it records a rationale the code cannot express, and it stays to one line when possible. When a public type or member needs documenting, terse /// XML doc comments state its contract instead of restating the signature.

Critical Rules

These are the most frequently violated conventions. Claude cannot fetch the linked docs at runtime, so these are inlined here:

  • Use TryAdd* for DI registration (TryAddScoped, TryAddTransient) — prevents duplicate registrations when multiple modules register the same service
  • File-scoped namespaces — namespace Bit.Core.Vault; not namespace Bit.Core.Vault { ... }
  • Nullable reference types are enabled (ADR-0024) — use ! (null-forgiving) when you know a value isn't null; use required modifier for properties that must be set during construction
  • Async suffix on all async methods — CreateAsync, not Create, when the method returns Task
  • Controller actions return ActionResult<T> — not IActionResult or bare T
  • Testing with xUnit — use [Theory, BitAutoData] (not [AutoData]), SutProvider<T> for automatic SUT wiring, and Substitute.For<T>() from NSubstitute for mocking

Examples

GUID generation

// CORRECT — sequential COMB prevents index fragmentation
var id = CoreHelpers.GenerateComb();

// WRONG — random GUIDs fragment clustered indexes
var id = Guid.NewGuid();

DI registration

// CORRECT — idempotent, won't duplicate
services.TryAddScoped<ICipherService, CipherService>();

// WRONG — silently duplicates registration, last-wins causes subtle bugs
services.AddScoped<ICipherService, CipherService>();

Namespace style

// CORRECT — file-scoped
namespace Bit.Core.Vault.Commands;

// WRONG — block-scoped
namespace Bit.Core.Vault.Commands
{
    // ...
}

Further Reading

Skills เพิ่มเติมจาก bitwarden

figma-to-angular
bitwarden
ทักษะนี้จะเปลี่ยนสเปกการออกแบบจาก Figma ให้เป็นคอมโพเนนต์ Angular ที่สมบูรณ์พร้อมกับสตอรีบุ๊กสตอรีใน Bitwarden Clients monorepo ผลลัพธ์ควรตรงกับการออกแบบทางสายตาในขณะที่ปฏิบัติตามข้อกำหนดของโค้ดเบสทั้งหมด
force-multiplier
bitwarden
ใช้เจตนาหนึ่งกับหลายเป้าหมายพร้อมกัน — กลุ่ม repositories ในระบบนิเวศ Bitwarden หรือหลาย projects ภายใน monorepo — เป็น N ที่สอดคล้องกัน,…
analyzing-git-sessions
bitwarden
วิเคราะห์ git commits และการเปลี่ยนแปลงภายในกรอบเวลาหรือช่วงของ commits โดยให้สรุปที่มีโครงสร้างสำหรับการตรวจสอบโค้ด การย้อนหลัง บันทึกการทำงาน หรือเซสชัน…
coordinating-cross-team-breakdown
bitwarden
ประสานงานการตรวจสอบและอนุมัติข้ามทีมสำหรับ Bitwarden Tech Breakdown ใช้เมื่อระบุทีมที่ได้รับผลกระทบ สร้างตารางอนุมัติส่วนที่ 3 และติดตามผล...
assessing-jira-issue-relevance
bitwarden
ใช้เมื่อผู้ใช้ระบุคีย์ Jira issue เพียงหนึ่งรายการและถามว่ายังเกี่ยวข้องอยู่หรือไม่ ยังใช้งานได้หรือไม่ ยังรอดำเนินการอยู่หรือไม่ ยังเป็นบั๊กอยู่หรือไม่ ได้รับการแก้ไขแล้วหรือไม่ หรือสามารถ...
assessing-test-coverage
bitwarden
ใช้เมื่อต้องการตรวจสอบว่ามีการครอบคลุมการทดสอบใดอยู่แล้วสำหรับการเปลี่ยนแปลงเฉพาะ (PR, คีย์ Jira, เอกสาร Tech Breakdown, CSV ของ Testmo, พาธที่เปลี่ยนแปลง หรือชื่อที่ระบุ…
retrospecting
bitwarden
ดำเนินการวิเคราะห์เซสชัน Claude Code อย่างครอบคลุม โดยตรวจสอบประวัติ git, บันทึกการสนทนา, การเปลี่ยนแปลงโค้ด และรวบรวมความคิดเห็นจากผู้ใช้เพื่อสร้าง…
reviewing-incremental-changes
bitwarden
ใช้ทักษะนี้เมื่อตรวจสอบ PR ซ้ำที่มีความคิดเห็นอยู่แล้ว หรือเมื่อตอบกลับการเปลี่ยนแปลงของนักพัฒนาหลังจากการตรวจสอบครั้งแรก ใช้เมื่อมีเธรด PR อยู่หรือ…