Files
member-platform/docs/FRONTEND_API_CONTRACT.md

231 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Frontend API Contractmemberapi
Base URL`https://memberapi.ose.tw`
## 0. OIDC 登入(目前主流程)
### GET `/auth/oidc/url?redirect_uri=<frontend-callback-url>`
200 Response:
```json
{
"authorize_url": "https://auth.ose.tw/application/o/authorize/..."
}
```
### POST `/auth/oidc/exchange`
Request:
```json
{
"code": "authorization-code",
"redirect_uri": "http://localhost:5173/auth/callback"
}
```
200 Response:
```json
{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email"
}
```
## 1. 使用者資訊
### GET `/me`
Headers:
- `Authorization: Bearer <access_token>`
200 Response:
```json
{
"sub": "authentik-sub-123",
"email": "user@example.com",
"display_name": "User Name"
}
```
401 Error:
```json
{ "detail": "missing_bearer_token" }
```
```json
{ "detail": "invalid_bearer_token" }
```
## 2. 我的權限快照
### GET `/me/permissions/snapshot`
Headers:
- `Authorization: Bearer <access_token>`
200 Response:
```json
{
"authentik_sub": "authentik-sub-123",
"permissions": [
{
"scope_type": "site",
"scope_id": "tw-main",
"module": "campaign",
"action": "view"
}
]
}
```
## 3. Grant 權限
### POST `/admin/permissions/grant`
Headers:
- `X-Client-Key: <client_key>`
- `X-API-Key: <plain_api_key>`
Request:
```json
{
"authentik_sub": "authentik-sub-123",
"email": "user@example.com",
"display_name": "User Name",
"scope_type": "site",
"scope_id": "tw-main",
"module": "campaign",
"action": "view"
}
```
200 Response:
```json
{
"permission_id": "uuid",
"result": "granted"
}
```
## 4. Revoke 權限
### POST `/admin/permissions/revoke`
Headers:
- `X-Client-Key: <client_key>`
- `X-API-Key: <plain_api_key>`
Request:
```json
{
"authentik_sub": "authentik-sub-123",
"scope_type": "site",
"scope_id": "tw-main",
"module": "campaign",
"action": "view"
}
```
200 Response:
```json
{
"deleted": 1,
"result": "revoked"
}
```
404 Response:
```json
{ "detail": "user_not_found" }
```
## 5. Health Check
### GET `/healthz`
200 Response:
```json
{ "status": "ok" }
```
## 6. 組織管理admin
### GET `/admin/organizations`
Headers:
- `X-Client-Key: <client_key>`
- `X-API-Key: <plain_api_key>`
Query:
- `keyword` (optional)
- `status` (optional: `active|inactive`)
- `limit` (default `50`)
- `offset` (default `0`)
### POST `/admin/organizations`
```json
{
"org_code": "ose-main",
"name": "Ose Main",
"tax_id": "12345678",
"status": "active"
}
```
### PATCH `/admin/organizations/{org_id}`
```json
{
"name": "Ose Main Updated",
"status": "inactive"
}
```
### POST `/admin/organizations/{org_id}/activate`
### POST `/admin/organizations/{org_id}/deactivate`
## 7. 會員管理admin
### GET `/admin/members`
Headers:
- `X-Client-Key: <client_key>`
- `X-API-Key: <plain_api_key>`
Query:
- `keyword` (optional)
- `is_active` (optional: `true|false`)
- `limit` (default `50`)
- `offset` (default `0`)
### POST `/admin/members`
```json
{
"authentik_sub": "authentik-sub-123",
"email": "user@example.com",
"display_name": "User Name",
"is_active": true
}
```
### PATCH `/admin/members/{member_id}`
```json
{
"display_name": "New Name",
"is_active": false
}
```
### POST `/admin/members/{member_id}/activate`
### POST `/admin/members/{member_id}/deactivate`
## 8. 會員/組織關聯admin
### GET `/admin/members/{member_id}/organizations`
### POST `/admin/members/{member_id}/organizations/{org_id}`
### DELETE `/admin/members/{member_id}/organizations/{org_id}`
## 9. 系統對系統查詢internal
Headers:
- `X-Internal-Secret: <internal_shared_secret>`
Endpoints:
- `GET /internal/members`
- `GET /internal/members/by-sub/{authentik_sub}`
- `GET /internal/organizations`
- `GET /internal/organizations/by-code/{org_code}`
- `GET /internal/members/{member_id}/organizations`
## 10. 常見錯誤碼
- `401 invalid_client`
- `401 invalid_api_key`
- `401 client_expired`
- `403 origin_not_allowed`
- `403 ip_not_allowed`
- `403 path_not_allowed`
- `503 internal_secret_not_configured`
- `503 authentik_admin_not_configured`