Skip to content

✨ Redesign REST API with namespaced routing and integrated account resource - #12

Merged
turtton merged 1 commit into
mainfrom
feat/api-redesign
Jul 19, 2026
Merged

✨ Redesign REST API with namespaced routing and integrated account resource#12
turtton merged 1 commit into
mainfrom
feat/api-redesign

Conversation

@turtton

@turtton turtton commented Jul 18, 2026

Copy link
Copy Markdown
Member

Summary

.review/api-redesign.md の設計書に基づく REST API 再設計の実装。4フェーズ+仕上げ3タスクを1コミットに集約。

  • 名前空間4分離: /api/v1 (クライアント, JWT) / /api/v1/admin (モデレーション, JWT+Keto) / /internal/v1 (サービス間, JWT) / /ap (連合, 公開)。Actor endpoint は Accept 交渉を廃止し常時 application/activity+json。webfinger links も /ap/...
  • 統合アカウント表現: Account+Profile+Metadata を1リソースに統合。GET /api/v1/accounts/{id} 新設、PUTPATCH 化(absent/null/value 三値を単一DBトランザクションで適用)、fields は index-based diff でイベント生成。profile/metadata REST エンドポイント廃止(4削減)、クライアント応答から public_key 除去
  • ActorUrlBuilder: 5箇所に散在していた連合URL構築を kernel に一元化(ACTORS_PATH 1行で将来のパス変更が完結)
  • signing_keys 移行完遂: accounts.private_key/public_key 列を DROP(マイグレーション同梱)。Entity/Event から鍵フィールドを削除し、秘密鍵漏洩の構造的リスクを解消
  • 値オブジェクト検証: ProfileDisplayName(100)/ProfileSummary(2000)/MetadataLabel(255)/MetadataContent(1000)/ModerationReason(500)/ImageUrl(2048) に長さ上限、新設 KernelError::Validation → HTTP 400
  • OpenAPI 単一ソース化: kernel 型に feature-gated utoipa::ToSchema を derive し server 重複型を削除。Actor.url のドリフトを構造的に解消

