feat: create application DTOs

Add data-transfer-object interfaces for the application layer:
upload, file, bucket, S3, and auth domains.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude
2026-07-28 17:56:49 +07:00
parent ee3167fbfb
commit 5e29589f1a
5 changed files with 294 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
/**
* Input for the login endpoint.
* The caller provides the admin API token to obtain a session cookie.
*/
export interface LoginInput {
/** Admin API token for authentication */
token: string;
}
/**
* Active authentication session information.
*/
export interface AuthSession {
/** Authenticated username (currently always "admin") */
username: string;
/** Session expiry timestamp; null for bearer-token sessions */
expiresAt: Date | null;
/** Authentication method used */
method: 'cookie' | 'bearer';
}
/**
* Response payload for a successful login.
*/
export interface LoginResponse {
/** Authenticated username */
username: string;
}
/**
* Response payload for logout.
*/
export interface LogoutResponse {
/** Whether the logout succeeded */
success: boolean;
}
/**
* Response payload for the current-user (/me) endpoint.
*/
export interface UserInfoResponse {
/** Authenticated username */
username: string;
/** ISO-8601 session expiry timestamp; null when using bearer token */
expiresAt: string | null;
}
+47
View File
@@ -0,0 +1,47 @@
/**
* Input for creating a new bucket.
*/
export interface CreateBucketInput {
/** Bucket name (must match S3 naming rules: 3-63 chars, lowercase, no underscore) */
name: string;
}
/**
* Single bucket representation returned by bucket endpoints.
*/
export interface BucketResponse {
/** Bucket UUID */
id: string;
/** Bucket name */
name: string;
/** ISO-8601 timestamp of when the bucket was created */
createdAt: string;
/** Number of non-deleted objects in the bucket */
objectCount?: number;
}
/**
* Response payload for the list-buckets endpoint.
*/
export interface BucketListResponse {
/** Array of buckets */
buckets: BucketResponse[];
}
/**
* Response payload for bucket creation.
*/
export interface CreateBucketResponse {
/** Bucket UUID */
id: string;
/** Bucket name */
name: string;
}
/**
* Response payload for bucket deletion.
*/
export interface DeleteBucketResponse {
/** Whether the deletion succeeded */
success: boolean;
}
+68
View File
@@ -0,0 +1,68 @@
/**
* Public file information response returned by the file-info endpoint.
* Mirrors the JSON shape of GET /file/:publicId/info.
*/
export interface FileInfoResponse {
/** Public, shareable identifier (nanoid) */
public_id: string;
/** Stored file name */
file_name: string;
/** MIME type of the stored file */
mime_type: string;
/** File size in bytes */
size_bytes: number;
/** High-level file category (e.g. "document", "photo") */
file_type: string;
/** ISO-8601 timestamp of when the file record was created */
created_at: string;
}
/**
* Summary-level file metadata used internally for constructing
* upload responses and object listing entries.
*/
export interface FileMetadata {
/** Public, shareable identifier (nanoid) */
publicId: string;
/** Telegram file identifier used to retrieve the file from Telegram CDN */
telegramFileId: string;
/** Telegram unique file identifier (persists across reuploads) */
telegramFileUniqueId: string;
/** Chat ID where the file or archive was stored */
storageChatId: number;
/** Message ID of the stored file or archive */
storageMessageId: number;
/** Stored file name */
fileName: string;
/** MIME type of the stored file */
mimeType: string;
/** File size in bytes */
sizeBytes: number;
/** High-level file category */
fileType: string;
/** Telegram user ID of the uploader; 0 when unknown or system */
uploaderId: number;
/** Timestamp of file record creation */
createdAt: Date | string | number;
}
/**
* Upload response shape returned to API callers.
* Mirrors the JSON output of the /api/upload endpoint.
*/
export interface UploadResponse {
/** Public, shareable identifier */
public_id: string;
/** Stored file name */
file_name: string;
/** MIME type */
mime_type: string;
/** File size in bytes */
size_bytes: number;
/** High-level file category */
file_type: string;
/** ISO-8601 creation timestamp */
created_at: string;
/** Public download URL */
download_url: string;
}
+87
View File
@@ -0,0 +1,87 @@
/**
* A single S3 object as it appears in listing results.
*/
export interface S3ObjectResponse {
/** The object key (full path within the bucket) */
key: string;
/** Stored file name (basename of the key) */
fileName: string;
/** MIME type of the stored object */
mimeType: string;
/** Object size in bytes */
sizeBytes: number;
/** High-level file category */
fileType: string;
/** SHA-256 hex digest of the object content */
etag: string | null;
/** ISO-8601 timestamp of last modification */
lastModified: string;
/** Public download URL */
downloadUrl: string;
}
/**
* Response payload for S3 ListObjectsV1 / ListObjectsV2.
*/
export interface S3ListObjectsResponse {
/** Array of object summaries */
objects: S3ObjectResponse[];
/** Common prefixes when a delimiter was used (e.g. "folder/" entries) */
prefixes: string[];
/** Whether more results are available */
isTruncated: boolean;
/** Token to pass as continuation-token to retrieve the next page */
nextContinuationToken: string | null;
}
/**
* Input for the copy-object operation (Web API v1).
*/
export interface S3CopyObjectInput {
/** Source object key within the same or source bucket */
sourceKey: string;
/** Destination bucket name; defaults to the source bucket when omitted */
destBucket?: string;
/** Destination object key */
destKey: string;
}
/**
* Response payload for the copy-object operation.
*/
export interface S3CopyObjectResponse {
/** Source object key that was copied */
sourceKey: string;
/** Destination object key */
destKey: string;
/** Destination bucket name */
destBucket: string;
}
/**
* Summary of a multipart upload in listing results.
*/
export interface S3MultipartUploadResponse {
/** The object key being uploaded */
key: string;
/** Upload identifier (nanoid) */
uploadId: string;
/** ISO-8601 timestamp when the upload was initiated */
initiatedAt: Date;
/** Identifier string of the upload initiator */
initiatedBy: string;
}
/**
* Summary of a single part within a multipart upload.
*/
export interface S3MultipartPartResponse {
/** 1-indexed part number */
partNumber: number;
/** ETag of the part content */
etag: string;
/** Part size in bytes */
sizeBytes: number;
/** ISO-8601 timestamp when the part was stored */
createdAt: Date;
}
+46
View File
@@ -0,0 +1,46 @@
/**
* Input for the upload file use case.
* Carries all metadata needed to persist an uploaded file,
* including its temporary location on disk and optional bucket/S3 context.
*/
export interface UploadInput {
/** Absolute path to the temporary file on disk */
tempPath: string;
/** SHA-256 hex digest of the file content */
fileHash: string;
/** Original file name (may include extension) */
fileName: string;
/** MIME type detected from content inspection or request header */
mimeType: string;
/** High-level file category (e.g. "document", "photo", "video") */
fileType: string;
/** File size in bytes */
sizeBytes: number;
/** Telegram user ID of the uploader; 0 when unknown or system */
uploaderId?: number;
/** Target bucket UUID for S3-compatible storage; null when un-bucketed */
bucketId?: string | null;
/** Object key within the bucket for S3-compatible storage; null when un-bucketed */
s3Key?: string | null;
}
/**
* Output from the upload file use case.
* Contains the public-facing file metadata returned to the caller.
*/
export interface UploadOutput {
/** Public, shareable identifier (nanoid) */
publicId: string;
/** Stored file name (may have been normalized with extension) */
fileName: string;
/** MIME type of the stored file */
mimeType: string;
/** File size in bytes */
sizeBytes: number;
/** High-level file category */
fileType: string;
/** ISO-8601 timestamp of when the file record was created */
createdAt: Date;
/** Public download URL */
downloadUrl: string;
}