Upload Documents
++ Drag & drop files onto the Upload page or click Choose File. + DocuElevate converts images and office documents to PDF, runs OCR, and extracts metadata automatically. +
+diff --git a/.env.demo b/.env.demo index a2f567b5..f33432a0 100644 --- a/.env.demo +++ b/.env.demo @@ -478,3 +478,15 @@ EMBEDDING_MODEL=text-embedding-3-small # Maximum tokens to send to the embedding model. Set below the model's # context window (e.g. 8000 for an 8192-token model). EMBEDDING_MAX_TOKENS=8000 + +# **Support / Help Center – Zammad Integration** +# Base URL of your Zammad instance (required for chat and ticket form). +# ZAMMAD_URL=https://zammad.example.com +# Show a live-chat widget on the Help Center page (requires an online Zammad agent). +# ZAMMAD_CHAT_ENABLED=false +# Zammad chat topic ID (see Zammad → Channels → Chat → Topics). +# ZAMMAD_CHAT_ID=1 +# Show a "Submit a Ticket" feedback form on the Help Center page. +# ZAMMAD_FORM_ENABLED=false +# Support e-mail address displayed on the Help Center page. +# SUPPORT_EMAIL=support@example.com diff --git a/app/config.py b/app/config.py index 8c9b4a9c..68297ed9 100644 --- a/app/config.py +++ b/app/config.py @@ -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: diff --git a/app/main.py b/app/main.py index c03cdd1f..71507011 100644 --- a/app/main.py +++ b/app/main.py @@ -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 diff --git a/app/views/help.py b/app/views/help.py index 1df1c205..eff08b1b 100644 --- a/app/views/help.py +++ b/app/views/help.py @@ -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, + }, + ) diff --git a/docs/ConfigurationGuide.md b/docs/ConfigurationGuide.md index ef52229a..b33a22a8 100644 --- a/docs/ConfigurationGuide.md +++ b/docs/ConfigurationGuide.md @@ -1118,6 +1118,30 @@ Administrators can set the **site-wide default** colour scheme that is applied w UI_DEFAULT_COLOR_SCHEME=dark ``` +### Support / Help Center – Zammad Integration + +The Help Center page (`/help`) can optionally integrate with a [Zammad](https://zammad.com/) instance to offer live chat and a ticket-creation form directly within DocuElevate. + +| **Variable** | **Description** | **Default** | +|-------------------------|-------------------------------------------------------------------------------------------------------|-------------| +| `ZAMMAD_URL` | Base URL of your Zammad instance (e.g. `https://zammad.example.com`). Required for chat and form. | *(unset)* | +| `ZAMMAD_CHAT_ENABLED` | Show a Zammad live-chat widget on the Help Center page. | `false` | +| `ZAMMAD_CHAT_ID` | Zammad chat topic ID (see *Channels → Chat → Topics* in Zammad admin). | `1` | +| `ZAMMAD_FORM_ENABLED` | Show a "Submit a Ticket" feedback form on the Help Center page. | `false` | +| `SUPPORT_EMAIL` | Support e-mail address displayed on the Help Center page. | *(unset)* | + +**Example:** + +```dotenv +ZAMMAD_URL=https://zammad.example.com +ZAMMAD_CHAT_ENABLED=true +ZAMMAD_CHAT_ID=1 +ZAMMAD_FORM_ENABLED=true +SUPPORT_EMAIL=support@example.com +``` + +> **Note:** The live-chat widget requires at least one Zammad agent to be online. If no agent is available, the widget will not appear. Enable Zammad's debug mode (`debug: true`) for troubleshooting. + ## Duplicate Document Detection DocuElevate detects and flags documents that share the same content, even if they arrive as separate uploads. diff --git a/frontend/templates/base.html b/frontend/templates/base.html index 7b0d9d14..ffb7f7c6 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -172,6 +172,13 @@ {% if request and request.url.path == '/status' %}aria-current="page"{% endif %}> Status +
+ + API Docs + + + Developer Docs + @@ -179,11 +186,11 @@ {% endif %}{# end multi_user_enabled / is_logged_in check #} - + aria-label="Help Center" + title="Help Center" + {% if request and request.url.path == '/help' %}aria-current="page"{% endif %}> Help @@ -314,16 +321,22 @@ {% if request and request.url.path == '/status' %}aria-current="page"{% endif %}> Status + + API Docs + + + Developer Docs + {% endif %}{# end multi_user_enabled / is_logged_in check #} - + aria-label="Help Center" + {% if request and request.url.path == '/help' %}aria-current="page"{% endif %}> Help diff --git a/frontend/templates/help.html b/frontend/templates/help.html new file mode 100644 index 00000000..b96ea5f6 --- /dev/null +++ b/frontend/templates/help.html @@ -0,0 +1,510 @@ +{% extends "base.html" %} +{% block title %}Help Center – DocuElevate{% endblock %} + +{% block head_extra %} + + + + + + + + + + + + + + +{% endblock %} + +{% block content %} ++ Everything you need to get the most out of DocuElevate. + Browse topics below or search for what you need. +
++ Drag & drop files onto the Upload page or click Choose File. + DocuElevate converts images and office documents to PDF, runs OCR, and extracts metadata automatically. +
++ Head to Settings → Integrations and link your cloud accounts. + Processed documents are automatically routed to every destination you configure. +
++ Create Pipelines to define multi-step processing and routing rules. + Combine OCR, AI extraction, format conversion, and delivery in a single flow. +
++ The fastest way to get started. Open the Upload page, drop one or more files, and DocuElevate takes care of the rest. + Supported formats include PDF, JPEG, PNG, TIFF, DOCX, XLSX, and more. +
++ Forward documents to a dedicated mailbox. Under Email Ingestion, add one or more IMAP accounts. + DocuElevate polls for new messages and processes attachments automatically. +
+
+ Integrate programmatically by POST-ing files to /api/upload.
+ Ideal for scripts, watched folders, scanners, or third-party tools like Zapier and n8n.
+
+ Point network scanners (HP, Fujitsu ScanSnap, Brother) at DocuElevate's upload endpoint or + use any mobile scanning app that supports custom HTTP destinations. +
+OAuth-linked. Files land in your chosen folder.
+Service account or OAuth. Supports shared drives.
+Microsoft Graph API integration.
+Any S3-compatible bucket (AWS, MinIO, Wasabi).
+Self-hosted cloud storage via WebDAV.
+Push documents straight into Paperless for archival.
+Secure file transfer to any server.
+Processed files sent as SMTP attachments.
+POST metadata to any external endpoint.
++ A Pipeline is a series of processing steps that run automatically whenever a document is ingested. + Each step can transform, enrich, or route the document. +
+Upload a file from any terminal:
+curl -X POST https://your-instance/api/upload \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -F "file=@/path/to/document.pdf"
+
+ Use inotifywait (Linux), fswatch (macOS), or any file-watcher script to
+ POST new files as soon as they appear in a local directory.
+
+ Configure your HP, Fujitsu ScanSnap, or Brother scanner to use DocuElevate's upload URL as a + Scan-to-Network destination. Scans are processed the moment they arrive. +
+
+ Apps like Adobe Scan, Microsoft Lens, or Genius Scan
+ can export to a custom HTTP endpoint. Point them at /api/upload.
+
+ Connect DocuElevate to thousands of other apps via integration platforms.
+ Use the HTTP/Webhook module to POST files to the upload API.
+
+ Can't find what you're looking for? Our support team is here to help. +
+ + {% if support_email %} ++ Describe your issue below and we'll get back to you as soon as possible. +
+ ++ Contact your administrator for support information. +
+