2026-01-21 23:09:33 +08:00
|
|
|
|
# Capability: API (OpenAPI-backed)
|
|
|
|
|
|
|
|
|
|
|
|
## Purpose
|
|
|
|
|
|
Describe the core HTTP API behavior and constraints. The OpenAPI 3.1 contract lives in `spec/openapi.yaml`.
|
|
|
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Health check
|
|
|
|
|
|
The system SHALL expose a health endpoint for availability checks.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Health endpoint returns OK
|
|
|
|
|
|
- **WHEN** a client calls `GET /health`
|
|
|
|
|
|
- **THEN** the server returns `200`
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Authentication
|
|
|
|
|
|
The system SHALL support email+password registration and login.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Register then login
|
|
|
|
|
|
- **WHEN** a user registers with a valid email and password
|
|
|
|
|
|
- **THEN** the server returns a JWT token
|
|
|
|
|
|
- **WHEN** the user logs in with the same credentials
|
|
|
|
|
|
- **THEN** the server returns a JWT token
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Public bookmarks visibility
|
|
|
|
|
|
The system SHALL allow anonymous users to view public bookmarks.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: List public bookmarks without auth
|
|
|
|
|
|
- **WHEN** a client calls `GET /bookmarks/public` without a token
|
|
|
|
|
|
- **THEN** the server returns `200` and a list of bookmarks
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Private bookmarks visibility
|
|
|
|
|
|
The system SHALL restrict private bookmark data to authenticated users.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: List my bookmarks requires auth
|
|
|
|
|
|
- **WHEN** a client calls `GET /bookmarks` without a token
|
|
|
|
|
|
- **THEN** the server returns an auth error
|
|
|
|
|
|
- **WHEN** a client calls `GET /bookmarks` with a valid token
|
|
|
|
|
|
- **THEN** the server returns `200` and the user's bookmarks
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Sync (LWW)
|
|
|
|
|
|
The system SHALL support last-write-wins (LWW) synchronization for folders and bookmarks.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Push local changes then pull
|
|
|
|
|
|
- **WHEN** an authenticated client calls `POST /sync/push` with folders/bookmarks
|
|
|
|
|
|
- **THEN** the server stores the items using LWW semantics
|
|
|
|
|
|
- **WHEN** the client calls `GET /sync/pull`
|
|
|
|
|
|
- **THEN** the server returns folders/bookmarks and `serverTime`
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Admin user management (email-based)
|
|
|
|
|
|
The system SHALL treat exactly one configured email as an administrator and allow that user to manage/view users.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Non-admin cannot access admin APIs
|
|
|
|
|
|
- **GIVEN** an authenticated user whose email is not equal to `ADMIN_EMAIL`
|
|
|
|
|
|
- **WHEN** the user calls `GET /admin/users`
|
|
|
|
|
|
- **THEN** the server returns a 403 error
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Admin can list users
|
|
|
|
|
|
- **GIVEN** an authenticated user whose email equals `ADMIN_EMAIL`
|
|
|
|
|
|
- **WHEN** the user calls `GET /admin/users`
|
|
|
|
|
|
- **THEN** the server returns `200` and a list of users
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Admin can view a user's bookmarks
|
|
|
|
|
|
- **GIVEN** an authenticated admin user
|
|
|
|
|
|
- **WHEN** the admin calls `GET /admin/users/{id}/bookmarks`
|
|
|
|
|
|
- **THEN** the server returns `200` and that user's bookmarks
|
2026-01-23 23:55:08 +08:00
|
|
|
|
|
|
|
|
|
|
### Requirement: Credential storage API
|
|
|
|
|
|
The system SHALL provide authenticated CRUD APIs for credentials scoped to the current user.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Create credential
|
|
|
|
|
|
- **WHEN** an authenticated user calls `POST /credentials` with `siteOrigin`, `username`, and `password`
|
|
|
|
|
|
- **THEN** the server stores the credential and returns the created record
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: List credentials
|
|
|
|
|
|
- **WHEN** an authenticated user calls `GET /credentials?siteOrigin=...`
|
|
|
|
|
|
- **THEN** the server returns the matching credentials for that user
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Update credential
|
|
|
|
|
|
- **WHEN** an authenticated user calls `PATCH /credentials/{id}`
|
|
|
|
|
|
- **THEN** the server updates the credential and returns the updated record
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Delete credential
|
|
|
|
|
|
- **WHEN** an authenticated user calls `DELETE /credentials/{id}`
|
|
|
|
|
|
- **THEN** the server deletes the credential
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Credential plaintext access
|
|
|
|
|
|
The system SHALL allow authenticated users to request plaintext passwords for their own credentials.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: User requests plaintext
|
|
|
|
|
|
- **GIVEN** an authenticated user
|
|
|
|
|
|
- **WHEN** the user calls `GET /credentials?includePassword=true`
|
|
|
|
|
|
- **THEN** the server returns plaintext passwords for that user
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Admin requests plaintext for a user
|
|
|
|
|
|
- **GIVEN** an authenticated admin user
|
|
|
|
|
|
- **WHEN** the admin calls `GET /admin/users/{id}/credentials?includePassword=true`
|
|
|
|
|
|
- **THEN** the server returns plaintext passwords for that user
|
|
|
|
|
|
|
|
|
|
|
|
### Requirement: Admin credential management
|
|
|
|
|
|
The system SHALL allow an admin to list and manage any user’s credentials.
|
|
|
|
|
|
|
|
|
|
|
|
#### Scenario: Admin lists user credentials
|
|
|
|
|
|
- **GIVEN** an authenticated admin user
|
|
|
|
|
|
- **WHEN** the admin calls `GET /admin/users/{id}/credentials`
|
|
|
|
|
|
- **THEN** the server returns that user’s credentials
|