Skip to content

Implement v4.8.0: Reporting & Sharing#7

Open
ccleberg wants to merge 4 commits into
mainfrom
feat/v4.8.0
Open

Implement v4.8.0: Reporting & Sharing#7
ccleberg wants to merge 4 commits into
mainfrom
feat/v4.8.0

Conversation

@ccleberg

Copy link
Copy Markdown
Member

Delivers the v4.8.0 "Reporting & Sharing" roadmap phase.

What

  • Markdown + PDF export formatsDomainExportFormat gains .markdown and .pdf. Markdown reuses the exact same content as the existing text export via a line-based transform (section "Title\n----" underlines become "## Title", the leading title becomes H1, other lines become bullets) so the two formats can never drift apart. PDF renders that Markdown as a simple monospaced multi-page document via UIGraphicsPDFRenderer, mirroring the approach AuditExporter already uses for audit sessions.
  • Scheduled report generation — new ScheduledReportService/ScheduledReportScheduler (Settings → Scheduled Reports). A BGTaskScheduler-driven daily/weekly job builds a markdown/PDF/JSON report bundle for every tracked domain, writes it to a local Documents subdirectory, logs the run, and fires a "Scheduled Report Ready" notification. Mirrors DomainMonitoringService's headless, storage-backed design (no live view model needed) and its own BGTaskScheduler identifier. Gated behind the existing Pro .automatedMonitoring capability, same bucket as monitoring.
  • Stronger share affordances — "Export Markdown"/"Export PDF" added to the single-result, batch, watchlist, and workflow export menus (Pro-gated like the existing CSV/JSON options); each generated scheduled report is individually shareable from its log entry via the existing ExportPresenter.
  • Export consistency, verified — checked whether the local API needed changes for parity: it already serves the canonical DomainReport directly with no field allowlist, so reputation, domainPricing, and everything else added since v4.7.0 already flow through automatically. No code change was needed there — documented the finding instead of making an unasked-for change.

Version

Bumped to 4.8.0 (build 40) across app, widget, and share extension targets.

Verification

  • xcodebuild build (scheme DomainDig, iOS 26 sim) → BUILD SUCCEEDED after each commit.
  • Installed + launched on simulator after each major slice: no crash (background task registration, new Settings screen, export menus all load without issue).

Honest gaps

  • Scheduled report generation's "Generate Now" path was not interactively tap-tested — I verified it via build success, code review, and the fact it reuses the exact same DomainReportExporter/DomainReportBuilder/DomainDataPortabilityService calls that DomainMonitoringService already exercises successfully in production. No UI automation was available to actually tap through Settings → Scheduled Reports → Generate Now and confirm a file lands on disk. This is the top thing to check in UAT.
  • Scheduled-report settings/logs are UserDefaults-only, not part of DomainDataPortabilityService backup/restore — same scope decision as v4.7.0's watchlist saved views (local automation config, not user-authored content). Flagging again in case that's the wrong call across both features.
  • Small pre-existing pattern I noticed but didn't touch: the five export menus (ContentView×2, WatchlistView, WorkflowsView×2) each hand-list format buttons with duplicated Pro-gate logic, rather than iterating DomainExportFormat.allCases the way AuditExporter's menu already does. I made DomainExportFormat CaseIterable/Identifiable specifically because of this, but chose not to refactor the other four (pre-existing, working) menus to match — that would touch code unrelated to this task. Worth a follow-up if you want the menus deduplicated.

ccleberg added 4 commits July 17, 2026 11:09
- DomainExportFormat gains .markdown and .pdf (CaseIterable, Identifiable,
  titled), alongside the existing text/csv/json.
- Markdown reuses the existing text-export content verbatim via a line-based
  transform (section "Title\n----" underlines become "## Title", the leading
  title becomes an H1, other lines become bullets), so the two formats can
  never drift apart.
- PDF renders that Markdown as a simple monospaced multi-page document via
  UIGraphicsPDFRenderer (mirrors AuditExporter's existing PDF approach;
  degrades to raw Markdown bytes on non-UIKit platforms).
- Replaced the single/batch/tracked-domains/workflow share call sites' hand-
  written per-format switches with format-agnostic functions
  (exportSingleReportData, exportBatchReportData, exportTrackedDomainsData,
  exportWorkflowData) that delegate straight to DomainReportExporter, removing
  the now-orphaned per-format helper functions those switches used to call.
Adds "Export Markdown"/"Export PDF" (and batch/workflow equivalents) to the
single-result, batch, watchlist, and workflow export menus, gated behind
.advancedExports like the existing CSV/JSON options. Matches the existing
menu structure and Pro-gate wording per file rather than introducing a new
shared component, consistent with how CSV/JSON were already duplicated across
these five menus before this change.
- ScheduledReportService (@mainactor, headless/storage-backed like
  DomainMonitoringService): builds the latest report for every tracked domain
  from persisted history, exports it via DomainReportExporter in the
  configured format (markdown/PDF/JSON), writes it to a local Documents
  subdirectory, logs the run, and fires a "Scheduled Report Ready" local
  notification.
- ScheduledReportScheduler mirrors DomainMonitoringScheduler's BGTaskScheduler
  approach with its own task identifier (net.cleberg.DomainDig.report.schedule,
  added to Info.plist) and a daily/weekly cadence.
- ScheduledReportsView (Settings → Scheduled Reports): enable toggle, cadence
  and format pickers, "Generate Now", and a log of past reports each shareable
  via the existing ExportPresenter share sheet.
- Gated behind the existing .automatedMonitoring capability (Pro), consistent
  with monitoring being the other background-automation feature.
- Settings/logs persist via UserDefaults (DomainExportFormat is now Codable),
  not DomainDataPortabilityService backup/restore — this is local automation
  configuration, not user-authored content, same reasoning as v4.7.0's
  watchlist saved views.
Bump AppVersion/marketing version to 4.8.0 and build number to 40 across the
app, widget, and share extension targets. Mark v4.8.0 (markdown/PDF export,
scheduled reports, stronger share affordances, verified local API consistency)
shipped in RELEASE_ROADMAP.md.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant