feat: migrate clients module to patients + add docs
This commit is contained in:
76
scripts/apply-organization-seed.sh
Executable file
76
scripts/apply-organization-seed.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ============================================================================
|
||||
# Apply Organization Seed Migration
|
||||
# ============================================================================
|
||||
# Epic: E3.S1 - Organization seed
|
||||
# Purpose: Create default organization for development
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Applying organization seed migration..."
|
||||
echo ""
|
||||
|
||||
# Load environment variables
|
||||
if [ -f .env.local ]; then
|
||||
export $(cat .env.local | grep -v '^#' | grep -v '^$' | xargs)
|
||||
fi
|
||||
|
||||
# Check if Supabase is available
|
||||
echo "Checking Supabase connection..."
|
||||
curl -s -o /dev/null -w "%{http_code}" "${NEXT_PUBLIC_SUPABASE_URL}/rest/v1/" -H "apikey: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}" | grep -q "200" || {
|
||||
echo "❌ Cannot connect to Supabase. Please check if:"
|
||||
echo " - Supabase is online (not under maintenance)"
|
||||
echo " - Environment variables are set correctly"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "✅ Supabase is reachable"
|
||||
echo ""
|
||||
|
||||
# Apply migration using psql
|
||||
MIGRATION_FILE="supabase/migrations/20251122_seed_default_organization.sql"
|
||||
|
||||
if [ ! -f "$MIGRATION_FILE" ]; then
|
||||
echo "❌ Migration file not found: $MIGRATION_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📄 Applying migration: $MIGRATION_FILE"
|
||||
echo ""
|
||||
|
||||
# Get database connection string from Supabase dashboard
|
||||
# Format: postgresql://postgres:[PASSWORD]@db.dqugbrpwtisgyxscpefg.supabase.co:5432/postgres
|
||||
# You can find this in: Supabase Dashboard > Project Settings > Database > Connection string
|
||||
|
||||
echo "⚠️ To apply this migration, run the SQL file in Supabase SQL Editor:"
|
||||
echo ""
|
||||
echo " 1. Go to https://supabase.com/dashboard/project/dqugbrpwtisgyxscpefg/sql"
|
||||
echo " 2. Copy and paste the contents of:"
|
||||
echo " $MIGRATION_FILE"
|
||||
echo " 3. Click 'Run'"
|
||||
echo ""
|
||||
echo "Or use the Supabase CLI:"
|
||||
echo " npx supabase db push"
|
||||
echo ""
|
||||
echo "Or use psql (if you have database password):"
|
||||
echo " psql 'postgresql://postgres:[PASSWORD]@db.dqugbrpwtisgyxscpefg.supabase.co:5432/postgres' -f $MIGRATION_FILE"
|
||||
echo ""
|
||||
|
||||
# Alternative: Use Supabase Management API to apply migration
|
||||
# This requires the service role key
|
||||
# Uncomment if you want to use this method:
|
||||
#
|
||||
# echo "Applying migration via Supabase Management API..."
|
||||
#
|
||||
# MIGRATION_SQL=$(cat "$MIGRATION_FILE")
|
||||
#
|
||||
# curl -X POST \
|
||||
# "${NEXT_PUBLIC_SUPABASE_URL}/rest/v1/rpc/exec" \
|
||||
# -H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
||||
# -H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
|
||||
# -H "Content-Type: application/json" \
|
||||
# -d "{\"query\": $(jq -Rs . <<< "$MIGRATION_SQL")}"
|
||||
|
||||
echo "✅ Script completed. Please apply the migration manually as described above."
|
||||
165
scripts/seed-organization.ts
Normal file
165
scripts/seed-organization.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* ============================================================================
|
||||
* Seed Default Organization
|
||||
* ============================================================================
|
||||
* Epic: E3.S1 - Organization seed
|
||||
* Purpose: Create default GGZ organization for development
|
||||
* Usage: npx tsx scripts/seed-organization.ts
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
|
||||
// Load environment variables
|
||||
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY!;
|
||||
|
||||
if (!supabaseUrl || !supabaseServiceKey) {
|
||||
console.error('❌ Missing Supabase environment variables');
|
||||
console.error(' NEXT_PUBLIC_SUPABASE_URL:', supabaseUrl ? '✓' : '✗');
|
||||
console.error(' SUPABASE_SERVICE_ROLE_KEY:', supabaseServiceKey ? '✓' : '✗');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Create Supabase admin client (bypasses RLS)
|
||||
const supabase = createClient(supabaseUrl, supabaseServiceKey, {
|
||||
auth: {
|
||||
autoRefreshToken: false,
|
||||
persistSession: false
|
||||
}
|
||||
});
|
||||
|
||||
interface Organization {
|
||||
id: string;
|
||||
identifier_agb: string;
|
||||
identifier_kvk: string;
|
||||
name: string;
|
||||
alias: string[];
|
||||
type_code: string;
|
||||
type_display: string;
|
||||
telecom_phone: string;
|
||||
telecom_email: string;
|
||||
telecom_website: string;
|
||||
address_line: string[];
|
||||
address_city: string;
|
||||
address_postal_code: string;
|
||||
address_country: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
const defaultOrganization: Organization = {
|
||||
id: '00000000-0000-0000-0000-000000000001',
|
||||
identifier_agb: 'AGB-DEMO-001',
|
||||
identifier_kvk: '12345678',
|
||||
name: 'Demo GGZ Instelling',
|
||||
alias: ['Demo GGZ', 'DGGZ'],
|
||||
type_code: 'prov',
|
||||
type_display: 'Healthcare Provider',
|
||||
telecom_phone: '030-1234567',
|
||||
telecom_email: 'info@demo-ggz.nl',
|
||||
telecom_website: 'https://demo-ggz.nl',
|
||||
address_line: ['Demonstratiestraat 1'],
|
||||
address_city: 'Utrecht',
|
||||
address_postal_code: '3511 AB',
|
||||
address_country: 'NL',
|
||||
active: true
|
||||
};
|
||||
|
||||
async function seedOrganization() {
|
||||
console.log('🚀 Seeding default organization...\n');
|
||||
|
||||
try {
|
||||
// Check if organization already exists
|
||||
const { data: existing, error: checkError } = await supabase
|
||||
.from('organizations')
|
||||
.select('id, name, identifier_agb')
|
||||
.eq('identifier_agb', 'AGB-DEMO-001')
|
||||
.maybeSingle();
|
||||
|
||||
if (checkError) {
|
||||
throw new Error(`Error checking existing organization: ${checkError.message}`);
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
console.log('ℹ️ Organization already exists:');
|
||||
console.log(` ID: ${existing.id}`);
|
||||
console.log(` Name: ${existing.name}`);
|
||||
console.log(` AGB: ${existing.identifier_agb}`);
|
||||
console.log('\n🔄 Updating organization...\n');
|
||||
|
||||
// Update existing organization
|
||||
const { error: updateError } = await supabase
|
||||
.from('organizations')
|
||||
.update({
|
||||
identifier_kvk: defaultOrganization.identifier_kvk,
|
||||
name: defaultOrganization.name,
|
||||
alias: defaultOrganization.alias,
|
||||
type_code: defaultOrganization.type_code,
|
||||
type_display: defaultOrganization.type_display,
|
||||
telecom_phone: defaultOrganization.telecom_phone,
|
||||
telecom_email: defaultOrganization.telecom_email,
|
||||
telecom_website: defaultOrganization.telecom_website,
|
||||
address_line: defaultOrganization.address_line,
|
||||
address_city: defaultOrganization.address_city,
|
||||
address_postal_code: defaultOrganization.address_postal_code,
|
||||
address_country: defaultOrganization.address_country,
|
||||
active: defaultOrganization.active,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', existing.id);
|
||||
|
||||
if (updateError) {
|
||||
throw new Error(`Error updating organization: ${updateError.message}`);
|
||||
}
|
||||
|
||||
console.log('✅ Organization updated successfully');
|
||||
} else {
|
||||
console.log('➕ Creating new organization...\n');
|
||||
|
||||
// Insert new organization
|
||||
const { error: insertError } = await supabase
|
||||
.from('organizations')
|
||||
.insert([defaultOrganization]);
|
||||
|
||||
if (insertError) {
|
||||
throw new Error(`Error inserting organization: ${insertError.message}`);
|
||||
}
|
||||
|
||||
console.log('✅ Organization created successfully');
|
||||
}
|
||||
|
||||
// Verify the organization exists
|
||||
const { data: verified, error: verifyError } = await supabase
|
||||
.from('organizations')
|
||||
.select('*')
|
||||
.eq('identifier_agb', 'AGB-DEMO-001')
|
||||
.single();
|
||||
|
||||
if (verifyError) {
|
||||
throw new Error(`Error verifying organization: ${verifyError.message}`);
|
||||
}
|
||||
|
||||
console.log('\n✅ Verification successful:');
|
||||
console.log(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||
console.log(` ID: ${verified.id}`);
|
||||
console.log(` Name: ${verified.name}`);
|
||||
console.log(` AGB: ${verified.identifier_agb}`);
|
||||
console.log(` KVK: ${verified.identifier_kvk}`);
|
||||
console.log(` Email: ${verified.telecom_email}`);
|
||||
console.log(` Website: ${verified.telecom_website}`);
|
||||
console.log(` Address: ${verified.address_line.join(', ')}`);
|
||||
console.log(` City: ${verified.address_city} ${verified.address_postal_code}`);
|
||||
console.log(` Active: ${verified.active ? 'Yes' : 'No'}`);
|
||||
console.log(' ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
console.log('🎉 E3.S1 - Organization seed completed!\n');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Error seeding organization:');
|
||||
console.error(error instanceof Error ? error.message : error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the seed function
|
||||
seedOrganization();
|
||||
Reference in New Issue
Block a user