# Phase 7 Execution Plan: Modular Reporting Extraction

## 1. Purpose

Phase 7 extracts reporting into a reusable `SchoolCore` module that can support any school system while allowing **Islamic Sunday School**-specific reports through extension read models, report builders, labels, and export templates.

The reporting module must own the invariant parts of reporting:

- report definitions
- report authorization
- report input validation
- read models
- query objects
- school-scoped report queries
- export generation
- report snapshots
- report audit logs
- scheduled reports
- report caching rules
- cross-school isolation
- consistent calculations sourced from domain modules

Islamic Sunday School may customize:

- Qur’an progress reports
- Arabic level reports
- Islamic studies progress reports
- halaqa/group reports
- Sunday program attendance reports
- masjid family/community reports
- volunteer/program team reports
- scholarship/sadaqah-supported fee reports, if applicable
- Islamic Sunday School dashboard labels

Reporting must not become the place where business rules go to escape tests. Reports should display truth produced by services, policies, and read models. They should not invent finance balances, attendance counts, promotion rules, or student statuses with random raw SQL and optimism.

---

## 2. Required Dependency Direction

Reporting must follow the modular platform boundary:

```text
App\Domain\IslamicSundaySchool\Reporting
        ↓ depends on
App\Domain\SchoolCore\Reporting
        ↓ depends on
App\Domain\SchoolCore\Shared
```

Allowed reporting dependencies:

```text
SchoolCore\Reporting -> SchoolCore\Students read models/contracts
SchoolCore\Reporting -> SchoolCore\Attendance read models/contracts
SchoolCore\Reporting -> SchoolCore\Finance read models/contracts
SchoolCore\Reporting -> SchoolCore\Communication read models/contracts
SchoolCore\Reporting -> SchoolCore\Shared context/audit/export contracts
IslamicSundaySchool\Reporting -> SchoolCore\Reporting contracts
```

Forbidden dependencies:

```text
SchoolCore\Reporting -> IslamicSundaySchool\*
SchoolCore\Reporting -> Http\Request
SchoolCore\Reporting -> auth()
SchoolCore\Reporting -> controller classes
SchoolCore\Reporting -> Islamic Sunday School vocabulary
SchoolCore\Reporting -> direct unscoped school queries
SchoolCore\Reporting -> mutation services for write-side behavior
```

Reporting may consume read-side contracts. It must not call mutation services to “calculate” state by causing side effects. Yes, that has happened in real systems. Humanity has been unsupervised near databases for too long.

---

## 3. Target Namespace Structure

Create the reporting module under `SchoolCore`:

```text
app/
  Domain/
    SchoolCore/
      Reporting/
        Contracts/
          ReportRegistryContract.php
          ReportDefinitionContract.php
          ReportRunnerContract.php
          ReportAuthorizationPolicyContract.php
          ReportExportServiceContract.php
          ReportSnapshotServiceContract.php
          ScheduledReportServiceContract.php
          ReportAuditLoggerContract.php
          ReportCacheServiceContract.php
        DTO/
          ReportRequestData.php
          ReportFilterData.php
          ReportColumnData.php
          ReportSortData.php
          ReportResultData.php
          ReportExportData.php
          ReportSnapshotData.php
          ScheduledReportData.php
          ReportAuditData.php
        Enums/
          ReportCategory.php
          ReportFormat.php
          ReportStatus.php
          ReportVisibility.php
          ReportAuditAction.php
          ReportScheduleFrequency.php
        Exceptions/
          ReportingException.php
          ReportNotFoundException.php
          UnauthorizedReportAccessException.php
          InvalidReportFilterException.php
          ReportExportException.php
          ReportTimeoutException.php
        Services/
          ReportRegistry.php
          ReportRunner.php
          ReportExportService.php
          ReportSnapshotService.php
          ScheduledReportService.php
          ReportAuditLogger.php
          ReportCacheService.php
        Reports/
          Students/
            StudentRosterReport.php
            StudentEnrollmentReport.php
            GuardianContactReport.php
          Attendance/
            AttendanceSummaryReport.php
            StudentAttendanceHistoryReport.php
            StaffAttendanceSummaryReport.php
          Finance/
            InvoiceSummaryReport.php
            OutstandingBalanceReport.php
            PaymentSummaryReport.php
          Communication/
            MessageDeliveryReport.php
            RecipientEngagementReport.php
        ReadModels/
          StudentReportReadModel.php
          AttendanceReportReadModel.php
          FinanceReportReadModel.php
          CommunicationReportReadModel.php
        Repositories/
          ReportReadRepository.php
          ReportSnapshotRepository.php
          ScheduledReportRepository.php
        Support/
          ReportQueryBuilder.php
          ReportColumnFormatter.php
          ReportFilterValidator.php
          ReportExportFilenameBuilder.php
          ReportContext.php
```

Islamic Sunday School-specific reporting goes here:

