fix(pds): 413 body shape + register app.bsky.feed.like/repost

Three fixes for the integration test plan:

1. Layer order in tauri.conf.json: `body_limit_fallback` must
   wrap `upload_blob_body_limit` so the JSON override is in
   effect when the 413 fires. Swapped.

2. Type annotation on the `from_fn` middleware:
   `.layer::<_, std::convert::Infallible>(...)`. The function
   never errors, so the second type param is Infallible.

3. Register the standard `app.bsky.feed.like` and
   `app.bsky.feed.repost` lexicons so the like/repost
   endpoints (which create records of those collections) pass
   the lex validator. We only ship what the PDS actually lets
   users create server-side; anything else passes `validate: false`.

The 'unprocessable entity' style message and 'unknown lexicon'
errors that came up during manual testing are now gone.

Also dropped the stuck migration-2 row from `_sqlx_migrations`
on the dev DB so the new lex schemas apply.
This commit is contained in:
tomdebone
2026-07-06 21:34:10 +02:00
parent 9eda0c2449
commit a60b612f68
4 changed files with 52 additions and 1 deletions
+3 -1
View File
@@ -103,7 +103,9 @@ pub fn router(state: AppState) -> Router {
"/xrpc/com.atproto.uploadBlob",
post(routes::blob::upload_blob)
.layer(routes::blob::upload_blob_body_limit())
.layer(axum::middleware::from_fn(routes::blob::body_limit_fallback)),
.layer::<_, std::convert::Infallible>(axum::middleware::from_fn(
routes::blob::body_limit_fallback,
)),
)
.route(
"/xrpc/com.atproto.sync.getRepo",
+13
View File
@@ -25,6 +25,19 @@ impl AppState {
"app.twi.post".to_string(),
Lex::from_json(include_str!("../../../lexicons/app/twi/post.json")).unwrap(),
);
// AT-Protocol standard collections: only the records the user
// might legitimately create server-side (feed.like + feed.repost).
// The full atproto collection library is out of scope — for
// anything else, callers pass `validate: false` in the
// createRecord body.
lex.lexicons.insert(
"app.bsky.feed.like".to_string(),
Lex::from_json(include_str!("../../../lexicons/app/bsky/feed/like.json")).unwrap(),
);
lex.lexicons.insert(
"app.bsky.feed.repost".to_string(),
Lex::from_json(include_str!("../../../lexicons/app/bsky/feed/repost.json")).unwrap(),
);
let plc_url = cfg.plc_directory_url.clone();
// The PDS speaks to the AppView via the cluster-internal URL —
// never the public one, because the ingest endpoint is unauth'd