Merge remote-tracking branch 'wavelet/main'

This commit is contained in:
ryan
2026-09-03 09:56:59 +08:00
13 changed files with 251 additions and 11 deletions
+24 -11
View File
@@ -9,19 +9,32 @@ import (
"time"
)
// UploadMetadataDTO represents upload metadata JSON.
type UploadMetadataDTO struct {
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Duration float64 `json:"duration,omitempty"`
OriginalMime string `json:"original_mime,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
ClientIP string `json:"client_ip,omitempty"`
Bucket string `json:"bucket,omitempty"`
Extra map[string]any `json:"extra,omitempty"`
}
// UploadDTO represents an uploaded file record.
type UploadDTO struct {
ID uint64 `json:"id"`
UserID uint64 `json:"user_id"`
FileName string `json:"file_name"`
FilePath string `json:"file_path"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
Hash string `json:"hash"`
Status string `json:"status"`
Type string `json:"type"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID uint64 `json:"id"`
UserID uint64 `json:"user_id"`
FileName string `json:"file_name"`
FilePath string `json:"file_path"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
Hash string `json:"hash"`
Status string `json:"status"`
Type string `json:"type"`
Metadata UploadMetadataDTO `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// OpenedUploadDTO encapsulates the retrieved object stream and its metadata.
+10
View File
@@ -78,6 +78,16 @@ func toUploadDTO(u *models.Upload) contracts.UploadDTO {
Hash: u.Hash,
Status: string(u.Status),
Type: u.Type,
Metadata: contracts.UploadMetadataDTO{
Width: u.Metadata.Width,
Height: u.Metadata.Height,
Duration: u.Metadata.Duration,
OriginalMime: u.Metadata.OriginalMime,
UserAgent: u.Metadata.UserAgent,
ClientIP: u.Metadata.ClientIP,
Bucket: u.Metadata.Bucket,
Extra: u.Metadata.Extra,
},
CreatedAt: u.CreatedAt,
UpdatedAt: u.UpdatedAt,
}
+114
View File
@@ -0,0 +1,114 @@
# wavelet — Full-Stack Boilerplate Config
# Copy this file to config.yaml and fill in your values.
# Fields marked with <...> are required; others have sensible defaults.
# ─── Application ────────────────────────────────────────────────────────────────
app:
app_name: "wavelet"
env: "development" # development | testing | production
addr: ":8000"
node_id: 1 # Snowflake node ID (0-1023). Must be unique per instance.
graceful_shutdown_timeout: 30
session_cookie_name: "wavelet_session_id" # Change to something unique before deploy
session_secret: "<uniq-random-string>" # Cannot be changed after first start
session_domain: "" # e.g. ".yourdomain.com"
session_age: 86400 # Session lifetime in seconds (default: 24h)
session_secure: false
session_http_only: false
api_prefix: "/api"
# ─── PostgreSQL ─────────────────────────────────────────────────────────────────
# Supports Standalone and Primary-Replica (read/write split) modes.
database:
enabled: true
sqlite_path: "wavelet.db" # PostgreSQL 禁用时使用此 SQLite 文件路径
host: "127.0.0.1"
port: 5432
username: "postgres"
password: "postgres"
database: "wavelet"
max_idle_conn: 16
max_open_conn: 128
conn_max_lifetime: 1800
conn_max_idle_time: 600
log_level: "info" # error | warn | info | debug | silent;SQL 语句仅在 log.level=debug 时输出
ssl_mode: "disable"
time_zone: "UTC"
application_name: "wavelet-server"
prefer_simple_protocol: false
search_path: "public"
statement_cache_capacity: 256
default_query_exec_mode: "cache_statement"
slow_threshold: 200ms
# Optional read replicas:
# replicas:
# - host: "replica1.db.internal"
# port: 5432
# - host: "replica2.db.internal"
# port: 5432
# ─── Redis ──────────────────────────────────────────────────────────────────────
# Supports Standalone, Sentinel (HA), and Cluster modes.
redis:
enabled: true
addrs:
- "127.0.0.1:6379"
username: ""
password: ""
db: 0 # Ignored in Cluster mode
cluster_mode: false # Set true to enable Cluster mode
master_name: "" # Set non-empty to enable Sentinel mode
key_prefix: "wavelet:"
pool_size: 100
min_idle_conn: 10
dial_timeout: 5
read_timeout: 3
write_timeout: 3
max_retries: 3
pool_timeout: 4
conn_max_idle_time: 300
maint_notifications: false # 启动时开关;启用 Redis maintenance notifications 自动协商,修改后需重启
# ─── Logging ────────────────────────────────────────────────────────────────────
log:
level: "info" # debug | info | warn | error | fatal | panic
format: "console" # console | json
output: "stdout" # stdout | file
file_path: "./logs/app.log"
max_size: 100 # MB per log file
max_age: 30 # Days to retain old log files
max_backups: 10
compress: true
# ─── Async Task Worker ──────────────────────────────────────────────────────────
worker:
concurrency: 20
strict_priority: false
queues:
- name: webhook
priority: 10
- name: whitelist_only
priority: 5
- name: default
priority: 3
# ─── OpenTelemetry Tracing ──────────────────────────────────────────────────────
otel:
sampling_rate: 0.0 # Trace sampling rate (0.0 – 1.0)
tracer_name: "github.com/Rain-kl/Wavelet" # Global tracer instrumentation name
# ─── ClickHouse (optional) ──────────────────────────────────────────────────────
clickhouse:
enabled: false
hosts:
- "127.0.0.1:9000"
username: "default"
password: ""
database: "wavelet"
max_idle_conn: 10
max_open_conn: 100
conn_max_lifetime: 3600
dial_timeout: 5
block_buffer_size: 10
+21
View File
@@ -0,0 +1,21 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: template-single
labels:
app: template-single
spec:
replicas: 1
selector:
matchLabels:
app: template-single
template:
metadata:
labels:
app: template-single
spec:
containers:
- name : main
image: template-single
imagePullPolicy: Always
+8
View File
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
+12
View File
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: template-single
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8000
selector:
app: template-single
+14
View File
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: template-single-configmap
data:
config.yaml: |
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
logger:
level : "all"
stdout: true
+10
View File
@@ -0,0 +1,10 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: template-single
spec:
template:
spec:
containers:
- name : main
image: template-single:develop
@@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- configmap.yaml
patchesStrategicMerge:
- deployment.yaml
namespace: default
+16
View File
@@ -0,0 +1,16 @@
FROM loads/alpine:3.8
###############################################################################
# INSTALLATION
###############################################################################
ENV WORKDIR /app
ADD resource $WORKDIR/
ADD ./temp/linux_amd64/main $WORKDIR/main
RUN chmod +x $WORKDIR/main
###############################################################################
# START
###############################################################################
WORKDIR $WORKDIR
CMD ./main
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
# This shell is executed before docker build.
View File
View File