원클릭으로
rust-conventions
Rust coding conventions and patterns for auth9-core development.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Rust coding conventions and patterns for auth9-core development.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Run E2E tests for Auth9 portal using Playwright with hybrid testing strategy.
Run tests, check logs, and troubleshoot Auth9 services in Docker and Kubernetes environments.
Run performance benchmarks for auth9-core API using hey load testing tool.
Execute scenario-based QA testing with browser automation, database validation, and automatic ticket creation for failures.
Reset Auth9 local Docker development environment to a clean state.
Run tests and check coverage for Auth9 backend, frontend, and SDK with mock-based testing patterns.
| name | rust-conventions |
| description | Rust coding conventions and patterns for auth9-core development. |
| Component | Library |
|---|---|
| Web | axum + Tower middleware |
| gRPC | tonic |
| Database | sqlx (compile-time SQL, TiDB) |
| Async | tokio |
| Logging | tracing |
| Cache | redis-rs, NoOpCacheManager (tests) |
| Testing | mockall, wiremock |
auth9-core/src/
├── domain/ # Pure models with validation
├── service/ # Business logic (depends on repo traits)
├── repository/ # Data access (mockable traits)
├── api/ # HTTP handlers (thin)
├── grpc/ # gRPC handlers (thin)
└── cache/ # CacheManager + NoOpCacheManager
// ❌ BAD
let result = db.query().await.ok();
// ✅ GOOD - use Result with context
let result = db.query()
.await
.context("Failed to query tenant")?;
// ✅ GOOD - custom error types
#[derive(thiserror::Error, Debug)]
pub enum ServiceError {
#[error("Tenant not found: {0}")]
TenantNotFound(Uuid),
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
}
All tests run fast (~1-2s) with no Docker:
| Component | Approach |
|---|---|
| Repository | Mock traits with mockall |
| Service | Unit tests with mock repos |
| gRPC | NoOpCacheManager + mocks |
| External HTTP (OIDC) | wiremock HTTP mocking |
#[cfg_attr(test, mockall::automock)]
#[async_trait]
pub trait TenantRepository: Send + Sync {
async fn create(&self, input: &CreateTenantInput) -> Result<Tenant>;
async fn find_by_id(&self, id: StringUuid) -> Result<Option<Tenant>>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::repository::tenant::MockTenantRepository;
#[tokio::test]
async fn test_create_tenant() {
let mut mock = MockTenantRepository::new();
mock.expect_find_by_slug()
.returning(|_| Ok(None));
mock.expect_create()
.returning(|input| Ok(Tenant { name: input.name.clone(), ..Default::default() }));
let service = TenantService::new(Arc::new(mock), None);
let result = service.create(input).await;
assert!(result.is_ok());
}
}
use auth9_core::cache::NoOpCacheManager;
#[tokio::test]
async fn test_exchange_token() {
let cache = NoOpCacheManager::new(); // No Redis
let service = TokenExchangeService::new(jwt_manager, cache, repos...);
// ...
}
use wiremock::{Mock, ResponseTemplate, MockServer};
#[tokio::test]
async fn test_oidc_http() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/.well-known/openid-configuration"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"issuer": mock_server.uri()
})))
.mount(&mock_server).await;
// Use mock_server.uri()
}
cargo test # All tests (fast)
cargo llvm-cov --html # Coverage report
cargo clippy # Lint
cargo fmt # Format