Report Period
Data Entity
Description
Configuration entity defining the start and end dates of a Bufdir reporting period for an organization. Organizations may have different period definitions, and periods scope the activity aggregation window for report generation.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Unique identifier for the reporting period record. | PKrequiredunique |
organization_id |
uuid |
Foreign key referencing the organization that owns and defines this reporting period. Each organization manages its own period boundaries independently. | required |
label |
string |
Human-readable display name for the period shown in the UI selector, e.g. '2024 Annual Report', 'H1 2025', 'Q3 2024'. Used in Report Period Selector Widget dropdown. | required |
period_start |
datetime |
Inclusive start date of the reporting window. Activities on or after this date are included in aggregation for this period. Stored as UTC date with time zeroed to midnight. | required |
period_end |
datetime |
Inclusive end date of the reporting window. Activities on or before this date are included in aggregation. Stored as UTC end-of-day (23:59:59) for inclusive range queries. | required |
period_type |
enum |
Categorizes the period granularity for display grouping and Bufdir schema compliance. Determines how the period is labeled and validated. | required |
year |
integer |
Calendar year this period primarily belongs to, derived from period_start. Used for grouping periods in the selector widget and for Bufdir report year attribution. Must match the year component of period_start. | required |
is_locked |
boolean |
Indicates whether this period is locked from modification. A period becomes locked once a finalized bufdir_report references it. Locked periods cannot have their dates or label changed. | required |
status |
enum |
Lifecycle status of the period. 'draft' periods are being configured, 'active' periods accept report generation, 'closed' periods have passed their end date, 'locked' periods have at least one finalized report submission. | required |
bufdir_schema_version |
string |
Bufdir reporting schema version this period's reports must conform to. Enables the system to generate exports in the correct schema format as Bufdir updates their API. Defaults to the current active schema version. | - |
notes |
text |
Optional internal coordinator notes about this reporting period, such as special instructions or deviations from standard configuration. Not included in Bufdir exports. | - |
created_by |
uuid |
User ID of the admin or coordinator who created this period definition. Used for audit trail. | required |
created_at |
datetime |
Timestamp when the period record was created. Set automatically on insert. | required |
updated_at |
datetime |
Timestamp of the last modification to this record. Updated automatically via trigger on any field change. | required |
Database Indexes
idx_report_periods_org_id
Columns: organization_id
idx_report_periods_org_year
Columns: organization_id, year
idx_report_periods_org_type_year
Columns: organization_id, period_type, year
idx_report_periods_status
Columns: status
idx_report_periods_period_range
Columns: organization_id, period_start, period_end
Validation Rules
period_end_after_period_start
error
Validation failed
year_matches_period_start
error
Validation failed
label_non_empty
error
Validation failed
organization_id_references_valid_org
error
Validation failed
period_start_not_in_future_for_active
warning
Validation failed
bufdir_schema_version_format
error
Validation failed
max_period_duration
error
Validation failed
Business Rules
no_overlapping_periods_per_org
No two report periods for the same organization may have overlapping date ranges. Overlap is defined as any case where a new period's start date falls within an existing period's range or vice versa. This ensures unambiguous activity attribution for Bufdir report generation.
locked_period_immutable
Once is_locked is set to true, no field on the record (period_start, period_end, label, period_type, status) may be modified. Locking occurs when a finalized bufdir_reports record references this period. Attempts to update a locked period must return an error.
period_locked_on_report_finalization
When a bufdir_reports record associated with this period transitions to a finalized or submitted status, this period's is_locked field must be set to true and status set to 'locked'. This is enforced via a Supabase database trigger or Edge Function hook on the bufdir_reports table.
no_delete_if_reports_reference
A report_period record cannot be deleted if one or more bufdir_reports rows reference it via the period_id foreign key. The cascade behavior must be RESTRICT, not CASCADE, to preserve report history integrity.
org_scoped_access
Users may only read or write report_period records belonging to their own organization. Supabase RLS policy must enforce this using auth.uid() mapped through user_organization_memberships to organization_id. Coordinators and admins within the org may read; only admins may create or modify.
unique_period_type_per_year_per_org
For period_type values 'annual' and 'semi_annual', only one period of each type may exist per organization per year. For 'annual', exactly one record per year per org. For 'semi_annual', a maximum of two records per year per org. This prevents accidental duplicate period definitions.
auto_status_close_on_end_date
When the current date surpasses period_end and the period is not yet locked, the status must transition from 'active' to 'closed'. This is evaluated lazily at read time or via a scheduled Edge Function to keep records consistent.
CRUD Operations
Storage Configuration
Entity Relationships
Each Bufdir report is generated for a specific defined reporting period
Each organization defines its own set of Bufdir reporting period boundaries