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:
2026-03-23 09:49:28 -06:00
parent d611a07cc2
commit 5714acf741
19 changed files with 3935 additions and 0 deletions

View 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()