```text
app/
  Domain/
    IslamicSundaySchool/
      Reporting/
        Reports/
          QuranProgressReport.php
          ArabicLevelReport.php
          IslamicStudiesProgressReport.php
          HalaqaAttendanceReport.php
          SundayProgramAttendanceReport.php
          MasjidFamilySummaryReport.php
          VolunteerTeamReport.php
          IslamicSundaySchoolDashboardReport.php
        ReadModels/
          QuranProgressReadModel.php
          ArabicProgressReadModel.php
          IslamicStudiesProgressReadModel.php
          HalaqaReportReadModel.php
          MasjidFamilyReportReadModel.php
        ExportTemplates/
          QuranProgressExportTemplate.php
          FamilySummaryExportTemplate.php
        Providers/
          IslamicSundaySchoolReportingServiceProvider.php
```

---

## 4. Core Design Rules

### 4.1 Reporting services must require `SchoolContext`

Every public reporting method must receive `SchoolContext`.

Example:

```php
public function run(
    SchoolContext $context,
    ReportRequestData $data
): ReportResult;
```

A report without `SchoolContext` is invalid. A report without school scoping is a data leak wearing a chart.

### 4.2 Reports must be read-only

Reports may:

```text
- query read models
- call read-only repositories
- format output
- export files
- create report snapshots
- create report audit logs
```

Reports may not:

```text
- mutate invoices
- recalculate balances directly
- modify attendance records
- promote students
- update communication status
- create domain records
```

If a report needs a calculated value, it must come from a domain read model or calculation service owned by that domain.

### 4.3 Reports must not duplicate business logic

Reporting must consume:

```text
Finance BalanceCalculator/read model
Attendance summary read model
Student lifecycle read model
Communication delivery read model
```

Forbidden:

```text
A report writing its own invoice balance calculation
A report counting attendance differently from AttendanceService
A report deciding promotion eligibility
A report inferring communication delivery status from provider payloads directly
```

That is how dashboards become folklore.

### 4.4 Islamic Sunday School reports must live in extension layer

Core reports may use neutral concepts:

```text
student
guardian
household
enrollment
assignment
attendance session
finance balance
communication delivery
program
group
level
```

Islamic Sunday School reports may use extension concepts:

```text
Qur'an level
Arabic level
Islamic studies track
halaqa
masjid family/community
Sunday program
volunteer team
```

Core must not import or hardcode those concepts.

### 4.5 Report exports must be auditable

Every export must log:

```text
who exported
what report
filters used
record count
format
timestamp
school context
```

Exports often contain sensitive student, guardian, finance, or attendance data. Treat exports like controlled data access, not “just a CSV,” because CSV files are how private data escapes wearing business casual.

---

## 5. Core Contracts

### 5.1 `ReportRegistryContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;

interface ReportRegistryContract
{
    /**
     * @return ReportDefinitionContract[]
     */
    public function availableReports(SchoolContext $context): array;

    public function get(string $reportKey): ReportDefinitionContract;

    public function register(ReportDefinitionContract $definition): void;
}
```

### 5.2 `ReportDefinitionContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

interface ReportDefinitionContract
{
    public function key(): string;

    public function name(): string;

    public function category(): ReportCategory;

    public function filters(): array;

    public function columns(): array;

    public function supportedFormats(): array;

    public function visibility(): ReportVisibility;
}
```

### 5.3 `ReportRunnerContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;
use App\Domain\SchoolCore\Reporting\DTO\ReportRequestData;

interface ReportRunnerContract
{
    public function run(SchoolContext $context, ReportRequestData $data): ReportResult;
}
```

### 5.4 `ReportAuthorizationPolicyContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;

interface ReportAuthorizationPolicyContract
{
    public function canViewReport(
        SchoolContext $context,
        ReportDefinitionContract $report
    ): bool;

    public function canExportReport(
        SchoolContext $context,
        ReportDefinitionContract $report
    ): bool;

    public function filterAllowedColumns(
        SchoolContext $context,
        ReportDefinitionContract $report,
        array $columns
    ): array;
}
```

### 5.5 `ReportExportServiceContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;
use App\Domain\SchoolCore\Reporting\DTO\ReportExportData;

interface ReportExportServiceContract
{
    public function export(SchoolContext $context, ReportExportData $data): ReportExportResult;
}
```

### 5.6 `ReportSnapshotServiceContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;

interface ReportSnapshotServiceContract
{
    public function createSnapshot(
        SchoolContext $context,
        ReportResult $result
    ): ReportSnapshotResult;

    public function getSnapshot(
        SchoolContext $context,
        string $snapshotId
    ): ReportSnapshotView;
}
```

### 5.7 `ScheduledReportServiceContract`

```php
namespace App\Domain\SchoolCore\Reporting\Contracts;

use App\Domain\SchoolCore\Shared\Context\SchoolContext;
use App\Domain\SchoolCore\Reporting\DTO\ScheduledReportData;

interface ScheduledReportServiceContract
{
    public function schedule(SchoolContext $context, ScheduledReportData $data): ScheduledReportResult;

