All new migrations are now embedded in post-deploy.sql (idempotent),
so they run automatically on `docker compose up` via the migrate container.
Both deploy/ and docker/migrate/ copies are kept in sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add deploy/post-deploy.sql: idempotent script that ensures storage
RLS policies, buckets, notifications table, and migration 017 are
applied on every deploy
- Add migrate service to docker-compose: one-shot container that runs
post-deploy.sql after storage-api creates its tables
- Add migrate command to deploy.sh with retry logic
- Fix studio/storage healthchecks (start_period, || exit 0)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix RLS policies: Add WITH CHECK clause to all FOR ALL policies
(fixes 502 errors on admin settings and other updates)
- Add /notifications page for users to view all notifications
- Add /admin/notifications page for admins to create/manage notifications
- Add notifications link to admin sidebar
- Fix NotificationCenter to use goto() for internal navigation
- Fix email.ts to fall back to environment variables for SMTP
(allows welcome emails to work when app_settings SMTP not configured)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Supabase postgres image includes a migrate.sh that tries to connect
as supabase_admin without proper credentials. Override it with an empty
script since migrations are handled by init.sql.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move GRANT statements for document_folders and user_notification_preferences
to after their respective CREATE TABLE statements. The grants were failing
because they referenced tables that hadn't been created yet.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix admin settings 502 error by adding INSERT/UPDATE/DELETE grants
- Fix Button component to render <a> when href prop is provided
- Add welcome email for admin created during initial setup
- Add in-app notifications system with NotificationCenter component
- Add notifications table with RLS policies and welcome trigger
- Add API endpoints for fetching and marking notifications as read
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
init.sql changes:
- Add INSERT grant for members table (for /join signup)
- Add INSERT grant for dues_payments (for board recording payments)
- Add full CRUD grants for events, documents, document_folders
- Add UPDATE grant for email_templates (admin management)
- Add anon role grants for public event viewing and RSVP creation
README changes:
- Add "Important Notes" section explaining dynamic env vars
- Add first-time setup and database initialization docs
- Add troubleshooting for 403 errors with grant fix commands
- Add troubleshooting for "account not configured" errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
RLS policies define WHAT rows can be accessed, but GRANT statements
control WHETHER a table can be accessed at all. This was causing 403
errors when authenticated users tried to access tables.
Added grants for:
- Core tables: members, membership_statuses, membership_types
- Dues: dues_payments (SELECT)
- Events: events, event_types, event_rsvps (full CRUD), event_rsvps_public
- Documents: documents, document_categories, document_folders
- Settings: app_settings (SELECT for public settings)
- Email: email_logs (SELECT for own logs)
- Preferences: user_notification_preferences (SELECT, INSERT, UPDATE)
- Views: members_with_dues, events_with_counts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These fields can be filled in later by the user. The admin setup page
only collects essential fields (name, email, password).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Supabase postgres image's internal migrate.sh requires supabase_admin
to have a password matching POSTGRES_PASSWORD. Added zz-set-passwords.sh
to run after init.sql and set passwords dynamically using the environment
variable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Supabase postgres image sets these passwords based on POSTGRES_PASSWORD.
Hardcoding 'postgres' caused the image's migrate.sh to fail.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- storage.objects and storage.buckets are created by storage-api service
- Wrapped all storage bucket inserts and policy operations in DO blocks
- Check if table exists before running storage operations
- Prevents errors during initial database setup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These functions are normally created by GoTrue but our init.sql
runs first. Needed for RLS policies that use auth.uid().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added GRANT ALL for service_role on:
- membership_statuses, membership_types, members tables
- All tables and sequences in public schema
- Default privileges for future tables
Fixes 'permission denied' errors during admin setup.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The auth.users table is created by GoTrue, not the database init.
FK constraints to auth.users fail because init.sql runs before auth starts.
Removed FK from members and audit_logs tables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- PostgREST and postgres-meta images don't have /bin/sh
- Removed CMD-SHELL healthchecks that were causing unhealthy status
- Changed dependent services from service_healthy to service_started
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed from single DOMAIN variable to PORTAL_DOMAIN and API_DOMAIN
- Matches nginx config: portal.monacousa.org, api.monacousa.org, studio.monacousa.org
- Updated docker-compose.yml to use correct domain variables with defaults
- Updated setup.sh to validate both domain variables
- Updated .env.example with separate domain configuration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use openssl rand -hex for secrets (no special chars)
- Use awk instead of sed for .env updates (handles any chars)
- Use awk for kong.yml generation (handles JWT tokens)
- Suppress source errors for malformed .env
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove Traefik service and related labels
- Expose ports to localhost only (3000, 8000, 3001)
- Update README with nginx proxy configuration examples
- Remove ACME_EMAIL and Traefik auth from .env.example
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- docker-compose.yml: Standalone compose with Traefik, Supabase, portal
- init.sql: Combined database schema + all 16 migrations
- kong.yml.template: Kong config with API key placeholders
- setup.sh: Auto-generates secrets (JWT, passwords, API keys)
- .env.example: Comprehensive environment template
- README.md: Complete deployment guide
No source code cloning required - just copy files and run setup.sh
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>