# Frontend API Contract(memberapi) Base URL:`https://memberapi.ose.tw` ## 0. OIDC 登入(目前主流程) ### GET `/auth/oidc/url?redirect_uri=` 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": "", "token_type": "Bearer", "expires_in": 3600, "scope": "openid profile email" } ``` ## 1. 使用者資訊 ### GET `/me` Headers: - `Authorization: Bearer ` 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 ` 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: ` - `X-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: ` - `X-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: ` - `X-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: ` - `X-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: ` 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`