Configure Supabase Storage bucket for Bufdir exports
epic-bufdir-reporting-export-foundation-task-003 — Create and configure a dedicated Supabase Storage bucket named 'bufdir-exports' with org-scoped path structure (/{org_id}/{year}/{export_id}/). Set bucket to private, configure MIME type restrictions to Excel, CSV, and PDF, and define maximum file size limits. Document the path convention for downstream consumers.
Acceptance Criteria
Technical Requirements
Implementation Notes
Supabase bucket configuration (allowed MIME types, file size limits) can be set either via the dashboard or programmatically using the Supabase Management API or a seed script. Prefer a seed/migration script for reproducibility across environments. RLS on storage.objects uses path-based policies — the policy expression should use (storage.foldername(name))[1] = auth.jwt()->>'org_id' or equivalent to match the first path segment. The year segment in the path (/{org_id}/{year}/{export_id}/) is derived from the export's period_start year at upload time — document this derivation rule explicitly.
Export filenames should include the org_id and period for human readability: e.g. nhf_2024_Q4_{export_id}.xlsx. Confirm the 50 MB limit is sufficient for the largest expected Bufdir export (HLF had ~380 individual activity records per year per person — multiply by expected number of peer mentors).
Testing Requirements
No automated flutter_test needed for bucket creation itself. Provide a manual smoke-test checklist: (1) create bucket via migration/script on local Supabase and verify it appears in storage dashboard; (2) upload xlsx file to valid path with service role — expect 200; (3) upload json file to valid path — expect 400/415; (4) upload to another org's path with a user JWT — expect 403; (5) list objects under own org path with user JWT — expect only own files. Include these steps in the task PR description so the reviewer can run them.
RLS policies for the audit log and schema config tables must correctly handle multi-chapter membership hierarchies (up to 1,400 local chapters for NHF). Incorrect policies could either over-expose data across organisations or prevent legitimate coordinator access, both of which are serious compliance failures.
Mitigation & Contingency
Mitigation: Design RLS policies using the existing org hierarchy resolver pattern. Write integration tests that verify cross-organisation isolation with representative fixture data covering NHF's multi-level hierarchy before merging.
Contingency: If RLS policies prove too complex to express safely in Postgres, implement a Supabase Edge Function as a data access proxy that enforces isolation in application code, with RLS serving as a secondary defence layer.
Bufdir's column schema is expected to evolve as Norse Digital Products negotiates a simplified digital reporting format. If the schema config versioning model is too rigid, applying Bufdir schema updates without a code deployment could fail, forcing emergency releases.
Mitigation & Contingency
Mitigation: Design the schema config table to store the full JSON column mapping as a JSONB field with a version number. Provide an admin API to upsert new versions without any schema migration required.
Contingency: If the versioning model is insufficient for a Bufdir schema change, fall back to a code deployment with the updated default schema, using the database config only for org-specific overrides.