application.yaml 5.2 KB
# vibe_erp — production-ish defaults.
#
# This is the baseline configuration baked into the shipping image. It is
# deliberately non-secret: every sensitive value is read from an environment
# variable so the same image works for self-hosted and (eventually) hosted
# deployments. See architecture spec sections 10 and 11.
#
# Customer overrides live in /opt/vibe-erp/config/vibe-erp.yaml on the
# mounted volume. Plug-in configuration lives in metadata__plugin_config,
# never here.
#
# vibe_erp is single-tenant per instance: one running process serves
# exactly one company against an isolated database. There is no
# multi-tenancy configuration here, by design.

spring:
  application:
    name: vibe-erp
  datasource:
    url: ${VIBEERP_DB_URL}
    username: ${VIBEERP_DB_USER}
    password: ${VIBEERP_DB_PASSWORD}
    driver-class-name: org.postgresql.Driver
  jpa:
    # Liquibase owns the schema; Hibernate must never touch DDL.
    hibernate:
      ddl-auto: validate
    open-in-view: false
  liquibase:
    # Flowable 7.x ships a FlowableLiquibaseEnvironmentPostProcessor that
    # FORCES `spring.liquibase.enabled=false` unless the consumer has set
    # an explicit value (it logs a WARN saying "Flowable pulls in Liquibase
    # but does not use the Spring Boot configuration for it"). Without the
    # explicit `true` below, our master.xml never runs and JPA fails schema
    # validation at boot with "Schema-validation: missing table catalog__item".
    # Setting it here preserves vibe_erp's Liquibase-owned schema story.
    enabled: true
    change-log: classpath:db/changelog/master.xml

# Flowable embedded process engine (platform-workflow). Shares the same
# datasource as the rest of the framework — Flowable manages its own
# ACT_* tables via its internal MyBatis schema management, which does
# not conflict with our Liquibase master changelog (they are disjoint
# namespaces). Auto-deploys any BPMN file found at
# classpath*:/processes/*.bpmn20.xml on boot.
flowable:
  database-schema-update: true
  # Disable async job executor — the framework's background-job story
  # lives in Quartz (platform-jobs), not in Flowable.
  async-executor-activate: false
  process:
    servlet:
      # We expose our own thin HTTP surface at /api/v1/workflow/**;
      # Flowable's built-in REST endpoints are off.
      enabled: false

# Quartz scheduler (platform-jobs, P1.10). Persistent JDBC job store
# against the host Postgres so cron + one-shot schedules survive
# restarts. Spring Boot's QuartzDataSourceScriptDatabaseInitializer
# runs the QRTZ_* DDL on first boot and skips on subsequent boots
# (it checks for an existing QRTZ_LOCKS table first), which
# coexists peacefully with our Liquibase-owned schema in the same
# way Flowable's ACT_* tables do.
spring.quartz:
  job-store-type: jdbc
  jdbc:
    initialize-schema: always
  # Spring Boot's Quartz starter wires the JobStore class and the
  # DataSource automatically when job-store-type=jdbc. DO NOT set
  # `org.quartz.jobStore.class` in the properties below — that
  # overrides Spring Boot's `LocalDataSourceJobStore` with
  # `JobStoreTX`, which then throws "DataSource name not set" at
  # scheduler init because Quartz-standalone expects a `dataSource`
  # property that Spring Boot doesn't provide.
  properties:
    org.quartz.scheduler.instanceName: vibeerp-scheduler
    org.quartz.scheduler.instanceId: AUTO
    org.quartz.threadPool.threadCount: "4"
    org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    org.quartz.jobStore.isClustered: "false"

server:
  port: 8080
  shutdown: graceful

management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus

vibeerp:
  instance:
    # Display name of the company that owns this instance. Shown in branding,
    # report headers, and audit logs. There is exactly ONE company per
    # running instance — provisioning a second customer means deploying a
    # second instance with its own database.
    company-name: ${VIBEERP_COMPANY_NAME:vibe_erp instance}
  security:
    jwt:
      # HMAC-SHA256 secret. Must be at least 32 characters in production.
      # Set the VIBEERP_JWT_SECRET environment variable; the framework
      # refuses to start if a shorter value is used.
      secret: ${VIBEERP_JWT_SECRET:}
      issuer: vibe-erp
      access-token-ttl: PT15M
      refresh-token-ttl: P7D
  plugins:
    directory: ${VIBEERP_PLUGINS_DIR:/opt/vibe-erp/plugins}
    auto-load: true
  i18n:
    default-locale: en-US
    fallback-locale: en-US
    available-locales: en-US,zh-CN,de-DE,ja-JP,es-ES
  files:
    # "local" or "s3". Local-disk is the default; S3 is for cloud
    # deployments or when multiple instances share one object store.
    backend: local
    local-path: ${VIBEERP_FILES_DIR:/opt/vibe-erp/files}
    # S3 config (only read when backend=s3). Works with AWS S3,
    # MinIO, DigitalOcean Spaces, or any S3-compatible service.
    # s3:
    #   bucket: ${VIBEERP_S3_BUCKET:}
    #   region: ${VIBEERP_S3_REGION:us-east-1}
    #   endpoint-url: ${VIBEERP_S3_ENDPOINT:}
    #   access-key: ${VIBEERP_S3_ACCESS_KEY:}
    #   secret-key: ${VIBEERP_S3_SECRET_KEY:}
    #   key-prefix: ${VIBEERP_S3_KEY_PREFIX:}

logging:
  level:
    org.vibeerp: INFO
    org.springframework: WARN