File size: 2,423 Bytes
c86f1ad
 
 
c626bd5
 
c86f1ad
 
c626bd5
 
c86f1ad
ee91f18
c86f1ad
 
406e096
c626bd5
 
 
406e096
c626bd5
 
c86f1ad
406e096
c626bd5
c86f1ad
 
 
 
 
 
 
 
 
 
ee91f18
c86f1ad
 
 
 
 
c626bd5
ee91f18
 
 
 
c626bd5
 
c86f1ad
 
 
 
ee91f18
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field, model_validator
import os, secrets, pathlib

class Settings(BaseSettings):
    model_config = SettingsConfigDict(extra='ignore', env_prefix='', case_sensitive=True)

    app_name: str = "GrowthOps OS"
    environment: str = "prod"

    # JWT_SECRET は未設定でも起動できるようにし、後段で生成
    jwt_secret: str | None = Field(default=None, alias="JWT_SECRET")

    port: int = int(os.getenv("PORT", "7860"))

    use_internal_postgres: bool = Field(default=False, alias="USE_INTERNAL_POSTGRES")
    postgres_user: str = Field(default="app", alias="POSTGRES_USER")
    postgres_password: str = Field(default="app", alias="POSTGRES_PASSWORD")
    postgres_db: str = Field(default="growthops", alias="POSTGRES_DB")

    redis_url: str = Field(default="redis://127.0.0.1:6379/0", alias="REDIS_URL")
    otlp_endpoint: str | None = Field(default=None, alias="OTLP_ENDPOINT")

    @model_validator(mode="after")
    def _ensure_jwt_secret(self):
        if self.jwt_secret:
            return self
        path = pathlib.Path("/data/jwt_secret")
        if path.exists():
            self.jwt_secret = path.read_text().strip()
            return self
        secret = secrets.token_urlsafe(48)
        try:
            path.parent.mkdir(parents=True, exist_ok=True)
            path.write_text(secret)
        except Exception:
            pass
        self.jwt_secret = secret
        return self

def _sqlite_url_for_path(path: str) -> str:
    # 絶対パスなら "sqlite+pysqlite:////abs/path"
    return "sqlite+pysqlite:///" + (path if path.startswith("/") else path)

def build_database_url(settings: Settings) -> str:
    if settings.use_internal_postgres:
        return (
            f"postgresql+psycopg2://{settings.postgres_user}:"
            f"{settings.postgres_password}@127.0.0.1:5432/{settings.postgres_db}"
        )

    # まず /data を試す
    try:
        os.makedirs("/data", exist_ok=True)
        testfile = "/data/.writetest"
        with open(testfile, "w") as f:
            f.write("ok")
        os.remove(testfile)
        return _sqlite_url_for_path("/data/growthops.sqlite3")
    except Exception:
        # /data が使えない環境では /tmp にフォールバック
        os.makedirs("/tmp", exist_ok=True)
        return _sqlite_url_for_path("/tmp/growthops.sqlite3")