If your change touches SQLx queries, migrations, or query result shapes, refresh and verify SQLx metadata according to the project workflow before submitting.
## Documentation
The documentation site lives in `docs/`.
```bash
cd docs
npm install
npm run validate
```
Documentation changes should keep Chinese and English pages aligned when a page exists in both locales.
Provider work starts with the [Provider Development Guide](docs/src/content/docs/en/develop/provider-development.mdx). Keep the provider's upstream client and DTOs, Core source config and target, public protobuf/API, OpenAPI, management and CLI surfaces, and Flutter App flow aligned. Validate typed parse/preview results, generated playback resources, local and remote execution paths, provider credentials, and page/cursor behavior.
Provider changes that affect the Flutter App also require its standard checks:
- Static configuration fields: update the configuration index, full configuration example, environment variable reference, and the relevant topic page.
- Runtime settings: update the runtime settings reference.
- CLI commands: update the CLI reference.
- HTTP/OpenAPI paths: update OpenAPI and client integration docs if behavior changes.
- gRPC/protobuf APIs: update gRPC and client integration docs if behavior changes.
- Authentication, MFA, OAuth2, token, permission, or management behavior: update the security model and relevant runbooks.
- Docker Compose, Helm, Service, Ingress, metrics, or storage templates: update deployment docs and the production checklist.
## API and Compatibility
This project is still under active design. Do not preserve obsolete paths, protobuf fields, or configuration shapes unless maintainers explicitly require compatibility. Prefer clear current architecture over compatibility shims for old experimental designs.
Keep database schema constraints focused on stable storage integrity, not product policy.
Database migrations may enforce long-lived persistence invariants such as primary keys, foreign keys, required storage columns, identity uniqueness, unique indexes, lookup indexes, and data-shape rules that are unlikely to change without a deliberate storage migration. They should not encode business-level validation that changes with product behavior.
Do not put these in SQL `CHECK` constraints, database enum types, or string enum lists:
- Role, status, signup-method, review-state, provider-type, or other business enum value lists.
- Workflow/state-machine coupling such as "pending means reviewed_at is null" or "rejected requires a reason".
- Numeric ranges that are product choices rather than physical storage constraints.
Store enum-like fields such as status, role, signup method, message type, and review state as numeric codes (`SMALLINT` is usually enough), and keep the meaning/mapping in Rust domain types. Avoid persisting those values as strings.
Implement volatile business rules in the domain/service layer, keep repository inputs typed where practical, and cover them with focused tests. If direct database writes could create invalid business state, prefer service-only write paths, operational consistency checks, or repair tooling over moving volatile policy into the schema.
`UNIQUE` is allowed when the rule is a stable identity or near-permanent uniqueness invariant and database atomicity is valuable: usernames, emails, provider instance names, OAuth account identities, idempotency keys, and one-active-row-per-stable-scope patterns are typical examples. Do not use `UNIQUE` for product policy that may be relaxed, re-scoped, or reinterpreted during normal feature work. A new project is not an exception: migrations should still avoid business constraints that would make ordinary product changes require database constraint churn.
User-facing labels and display names, such as room names, should be treated as product policy unless they are explicitly defined as stable identifiers. Enforce those rules in services, using transactional locks or other coordination where concurrency matters.