Files
timeline-frontend/API_DOCUMENTATION.md
jhao 5a0aa2b3c1
All checks were successful
test/timeline-frontend/pipeline/head This commit looks good
feat: 添加评论、反应、离线编辑及主题定制功能
- 实现评论系统,包括评论输入、列表展示和集成指南
- 添加反应功能组件(ReactionBar、ReactionButton、ReactionPicker)
- 实现离线编辑支持,包括同步状态管理和冲突解决
- 添加主题定制功能,支持多种配色方案和主题预览
- 新增多视图布局选项(时间线、分组、砌体视图)
- 实现个人资料编辑器,支持头像、简介和自定义字段编辑
- 添加统计页面,展示存储使用情况和上传趋势
- 新增相册管理功能,支持相册创建、编辑和照片管理
- 实现响应式设计和加载骨架屏组件
- 扩展国际化支持,新增孟加拉语、波斯语、印尼语、日语、葡萄牙语等语言
- 添加错误边界组件和离线指示器
- 更新配置文件、路由和依赖项
- 新增完整的文档、测试用例和集成指南
2026-02-25 15:02:05 +08:00

816 lines
14 KiB
Markdown

# API Documentation - Personal User Enhancements
This document provides comprehensive API documentation for the personal user enhancements features.
## Table of Contents
1. [Smart Collections](#smart-collections)
2. [Album Management](#album-management)
3. [Personal Statistics](#personal-statistics)
4. [Offline Sync](#offline-sync)
5. [Comments](#comments)
6. [Reactions](#reactions)
7. [User Preferences](#user-preferences)
8. [Profile Customization](#profile-customization)
---
## Smart Collections
### Get Smart Collections
Retrieve all smart collections for the current user.
**Endpoint:** `GET /api/v1/collections/smart`
**Response:**
```typescript
{
collections: Array<{
id: string;
userId: string;
type: 'date' | 'location' | 'person';
name: string;
criteria: {
year?: number;
month?: number;
day?: number;
location?: {
name: string;
latitude: number;
longitude: number;
radius?: number;
};
personId?: string;
personName?: string;
};
contentCount: number;
thumbnailUrl?: string;
createdAt: string;
updatedAt: string;
}>;
}
```
### Get Collection Content
Retrieve content items within a specific smart collection.
**Endpoint:** `GET /api/v1/collections/smart/:id/content`
**Query Parameters:**
- `page` (number): Page number (default: 1)
- `pageSize` (number): Items per page (default: 20)
**Response:**
```typescript
{
collectionId: string;
items: Array<{
id: string;
type: 'photo' | 'story';
thumbnailUrl: string;
createdAt: string;
metadata: Record<string, any>;
}>;
total: number;
page: number;
pageSize: number;
}
```
---
## Album Management
### List Albums
Get all albums for the current user.
**Endpoint:** `GET /api/v1/albums`
**Response:**
```typescript
{
albums: Array<{
id: string;
userId: string;
name: string;
description?: string;
coverPhotoId?: string;
coverPhotoUrl?: string;
photoCount: number;
createdAt: string;
updatedAt: string;
}>;
}
```
### Create Album
Create a new album.
**Endpoint:** `POST /api/v1/albums`
**Request Body:**
```typescript
{
name: string; // Required
description?: string;
coverPhotoId?: string;
}
```
**Response:**
```typescript
{
id: string;
userId: string;
name: string;
description?: string;
coverPhotoId?: string;
coverPhotoUrl?: string;
photoCount: number;
createdAt: string;
updatedAt: string;
}
```
### Get Album Details
Get detailed information about a specific album including photos.
**Endpoint:** `GET /api/v1/albums/:id`
**Response:**
```typescript
{
id: string;
userId: string;
name: string;
description?: string;
coverPhotoId?: string;
coverPhotoUrl?: string;
photoCount: number;
photos: Array<{
id: string;
photoId: string;
albumId: string;
order: number;
photoUrl: string;
thumbnailUrl: string;
addedAt: string;
}>;
createdAt: string;
updatedAt: string;
}
```
### Update Album
Update album information.
**Endpoint:** `PUT /api/v1/albums/:id`
**Request Body:**
```typescript
{
name?: string;
description?: string;
coverPhotoId?: string;
}
```
### Delete Album
Delete an album (photos are preserved).
**Endpoint:** `DELETE /api/v1/albums/:id`
**Response:** `204 No Content`
### Add Photos to Album
Add one or more photos to an album.
**Endpoint:** `POST /api/v1/albums/:id/photos`
**Request Body:**
```typescript
{
photoIds: string[]; // Array of photo IDs to add
}
```
### Remove Photos from Album
Remove photos from an album.
**Endpoint:** `DELETE /api/v1/albums/:id/photos`
**Request Body:**
```typescript
{
photoIds: string[]; // Array of photo IDs to remove
}
```
### Reorder Photos
Change the order of photos in an album.
**Endpoint:** `PUT /api/v1/albums/:id/photos/order`
**Request Body:**
```typescript
{
photoIds: string[]; // Array of photo IDs in desired order
}
```
### Set Cover Photo
Set the cover photo for an album.
**Endpoint:** `PUT /api/v1/albums/:id/cover`
**Request Body:**
```typescript
{
coverPhotoId: string;
}
```
---
## Personal Statistics
### Get Statistics Overview
Get comprehensive statistics for the current user.
**Endpoint:** `GET /api/v1/statistics/overview`
**Response:**
```typescript
{
userId: string;
totalPhotos: number;
totalStories: number;
totalStorageBytes: number;
calculatedAt: string;
}
```
### Get Upload Trends
Get monthly and yearly upload trends.
**Endpoint:** `GET /api/v1/statistics/uploads`
**Query Parameters:**
- `period` (string): 'monthly' or 'yearly' (default: 'monthly')
**Response:**
```typescript
{
trends: Array<{
period: string; // 'YYYY-MM' or 'YYYY'
photoCount: number;
storyCount: number;
storageBytes: number;
}>;
}
```
### Get Storage Breakdown
Get storage usage breakdown by content type.
**Endpoint:** `GET /api/v1/statistics/storage`
**Response:**
```typescript
{
breakdown: {
photos: number;
videos: number;
documents: number;
other: number;
};
}
```
### Refresh Statistics
Force recalculation of statistics.
**Endpoint:** `POST /api/v1/statistics/refresh`
**Response:** `202 Accepted`
---
## Offline Sync
### Upload Offline Changes
Upload a batch of offline changes for synchronization.
**Endpoint:** `POST /api/v1/sync/changes`
**Request Body:**
```typescript
{
changes: Array<{
id: string;
entityType: 'story' | 'album' | 'photo';
entityId: string;
operation: 'create' | 'update' | 'delete';
data: any;
timestamp: string;
}>;
}
```
**Response:**
```typescript
{
success: boolean;
syncedCount: number;
failedCount: number;
conflicts: Array<{
changeId: string;
entityType: string;
entityId: string;
localVersion: any;
serverVersion: any;
conflictType: 'modified' | 'deleted';
}>;
}
```
### Get Sync Status
Get current synchronization status.
**Endpoint:** `GET /api/v1/sync/status`
**Response:**
```typescript
{
lastSyncAt?: string;
pendingChanges: number;
isSyncing: boolean;
}
```
### Resolve Conflict
Resolve a synchronization conflict.
**Endpoint:** `POST /api/v1/sync/resolve-conflict`
**Request Body:**
```typescript
{
conflictId: string;
strategy: 'keep-local' | 'keep-server' | 'merge';
mergedData?: any; // Required if strategy is 'merge'
}
```
---
## Comments
### Get Comments
Get comments for a specific entity (story or photo).
**Endpoint:** `GET /api/v1/comments/:entityType/:entityId`
**Path Parameters:**
- `entityType`: 'story' or 'photo'
- `entityId`: ID of the entity
**Response:**
```typescript
{
comments: Array<{
id: string;
entityType: 'story' | 'photo';
entityId: string;
userId: string;
userName: string;
userAvatarUrl?: string;
text: string;
createdAt: string;
updatedAt?: string;
isEdited: boolean;
canEdit: boolean;
canDelete: boolean;
}>;
}
```
### Create Comment
Add a comment to an entity.
**Endpoint:** `POST /api/v1/comments`
**Request Body:**
```typescript
{
entityType: 'story' | 'photo';
entityId: string;
text: string; // 1-1000 characters
}
```
**Response:**
```typescript
{
id: string;
entityType: 'story' | 'photo';
entityId: string;
userId: string;
userName: string;
userAvatarUrl?: string;
text: string;
createdAt: string;
isEdited: false;
canEdit: true;
canDelete: true;
}
```
### Update Comment
Edit an existing comment (within 24 hours).
**Endpoint:** `PUT /api/v1/comments/:id`
**Request Body:**
```typescript
{
text: string; // 1-1000 characters
}
```
### Delete Comment
Delete a comment.
**Endpoint:** `DELETE /api/v1/comments/:id`
**Response:** `204 No Content`
---
## Reactions
### Get Reactions
Get reactions for a specific entity.
**Endpoint:** `GET /api/v1/reactions/:entityType/:entityId`
**Path Parameters:**
- `entityType`: 'story' or 'photo'
- `entityId`: ID of the entity
**Response:**
```typescript
{
entityType: 'story' | 'photo';
entityId: string;
counts: {
like: number;
love: number;
laugh: number;
wow: number;
sad: number;
};
userReaction?: 'like' | 'love' | 'laugh' | 'wow' | 'sad';
recentReactions: Array<{
id: string;
userId: string;
userName: string;
userAvatarUrl?: string;
type: 'like' | 'love' | 'laugh' | 'wow' | 'sad';
createdAt: string;
}>;
}
```
### Add/Update Reaction
Add or update a reaction on an entity.
**Endpoint:** `POST /api/v1/reactions`
**Request Body:**
```typescript
{
entityType: 'story' | 'photo';
entityId: string;
type: 'like' | 'love' | 'laugh' | 'wow' | 'sad';
}
```
### Remove Reaction
Remove user's reaction from an entity.
**Endpoint:** `DELETE /api/v1/reactions/:entityType/:entityId`
**Response:** `204 No Content`
---
## User Preferences
### Get Preferences
Get all user preferences.
**Endpoint:** `GET /api/v1/preferences`
**Response:**
```typescript
{
userId: string;
theme: {
mode: 'light' | 'dark' | 'auto';
colorScheme: string;
};
layout: {
galleryLayout: 'grid' | 'list';
timelineLayout: 'grid' | 'list';
albumLayout: 'grid' | 'list';
cardSize: 'small' | 'medium' | 'large';
};
timeline: {
displayMode: 'chronological' | 'grouped' | 'masonry';
};
updatedAt: string;
}
```
### Update Theme Preferences
Update theme settings.
**Endpoint:** `PUT /api/v1/preferences/theme`
**Request Body:**
```typescript
{
mode?: 'light' | 'dark' | 'auto';
colorScheme?: string;
}
```
### Update Layout Preferences
Update layout settings.
**Endpoint:** `PUT /api/v1/preferences/layout`
**Request Body:**
```typescript
{
galleryLayout?: 'grid' | 'list';
timelineLayout?: 'grid' | 'list';
albumLayout?: 'grid' | 'list';
cardSize?: 'small' | 'medium' | 'large';
}
```
### Update Timeline Preferences
Update timeline display settings.
**Endpoint:** `PUT /api/v1/preferences/timeline`
**Request Body:**
```typescript
{
displayMode: 'chronological' | 'grouped' | 'masonry';
}
```
---
## Profile Customization
### Get Profile
Get user profile information.
**Endpoint:** `GET /api/v1/profile`
**Response:**
```typescript
{
userId: string;
coverPhotoUrl?: string;
bio?: string;
customFields: Array<{
id: string;
name: string;
value: string;
visibility: 'public' | 'private';
order: number;
}>;
updatedAt: string;
}
```
### Update Profile
Update profile information.
**Endpoint:** `PUT /api/v1/profile`
**Request Body:**
```typescript
{
bio?: string; // 0-500 characters
}
```
### Upload Cover Photo
Upload a new cover photo.
**Endpoint:** `POST /api/v1/profile/cover`
**Request:** `multipart/form-data`
- `file`: Image file (max 5MB, min 1200x400px)
**Response:**
```typescript
{
coverPhotoUrl: string;
}
```
### Update Custom Fields
Update profile custom fields.
**Endpoint:** `PUT /api/v1/profile/custom-fields`
**Request Body:**
```typescript
{
fields: Array<{
id?: string; // Omit for new fields
name: string;
value: string;
visibility: 'public' | 'private';
order: number;
}>;
}
```
---
## WebSocket Topics
Real-time updates are delivered via WebSocket (STOMP protocol).
### Comment Updates
**Topic:** `/topic/comments/{entityType}/{entityId}`
**Message Format:**
```typescript
{
type: 'comment_added' | 'comment_updated' | 'comment_deleted';
comment: Comment; // Full comment object
}
```
### Reaction Updates
**Topic:** `/topic/reactions/{entityType}/{entityId}`
**Message Format:**
```typescript
{
type: 'reaction_added' | 'reaction_updated' | 'reaction_removed';
reaction: Reaction; // Full reaction object
summary: ReactionSummary; // Updated counts
}
```
### Collection Updates
**Topic:** `/topic/collections/updates`
**Message Format:**
```typescript
{
type: 'collection_created' | 'collection_updated';
collection: SmartCollection;
}
```
### Personal Notifications
**Topic:** `/user/queue/notifications`
**Message Format:**
```typescript
{
type: 'comment' | 'reaction' | 'sync_complete' | 'sync_conflict';
title: string;
message: string;
data: any;
timestamp: string;
}
```
---
## Error Responses
All endpoints follow a consistent error response format:
```typescript
{
error: {
code: string; // Error code (e.g., 'VALIDATION_ERROR')
message: string; // Human-readable error message
details?: any; // Additional error details
timestamp: string; // ISO 8601 timestamp
}
}
```
### Common HTTP Status Codes
- `200 OK`: Successful request
- `201 Created`: Resource created successfully
- `204 No Content`: Successful request with no response body
- `400 Bad Request`: Invalid request data
- `401 Unauthorized`: Authentication required
- `403 Forbidden`: Insufficient permissions
- `404 Not Found`: Resource not found
- `409 Conflict`: Resource conflict (e.g., sync conflict)
- `422 Unprocessable Entity`: Validation error
- `429 Too Many Requests`: Rate limit exceeded
- `500 Internal Server Error`: Server error
- `503 Service Unavailable`: Service temporarily unavailable
---
## Rate Limiting
API requests are rate-limited to prevent abuse:
- **Standard endpoints**: 100 requests per minute per user
- **Upload endpoints**: 20 requests per minute per user
- **Statistics refresh**: 5 requests per hour per user
Rate limit headers are included in responses:
- `X-RateLimit-Limit`: Maximum requests allowed
- `X-RateLimit-Remaining`: Remaining requests in current window
- `X-RateLimit-Reset`: Timestamp when limit resets
---
## Pagination
List endpoints support pagination with the following query parameters:
- `page` (number): Page number (1-indexed, default: 1)
- `pageSize` (number): Items per page (default: 20, max: 100)
Paginated responses include:
```typescript
{
items: Array<T>;
total: number;
page: number;
pageSize: number;
totalPages: number;
}
```
---
## Authentication
All API requests require authentication via JWT token in the Authorization header:
```
Authorization: Bearer <token>
```
Tokens are obtained through the login endpoint and should be refreshed before expiration.