    public function cancel(SchoolContext $context, int $scheduleId): ScheduledReportResult;
}
```

---

## 6. DTO Requirements

Do not pass raw request arrays into reporting services.

### 6.1 `ReportRequestData`

Fields:

```text
report_key
filters
columns, nullable
sorts, nullable
page, nullable
per_page, nullable
include_totals, default false
timezone, nullable
locale, nullable
snapshot, default false
metadata, nullable
```

### 6.2 `ReportFilterData`

Fields:

```text
field
operator
value
value_to, nullable
required, bool
```

Supported operators should be explicit:

```text
equals
not_equals
in
not_in
between
date_between
contains
starts_with
is_null
is_not_null
```

### 6.3 `ReportExportData`

Fields:

```text
report_key
filters
columns, nullable
format
snapshot_id, nullable
filename, nullable
include_sensitive_columns, default false
idempotency_key, nullable
metadata, nullable
```

### 6.4 `ScheduledReportData`

Fields:

```text
report_key
filters
columns, nullable
format
frequency
run_at
recipient_user_ids
recipient_emails, nullable if policy allows
expires_at, nullable
metadata, nullable
```

### 6.5 `ReportResultData`

Fields:

```text
report_key
columns
rows
totals, nullable
page, nullable
per_page, nullable
total_rows, nullable
generated_at
snapshot_id, nullable
warnings, nullable array
```

---

## 7. Report Categories

Core report categories:

```text
students
guardians
enrollment
attendance
finance
communication
staff
operations
audit
```

Islamic Sunday School extension categories:

```text
quran
arabic
islamic_studies
halaqa
program_attendance
masjid_family
volunteer_programs
```

These extension categories may appear in the registry only when the `islamic_sunday_school` domain profile is active or when the extension provider is installed and authorized.

---

## 8. Report Registry Strategy

### 8.1 Core registry

The registry must support:

```text
core reports
extension reports
visibility filtering
authorization filtering
school/domain profile filtering
```

### 8.2 Registration flow

Core provider registers core reports:

```php
$this->app->tag([
    StudentRosterReport::class,
    AttendanceSummaryReport::class,
    InvoiceSummaryReport::class,
    MessageDeliveryReport::class,
], 'schoolcore.reports');
```

Islamic Sunday School provider registers extension reports:

```php
$this->app->tag([
    QuranProgressReport::class,
    ArabicLevelReport::class,
    IslamicStudiesProgressReport::class,
    HalaqaAttendanceReport::class,
    MasjidFamilySummaryReport::class,
], 'schoolcore.reports');
```

### 8.3 Registry rules

```text
- Report keys must be globally unique.
- Extension report keys should be prefixed.
- Report definitions must declare required permissions.
- Registry must filter unavailable extension reports by domain profile.
```

Example keys:

```text
students.roster
attendance.summary
finance.outstanding_balance
communication.delivery
islamic.quran_progress
islamic.arabic_level
islamic.halaqa_attendance
islamic.masjid_family_summary
```

---

## 9. Read Model Strategy

Reports should query read models instead of raw operational tables wherever practical.

### 9.1 Core read models

Required read model contracts or repositories:

```text
StudentReportReadModel
AttendanceReportReadModel
FinanceReportReadModel
CommunicationReportReadModel
StaffReportReadModel
```

### 9.2 Extension read models

Islamic Sunday School read models:

```text
QuranProgressReadModel
ArabicProgressReadModel
IslamicStudiesProgressReadModel
HalaqaReportReadModel
MasjidFamilyReportReadModel
```

### 9.3 Read model rules

```text
- every query must include school_id from SchoolContext
- every date filter must respect context timezone
- sensitive columns require explicit authorization
- reports must not join extension tables unless inside extension report/read model
- totals must match owning domain calculation services
```

---

## 10. Core Reports

### 10.1 Student roster report

Purpose:

```text
List active students by school, enrollment, assignment, guardian summary, and status.
```

Must support filters:

```text
academic_year
term
program
group/class
status
enrollment_status
age range
guardian contact availability
```

Must not include by default:

```text
sensitive notes
medical data
religious extension fields
finance balance
```

### 10.2 Guardian contact report

Purpose:

```text
List guardian contact information according to authorization and communication policy.
```

Required protections:

```text
mask contact fields where policy requires
respect guardian relationship visibility
exclude restricted contacts
audit exports
```

### 10.3 Attendance summary report

Purpose:

```text
Show attendance counts and rates by session/date/group/student/staff.
```

Must consume:

```text
SchoolCore\Attendance read model
```

Must not:

```text
recalculate duplicate scan behavior
invent status mappings
count raw scan logs as attendance records
```

### 10.4 Finance outstanding balance report

Purpose:

```text
Show outstanding balances by student/guardian/invoice.
```

Must consume:

```text
SchoolCore\Finance read model or BalanceCalculator output
```

Must not:

```text
calculate balances using ad hoc SQL
ignore refunds/reversals
show finance fields to unauthorized actors
```

### 10.5 Communication delivery report

Purpose:

```text
Show message delivery status, excluded recipients, failed deliveries, and retry state.
```

Must consume:

```text
SchoolCore\Communication delivery read model
```

Must not:

```text
query provider payloads directly outside the delivery status model
```

---

## 11. Islamic Sunday School Reports

### 11.1 Qur’an progress report

Purpose:

```text
Track Qur’an level, memorization progress summary, recitation placement, teacher/group, and progress status.
```

Rules:

```text
- lives in IslamicSundaySchool\Reporting
- reads from IslamicSundaySchool student/curriculum read models
- must be school-scoped
- sensitive notes require explicit permission
- may join core student/enrollment read models through contracts
```

### 11.2 Arabic level report

Purpose:

```text
Track Arabic level placement, progress, teacher/group, and placement changes.
```

Rules:

```text
- core only knows neutral level/program concepts
- extension maps Arabic-specific levels and labels
```

### 11.3 Islamic studies progress report

Purpose:

```text
Track Islamic studies track, class/group, completion status, and teacher evaluation summary.
```

Rules:

```text
- no religious-specific concepts in SchoolCore
- extension owns labels and calculations
```

### 11.4 Halaqa attendance report

Purpose:

```text
Show attendance by halaqa/group/session for Islamic Sunday School programs.
```

Rules:

```text
- attendance facts come from SchoolCore\Attendance
- halaqa/group mapping comes from IslamicSundaySchool extension
- duplicate scans must not inflate counts
```

### 11.5 Masjid family/community summary report

Purpose:

```text
Summarize students and guardians by masjid family/community profile, household, volunteer participation, and program enrollment.
```

Rules:

```text
- contact information must obey guardian/communication policies
- sensitive family/community notes require strict permission
```

### 11.6 Volunteer team report

Purpose:

```text
Show volunteer/program team members, assigned sessions, attendance, and communication status.
```

Rules:

```text
- volunteers should map to neutral staff/volunteer subject types in core
- extension owns Islamic Sunday School labels and grouping
```

---

## 12. Report Authorization

Minimum report permissions:

```text
report.view
report.export
report.schedule
report.audit.view
report.students.view
report.guardians.view
report.attendance.view
report.finance.view
report.communication.view
report.staff.view
report.sensitive.view
```

Islamic Sunday School extension permissions:

```text
report.islamic.quran.view
report.islamic.arabic.view
report.islamic.studies.view
report.islamic.halaqa.view
report.islamic.masjid_family.view
report.islamic.volunteer.view
report.islamic.sensitive_notes.view
```

Every report must define:

```text
required permission
allowed roles
sensitive columns
export permission
school/domain profile availability
```

Every report endpoint must test:

```text
unauthenticated
wrong school
wrong role
wrong domain profile
allowed admin
allowed staff
teacher assigned-scope view, if supported
guardian own-student view, if supported
export denied when view-only
```

---

## 13. Sensitive Data Rules

Reports may expose sensitive data accidentally because tables are easy to join and humans are easy to disappoint.

Sensitive categories:

```text
student personal data
guardian contact data
finance balances/payments
attendance history
communication delivery logs
sensitive imam/admin notes
scholarship/sadaqah support indicators
discipline/behavior notes, if present
medical data, if ever supported
```

Rules:

```text
- sensitive columns require explicit permission
- export requires stronger permission than view
- exports must be audited
- reports should mask fields by default where practical
- snapshots containing sensitive fields must have retention rules
```

---

## 14. Export Strategy

Supported formats:

```text
csv
xlsx
pdf, optional
json, internal/admin only if allowed
```

Export requirements:

```text
- use ReportExportServiceContract
- validate format against report definition
- include generated_at and school context metadata
- include filters used
- use safe filenames
- store or stream based on policy
- audit every export
```

Export filename format:

```text
{school_slug}_{report_key}_{date}_{snapshot_id}.{format}
```

Example:

```text
al-noor_islamic.quran_progress_2026-05-29_ab12cd.xlsx
```

### 14.1 Export retention

Define per report:

```text
not stored / streamed only
stored for 24 hours
stored for 7 days
stored until manually deleted
```

Sensitive exports should default to short retention.

---

## 15. Report Snapshots

### 15.1 Why snapshots exist

Snapshots preserve what the user saw at the time of generation.

Required for:

```text
bulk communication recipient previews
finance reports used for reconciliation
attendance reports used for official records
scheduled reports
exports
```

### 15.2 Snapshot fields

Suggested table:

```text
report_snapshots
```

Fields:

```text
id
school_id
actor_user_id
report_key
filters_json
columns_json
result_summary_json
snapshot_storage_path, nullable
sensitive_data_flag
expires_at, nullable
created_at
```

### 15.3 Snapshot rules

```text
- snapshots must be school-scoped
- sensitive snapshots require retention policy
- snapshot access must re-check authorization
- snapshots should not bypass current permission rules
```

---

## 16. Scheduled Reports

Scheduled reports are useful and dangerous, the perfect combination for a feature request.

Required behavior:

```text
- schedule owner must have report.schedule permission
- recipients must be authorized to receive the report
- every scheduled run resolves fresh SchoolContext
- every scheduled run creates audit log
- delivery uses Communication module where possible
- sensitive reports require explicit recipient validation
```

Do not email finance or student-sensitive exports to arbitrary addresses without policy approval.

---

## 17. Caching Strategy

Reports may be cached only when safe.

Cache key must include:

```text
school_id
academic_year_id
term_id, nullable
actor permission scope
report_key
filters
columns
locale
timezone
```

Rules:

```text
- do not share cached sensitive reports across actors unless policy allows
- invalidate finance reports after finance mutation
- invalidate attendance reports after attendance mutation
- invalidate student reports after lifecycle mutation
- invalidate communication reports after delivery status update
```

If cache correctness is hard to prove, do not cache. Slow truth beats fast lies, a lesson dashboards learn only after leadership screenshots them.

---

## 18. Audit Logging Requirements

Every report action must create an audit event.

Required audit fields:

```text
school_id
academic_year_id, nullable
term_id, nullable
actor_user_id
actor_role_snapshot
action
report_key
entity_type, nullable
entity_id, nullable
filters_json, nullable
columns_json, nullable
format, nullable
row_count, nullable
sensitive_data_flag
request_id
ip_address, nullable
user_agent, nullable
created_at
```

Required actions:

```text
report.viewed
report.exported
report.snapshot.created
report.snapshot.viewed
report.scheduled
report.schedule.cancelled
report.schedule.failed
```

Audit logs are append-only.

---

## 19. FormRequest Requirements

Create or update:

```text
RunReportRequest
ExportReportRequest
ScheduleReportRequest
CancelScheduledReportRequest
ViewReportSnapshotRequest
ListReportsRequest
```

Each FormRequest must define:

```text
authorize()
rules()
messages(), if needed
toDTO(), optional but recommended
```

Controllers should use:

```php
$data = $request->toDTO();
```

Not raw request array merging, because apparently arrays with no boundaries are still the default foot-gun.

---

## 20. Controller Target Shape

Target flow:

```text
ReportController
  -> RunReportRequest
  -> SchoolContext
  -> ReportRequestData
  -> ReportRunnerContract::run()
  -> ReportResource
```

Export flow:

```text
ReportExportController
  -> ExportReportRequest
  -> SchoolContext
  -> ReportExportData
  -> ReportExportServiceContract::export()
  -> file response or export resource
```

Controllers may not:

```text
- build raw report SQL
- authorize only by logged-in status
- expose all columns by default
- export without audit
- call extension reports directly by concrete class
```

---

## 21. Migration Strategy

### 21.1 Use vertical slices

Recommended order:

```text
1. Report registry and definitions
2. Report authorization policy
3. Student roster report
4. Attendance summary report
5. Finance outstanding balance report
6. Communication delivery report
7. Export service
8. Report snapshots
9. Islamic Sunday School extension reports
10. Scheduled reports and caching
```

Why this order:

```text
- registry creates the seam
- authorization prevents report leaks
- student/attendance/finance/communication reports validate read-model integration
- exports need audit and retention before broad use
- Islamic reports should extend proven core mechanisms
- scheduling/caching comes last because stale scheduled sensitive exports are a very stupid way to create an incident
```

### 21.2 Compatibility layer

Existing report controllers may remain temporarily, but must delegate to new contracts.

Example:

```text
LegacyReportController
  -> RunReportRequest
  -> SchoolContext
  -> ReportRunnerContract
```

Legacy report methods must be labeled:

```text
canonical
adapter
deprecated
remove
```

No unlabeled duplicate report logic.

---

## 22. First Implementation Slice: Report Registry

### Objective

Create the report registry and define report metadata.

### Tasks

```text
REP-001. Create Reporting module scaffold.
REP-002. Create ReportDefinitionContract.
REP-003. Create ReportRegistryContract.
REP-004. Implement ReportRegistry.
REP-005. Add report provider tagging.
REP-006. Register initial core report definitions.
REP-007. Add tests for registry lookup and availability filtering.
```

### Required tests

```text
- lists available reports
- returns report by key
- rejects unknown report key
- filters reports by permission
- filters extension reports by domain profile
- report keys are unique
```

### Done when

```text
- reports are discoverable through registry
- Islamic Sunday School reports can register without core imports
```

---

## 23. Second Implementation Slice: Report Authorization

### Objective

Prevent report data leakage before adding more reports.

### Tasks

```text
REP-008. Create ReportAuthorizationPolicyContract.
REP-009. Implement default policy.
REP-010. Add column-level authorization.
REP-011. Add export-specific authorization.
REP-012. Add sensitive data flagging.
```

### Required tests

```text
- unauthenticated user cannot view reports
- wrong-school user cannot view report
- view-only user cannot export
- sensitive columns are removed without permission
- Islamic report unavailable outside Islamic Sunday School profile
```

### Done when

```text
- every report requires explicit permission
- export permission is separate from view permission
```

---

## 24. Third Implementation Slice: Student Roster Report

### Objective

Create a reusable core student roster report.

### Tasks

```text
REP-013. Create StudentReportReadModel.
REP-014. Create StudentRosterReport.
REP-015. Add filters for status, enrollment, group, academic year, term.
REP-016. Add report result resource.
REP-017. Add tests for school scoping and field permissions.
```

### Required tests

```text
- returns active students in school
- excludes other schools
- filters by enrollment status
- filters by group/class
- guardian contact fields follow permission policy
- archived students excluded by default
```

### Done when

```text
- student roster report uses read model
- no student lifecycle rules are duplicated in the report
```

---

## 25. Fourth Implementation Slice: Attendance Summary Report

### Objective

Create core attendance reporting from attendance read models.

### Tasks

```text
REP-018. Create AttendanceReportReadModel.
REP-019. Create AttendanceSummaryReport.
REP-020. Add filters by date range, session, group, subject type.
REP-021. Ensure duplicate scan logs do not inflate attendance.
REP-022. Add tests against AttendanceService/read-model truth.
```

### Required tests

```text
- attendance count matches Attendance module
- duplicate scans are not double-counted
- filters by session/date range
- excludes other schools
- status counts use canonical statuses
```

### Done when

```text
- attendance reports do not query raw scan logs as source of truth
```

---

## 26. Fifth Implementation Slice: Finance Outstanding Balance Report

### Objective

Create core finance reporting from finance read models.

### Tasks

```text
REP-023. Create FinanceReportReadModel.
REP-024. Create OutstandingBalanceReport.
REP-025. Pull balances from Finance read model/BalanceCalculator output.
REP-026. Add filters by student, guardian, status, date range.
REP-027. Add export-sensitive authorization.
```

### Required tests

```text
- balance matches Finance module calculation
- refunds/reversals are reflected correctly
- finance data hidden from unauthorized role
- excludes other schools
- export is audited
```

### Done when

```text
- finance report does not duplicate invoice balance logic
```

---

## 27. Sixth Implementation Slice: Communication Delivery Report

### Objective

Create core communication delivery reporting.

### Tasks

```text
REP-028. Create CommunicationReportReadModel.
REP-029. Create MessageDeliveryReport.
REP-030. Add filters by channel, status, category, date range.
REP-031. Include excluded recipient counts.
REP-032. Add delivery failure summaries.
```

### Required tests

```text
- shows sent/delivered/failed/excluded counts
- filters by channel
- excludes other schools
- hides recipient details without permission
- matches Communication module delivery logs
```

### Done when

```text
- delivery report consumes Communication read model
```

---

## 28. Seventh Implementation Slice: Export Service

### Objective

Create safe, auditable report exports.

### Tasks

```text
REP-033. Create ReportExportServiceContract.
REP-034. Implement CSV export.
REP-035. Implement XLSX export if required.
REP-036. Add safe filename builder.
REP-037. Add export audit logs.
REP-038. Add retention policy.
```

### Required tests

```text
- exports allowed report
- rejects unauthorized export
- rejects unsupported format
- masks/excludes sensitive columns
- writes report.exported audit log
- generated file name is safe
```

### Done when

```text
- exports go through ReportExportService
- export access is audited
```

---

## 29. Eighth Implementation Slice: Report Snapshots

### Objective

Preserve report results for exports, audits, and scheduled reports.

### Tasks

```text
REP-039. Create ReportSnapshotServiceContract.
REP-040. Create report_snapshots table/model.
REP-041. Store snapshot metadata and result reference.
REP-042. Add snapshot authorization.
REP-043. Add retention behavior.
```

### Required tests

```text
- creates snapshot
- retrieves snapshot in same school
- rejects snapshot from another school
- re-checks authorization on access
- expires snapshot according to policy
```

### Done when

```text
- report snapshots are school-scoped and permission-checked
```

---

## 30. Ninth Implementation Slice: Islamic Sunday School Reports

### Objective

Add Islamic Sunday School-specific reporting through extension reports and read models.

### Tasks

```text
REP-044. Create IslamicSundaySchool Reporting namespace.
REP-045. Create QuranProgressReport.
REP-046. Create ArabicLevelReport.
REP-047. Create IslamicStudiesProgressReport.
REP-048. Create HalaqaAttendanceReport.
REP-049. Create MasjidFamilySummaryReport.
REP-050. Register reports through IslamicSundaySchoolReportingServiceProvider.
```

### Required tests

```text
- Islamic reports only available for islamic_sunday_school profile
- Qur'an report excludes other schools
- Arabic report uses extension read model
- Halaqa attendance report uses Attendance read model facts
- Masjid family report respects contact permissions
- SchoolCore does not import IslamicSundaySchool reporting classes
```

### Done when

```text
- Islamic Sunday School reports extend registry without core changes
```

---

## 31. Tenth Implementation Slice: Scheduled Reports and Caching

### Objective

Add scheduled report support and safe caching after core reporting is stable.

### Tasks

```text
REP-051. Create ScheduledReportServiceContract.
REP-052. Create scheduled_reports table/model.
REP-053. Add scheduled report job.
REP-054. Add authorized recipient validation.
REP-055. Add ReportCacheServiceContract.
REP-056. Add cache invalidation hooks.
```

### Required tests

```text
- schedules allowed report
- rejects unauthorized schedule
- scheduled run resolves SchoolContext
- scheduled run creates audit log
- sensitive report cannot be sent to unauthorized recipient
- cache key includes school and permission scope
```

### Done when

```text
- scheduled reports are safe enough to exist
- caching cannot cross permission/school boundaries
```

---

## 32. Database and Schema Requirements

### 32.1 Required indexes

Add or verify:

```text
report_snapshots.school_id indexed
report_snapshots.actor_user_id indexed
report_snapshots.report_key indexed
report_snapshots.expires_at indexed
report_snapshots.created_at indexed

