feat(help): restructure /help as user-facing Help Center with Zammad integration

- Replace MkDocs redirect with a branded, SEO-optimised Help Center template
- Add sections: Quick Start, Sources, Destinations, Workflows, FAQ, Support
- Integrate optional Zammad live-chat widget and ticket form
- Add config settings: ZAMMAD_URL, ZAMMAD_CHAT_ENABLED, ZAMMAD_CHAT_ID,
  ZAMMAD_FORM_ENABLED, SUPPORT_EMAIL
- Move MkDocs developer docs from /help to /developer-docs
- Move interactive API docs (Swagger/ReDoc) to /admin/api-docs and /admin/api-redoc
- Add API Docs and Developer Docs links to Admin menu (desktop + mobile)
- Update navigation Help link from /help/ to /help
- Update .env.demo with Zammad configuration examples
- Document new settings in docs/ConfigurationGuide.md
- Rewrite tests to cover new Help Center behaviour

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-08 17:25:34 +00:00
parent 78c9df4bb0
commit af3eed4040
8 changed files with 744 additions and 49 deletions
+27
View File
@@ -914,6 +914,33 @@ class Settings(BaseSettings):
description="Allowed request headers for CORS. Use ['*'] to allow all headers.",
)
# ---------------------------------------------------------------------------
# Support / Help Center Zammad integration
# ---------------------------------------------------------------------------
zammad_url: Optional[str] = Field(
default=None,
description=(
"Base URL of your Zammad instance (e.g. https://zammad.example.com). "
"Required for the chat widget and feedback form on the Help Center page."
),
)
zammad_chat_enabled: bool = Field(
default=False,
description="Show the Zammad live-chat widget on the Help Center page.",
)
zammad_chat_id: int = Field(
default=1,
description="Zammad chat topic ID to use for the live-chat widget.",
)
zammad_form_enabled: bool = Field(
default=False,
description="Show the Zammad feedback / ticket form on the Help Center page.",
)
support_email: Optional[str] = Field(
default=None,
description="Support e-mail address displayed on the Help Center page.",
)
@model_validator(mode="before")
@classmethod
def strip_outer_quotes(cls, data: Any) -> Any:
+11 -4
View File
@@ -137,7 +137,12 @@ async def lifespan(app: FastAPI):
notify_shutdown()
app = FastAPI(title="DocuElevate", lifespan=lifespan)
app = FastAPI(
title="DocuElevate",
lifespan=lifespan,
docs_url="/admin/api-docs",
redoc_url="/admin/api-redoc",
)
# Initialize rate limiter and attach to app state
limiter = create_limiter(redis_url=settings.redis_url, enabled=settings.rate_limiting_enabled)
@@ -202,14 +207,16 @@ if os.path.exists(static_dir):
else:
print(f"WARNING: Static directory not found at {static_dir}. Static files will not be served.")
# Mount the built MkDocs documentation site at /help/
# Mount the built MkDocs developer documentation at /developer-docs/
# These docs target administrators and developers, not end-users.
# The user-facing Help Center is served by the /help view instead.
# The docs are pre-built into docs_build/ during the Docker image build.
# When running locally, run `mkdocs build` from the repo root first.
docs_build_dir = pathlib.Path(__file__).parents[1] / "docs_build"
if os.path.exists(docs_build_dir):
app.mount("/help", StaticFiles(directory=str(docs_build_dir), html=True), name="help_docs")
app.mount("/developer-docs", StaticFiles(directory=str(docs_build_dir), html=True), name="developer_docs")
else:
print(f"INFO: Help docs not found at {docs_build_dir}. Run 'mkdocs build' to generate them.")
print(f"INFO: Developer docs not found at {docs_build_dir}. Run 'mkdocs build' to generate them.")
# Custom exception handlers that return JSON for API routes and HTML for frontend routes
+24 -9
View File
@@ -1,27 +1,42 @@
"""
Help documentation view routes.
Help Center view routes.
Serves the built MkDocs documentation site at /help.
The static site is built during the Docker image build and placed at docs_build/.
Renders a user-facing, SEO-optimised Help Center page at ``/help``.
The page is designed for SaaS end-users and includes guidance on
features, integrations, workflows, and optional Zammad support widgets
(live-chat and feedback form).
The developer-oriented MkDocs documentation is served separately at
``/docs`` and is intentionally **not** cross-linked from this page.
"""
import logging
import pathlib
from fastapi import Request
from fastapi.responses import RedirectResponse
from app.views.base import APIRouter
from app.config import settings
from app.views.base import APIRouter, templates
logger = logging.getLogger(__name__)
router = APIRouter()
# Path to the built MkDocs documentation
# Path to the built MkDocs documentation (kept for reference / backwards compat)
_DOCS_BUILD_DIR = pathlib.Path(__file__).parents[2] / "docs_build"
@router.get("/help", include_in_schema=False)
async def help_redirect(request: Request) -> RedirectResponse:
"""Redirect /help to /help/ so the MkDocs index is served correctly."""
return RedirectResponse(url="/help/", status_code=301)
async def help_center(request: Request):
"""Render the end-user Help Center page."""
return templates.TemplateResponse(
"help.html",
{
"request": request,
"zammad_url": settings.zammad_url,
"zammad_chat_enabled": settings.zammad_chat_enabled,
"zammad_chat_id": settings.zammad_chat_id,
"zammad_form_enabled": settings.zammad_form_enabled,
"support_email": settings.support_email,
},
)