Add comprehensive documentation for DMARQ, including user guides, deployment instructions, and feature descriptions

- Created main documentation index and user guide with sections on getting started, dashboard overview, managing domains, and reports.
- Added detailed deployment guide for Docker and manual installation.
- Included user-friendly explanations of DMARC, its benefits, and how to manage domains and reports.
- Implemented visual assets for dashboard, domains, IMAP, and reports.
- Established requirements for documentation build using MkDocs and Material theme.
- Integrated navigation structure for easy access to all documentation sections.
This commit is contained in:
Christian Krakau-Louis
2025-04-21 01:49:34 +02:00
parent 1b79ec4f20
commit 5e8b1f033f
29 changed files with 1947 additions and 110 deletions
+30 -12
View File
@@ -1,7 +1,7 @@
from datetime import datetime
from typing import List, Optional
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Text
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Text, Index
from sqlalchemy.orm import relationship
from app.core.database import Base
@@ -13,30 +13,40 @@ class DMARCReport(Base):
__tablename__ = "dmarc_reports"
id = Column(Integer, primary_key=True, index=True)
domain_id = Column(Integer, ForeignKey("domains.id"), nullable=False)
domain_id = Column(Integer, ForeignKey("domains.id"), nullable=False, index=True)
# Report metadata
report_id = Column(String, index=True, nullable=False)
org_name = Column(String, nullable=False)
begin_date = Column(Integer, nullable=False) # Unix timestamp
end_date = Column(Integer, nullable=False) # Unix timestamp
org_name = Column(String, nullable=False, index=True)
begin_date = Column(Integer, nullable=False, index=True) # Unix timestamp
end_date = Column(Integer, nullable=False, index=True) # Unix timestamp
source_email = Column(String, nullable=True)
# Policy information
policy = Column(String, nullable=True) # none, quarantine, reject
policy = Column(String, nullable=True, index=True) # none, quarantine, reject
subdomain_policy = Column(String, nullable=True)
adkim = Column(String(1), nullable=True) # r (relaxed) or s (strict)
aspf = Column(String(1), nullable=True) # r (relaxed) or s (strict)
percentage = Column(Integer, nullable=True)
# Processing metadata
processed_at = Column(DateTime, default=datetime.utcnow)
processed_at = Column(DateTime, default=datetime.utcnow, index=True)
raw_data = Column(Text, nullable=True) # Original XML content (optional)
# Relationships
domain = relationship("Domain", back_populates="reports")
records = relationship("ReportRecord", back_populates="report", cascade="all, delete-orphan")
# Indexes for common queries
__table_args__ = (
# Composite index for domain and date range queries (common dashboard queries)
Index('ix_dmarc_reports_domain_dates', 'domain_id', 'begin_date', 'end_date'),
# Index for finding reports by policy
Index('ix_dmarc_reports_policy', 'policy'),
# Index for finding recent reports (dashboard statistics)
Index('ix_dmarc_reports_processed', 'processed_at'),
)
def __repr__(self):
return f"<DMARCReport {self.report_id} for {self.domain_id}>"
@@ -47,19 +57,19 @@ class ReportRecord(Base):
__tablename__ = "report_records"
id = Column(Integer, primary_key=True, index=True)
report_id = Column(Integer, ForeignKey("dmarc_reports.id"), nullable=False)
report_id = Column(Integer, ForeignKey("dmarc_reports.id"), nullable=False, index=True)
# Source information
source_ip = Column(String, nullable=False, index=True)
count = Column(Integer, nullable=False, default=0)
# Policy evaluation
disposition = Column(String, nullable=False) # none, quarantine, reject
dkim = Column(String, nullable=True) # pass, fail
spf = Column(String, nullable=True) # pass, fail
disposition = Column(String, nullable=False, index=True) # none, quarantine, reject
dkim = Column(String, nullable=True, index=True) # pass, fail
spf = Column(String, nullable=True, index=True) # pass, fail
# Identifiers
header_from = Column(String, nullable=True)
header_from = Column(String, nullable=True, index=True)
envelope_from = Column(String, nullable=True)
# Authentication details (optional JSON fields)
@@ -69,5 +79,13 @@ class ReportRecord(Base):
# Relationships
report = relationship("DMARCReport", back_populates="records")
# Indexes for common queries
__table_args__ = (
# Composite index for source IP and evaluation results (for filtering)
Index('ix_report_records_source_auth', 'source_ip', 'dkim', 'spf'),
# Composite index for disposition and count (for statistics)
Index('ix_report_records_disposition', 'disposition', 'count'),
)
def __repr__(self):
return f"<ReportRecord {self.id} ({self.source_ip})>"