Implement Phase 1 backend: FastAPI upload API with MinIO and PostgreSQL

- Add FastAPI app with CORS and auth middleware (Bearer token)
- Add POST /api/v1/transactions/upload endpoint (multipart/form-data)
- Add MinIO storage service with date-partitioned object keys
- Add PostgreSQL database service for transaction metadata
- Add Dockerfile and docker-compose.yml for deployment
- Add config.example.yaml template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-05-21 16:42:08 +08:00
parent a7ae5cba5d
commit e3c84540eb
16 changed files with 306 additions and 0 deletions

41
app/services/minio.py Normal file
View File

@@ -0,0 +1,41 @@
import uuid
from datetime import datetime, timezone
from pathlib import PurePosixPath
import boto3
from botocore.config import Config as BotoConfig
from app.config import settings
def _get_client():
return boto3.client(
"s3",
endpoint_url=settings.minio.endpoint,
aws_access_key_id=settings.minio.access_key,
aws_secret_access_key=settings.minio.secret_key,
config=BotoConfig(signature_version="s3v4"),
)
def _generate_object_key(filename: str) -> str:
now = datetime.now(timezone.utc)
date_prefix = now.strftime("%Y/%m/%d")
ext = PurePosixPath(filename).suffix or ".jpg"
return f"{date_prefix}/{uuid.uuid4().hex}{ext}"
def upload_image(file_bytes: bytes, original_filename: str) -> str:
client = _get_client()
object_key = _generate_object_key(original_filename)
content_type = "image/jpeg"
if original_filename.lower().endswith(".png"):
content_type = "image/png"
client.put_object(
Bucket=settings.minio.bucket,
Key=object_key,
Body=file_bytes,
ContentType=content_type,
)
return object_key