Add documentation system Phase 1 - Core infrastructure
- Created documentation blueprint (doc_bp) with routes and navigation
- Added documentation menu item (📖) to navbar for all users
- Implemented hierarchical navigation with 9 sections, 33 pages
- Created base layout with sidebar, breadcrumb, and prev/next navigation
- Added documentation.css with dark mode support
- Created first 3 getting-started pages (what-is-backupchecks, first-login, quick-start)
- Updated changelog
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
73b1f25279
commit
908785ee73
@ -10,6 +10,7 @@ from .models import User # noqa: F401
|
||||
from .auth import login_manager
|
||||
from .auth.routes import auth_bp
|
||||
from .main.routes import main_bp
|
||||
from .main.routes_documentation import doc_bp
|
||||
from .migrations import run_migrations
|
||||
from .auto_importer_service import start_auto_importer
|
||||
|
||||
@ -62,6 +63,7 @@ def create_app():
|
||||
|
||||
app.register_blueprint(auth_bp)
|
||||
app.register_blueprint(main_bp)
|
||||
app.register_blueprint(doc_bp)
|
||||
|
||||
@app.template_filter("local_datetime")
|
||||
def format_local_datetime(utc_dt, format="%Y-%m-%d %H:%M:%S"):
|
||||
|
||||
@ -0,0 +1,185 @@
|
||||
"""Documentation routes.
|
||||
|
||||
Provides access to static HTML documentation pages for logged-in users.
|
||||
All pages are accessible to any authenticated user (admin, operator, reporter, viewer).
|
||||
"""
|
||||
|
||||
from flask import Blueprint, render_template, abort, redirect, url_for
|
||||
from flask_login import login_required
|
||||
|
||||
|
||||
doc_bp = Blueprint('documentation', __name__, url_prefix='/documentation')
|
||||
|
||||
|
||||
# Documentation structure (for navigation and routing)
|
||||
DOCUMENTATION_STRUCTURE = {
|
||||
'getting-started': {
|
||||
'title': 'Getting Started',
|
||||
'icon': '🏠',
|
||||
'pages': [
|
||||
{'slug': 'what-is-backupchecks', 'title': 'What is BackupChecks?'},
|
||||
{'slug': 'first-login', 'title': 'First Login & Dashboard'},
|
||||
{'slug': 'quick-start', 'title': 'Quick Start Checklist'},
|
||||
]
|
||||
},
|
||||
'users': {
|
||||
'title': 'User Management',
|
||||
'icon': '👥',
|
||||
'pages': [
|
||||
{'slug': 'users-and-roles', 'title': 'Users & Roles'},
|
||||
{'slug': 'login-authentication', 'title': 'Login & Authentication'},
|
||||
{'slug': 'profile-settings', 'title': 'Profile Settings'},
|
||||
]
|
||||
},
|
||||
'customers-jobs': {
|
||||
'title': 'Customers & Jobs',
|
||||
'icon': '💼',
|
||||
'pages': [
|
||||
{'slug': 'managing-customers', 'title': 'Managing Customers'},
|
||||
{'slug': 'configuring-jobs', 'title': 'Configuring Jobs'},
|
||||
{'slug': 'approved-jobs', 'title': 'Approved Jobs'},
|
||||
{'slug': 'job-schedules', 'title': 'Job Schedules'},
|
||||
]
|
||||
},
|
||||
'mail-import': {
|
||||
'title': 'Mail & Import',
|
||||
'icon': '📧',
|
||||
'pages': [
|
||||
{'slug': 'setup', 'title': 'Mail Import Setup'},
|
||||
{'slug': 'inbox-management', 'title': 'Inbox Management'},
|
||||
{'slug': 'mail-parsing', 'title': 'Mail Parsing'},
|
||||
{'slug': 'auto-import', 'title': 'Auto-Import Configuration'},
|
||||
]
|
||||
},
|
||||
'backup-review': {
|
||||
'title': 'Backup Review',
|
||||
'icon': '✅',
|
||||
'pages': [
|
||||
{'slug': 'approving-backups', 'title': 'Approving Backups'},
|
||||
{'slug': 'daily-jobs', 'title': 'Daily Jobs View'},
|
||||
{'slug': 'run-checks-modal', 'title': 'Run Checks Modal'},
|
||||
{'slug': 'overrides', 'title': 'Overrides & Exceptions'},
|
||||
{'slug': 'remarks-tickets', 'title': 'Remarks & Tickets'},
|
||||
]
|
||||
},
|
||||
'reports': {
|
||||
'title': 'Reports',
|
||||
'icon': '📊',
|
||||
'pages': [
|
||||
{'slug': 'creating-reports', 'title': 'Creating Reports'},
|
||||
{'slug': 'relative-periods', 'title': 'Relative Periods'},
|
||||
{'slug': 'scheduling', 'title': 'Report Scheduling'},
|
||||
{'slug': 'exporting-data', 'title': 'Exporting Data'},
|
||||
]
|
||||
},
|
||||
'autotask': {
|
||||
'title': 'Autotask Integration',
|
||||
'icon': '🎫',
|
||||
'pages': [
|
||||
{'slug': 'setup-configuration', 'title': 'Setup & Configuration'},
|
||||
{'slug': 'company-mapping', 'title': 'Company Mapping'},
|
||||
{'slug': 'creating-tickets', 'title': 'Creating Tickets'},
|
||||
{'slug': 'ticket-management', 'title': 'Ticket Management'},
|
||||
]
|
||||
},
|
||||
'settings': {
|
||||
'title': 'Settings',
|
||||
'icon': '⚙️',
|
||||
'pages': [
|
||||
{'slug': 'general', 'title': 'General Settings'},
|
||||
{'slug': 'mail-configuration', 'title': 'Mail Configuration'},
|
||||
{'slug': 'autotask-integration', 'title': 'Autotask Integration'},
|
||||
{'slug': 'reporting-settings', 'title': 'Reporting Settings'},
|
||||
{'slug': 'user-management', 'title': 'User Management'},
|
||||
{'slug': 'maintenance', 'title': 'Maintenance'},
|
||||
]
|
||||
},
|
||||
'troubleshooting': {
|
||||
'title': 'Troubleshooting',
|
||||
'icon': '❓',
|
||||
'pages': [
|
||||
{'slug': 'common-issues', 'title': 'Common Issues'},
|
||||
{'slug': 'faq', 'title': 'FAQ'},
|
||||
{'slug': 'support-contact', 'title': 'Support Contact'},
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_navigation_context(current_section=None, current_page=None):
|
||||
"""Build navigation context with active states."""
|
||||
return {
|
||||
'structure': DOCUMENTATION_STRUCTURE,
|
||||
'current_section': current_section,
|
||||
'current_page': current_page
|
||||
}
|
||||
|
||||
|
||||
def get_prev_next(section, page_slug):
|
||||
"""Get previous and next page for navigation."""
|
||||
# Flatten all pages into single list
|
||||
all_pages = []
|
||||
for sect_key, sect_data in DOCUMENTATION_STRUCTURE.items():
|
||||
for page in sect_data['pages']:
|
||||
all_pages.append({
|
||||
'section': sect_key,
|
||||
'slug': page['slug'],
|
||||
'title': page['title']
|
||||
})
|
||||
|
||||
# Find current page index
|
||||
current_idx = None
|
||||
for i, p in enumerate(all_pages):
|
||||
if p['section'] == section and p['slug'] == page_slug:
|
||||
current_idx = i
|
||||
break
|
||||
|
||||
if current_idx is None:
|
||||
return None, None
|
||||
|
||||
prev_page = all_pages[current_idx - 1] if current_idx > 0 else None
|
||||
next_page = all_pages[current_idx + 1] if current_idx < len(all_pages) - 1 else None
|
||||
|
||||
return prev_page, next_page
|
||||
|
||||
|
||||
@doc_bp.route('/')
|
||||
@doc_bp.route('/index')
|
||||
@login_required
|
||||
def index():
|
||||
"""Documentation home - redirect to first page."""
|
||||
return redirect(url_for('documentation.page', section='getting-started', page='what-is-backupchecks'))
|
||||
|
||||
|
||||
@doc_bp.route('/<section>/<page>')
|
||||
@login_required
|
||||
def page(section, page):
|
||||
"""Render a documentation page."""
|
||||
# Validate section and page exist
|
||||
if section not in DOCUMENTATION_STRUCTURE:
|
||||
abort(404)
|
||||
|
||||
section_data = DOCUMENTATION_STRUCTURE[section]
|
||||
page_exists = any(p['slug'] == page for p in section_data['pages'])
|
||||
if not page_exists:
|
||||
abort(404)
|
||||
|
||||
# Get page title
|
||||
page_title = next(p['title'] for p in section_data['pages'] if p['slug'] == page)
|
||||
|
||||
# Get navigation context
|
||||
nav_context = get_navigation_context(section, page)
|
||||
|
||||
# Get prev/next pages
|
||||
prev_page, next_page = get_prev_next(section, page)
|
||||
|
||||
# Render template
|
||||
template_path = f'documentation/{section}/{page}.html'
|
||||
return render_template(
|
||||
template_path,
|
||||
page_title=page_title,
|
||||
section_title=section_data['title'],
|
||||
navigation=nav_context,
|
||||
prev_page=prev_page,
|
||||
next_page=next_page
|
||||
)
|
||||
315
containers/backupchecks/src/static/css/documentation.css
Normal file
315
containers/backupchecks/src/static/css/documentation.css
Normal file
@ -0,0 +1,315 @@
|
||||
/* Documentation Container */
|
||||
.documentation-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
.doc-sidebar-wrapper {
|
||||
border-right: 1px solid #dee2e6;
|
||||
min-height: calc(100vh - 80px);
|
||||
}
|
||||
|
||||
.doc-nav {
|
||||
position: sticky;
|
||||
top: 20px;
|
||||
padding: 20px;
|
||||
max-height: calc(100vh - 100px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.doc-nav-header h5 {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #007bff;
|
||||
}
|
||||
|
||||
.doc-nav-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.doc-nav-section-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
padding: 8px 12px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.doc-nav-section.active .doc-nav-section-title {
|
||||
background-color: #e7f1ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.doc-nav-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.doc-nav-pages {
|
||||
list-style: none;
|
||||
padding-left: 30px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.doc-nav-pages li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.doc-nav-pages li a {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
color: #495057;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.doc-nav-pages li a:hover {
|
||||
background-color: #f8f9fa;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.doc-nav-pages li.active a {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Content Area */
|
||||
.doc-content-wrapper {
|
||||
padding: 20px 40px;
|
||||
}
|
||||
|
||||
.doc-content {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.doc-content h1 {
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 3px solid #007bff;
|
||||
}
|
||||
|
||||
.doc-content h2 {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.doc-content h3 {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.doc-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
margin: 20px 0;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.doc-content figcaption {
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
color: #6c757d;
|
||||
margin-top: -15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.doc-content .lead {
|
||||
font-size: 1.15rem;
|
||||
color: #6c757d;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
/* Code Blocks */
|
||||
.doc-content pre {
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.doc-content code {
|
||||
background-color: #f8f9fa;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.doc-content pre code {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
.doc-content table {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.doc-content table th,
|
||||
.doc-content table td {
|
||||
padding: 12px;
|
||||
border: 1px solid #dee2e6;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.doc-content table th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.doc-content table tr:nth-child(even) {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* Callout Boxes */
|
||||
.doc-callout {
|
||||
padding: 15px 20px;
|
||||
margin: 20px 0;
|
||||
border-left: 4px solid;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.doc-callout-info {
|
||||
background-color: #e7f3ff;
|
||||
border-left-color: #007bff;
|
||||
}
|
||||
|
||||
.doc-callout-warning {
|
||||
background-color: #fff3cd;
|
||||
border-left-color: #ffc107;
|
||||
}
|
||||
|
||||
.doc-callout-tip {
|
||||
background-color: #d4edda;
|
||||
border-left-color: #28a745;
|
||||
}
|
||||
|
||||
.doc-callout-danger {
|
||||
background-color: #f8d7da;
|
||||
border-left-color: #dc3545;
|
||||
}
|
||||
|
||||
.doc-callout strong {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
.doc-pagination {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
/* Dark mode support */
|
||||
[data-bs-theme="dark"] .doc-sidebar-wrapper {
|
||||
border-right-color: #495057;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-nav-section-title {
|
||||
background-color: #343a40;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-nav-section.active .doc-nav-section-title {
|
||||
background-color: #1a4d8f;
|
||||
color: #a8c9f5;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-nav-pages li a {
|
||||
color: #adb5bd;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-nav-pages li a:hover {
|
||||
background-color: #343a40;
|
||||
color: #a8c9f5;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-nav-pages li.active a {
|
||||
background-color: #0d6efd;
|
||||
color: white;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content h1 {
|
||||
border-bottom-color: #0d6efd;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content h2 {
|
||||
color: #a8c9f5;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content img {
|
||||
border-color: #495057;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content pre {
|
||||
background-color: #212529;
|
||||
border-color: #495057;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content code {
|
||||
background-color: #212529;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content table th,
|
||||
[data-bs-theme="dark"] .doc-content table td {
|
||||
border-color: #495057;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content table th {
|
||||
background-color: #343a40;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-content table tr:nth-child(even) {
|
||||
background-color: #2b3035;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-callout-info {
|
||||
background-color: #1a3a52;
|
||||
border-left-color: #0d6efd;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-callout-warning {
|
||||
background-color: #4a3f1f;
|
||||
border-left-color: #ffc107;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-callout-tip {
|
||||
background-color: #1f3d2a;
|
||||
border-left-color: #28a745;
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] .doc-callout-danger {
|
||||
background-color: #4a2329;
|
||||
border-left-color: #dc3545;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 991px) {
|
||||
.doc-sidebar-wrapper {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.doc-nav {
|
||||
position: static;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.doc-content-wrapper {
|
||||
padding: 20px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
[data-bs-theme="dark"] .doc-sidebar-wrapper {
|
||||
border-bottom-color: #495057;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
<nav class="doc-nav">
|
||||
<div class="doc-nav-header">
|
||||
<h5>📖 Documentation</h5>
|
||||
</div>
|
||||
|
||||
{% for section_key, section_data in navigation.structure.items() %}
|
||||
<div class="doc-nav-section {% if section_key == navigation.current_section %}active{% endif %}">
|
||||
<div class="doc-nav-section-title">
|
||||
<span class="doc-nav-icon">{{ section_data.icon }}</span>
|
||||
{{ section_data.title }}
|
||||
</div>
|
||||
|
||||
<ul class="doc-nav-pages">
|
||||
{% for page in section_data.pages %}
|
||||
<li class="{% if section_key == navigation.current_section and page.slug == navigation.current_page %}active{% endif %}">
|
||||
<a href="{{ url_for('documentation.page', section=section_key, page=page.slug) }}">
|
||||
{{ page.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</nav>
|
||||
@ -0,0 +1,59 @@
|
||||
{% extends "layout/base.html" %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/documentation.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block main_class %}container-fluid content-container{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="documentation-container">
|
||||
<div class="row g-0">
|
||||
<!-- Sidebar Navigation -->
|
||||
<div class="col-12 col-lg-3 doc-sidebar-wrapper">
|
||||
{% include 'documentation/_navigation.html' %}
|
||||
</div>
|
||||
|
||||
<!-- Content Area -->
|
||||
<div class="col-12 col-lg-9 doc-content-wrapper">
|
||||
<div class="doc-content">
|
||||
<!-- Breadcrumb -->
|
||||
<nav aria-label="breadcrumb" class="mb-4">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ url_for('documentation.index') }}">Documentation</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">{{ section_title }}</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ page_title }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<!-- Page Content -->
|
||||
{% block doc_content %}{% endblock %}
|
||||
|
||||
<!-- Previous/Next Navigation -->
|
||||
<div class="doc-pagination mt-5 pt-4 border-top">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
{% if prev_page %}
|
||||
<a href="{{ url_for('documentation.page', section=prev_page.section, page=prev_page.slug) }}"
|
||||
class="btn btn-outline-secondary">
|
||||
← {{ prev_page.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
{% if next_page %}
|
||||
<a href="{{ url_for('documentation.page', section=next_page.section, page=next_page.slug) }}"
|
||||
class="btn btn-outline-primary">
|
||||
{{ next_page.title }} →
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -0,0 +1,50 @@
|
||||
{% extends "documentation/base.html" %}
|
||||
|
||||
{% block doc_content %}
|
||||
<h1>First Login & Dashboard</h1>
|
||||
|
||||
<p class="lead">
|
||||
Learn how to log in to BackupChecks and navigate the dashboard interface.
|
||||
</p>
|
||||
|
||||
<div class="doc-callout doc-callout-info">
|
||||
<strong>📝 Coming Soon:</strong>
|
||||
This page is under construction. Full content will be added in a future update.
|
||||
</div>
|
||||
|
||||
<h2>Logging In</h2>
|
||||
|
||||
<p>To access BackupChecks:</p>
|
||||
|
||||
<ol>
|
||||
<li>Navigate to the BackupChecks URL in your web browser</li>
|
||||
<li>Enter your username and password</li>
|
||||
<li>Click the "Login" button</li>
|
||||
</ol>
|
||||
|
||||
<h2>Dashboard Overview</h2>
|
||||
|
||||
<p>The dashboard provides a quick overview of your backup status:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Today's Jobs:</strong> Summary of backup jobs expected today</li>
|
||||
<li><strong>Recent Activity:</strong> Latest backup reports and reviews</li>
|
||||
<li><strong>Statistics:</strong> Success rates and trends</li>
|
||||
<li><strong>Quick Actions:</strong> Common tasks and shortcuts</li>
|
||||
</ul>
|
||||
|
||||
<h2>Navigation</h2>
|
||||
|
||||
<p>Use the navigation bar at the top to access different sections:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Inbox:</strong> View incoming backup report emails</li>
|
||||
<li><strong>Customers:</strong> Manage customer accounts</li>
|
||||
<li><strong>Jobs:</strong> Configure backup jobs</li>
|
||||
<li><strong>Daily Jobs:</strong> Review today's backup status</li>
|
||||
<li><strong>Run Checks:</strong> Approve or reject backup runs</li>
|
||||
<li><strong>Reports:</strong> Generate and view reports</li>
|
||||
<li><strong>Settings:</strong> Configure system settings (admin only)</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,88 @@
|
||||
{% extends "documentation/base.html" %}
|
||||
|
||||
{% block doc_content %}
|
||||
<h1>Quick Start Checklist</h1>
|
||||
|
||||
<p class="lead">
|
||||
Follow this checklist to set up your first customer and backup job in BackupChecks.
|
||||
</p>
|
||||
|
||||
<div class="doc-callout doc-callout-info">
|
||||
<strong>📝 Coming Soon:</strong>
|
||||
This page is under construction. Full content will be added in a future update.
|
||||
</div>
|
||||
|
||||
<h2>Prerequisites</h2>
|
||||
|
||||
<p>Before you begin, ensure you have:</p>
|
||||
|
||||
<ul>
|
||||
<li>Admin or Operator access to BackupChecks</li>
|
||||
<li>Email credentials for the backup report mailbox</li>
|
||||
<li>Information about your first customer and their backup software</li>
|
||||
</ul>
|
||||
|
||||
<h2>Step 1: Configure Mail Import</h2>
|
||||
|
||||
<ol>
|
||||
<li>Navigate to <strong>Settings</strong> → <strong>Mail</strong></li>
|
||||
<li>Enter your IMAP server details (host, port, username, password)</li>
|
||||
<li>Test the connection</li>
|
||||
<li>Enable automatic mail import</li>
|
||||
</ol>
|
||||
|
||||
<h2>Step 2: Add a Customer</h2>
|
||||
|
||||
<ol>
|
||||
<li>Go to <strong>Customers</strong> in the navigation menu</li>
|
||||
<li>Click <strong>New Customer</strong></li>
|
||||
<li>Fill in the customer details (name, contact info)</li>
|
||||
<li>Save the customer</li>
|
||||
</ol>
|
||||
|
||||
<h2>Step 3: Configure a Job</h2>
|
||||
|
||||
<ol>
|
||||
<li>From the customer detail page, click <strong>New Job</strong></li>
|
||||
<li>Select the backup software type (Veeam, Synology, etc.)</li>
|
||||
<li>Configure job matching rules (sender email, subject keywords)</li>
|
||||
<li>Set the expected schedule</li>
|
||||
<li>Save the job configuration</li>
|
||||
</ol>
|
||||
|
||||
<h2>Step 4: Import First Backup Report</h2>
|
||||
|
||||
<ol>
|
||||
<li>Go to <strong>Inbox</strong></li>
|
||||
<li>Click <strong>Import Now</strong> to fetch recent emails</li>
|
||||
<li>Find your backup report email in the inbox</li>
|
||||
<li>Click on the email to view details</li>
|
||||
<li>Click <strong>Link to Job</strong> and select the job you created</li>
|
||||
</ol>
|
||||
|
||||
<h2>Step 5: Review and Approve</h2>
|
||||
|
||||
<ol>
|
||||
<li>Navigate to <strong>Daily Jobs</strong></li>
|
||||
<li>You should see your job listed for today</li>
|
||||
<li>Click <strong>Run Checks</strong> to review pending backups</li>
|
||||
<li>Approve or reject the backup run</li>
|
||||
</ol>
|
||||
|
||||
<div class="doc-callout doc-callout-tip">
|
||||
<strong>💡 Tip:</strong>
|
||||
After completing these steps, your job will automatically process future backup reports from the same sender.
|
||||
</div>
|
||||
|
||||
<h2>Next Steps</h2>
|
||||
|
||||
<p>Now that you have your first job configured, you can:</p>
|
||||
|
||||
<ul>
|
||||
<li>Add more customers and jobs</li>
|
||||
<li>Configure <a href="{{ url_for('documentation.page', section='autotask', page='setup-configuration') }}">Autotask integration</a> for automatic ticket creation</li>
|
||||
<li>Set up <a href="{{ url_for('documentation.page', section='reports', page='scheduling') }}">scheduled reports</a></li>
|
||||
<li>Configure <a href="{{ url_for('documentation.page', section='backup-review', page='overrides') }}">overrides</a> for special cases</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,160 @@
|
||||
{% extends "documentation/base.html" %}
|
||||
|
||||
{% block doc_content %}
|
||||
<h1>What is BackupChecks?</h1>
|
||||
|
||||
<p class="lead">
|
||||
BackupChecks is a backup monitoring and validation system designed to help IT teams
|
||||
verify that backups are running successfully across their customer infrastructure.
|
||||
</p>
|
||||
|
||||
<h2>Key Features</h2>
|
||||
|
||||
<ul>
|
||||
<li><strong>Automated Mail Parsing:</strong> Import backup reports via email and automatically parse results</li>
|
||||
<li><strong>Approval Workflow:</strong> Review and approve backup jobs on a daily basis</li>
|
||||
<li><strong>Customer Management:</strong> Organize backups by customer and manage multiple backup jobs per customer</li>
|
||||
<li><strong>Autotask Integration:</strong> Create tickets in Autotask PSA for failed backups</li>
|
||||
<li><strong>Reporting:</strong> Generate backup status reports with flexible scheduling</li>
|
||||
<li><strong>Role-Based Access:</strong> Admin, Operator, Reporter, and Viewer roles</li>
|
||||
</ul>
|
||||
|
||||
<div class="doc-callout doc-callout-info">
|
||||
<strong>💡 Note:</strong>
|
||||
Screenshots will be added in a future update to illustrate the dashboard and key features.
|
||||
</div>
|
||||
|
||||
<h2>How It Works</h2>
|
||||
|
||||
<p>BackupChecks follows a simple workflow:</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Import:</strong> Backup reports are sent via email to a configured mailbox</li>
|
||||
<li><strong>Parse:</strong> The system parses email content to extract backup status</li>
|
||||
<li><strong>Match:</strong> Reports are matched to configured jobs based on sender, subject, and content</li>
|
||||
<li><strong>Review:</strong> Operators review backup status and approve successful jobs</li>
|
||||
<li><strong>Alert:</strong> Failed backups can trigger Autotask tickets or manual follow-up</li>
|
||||
<li><strong>Report:</strong> Generate periodic reports to track backup health over time</li>
|
||||
</ol>
|
||||
|
||||
<div class="doc-callout doc-callout-tip">
|
||||
<strong>💡 Tip:</strong>
|
||||
Start with the <a href="{{ url_for('documentation.page', section='getting-started', page='quick-start') }}">Quick Start Checklist</a>
|
||||
to get your first customer and job configured.
|
||||
</div>
|
||||
|
||||
<h2>Who Should Use BackupChecks?</h2>
|
||||
|
||||
<p>BackupChecks is designed for:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Managed Service Providers (MSPs):</strong> Monitor backups across multiple customer environments</li>
|
||||
<li><strong>IT Departments:</strong> Track backup compliance for internal infrastructure</li>
|
||||
<li><strong>Backup Administrators:</strong> Centralize backup verification from multiple backup solutions</li>
|
||||
</ul>
|
||||
|
||||
<h2>Supported Backup Software</h2>
|
||||
|
||||
<p>BackupChecks supports parsing backup reports from:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Software</th>
|
||||
<th>Support Level</th>
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Veeam Backup & Replication</td>
|
||||
<td>Full</td>
|
||||
<td>Email notifications with detailed job status</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Acronis Cyber Protect</td>
|
||||
<td>Full</td>
|
||||
<td>Backup completion reports</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Synology Active Backup</td>
|
||||
<td>Full</td>
|
||||
<td>Task result notifications</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>QNAP Hybrid Backup Sync</td>
|
||||
<td>Full</td>
|
||||
<td>Job completion emails</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Custom/Other</td>
|
||||
<td>Configurable</td>
|
||||
<td>Manual job configuration for non-standard formats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="doc-callout doc-callout-warning">
|
||||
<strong>⚠️ Important:</strong>
|
||||
BackupChecks monitors backup <em>reports</em>, not the backup data itself. Ensure your backup software is configured to send email notifications on job completion.
|
||||
</div>
|
||||
|
||||
<h2>Architecture Overview</h2>
|
||||
|
||||
<p>BackupChecks is a web-based application with the following components:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Backend:</strong> Flask (Python) application with PostgreSQL database</li>
|
||||
<li><strong>Frontend:</strong> Bootstrap 5 for responsive UI</li>
|
||||
<li><strong>Mail Import:</strong> IMAP integration for automated email retrieval</li>
|
||||
<li><strong>Autotask API:</strong> Optional integration for ticket creation</li>
|
||||
<li><strong>Reporting:</strong> Built-in report generation with scheduling</li>
|
||||
</ul>
|
||||
|
||||
<h2>User Roles</h2>
|
||||
|
||||
<p>BackupChecks supports four user roles with different permissions:</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Role</th>
|
||||
<th>Permissions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>Admin</strong></td>
|
||||
<td>Full access to all features, settings, and configuration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Operator</strong></td>
|
||||
<td>Can review and approve backups, manage customers and jobs, create tickets</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Reporter</strong></td>
|
||||
<td>Can view and generate reports, no access to operational features</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Viewer</strong></td>
|
||||
<td>Read-only access to customers, jobs, and reports</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="doc-callout doc-callout-info">
|
||||
<strong>💡 Note:</strong>
|
||||
Users can be assigned multiple roles and can switch between them using the role selector in the navigation bar.
|
||||
</div>
|
||||
|
||||
<h2>Next Steps</h2>
|
||||
|
||||
<p>Ready to get started? Continue to:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="{{ url_for('documentation.page', section='getting-started', page='first-login') }}">First Login & Dashboard</a> - Learn about the dashboard interface</li>
|
||||
<li><a href="{{ url_for('documentation.page', section='getting-started', page='quick-start') }}">Quick Start Checklist</a> - Set up your first customer and job</li>
|
||||
<li><a href="{{ url_for('documentation.page', section='mail-import', page='setup') }}">Mail Import Setup</a> - Configure email integration</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
@ -80,6 +80,11 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('main.reports') }}">Reports</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.path.startswith('/documentation') %}active{% endif %}" href="{{ url_for('documentation.index') }}">
|
||||
<span class="nav-icon">📖</span> Documentation
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href='{{ url_for("main.changelog_page") }}'>Changelog</a>
|
||||
</li>
|
||||
@ -139,6 +144,11 @@
|
||||
<a class="nav-link" href="{{ url_for('main.parsers_overview') }}">Parsers</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.path.startswith('/documentation') %}active{% endif %}" href="{{ url_for('documentation.index') }}">
|
||||
<span class="nav-icon">📖</span> Documentation
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href='{{ url_for("main.changelog_page") }}'>Changelog</a>
|
||||
</li>
|
||||
|
||||
@ -2,6 +2,36 @@
|
||||
|
||||
This file documents all changes made to this project via Claude Code.
|
||||
|
||||
## [2026-02-08]
|
||||
|
||||
### Added
|
||||
- Added comprehensive documentation system for user onboarding and reference:
|
||||
- **Documentation Blueprint**: New `/documentation` route with dedicated blueprint (doc_bp)
|
||||
- **Navigation Structure**: Hierarchical documentation with 9 sections and 33 pages covering all features
|
||||
- Getting Started (3 pages): What is BackupChecks, First Login, Quick Start
|
||||
- User Management (3 pages): Users & Roles, Authentication, Profile Settings
|
||||
- Customers & Jobs (4 pages): Managing Customers, Configuring Jobs, Approved Jobs, Job Schedules
|
||||
- Mail & Import (4 pages): Setup, Inbox Management, Mail Parsing, Auto-Import
|
||||
- Backup Review (5 pages): Approving Backups, Daily Jobs, Run Checks Modal, Overrides, Remarks & Tickets
|
||||
- Reports (4 pages): Creating Reports, Relative Periods, Scheduling, Exporting Data
|
||||
- Autotask Integration (4 pages): Setup, Company Mapping, Creating Tickets, Ticket Management
|
||||
- Settings (6 pages): General, Mail, Autotask, Reporting, User Management, Maintenance
|
||||
- Troubleshooting (3 pages): Common Issues, FAQ, Support Contact
|
||||
- **UI Components**:
|
||||
- Sidebar navigation with collapsible sections and active page highlighting
|
||||
- Breadcrumb navigation for current location context
|
||||
- Previous/Next pagination buttons for sequential reading
|
||||
- Documentation menu item in main navbar (📖 icon) visible to all authenticated users
|
||||
- **Styling**:
|
||||
- Custom CSS with support for dark mode
|
||||
- Callout boxes (info, warning, tip, danger) for highlighting important content
|
||||
- Code blocks, tables, and image support
|
||||
- Responsive design for mobile and desktop
|
||||
- **Access Control**: Login required (@login_required) - accessible to all user roles
|
||||
- **Current Status**: Core infrastructure complete, first three getting-started pages created
|
||||
- **Placeholder Pages**: First-login and quick-start pages created with basic content structure
|
||||
- Full content for all pages will be added incrementally in future updates
|
||||
|
||||
## [2026-02-07]
|
||||
|
||||
### Changed
|
||||
|
||||
Loading…
Reference in New Issue
Block a user