feat(kayıt): yeni hane kaydı yalnızca davetle (REGISTRATION=invite_only)

- REGISTRATION ortam değişkeni: invite_only (varsayılan) | open
- invite_only: ilk hane serbest, sonrasında yalnızca davet koduyla katılım
- Backend'de zorunlu: 403 registration_closed; GET /api/auth/registration
- Kayıt ekranı: kayıt kapalıyken yalnızca davet kodu ve açıklama
- Entegrasyon testleri: kayıt politikası (2)
- Prettier ayarı eklendi (proje stiliyle uyumlu), kaynaklar biçimlendirildi

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-12 01:04:48 +03:00
parent 9cbeaaaf76
commit e188922c0f
29 changed files with 547 additions and 230 deletions
+16
View File
@@ -103,6 +103,7 @@ pub async fn register(
let password_hash = password::hash(req.password).await?;
let created = account::register(
&state.db,
state.config.registration,
NewAccount {
name,
email,
@@ -174,6 +175,21 @@ pub async fn login(
Ok((jar, Json(me)))
}
/// Kayıt ekranı için: yeni hane kurulabilir mi? (oturum gerektirmez)
#[derive(Serialize, TS)]
#[ts(export)]
pub struct RegistrationInfo {
/// `false` ise yalnızca davet koduyla kayıt yapılabilir
new_household_allowed: bool,
}
pub async fn registration_info(State(state): State<AppState>) -> AppResult<Json<RegistrationInfo>> {
let allowed = account::new_household_allowed(&state.db, state.config.registration).await?;
Ok(Json(RegistrationInfo {
new_household_allowed: allowed,
}))
}
pub async fn logout(jar: CookieJar) -> (StatusCode, CookieJar) {
(StatusCode::NO_CONTENT, jar.remove(removal_cookie()))
}
+1
View File
@@ -17,6 +17,7 @@ pub fn router(state: AppState) -> Router {
let api = Router::new()
.route("/health", get(health::health))
.route("/auth/register", post(auth::register))
.route("/auth/registration", get(auth::registration_info))
.route("/auth/login", post(auth::login))
.route("/auth/logout", post(auth::logout))
.route("/auth/me", get(auth::me))