Breaking changes

  • 全 REST パスが名前空間下移動(旧 /accounts/** 等は 404)
  • PUT /accounts/{id}PATCH /api/v1/accounts/{id} に、profile/metadata 個別エンドポイントは統合PATCHへ吸収
  • GET /internal/v1/accounts/{id}/public-key が JWT 必須に変更(設計どおり)
  • dev DB: accounts の鍵列 DROP マイグレーション適用。既存 dev アカウントは署名鍵再生成のため再作成推奨

設計中に発見し修正したバグ

  • FieldAction::Clear がイベントJSONの nullUnchanged として復元し、profile クリアが永続化されない問題
  • アカウント作成時に accounts 列用と signing_keys 用で異なる2つの鍵ペアを生成していた問題(signing_keys に一元化)

Verification

  • cargo test: 248 passed / 0 failed(kernel 84 / application 26 / driver 104 / server 34)、ビルド警告ゼロ
  • e2e/run-ap-e2e.sh 全スイート: 21 passed / 0 failed(basic flow 4 / mock AP 9 / Iceshrimp 4 / Mastodon 4)
  • OpenAPI ドリフトテスト・ルート smoke テスト通過

Follow-up

oversized file(250+ pure LOC)の整理は Oracle 協議のうえ、レビュー容易性のため本PRには含めず、stacked PR で別途実施します(activitypub service / http_signing / account service+route の directory module 化)。

…source

- Split routes into /api/v1 (client), /api/v1/admin (moderation),
  /internal/v1 (service-to-service), /ap (federation); the actor
  endpoint now always serves activity+json (Accept-negotiation 404 hack
  removed), and webfinger links point at /ap/...
- Integrate Account/Profile/Metadata into a single client-facing
  account resource: GET /api/v1/accounts/{id}, PUT->PATCH with
  absent/null/value tri-state semantics applied in one DB transaction,
  fields full-replacement via index-based event diff; remove the
  profile/metadata REST endpoints (4 endpoints dropped); public_key
  removed from client responses
- Centralize federation URL construction in kernel ActorUrlBuilder
  (single ACTORS_PATH const) and fix stale UUIDv7 doc in CLAUDE.md
- Complete signing_keys migration: drop accounts.private_key/public_key
  columns and entity/event fields, eliminating the structural
  private-key leak risk
- Add length limits to value objects (ProfileDisplayName 100,
  ProfileSummary 2000, MetadataLabel 255, MetadataContent 1000,
  ModerationReason 500, ImageUrl 2048) mapped to HTTP 400 via new
  KernelError::Validation
- Single-source ActivityPub OpenAPI schemas from kernel types behind an
  openapi cargo feature; resolves the Actor.url doc drift
- Fix FieldAction::Clear deserializing as Unchanged (cleared profile
  fields were silently persisted)
- Fix account creation generating two different keypairs (accounts
  columns vs signing_keys); key material now lives only in signing_keys
@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.14748% with 521 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.76%. Comparing base (0fe95c9) to head (6669ac4).

Files with missing lines Patch % Lines
application/src/service/account_detail/update.rs 0.00% 156 Missing ⚠️
application/src/service/account_detail/read.rs 0.00% 152 Missing ⚠️
application/src/service/account_detail/fields.rs 54.54% 60 Missing ⚠️
server/src/route/account.rs 28.20% 28 Missing ⚠️
server/src/schema/account.rs 68.00% 24 Missing ⚠️
application/src/transfer/account.rs 0.00% 21 Missing ⚠️
driver/src/database/postgres.rs 21.05% 15 Missing ⚠️
application/src/service/profile.rs 0.00% 12 Missing ⚠️
kernel/src/database.rs 0.00% 10 Missing ⚠️
driver/src/database/postgres/account.rs 60.86% 9 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #12      +/-   ##
==========================================
- Coverage   65.06%   64.76%   -0.31%     
==========================================
  Files         111      116       +5     
  Lines       14662    15203     +541     
==========================================
+ Hits         9540     9846     +306     
- Misses       5122     5357     +235     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@turtton
turtton merged commit 24f0adc into main Jul 19, 2026
13 checks passed
@turtton
turtton deleted the feat/api-redesign branch July 19, 2026 04:47
turtton added a commit that referenced this pull request Jul 19, 2026
## Summary

Stacked PR — base は #12 (`feat/api-redesign`)。#12 マージ後に base を `main` へ
retarget してください。

#12 で報告した oversized file 問題のうち、Oracle
協議で「即分割有効」と判定された4ファイルを、**純粋な機械的移動**(振る舞い変更ゼロ・公開APIパス不変・pub 拡大なし)で
directory module 化します。レビューはコミット単位でどうぞ。

| Commit | 対象 | Before | After (最大) |
|---|---|---|---|
| `9c1de30` | `application/src/service/activitypub.rs` | 1344 prod LOC |
directory 化: actor / collections / outbox / outbound_follow /
inbox(mod+handlers) / remote_actor / delivery / fetch — 最大 301 |
| `9404377` | `driver/src/http_signing.rs` | 893 prod LOC | directory 化:
signer / verifier / cavage(mod+parser) / actor_key / fetch / ssrf +
tests.rs — 最大 164、23テスト全維持 |
| `a48b60d` | `application/src/service/account.rs` | 509 prod LOC | use
case 別: read / create / update / deactivate / moderation / rehydrate —
最大 192 |
| `e9bc3eb` | `server/src/route/account.rs` | 403 prod LOC | API 面別:
client / admin / follow — 最大 208 |

## 方針(Oracle 協議結果)

-
分割は本PRの4ファイルのみ。`route/activitypub.rs`・`adapter/processor/account.rs`・`oauth2.rs`・`metadata/profile`
各 service・`driver/postgres/*` は着手トリガー付きで延期(follow-up issue を作成済み)
- `handler.rs`(DI registry)と
`kernel/entity/account.rs`(単一集約)は「分割しない」判断をサイズ例外として記録
- activitypub と http_signing の SSRF 類似コードの共通化は architecture change
のため今回スコープ外

## Verification(全コミットで実施)

- `cargo build --all-targets`: 警告ゼロ、`cargo test`: **248 passed / 0
failed**(baseline と完全一致)
- `openapi_spec_matches_committed_file` 通過、openapi.json **差分ゼロ**(再生成なし)
- http_signing ユニットテスト 23件 全維持
- `e2e/run-ap-e2e.sh` 全スイート: **21 passed / 0 failed**(FF1+FF2 後・FF3
後の2回実施)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant