refactor: 5 architectural improvements (Tasks 2-5 + Task 6 fix)
Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 5m2s
test / unit (pull_request) Successful in 16m19s
test / integration (pull_request) Failing after 17m15s

- feat(domain): Hashtag value object with canonical extract() — unifies two
  divergent private implementations; fields pre-compute raw/normalized/url_slug/ap_name

- feat(presentation): Deps<S: FromAppState> extractor — each handler now
  declares its exact dependency surface; AppState unchanged; handlers
  become unit-testable without mocking all 20 deps

- refactor(feed): replace 5 flat FeedRepository methods with FeedQuery/FeedScope
  — single query() method; SQL shared logic lives once; adding feed types
  no longer requires 5 edits

- refactor(activitypub): ActivityPubRepository + OutboundFederationPort moved
  out of domain::ports into activitypub-base::ap_ports — domain crate no
  longer knows about AP IDs, inboxes, or actor URLs

- fix(outbox): OutboxRelay now opens a per-row transaction so FOR UPDATE
  SKIP LOCKED actually holds the lock during publish + mark_delivered
This commit is contained in:
2026-05-15 18:54:20 +02:00
parent 6024a65060
commit 0592861edd
37 changed files with 1401 additions and 865 deletions

View File

@@ -2,6 +2,27 @@ use crate::{errors::ApiError, state::AppState};
use axum::{extract::FromRequestParts, http::request::Parts};
use domain::value_objects::UserId;
// ---------------------------------------------------------------------------
// Deps<S> extractor — narrows AppState to a handler-specific deps struct
// ---------------------------------------------------------------------------
pub struct Deps<S>(pub S);
pub trait FromAppState: Sized {
fn from_state(s: &AppState) -> Self;
}
impl<S: FromAppState + Send + 'static> FromRequestParts<AppState> for Deps<S> {
type Rejection = std::convert::Infallible;
async fn from_request_parts(
_parts: &mut Parts,
state: &AppState,
) -> Result<Self, Self::Rejection> {
Ok(Deps(S::from_state(state)))
}
}
pub struct AuthUser(pub UserId);
pub struct OptionalAuthUser(pub Option<UserId>);