writing-database-queries

작성자: bitwarden

Bitwarden database architecture, migrations, and dual-ORM strategy. Use when working with `.sql` files, stored procedures, EF migrations, or database schema…

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

Dual-ORM Architecture

Bitwarden maintains two data access implementations, split by database provider:

  • MSSQL: Dapper with stored procedures
  • PostgreSQL, MySQL, SQLite: Entity Framework Core

These implementations are mutually exclusive at runtime — SQL Server uses only Dapper, while the other providers use only EF Core. Both implementations conform to the same repository interfaces.

  • When adding new repository functionality, implement it in both Dapper and EF Core (unless the feature is explicitly EF-only).
  • When modifying an existing stored procedure in a backwards-compatible way (for example, adding a new parameter with a default), EF Core changes are not required.
  • Some commercial features (for example, Secrets Manager) are EF Core only.

Evolutionary Database Design (EDD)

Bitwarden Cloud uses a no-rollback approach to database deployments. The key implication: server deployments can be rolled back, but database migrations cannot, so migrations must be designed to avoid being a source of downtime.

All MSSQL migrations live in util/Migrator/DbScripts/ and execute in chronological order based on the migration filename (YYYY-MM-DD_##_Description.sql).

Note: You may see util/Migrator/DbScripts_transition/ and util/Migrator/DbScripts_finalization/ folders. These are not currently used; ignore them for now.

Simple additive changes (new nullable column, new table, new stored procedure) typically require only a single migration script in util/Migrator/DbScripts/.

Stored procedure compatibility

Stored procedure changes fall into two categories:

  • Non-breaking (DEFAULT parameters): Adding a parameter with a default value (e.g., @NewParam BIT = NULL) is backwards-compatible. Existing callers keep working; no _V2 is needed.
  • Breaking (_V2 versioning): Required when result-set structure changes, calling patterns change (e.g., single result → multiple result sets), required parameters are added without defaults, or query semantics differ. Implement this by creating ProcedureName_V2 while retaining the original procedure for backwards compatibility.

Table-level breaking changes (removing columns, changing types) typically cascade into stored procedure changes and often require the _V2 pattern.

Always defer to the developer on migration strategy. The approach is complex and context-dependent. When a database change is needed, write the migration script and ask the developer whether _V2 versioning or additional steps are required.

Key locations

  • src/Sql/dbo — Master schema source of truth
  • util/Migrator/DbScripts — All migrations (single folder, chronological)

ORM-Specific Implementation

When implementing Dapper repository methods, stored procedures, or MSSQL migration scripts, activate the implementing-dapper-queries skill.

When implementing EF Core repositories, generating EF migrations, or working with PostgreSQL/MySQL/SQLite, activate the implementing-ef-core skill.

Critical Rules

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

  • Migration file naming: YYYY-MM-DD_##_Description.sql (e.g., 2025-06-15_00_AddVaultColumn.sql)
  • All schema objects use dbo schema — never create objects in other schemas
  • Constraint naming: PK_TableName (primary key), FK_Child_Parent (foreign key), IX_Table_Column (index), DF_Table_Column (default)
  • Idempotent scripts: Use IF NOT EXISTS / IF COL_LENGTH(...) guards before schema changes in migration scripts
  • New repository functionality requires both Dapper and EF Core implementations — unless the feature is explicitly EF-only or the change is a backwards-compatible stored procedure modification
  • Integration tests use [DatabaseData] attribute — this runs the test against all configured database providers

Further Reading

bitwarden의 다른 스킬

figma-to-angular
bitwarden
이 스킬은 Figma 디자인 스펙을 Bitwarden Clients 모노레포 내에서 Storybook 스토리와 함께 완전히 구현된 Angular 컴포넌트로 변환합니다. 출력물은 모든 코드베이스 규칙을 따르면서 시각적으로 디자인과 일치해야 합니다.
force-multiplier
bitwarden
하나의 의도를 여러 대상에 동시에 적용합니다 — Bitwarden 생태계 전반의 저장소 플릿, 또는 모노레포 내 많은 프로젝트 — N개의 일관된 작업으로, …
analyzing-git-sessions
bitwarden
특정 기간이나 커밋 범위 내의 Git 커밋과 변경 사항을 분석하여 코드 리뷰, 회고, 작업 로그 또는 세션을 위한 구조화된 요약을 제공합니다.
coordinating-cross-team-breakdown
bitwarden
크로스 팀 리뷰 및 Bitwarden 기술 분석에 대한 승인을 조정합니다. 영향을 받는 팀을 식별하고, 파트 3 승인 테이블을 작성하며, 후속 조치를 진행할 때 사용하세요.
assessing-jira-issue-relevance
bitwarden
사용자가 개별 Jira 이슈 키를 제공하고 그것이 여전히 관련이 있는지, 여전히 적용 가능한지, 여전히 보류 중인지, 여전히 버그인지, 수정되었는지, 또는 …인지 물을 때 사용합니다.
assessing-test-coverage
bitwarden
특정 변경(PR, Jira 키, Tech Breakdown 문서, Testmo CSV, 변경된 경로 또는 명명된 항목)에 대해 이미 존재하는 테스트 커버리지를 파악할 때 사용합니다.
retrospecting
bitwarden
Claude Code 세션에 대한 포괄적인 분석을 수행하며, git 히스토리, 대화 로그, 코드 변경 사항을 검토하고 사용자 피드백을 수집하여 생성합니다…
reviewing-incremental-changes
bitwarden
이미 코멘트가 달린 PR을 재검토하거나 초기 리뷰 후 개발자의 변경 사항에 응답할 때 이 스킬을 사용하세요. PR 스레드가 존재하거나...