# Author: fruit.com.cn server: port: 8081 spring: application: name: fruitshorts-app-api autoconfigure: exclude: org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration datasource: driver-class-name: org.postgresql.Driver # 地址必须外置:不同环境(本机 / 测试 / 生产)连的库不一样, # 生产请用 DB_URL 注入(prod profile 会校验它非空)。 # reWriteBatchedInserts:pgjdbc 把批内多条 INSERT 重写成多值 INSERT, # 观看进度缓冲落库依赖它才能跑满批量吞吐。 url: ${DB_URL:jdbc:postgresql://127.0.0.1:5432/fruitshorts?reWriteBatchedInserts=true} username: ${DB_USER:fruitshorts} password: ${DB_PASSWORD:fruitshorts} jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai data: redis: host: ${REDIS_HOST:127.0.0.1} port: ${REDIS_PORT:6379} mybatis-plus: configuration: map-underscore-to-camel-case: true global-config: banner: false db-config: # 主键由应用侧雪花算法生成(S0),数据库不再自增 id-type: assign_id logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 sequence: # 单机开发用固定值;上多实例前必须改成按实例分配(环境变量注入),否则会撞 ID worker-id: 1 datacenter-id: 1 # 接口文档:/doc.html 打开 Swagger UI,/v3/api-docs 是机器可读契约(前端联调按它写) springdoc: swagger-ui: path: /doc.html api-docs: path: /v3/api-docs fruitshorts: web: # 可信代理 CIDR 列表(逗号分隔)。默认空 = 永不解析 XFF,直接用 request.getRemoteAddr()。 # 配了反代(Nginx/K8s ingress)时填上其 IP 段,才会从 XFF 取最右侧可信一跳。 # 生产若开启了 Tomcat RemoteIpValve(prod profile 已配),保持空即可。 trusted-proxies: ${FRUITSHORTS_TRUSTED_PROXIES:} auth: # 仅作 sys_config 缺失/非法时的兜底;运行时优先读取后台「系统配置」 register-max-per-ip-per-day: ${REGISTER_MAX_PER_IP_PER_DAY:5} register-max-per-device-per-day: ${REGISTER_MAX_PER_DEVICE_PER_DAY:3} interaction: # MACHINE_FIRST:机审通过即发布,命中 REVIEW 级敏感词才转人工 # PRE_REVIEW :全部先审后发(生产建议) comment-audit-mode: MACHINE_FIRST comment-max-length: 500 comment-per-minute: 5 download: # 这些值会通过 /app/downloads/policy 下发给客户端,改这里不用发版 max-per-device: 20 license-days: 30 wifi-only-default: true max-quality: AUTO commerce: store: # 商店票据校验实现:disabled = 明确报"未配置"(默认,无凭据时对外行为不变) # google-play = 走 Google Play Developer API verifier: ${STORE_VERIFIER:disabled} # 下面两项属付费凭据:只从环境变量/配置注入,不入库、不提交、不打进镜像 google-play-package-name: ${GOOGLE_PLAY_PACKAGE_NAME:} # 服务账号 JSON:文件路径 \| JSON 内容 \| base64(建议用环境变量给 base64) google-play-service-account-json: ${GOOGLE_PLAY_SERVICE_ACCOUNT_JSON:} google-play-timeout-seconds: 10 media: # 媒体根目录:容器里指向挂载卷;本地默认 ./data/uploads root-dir: ${MEDIA_ROOT_DIR:./data/uploads} public-prefix: /files chunk-size: 5242880 max-file-size: 2147483648 # 播放地址签名:生产必开(docs/12-上线检查清单),prod profile 里强制为 true signature-secret: ${MEDIA_SIGNATURE_SECRET:fruitshorts-media-dev-secret-change-me-in-production-32b} signature-required: ${MEDIA_SIGNATURE_REQUIRED:false} signature-ttl-minutes: 15 jwt: # 双密钥:管理端与客户端物理隔离,token 不能互换(AGENTS.md 强制约束 2) # 注意 app-secret 以前没写在这里,一直用代码里的 dev 默认值 —— 生产必须注入 JWT_APP_SECRET admin-secret: ${JWT_ADMIN_SECRET:fruitshorts-admin-dev-secret-change-me-in-production-32b} admin-ttl-hours: 12 app-secret: ${JWT_APP_SECRET:fruitshorts-app-dev-secret-change-me-in-production-32bytes} app-access-ttl-minutes: 120 app-refresh-ttl-days: 30 cors: allowed-origins: ${CORS_ALLOWED_ORIGINS:*} logging: level: com.fruitshorts: info management: endpoints: web: exposure: include: prometheus,health endpoint: health: show-details: always metrics: tags: application: ${spring.application.name}