scheduled_reports.school_id indexed
scheduled_reports.actor_user_id indexed
scheduled_reports.report_key indexed
scheduled_reports.next_run_at indexed
scheduled_reports.status indexed

report_audit_logs.school_id indexed
report_audit_logs.actor_user_id indexed
report_audit_logs.report_key indexed
report_audit_logs.created_at indexed
```

### 32.2 Recommended unique constraints

```text
unique(school_id, report_key, actor_user_id, idempotency_key) where idempotency_key is not null
unique(school_id, scheduled_report_name) if user-defined names are supported
```

---

## 33. Service Provider Bindings

Create:

```php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Domain\SchoolCore\Reporting\Contracts\ReportRunnerContract;
use App\Domain\SchoolCore\Reporting\Services\ReportRunner;

final class SchoolCoreReportingServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(ReportRegistryContract::class, ReportRegistry::class);
        $this->app->bind(ReportRunnerContract::class, ReportRunner::class);
        $this->app->bind(ReportAuthorizationPolicyContract::class, DefaultReportAuthorizationPolicy::class);
        $this->app->bind(ReportExportServiceContract::class, ReportExportService::class);
        $this->app->bind(ReportSnapshotServiceContract::class, ReportSnapshotService::class);
        $this->app->bind(ScheduledReportServiceContract::class, ScheduledReportService::class);
        $this->app->bind(ReportAuditLoggerContract::class, ReportAuditLogger::class);
        $this->app->bind(ReportCacheServiceContract::class, ReportCacheService::class);

        $this->app->tag([
            StudentRosterReport::class,
            GuardianContactReport::class,
            AttendanceSummaryReport::class,
            OutstandingBalanceReport::class,
            MessageDeliveryReport::class,
        ], 'schoolcore.reports');
    }
}
```

Islamic Sunday School provider:

```php
final class IslamicSundaySchoolReportingServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->tag([
            QuranProgressReport::class,
            ArabicLevelReport::class,
            IslamicStudiesProgressReport::class,
            HalaqaAttendanceReport::class,
            MasjidFamilySummaryReport::class,
            VolunteerTeamReport::class,
        ], 'schoolcore.reports');
    }
}
```

---

## 34. Architecture Tests

Add tests that fail if reporting boundaries are violated.

Required assertions:

```text
SchoolCore\Reporting must not depend on Domain\IslamicSundaySchool
SchoolCore\Reporting must not depend on Illuminate\Http\Request
SchoolCore\Reporting services must not call auth()
SchoolCore\Reporting services must not call request()
Controllers must not instantiate report concrete classes directly
Report controllers must call ReportRunnerContract or ReportExportServiceContract
Core report contracts must not contain Islamic Sunday School vocabulary
Reports must include SchoolContext
Exports must go through ReportExportServiceContract
```

Optional static checks:

```text
No direct finance balance calculation in reports
No raw attendance scan-log counting as attendance result
No report export without audit log
No scheduled report to arbitrary email without policy
No extension report registered from SchoolCore provider
```

---

## 35. Rollout Plan

### Step 1: Add reporting module scaffolding

```text
- create namespaces
- create contracts
- create DTOs
- create provider
- create registry
```

### Step 2: Add report authorization

```text
- view/export permissions
- sensitive column filtering
- school context enforcement
```

### Step 3: Migrate student roster

```text
- low-risk read-only core report
- proves registry/read model/resource flow
```

### Step 4: Migrate attendance summary

```text
- prove attendance read model integration
- prevent duplicate scan inflation
```

### Step 5: Migrate finance outstanding balance

```text
- prove finance read model integration
- protect sensitive finance fields
```

### Step 6: Migrate communication delivery

```text
- prove communication logs/read models
```

### Step 7: Add export service

```text
- CSV/XLSX
- audit
- retention
```

### Step 8: Add snapshots

```text
- stable exports
- audit support
```

### Step 9: Add Islamic Sunday School reports

```text
- Qur'an, Arabic, Islamic studies, halaqa, masjid family/community
- extension-only concepts remain outside core
```

### Step 10: Add scheduled reports and caching

```text
- only after authorization/export behavior is stable
```

---

## 36. Implementation Tickets

## REP-001: Create reporting module scaffold

### Description

Create the `SchoolCore\Reporting` namespace and initial contracts, DTO folders, report folders, read model folders, services, exceptions, enums, and provider.

### Acceptance Criteria

```text
- Namespace exists.
- Service provider is registered.
- Empty contracts compile.
- No controller behavior changes yet.
```

---

## REP-002: Add report registry

### Description

Create report registration and discovery system.

### Acceptance Criteria

```text
- Reports can be registered by provider.
- Reports can be fetched by key.
- Duplicate keys fail.
- Islamic Sunday School reports can register through extension provider.
```

---

## REP-003: Add report authorization policy

### Description

Add report view/export/column-level authorization.

### Acceptance Criteria

```text
- View and export are separate permissions.
- Sensitive columns are filtered.
- Wrong-school access fails.
- Extension reports filtered by domain profile.
```

---

## REP-004: Create student roster report

### Description

Create first core report using student read model.

### Acceptance Criteria

```text
- School-scoped.
- Filters by status/enrollment/group.
- Excludes archived students by default.
- Does not expose restricted guardian data.
```

---

## REP-005: Create attendance summary report

### Description

Create attendance report using attendance read model.

### Acceptance Criteria

```text
- Counts match Attendance module.
- Duplicate scans do not inflate counts.
- Canonical attendance statuses are used.
- Cross-school data is excluded.
```

---

## REP-006: Create finance outstanding balance report

### Description

Create finance report using finance read model.

### Acceptance Criteria

```text
- Balances match Finance module.
- Refunds/reversals are reflected.
- Unauthorized finance access fails.
- Export is audited.
```

---

## REP-007: Create communication delivery report

### Description

Create delivery report using communication read model.

### Acceptance Criteria

```text
- Shows sent/delivered/failed/excluded counts.
- Filters by channel/status/category/date.
- Hides recipient details without permission.
```

---

## REP-008: Add export service

### Description

Create safe CSV/XLSX export flow.

### Acceptance Criteria

```text
- Export requires permission.
- Unsupported formats fail.
- Sensitive columns are filtered.
- Export audit log is written.
- Safe filename is generated.
```

---

## REP-009: Add report snapshots

### Description

Create report snapshot storage and access controls.

### Acceptance Criteria

```text
- Snapshot is school-scoped.
- Snapshot access re-checks authorization.
- Sensitive snapshots follow retention rule.
```

---

## REP-010: Add Islamic Sunday School reports

### Description

Add Qur'an, Arabic, Islamic studies, halaqa, and masjid family/community reports as extension reports.

### Acceptance Criteria

```text
- Reports are registered by IslamicSundaySchool provider.
- Reports only available for islamic_sunday_school profile.
- SchoolCore does not import IslamicSundaySchool classes.
- Sensitive extension fields require explicit permission.
```

---

## REP-011: Add scheduled reports and caching

### Description

Add scheduled report execution and safe caching.

### Acceptance Criteria

```text
- Scheduled runs resolve SchoolContext.
- Recipients are authorized.
- Audit log is written.
- Cache key includes school and permission scope.
- Sensitive reports are not shared across actors incorrectly.
```

---

## REP-012: Add reporting architecture tests

### Description

Enforce reporting module boundaries in CI.

### Acceptance Criteria

```text
- SchoolCore\Reporting cannot import IslamicSundaySchool.
- Reporting services cannot call auth() or request().
- Core contracts contain no Islamic Sunday School vocabulary.
- Reports cannot export without audit.
- CI fails on boundary violation.
```

---

## 37. Definition of Done for Phase 7

Phase 7 is done when:

```text
- Reporting core contracts exist.
- Report registry exists.
- Report authorization policy exists.
- Student roster report uses read model.
- Attendance summary report uses Attendance read model.
- Finance outstanding balance report uses Finance read model.
- Communication delivery report uses Communication read model.
- Export service is auditable and permission-controlled.
- Report snapshots are school-scoped and permission-checked.
- Islamic Sunday School reports live in extension layer.
- Scheduled reports resolve SchoolContext and validate recipients.
- Report caching cannot cross school or permission boundaries.
- Architecture tests prevent SchoolCore from depending on IslamicSundaySchool.
- Legacy report methods are labeled canonical, adapter, deprecated, or remove.
```

---

## 38. Non-Goals

Do not include in Phase 7:

```text
- full BI/data warehouse platform
- drag-and-drop report builder
- public analytics dashboards
- machine learning predictions
- advanced charting library migration
- full PDF design system
- external accounting export suite
- parent-facing report portal redesign
```

Those can come later. Phase 7 is about trustworthy, scoped, reusable reporting. Fancy charts can wait until the numbers stop lying.

---

## 39. Main Risks

### Risk: reports duplicate business logic

Mitigation:

```text
- read model contracts
- domain-owned calculation services
- architecture/static checks
```

### Risk: cross-school data leakage

Mitigation:

```text
- mandatory SchoolContext
- school-scoped read repositories
- wrong-school tests
```

### Risk: sensitive export leakage

Mitigation:

```text
- export authorization
- sensitive column filtering
- audit logs
- retention policy
```

### Risk: Islamic Sunday School leakage into core

Mitigation:

```text
- extension reports
- architecture tests
- neutral core vocabulary
```

### Risk: stale cached reports

Mitigation:

```text
- permission-aware cache keys
- domain mutation invalidation
- disable caching when correctness is unclear
```

### Risk: scheduled reports sent to wrong recipients

Mitigation:

```text
- recipient authorization validation
- Communication module integration
- audit every scheduled run
```

---

## 40. Immediate Next Work Queue

Start here:

```text
1. REP-001 Create reporting module scaffold
2. REP-002 Add report registry
3. REP-003 Add report authorization policy
4. REP-004 Create student roster report
5. REP-005 Create attendance summary report
6. REP-006 Create finance outstanding balance report
7. REP-007 Create communication delivery report
8. REP-008 Add export service
9. REP-009 Add report snapshots
10. REP-010 Add Islamic Sunday School reports
11. REP-012 Add reporting architecture tests
12. REP-011 Add scheduled reports and caching
```

Do not start with PDF styling, charts, dashboards, or executive summary sparkle. First make the numbers correct, scoped, authorized, and auditable. Then the graphs can wear a little hat.
