feat(01-foundation-01): monorepo scaffolding, Docker Compose, and shared data models
- pyproject.toml: uv workspace with 5 member packages (shared, gateway, router, orchestrator, llm-pool) - docker-compose.yml: PostgreSQL 16 + Redis 7 + Ollama services on konstruct-net - .env.example: all required env vars documented, konstruct_app role (not superuser) - scripts/init-db.sh: creates konstruct_app role at DB init time - packages/shared/shared/config.py: Pydantic Settings loading all env vars - packages/shared/shared/models/message.py: KonstructMessage, ChannelType, SenderInfo, MessageContent - packages/shared/shared/models/tenant.py: Tenant, Agent, ChannelConnection SQLAlchemy 2.0 models - packages/shared/shared/models/auth.py: PortalUser model for admin portal auth - packages/shared/shared/db.py: async SQLAlchemy engine, session factory, get_session dependency - packages/shared/shared/rls.py: current_tenant_id ContextVar and configure_rls_hook with parameterized SET LOCAL - packages/shared/shared/redis_keys.py: tenant-namespaced key constructors (rate_limit, idempotency, session, engaged_thread)
This commit is contained in:
113
packages/shared/shared/config.py
Normal file
113
packages/shared/shared/config.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""
|
||||
Konstruct shared configuration.
|
||||
|
||||
Loads all environment variables via Pydantic Settings with sensible defaults
|
||||
for local development. All services import from this module.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""Application settings loaded from environment variables."""
|
||||
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env",
|
||||
env_file_encoding="utf-8",
|
||||
case_sensitive=False,
|
||||
extra="ignore",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Database
|
||||
# -------------------------------------------------------------------------
|
||||
database_url: str = Field(
|
||||
default="postgresql+asyncpg://konstruct_app:konstruct_dev@localhost:5432/konstruct",
|
||||
description="Async database URL — must use konstruct_app role, not superuser",
|
||||
)
|
||||
database_admin_url: str = Field(
|
||||
default="postgresql+asyncpg://postgres:postgres_dev@localhost:5432/konstruct",
|
||||
description="Admin database URL for Alembic migrations (superuser)",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Redis
|
||||
# -------------------------------------------------------------------------
|
||||
redis_url: str = Field(
|
||||
default="redis://localhost:6379/0",
|
||||
description="Redis connection URL",
|
||||
)
|
||||
celery_broker_url: str = Field(
|
||||
default="redis://localhost:6379/1",
|
||||
description="Celery broker URL",
|
||||
)
|
||||
celery_result_backend: str = Field(
|
||||
default="redis://localhost:6379/2",
|
||||
description="Celery result backend URL",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Slack
|
||||
# -------------------------------------------------------------------------
|
||||
slack_bot_token: str = Field(
|
||||
default="",
|
||||
description="Slack bot token (xoxb-...)",
|
||||
)
|
||||
slack_signing_secret: str = Field(
|
||||
default="",
|
||||
description="Slack signing secret for webhook verification",
|
||||
)
|
||||
slack_app_token: str = Field(
|
||||
default="",
|
||||
description="Slack app-level token for Socket Mode (xapp-...)",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# LLM Providers
|
||||
# -------------------------------------------------------------------------
|
||||
anthropic_api_key: str = Field(
|
||||
default="",
|
||||
description="Anthropic API key",
|
||||
)
|
||||
openai_api_key: str = Field(
|
||||
default="",
|
||||
description="OpenAI API key",
|
||||
)
|
||||
ollama_base_url: str = Field(
|
||||
default="http://localhost:11434",
|
||||
description="Ollama inference server base URL",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Auth / Security
|
||||
# -------------------------------------------------------------------------
|
||||
auth_secret: str = Field(
|
||||
default="insecure-dev-secret-change-in-production",
|
||||
description="Secret key for signing JWT tokens",
|
||||
)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Service URLs
|
||||
# -------------------------------------------------------------------------
|
||||
gateway_url: str = Field(default="http://localhost:8001")
|
||||
router_url: str = Field(default="http://localhost:8002")
|
||||
orchestrator_url: str = Field(default="http://localhost:8003")
|
||||
llm_pool_url: str = Field(default="http://localhost:8004")
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Application
|
||||
# -------------------------------------------------------------------------
|
||||
environment: str = Field(default="development")
|
||||
log_level: str = Field(default="INFO")
|
||||
debug: bool = Field(default=False)
|
||||
default_rate_limit_rpm: int = Field(
|
||||
default=60,
|
||||
description="Default requests per minute per tenant",
|
||||
)
|
||||
|
||||
|
||||
# Module-level singleton — imported by all services
|
||||
settings = Settings()
|
||||
Reference in New Issue
Block a user