d582f15681
- Implemented tests for import polling functionality, ensuring correct behavior for active and terminal import statuses. - Created tests for the login page, validating user interactions and error handling. - Added unit tests for money utility functions, covering parsing, formatting, and summation of monetary values. - Developed tests for query keys, ensuring proper scoping and invalidation roots. chore: setup testing environment and configuration - Added setup file for testing with Vitest and Testing Library. - Configured TypeScript and Vite for the frontend project. - Created Docker and Nginx configurations for local development and production environments. - Established a PostgreSQL initialization script for setting up application roles. docs: add README and environment configuration for infra - Included README for the infra directory, detailing local development setup and service descriptions. - Created an example environment configuration file for local development with placeholders for sensitive information.
69 lines
2.0 KiB
Python
69 lines
2.0 KiB
Python
import base64
|
|
import binascii
|
|
from functools import lru_cache
|
|
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(extra="ignore")
|
|
|
|
environment: str = "development"
|
|
database_url: str = "postgresql+psycopg://fin:fin@localhost:5432/fin"
|
|
redis_url: str = "redis://localhost:6379/0"
|
|
admin_bootstrap_token: str = ""
|
|
|
|
imports_kek_b64: str = ""
|
|
blob_dir: str = "./var/blobs"
|
|
s3_endpoint_url: str = ""
|
|
s3_region: str = "us-east-1"
|
|
s3_access_key_id: str = ""
|
|
s3_secret_access_key: str = ""
|
|
s3_bucket_statements: str = "finance-statements"
|
|
smtp_host: str = ""
|
|
smtp_port: int = 1025
|
|
smtp_use_tls: bool = False
|
|
smtp_from: str = "no-reply@finance.local"
|
|
public_base_url: str = "http://localhost:8080"
|
|
|
|
session_cookie_name: str = "fin_session"
|
|
csrf_cookie_name: str = "csrf_token"
|
|
cookie_secure: bool = True
|
|
session_ttl_days: int = 14
|
|
invite_ttl_days: int = 7
|
|
reset_ttl_hours: int = 4
|
|
|
|
max_upload_bytes: int = 20 * 1024 * 1024
|
|
max_xlsx_rows: int = 10_000
|
|
max_pdf_pages: int = 200
|
|
max_archive_uncompressed_bytes: int = 64 * 1024 * 1024
|
|
|
|
deletion_window_days: int = 30
|
|
|
|
celery_task_always_eager: bool = False
|
|
celery_broker_url: str = ""
|
|
|
|
default_locale: str = "ru"
|
|
default_timezone: str = "Europe/Moscow"
|
|
|
|
@property
|
|
def broker_url(self) -> str:
|
|
return self.celery_broker_url or self.redis_url
|
|
|
|
@property
|
|
def kek(self) -> bytes:
|
|
if not self.imports_kek_b64:
|
|
raise RuntimeError("IMPORTS_KEK_B64 must be configured (base64-encoded 32-byte KEK)")
|
|
try:
|
|
raw = base64.b64decode(self.imports_kek_b64, validate=True)
|
|
except (binascii.Error, ValueError) as exc:
|
|
raise RuntimeError("IMPORTS_KEK_B64 is not valid base64") from exc
|
|
if len(raw) != 32:
|
|
raise RuntimeError("IMPORTS_KEK_B64 must decode to exactly 32 bytes")
|
|
return raw
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|