mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-09-01 14:04:08 +00:00
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
112 lines
4.1 KiB
Markdown
112 lines
4.1 KiB
Markdown
# Memories API Documentation
|
|
|
|
The **Memories** feature allows users to back up their media to the server in an end-to-end encrypted format. The client-server communication happens primarily via the existing WebSocket connection using Protocol Buffers (`client_to_server.proto` and `server_to_client.proto`), while the actual binary file uploads/downloads use Amazon S3 presigned URLs via HTTP PUT/GET.
|
|
|
|
## 1. Checking Storage Quota
|
|
Before allowing a user to upload a memory, the client should query the user's current storage usage to ensure they haven't exceeded their limit.
|
|
|
|
**Request:**
|
|
```proto
|
|
// client_to_server.proto
|
|
message GetMemoriesUsage {}
|
|
```
|
|
**Response:**
|
|
```proto
|
|
// server_to_client.proto
|
|
message MemoriesUsage {
|
|
int64 max_bytes = 1;
|
|
int64 current_bytes = 2;
|
|
int64 count = 3;
|
|
}
|
|
```
|
|
If `current_bytes` + the new file size > `max_bytes`, the client should block the upload and optionally prompt the user to upgrade their plan or free up space.
|
|
|
|
## 2. Uploading a Memory
|
|
Uploading a memory is a three-step process: requesting presigned URLs, performing the actual HTTP uploads, and finally confirming the upload.
|
|
|
|
### Step 2.1: Request Upload URLs
|
|
The client requests permission to upload a new memory item, declaring its size and original capture date.
|
|
|
|
**Request:**
|
|
```proto
|
|
// client_to_server.proto
|
|
message RequestMemoriesUpload {
|
|
int64 size = 1; // Size of the FULL media file in bytes
|
|
int64 original_date = 2; // Unix timestamp (in milliseconds/seconds depending on your app's standard) of when the media was originally created
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```proto
|
|
// server_to_client.proto
|
|
message MemoriesUploadUrls {
|
|
string media_id = 1; // Unique identifier generated by the server for this memory
|
|
string thumbnail_upload_url = 2; // S3 presigned URL for uploading the encrypted thumbnail
|
|
string full_upload_url = 3; // S3 presigned URL for uploading the encrypted full media
|
|
}
|
|
```
|
|
|
|
### Step 2.2: Perform HTTP Uploads
|
|
Using the URLs returned in Step 2.1, the client encrypts the thumbnail and the full media locally, and performs an HTTP `PUT` request to the respective URLs.
|
|
|
|
*Note: The upload URLs are usually valid only for a short time (e.g. 15-60 minutes). Ensure you upload the data promptly.*
|
|
|
|
### Step 2.3: Confirm the Upload
|
|
After both the thumbnail and the full media are successfully uploaded via HTTP, the client **must** notify the server so it can mark the memory as fully uploaded and available.
|
|
|
|
**Request:**
|
|
```proto
|
|
// client_to_server.proto
|
|
message ConfirmMemoriesUpload {
|
|
string media_id = 1; // The media_id obtained in Step 2.1
|
|
}
|
|
```
|
|
*(The server will respond with an empty `Ok::None(true)` acknowledgment upon success).*
|
|
|
|
|
|
## 3. Retrieving Memories (Pagination)
|
|
To display a gallery or timeline of backed-up memories, the client requests a paginated list of media items. The endpoint returns a descending list (newest first) based on the original date.
|
|
|
|
**Request:**
|
|
```proto
|
|
// client_to_server.proto
|
|
message GetMemoriesList {
|
|
int64 offset_date = 1; // Unix timestamp to fetch memories older than this date (for pagination). Use MAX_INT64 for the first page.
|
|
int64 limit = 2; // Maximum number of items to return in this batch (e.g. 50)
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```proto
|
|
// server_to_client.proto
|
|
message MemoriesList {
|
|
repeated MediaItem items = 1;
|
|
}
|
|
|
|
message MediaItem {
|
|
string media_id = 1;
|
|
int64 original_date = 2;
|
|
string thumbnail_download_url = 3; // S3 presigned URL to download the encrypted thumbnail
|
|
}
|
|
```
|
|
The client can immediately use the `thumbnail_download_url` to fetch and decrypt the thumbnail for the gallery view.
|
|
|
|
## 4. Downloading Full Media
|
|
When a user taps on a memory to view it in full screen, the client requests a temporary download URL for the full-resolution file.
|
|
|
|
**Request:**
|
|
```proto
|
|
// client_to_server.proto
|
|
message GetMemoriesUrl {
|
|
string media_id = 1;
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```proto
|
|
// server_to_client.proto
|
|
message MemoriesUrl {
|
|
string full_download_url = 1; // S3 presigned URL to download the encrypted full media
|
|
}
|
|
```
|
|
The client can then perform an HTTP `GET` request to `full_download_url`, decrypt the payload locally, and display the full-resolution image or video.
|