chore(pm): vendor the Aramesh/PM platform under pm/ (squash of Aramesh/PM @ 91f3271)

The PM panel (PmPanelPage -> iframe /pm/) needs the project-management
platform served at /pm/ on the ERP domain. Source: org repo Aramesh/PM,
branch feature/project-management-platform. Update via:
git subtree pull --prefix=pm aramesh-pm feature/project-management-platform --squash
This commit is contained in:
MMD
2026-10-07 15:14:20 +03:30
87 changed files with 23922 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
"""PM settings — env prefix PM_ (mirrors the ERP PROCUREMENT_ pattern)."""
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="PM_", env_file=".env", extra="ignore")
DATABASE_URL: str = "postgresql+asyncpg://pm:pm@localhost:5432/pm"
SESSION_SECRET: str = "change-me"
SESSION_TTL_HOURS: int = 24 * 14
ADMIN_USER: str = "admin"
ADMIN_PASSWORD: str = "admin"
# Development role switching — the dashboard shows a role picker so the two
# roles can be tried without separate logins. Set PM_DEV_ROLE_SWITCH=false
# (production) to disable the dev endpoints entirely.
DEV_ROLE_SWITCH: bool = False
DEV_SUPERVISOR_USER: str = "supervisor"
DEV_SUPERVISOR_PASSWORD: str = "pm123456"
DEV_SUPERVISOR2_USER: str = "supervisor2"
DEV_SUPERVISOR2_PASSWORD: str = "pm123456"
def dev_demo_usernames(self) -> list[str]:
"""Accounts the dev role switcher may log in as (manager + supervisors)."""
return [self.ADMIN_USER, self.DEV_SUPERVISOR_USER, self.DEV_SUPERVISOR2_USER]
FILES_DIR: Path = Path("/data/files")
# ERP (procurement/inventory) integration — read-only service account
ERP_BASE_URL: str = "http://procurement-api:8000"
ERP_CASDOOR_ENDPOINT: str = "http://casdoor:8000"
ERP_CASDOOR_CLIENT_ID: str = "inventory-app-client"
ERP_CASDOOR_CLIENT_SECRET: str = "inventory-app-secret-2026"
ERP_CASDOOR_ORGANIZATION: str = "inventory"
ERP_SERVICE_USERNAME: str = "pm-service"
ERP_SERVICE_PASSWORD: str = ""
ERP_CACHE_TTL_SECONDS: int = 120
# Casdoor SSO — PM accepts the ERP-issued JWT as its own session.
# ISSUER = the browser-facing origin Casdoor advertises (casdoor `origin`),
# not the in-network endpoint; AUDIENCE = the inventory-app client id.
CASDOOR_ISSUER: str = "http://localhost:8080"
CASDOOR_AUDIENCE: str = "inventory-app-client"
settings = Settings()