360 lines
9.9 KiB
Markdown
360 lines
9.9 KiB
Markdown
# Deployment Guide - Post-Implementation Refinements
|
|
|
|
This guide covers the necessary steps to deploy the new features implemented in the post-implementation refinements.
|
|
|
|
---
|
|
|
|
## 1. Edge Function Deployment
|
|
|
|
### Deploy Pakasir Webhook (if not already deployed)
|
|
|
|
The webhook function receives payment notifications from Pakasir and updates order statuses.
|
|
|
|
```bash
|
|
# Navigate to supabase functions directory
|
|
cd supabase/functions
|
|
|
|
# Deploy the webhook function
|
|
supabase functions deploy pakasir-webhook
|
|
```
|
|
|
|
**Environment Variables Required:**
|
|
- `SUPABASE_URL` - Automatically set by Supabase
|
|
- `SUPABASE_SERVICE_ROLE_KEY` - Automatically set by Supabase
|
|
- `PAKASIR_WEBHOOK_SECRET` - Optional (Pakasir doesn't use secrets, but you can set one for future compatibility)
|
|
|
|
### Create Expired Orders Checker (Optional - Recommended)
|
|
|
|
For production, you may want to create a cron job or scheduled edge function to automatically cancel expired consulting orders. However, the current implementation handles this on the frontend when users view their expired orders.
|
|
|
|
If you want to implement automatic expiry checking:
|
|
|
|
```bash
|
|
# Create new edge function
|
|
mkdir -p supabase/functions/check-expired-orders
|
|
|
|
# Copy the implementation (not included in this PR)
|
|
# Deploy
|
|
supabase functions deploy check-expired-orders
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Database Schema Changes
|
|
|
|
### Add QR Regeneration Tracking (Optional)
|
|
|
|
The current implementation doesn't require this, but if you want to track how many times a QR has been regenerated:
|
|
|
|
```sql
|
|
-- Add column to track QR regeneration count
|
|
ALTER TABLE orders
|
|
ADD COLUMN qr_regeneration_count INTEGER DEFAULT 0;
|
|
|
|
-- Add index for efficient expiry checks
|
|
CREATE INDEX idx_orders_qr_expires_at ON orders(qr_expires_at);
|
|
```
|
|
|
|
### Verify Storage Bucket Exists
|
|
|
|
The logo/favicon upload feature uses the existing `content` bucket. Verify it exists:
|
|
|
|
```sql
|
|
-- Check if bucket exists
|
|
SELECT * FROM storage.buckets WHERE name = 'content';
|
|
```
|
|
|
|
If it doesn't exist, create it:
|
|
|
|
```sql
|
|
-- Create storage bucket for brand assets
|
|
INSERT INTO storage.buckets (id, name, public)
|
|
VALUES ('content', 'content', true);
|
|
```
|
|
|
|
**Storage Folder Structure:**
|
|
```
|
|
content/
|
|
├── brand-assets/
|
|
│ ├── logo/
|
|
│ │ └── logo-current.{ext}
|
|
│ └── favicon/
|
|
│ └── favicon-current.{ext}
|
|
└── editor-images/
|
|
└── {existing files}
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Environment Variables
|
|
|
|
### Supabase Dashboard Settings
|
|
|
|
Navigate to your Supabase project → Settings → Edge Functions → Environment Variables:
|
|
|
|
**Required Variables:**
|
|
```
|
|
SUPABASE_URL={your-supabase-url}
|
|
SUPABASE_SERVICE_ROLE_KEY={your-service-role-key}
|
|
PAKASIR_WEBHOOK_SECRET={optional-leave-empty}
|
|
```
|
|
|
|
### Pakasir Configuration
|
|
|
|
**1. Configure Webhook URL in Pakasir Dashboard:**
|
|
|
|
1. Login to your Pakasir account
|
|
2. Go to your Project detail page
|
|
3. Edit Project → Find "Webhook URL" field
|
|
4. Enter: `https://lovable.backoffice.biz.id/functions/v1/pakasir-webhook`
|
|
5. Save changes
|
|
|
|
**Important Notes:**
|
|
- Pakasir does NOT use webhook secrets
|
|
- They simply send POST notifications to the URL
|
|
- The webhook verifies `order_id` and `amount` for security
|
|
- Webhook payload format:
|
|
```json
|
|
{
|
|
"amount": 22000,
|
|
"order_id": "240910HDE7C9",
|
|
"project": "depodomain",
|
|
"status": "completed",
|
|
"payment_method": "qris",
|
|
"completed_at": "2024-09-10T08:07:02.819+07:00"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Frontend Deployment
|
|
|
|
The frontend changes are already pushed to git. Your CI/CD pipeline should automatically deploy them.
|
|
|
|
**Manual deployment (if needed):**
|
|
|
|
```bash
|
|
# Pull latest changes
|
|
git pull origin main
|
|
|
|
# Build and deploy (depending on your hosting)
|
|
npm run build
|
|
# Then deploy dist/ folder to your hosting provider
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Post-Deployment Checklist
|
|
|
|
### Testing Steps
|
|
|
|
**1. Test Logo/Favicon Upload:**
|
|
- [ ] Go to Admin → Settings → Branding tab
|
|
- [ ] Upload a logo file (PNG, SVG, JPG, or WebP, max 2MB)
|
|
- [ ] Verify logo preview appears
|
|
- [ ] Upload a different logo (should delete the old one)
|
|
- [ ] Check Supabase Storage: `content/brand-assets/logo/` should only have one `logo-current.{ext}` file
|
|
- [ ] Repeat for favicon upload
|
|
|
|
**2. Test Dynamic Badge Colors:**
|
|
- [ ] Go to Admin → Settings → Branding tab
|
|
- [ ] Change "Warna Aksen / Tombol" to a different color (e.g., #FF5733)
|
|
- [ ] Save settings
|
|
- [ ] View any order detail page
|
|
- [ ] Verify "Lunas" badge shows the new accent color
|
|
|
|
**3. Test Page Title:**
|
|
- [ ] Go to Admin → Settings → Branding tab
|
|
- [ ] Change "Nama Platform" to a custom name
|
|
- [ ] Save settings
|
|
- [ ] Refresh browser
|
|
- [ ] Verify browser tab shows custom name
|
|
|
|
**4. Test Status Badge Wording:**
|
|
- [ ] View any order with "pending" status
|
|
- [ ] Verify badge shows "Pending" (not "Menunggu Pembayaran")
|
|
|
|
**5. Test Expired QR Handling - Product Order:**
|
|
- [ ] Create a test product order with QRIS payment
|
|
- [ ] Wait for QR to expire (or manually update `qr_expires_at` in database to past time)
|
|
- [ ] View the order detail page
|
|
- [ ] Verify "Regenerate QR" button appears (not "Buat Booking Baru")
|
|
- [ ] Click "Regenerate QR"
|
|
- [ ] Verify new QR code appears
|
|
|
|
**6. Test Expired QR Handling - Consulting Order:**
|
|
- [ ] Create a test consulting order with QRIS payment
|
|
- [ ] Wait for QR to expire
|
|
- [ ] View the order detail page
|
|
- [ ] Verify "Buat Booking Baru" button appears (not "Regenerate QR")
|
|
- [ ] Verify alert message says "Waktu pembayaran telah habis. Slot konsultasi telah dilepaskan."
|
|
|
|
**7. Test Webhook:**
|
|
- [ ] Create a test order via Pakasir
|
|
- [ ] Complete payment in Pakasir dashboard
|
|
- [ ] Wait a few seconds for webhook to fire
|
|
- [ ] Check order status in database: `payment_status` should be "paid"
|
|
- [ ] Verify `qr_string` and `qr_expires_at` are cleared (null)
|
|
|
|
---
|
|
|
|
## 6. Troubleshooting
|
|
|
|
### Logo Upload Fails
|
|
|
|
**Issue:** Upload fails with error
|
|
|
|
**Solution:**
|
|
- Verify `content` bucket exists and is public
|
|
- Check RLS (Row Level Security) policies on storage.objects
|
|
- User should have INSERT and DELETE permissions on `brand-assets/*` path
|
|
|
|
**Required RLS Policy:**
|
|
```sql
|
|
-- Allow authenticated users to upload brand assets
|
|
CREATE POLICY "Authenticated users can upload brand assets"
|
|
ON storage.objects FOR INSERT
|
|
TO authenticated
|
|
WITH CHECK (bucket_id = 'content' AND name LIKE 'brand-assets/%');
|
|
|
|
-- Allow authenticated users to delete brand assets
|
|
CREATE POLICY "Authenticated users can delete brand assets"
|
|
ON storage.objects FOR DELETE
|
|
TO authenticated
|
|
USING (bucket_id = 'content' AND name LIKE 'brand-assets/%');
|
|
```
|
|
|
|
### Badge Colors Not Updating
|
|
|
|
**Issue:** Badge colors still showing old color
|
|
|
|
**Solution:**
|
|
- Hard refresh browser (Ctrl+Shift+R or Cmd+Shift+R)
|
|
- Check browser console for CSS variable errors
|
|
- Verify `brand_accent_color` is saved in `platform_settings` table
|
|
- Check `useBranding.tsx` is setting `--brand-accent` CSS variable
|
|
|
|
### Page Title Not Updating
|
|
|
|
**Issue:** Browser tab still shows old title
|
|
|
|
**Solution:**
|
|
- Hard refresh browser
|
|
- Check `useBranding.tsx` is updating `document.title`
|
|
- Verify `brand_name` is saved in `platform_settings` table
|
|
|
|
### Webhook Not Receiving Payments
|
|
|
|
**Issue:** Orders stay in "pending" status after payment
|
|
|
|
**Solution:**
|
|
- Verify webhook URL is correctly set in Pakasir dashboard
|
|
- Check Supabase logs: Edge Functions → pakasir-webhook → Logs
|
|
- Verify webhook is deployed: `supabase functions list`
|
|
- Check `orders` table has proper `payment_reference` matching Pakasir `order_id`
|
|
|
|
### QR Regeneration Fails
|
|
|
|
**Issue:** "Regenerate QR" button doesn't work
|
|
|
|
**Solution:**
|
|
- Verify `create-payment` edge function is deployed
|
|
- Check browser console for error messages
|
|
- Verify order is a product order (not consulting)
|
|
- Check order status is still "pending"
|
|
|
|
---
|
|
|
|
## 7. Feature Rollback
|
|
|
|
If you need to rollback any feature:
|
|
|
|
```bash
|
|
# Revert to previous commit
|
|
git revert HEAD
|
|
|
|
# Or reset to specific commit
|
|
git reset --hard <commit-hash>
|
|
git push origin main --force
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Performance Considerations
|
|
|
|
### Storage Cleanup
|
|
|
|
The logo/favicon upload auto-deletes old files, but you may want to periodically clean up:
|
|
|
|
```sql
|
|
-- Check for orphaned files in storage
|
|
SELECT name, created_at
|
|
FROM storage.objects
|
|
WHERE bucket_id = 'content'
|
|
AND name LIKE 'brand-assets/%'
|
|
ORDER BY created_at DESC;
|
|
```
|
|
|
|
### Database Indexes
|
|
|
|
The implementation uses existing indexes. No new indexes are required unless you added the optional `qr_regeneration_count` tracking.
|
|
|
|
---
|
|
|
|
## 9. Security Notes
|
|
|
|
### Webhook Security
|
|
|
|
- The webhook verifies `order_id` exists in your database
|
|
- **TODO:** Add amount verification to prevent fraudulent payments
|
|
- Consider adding IP whitelist for Pakasir webhooks (if they provide static IPs)
|
|
|
|
### File Upload Security
|
|
|
|
- File types are restricted to images only (PNG, SVG, JPG, WebP, ICO)
|
|
- File size limits: Logo (2MB), Favicon (1MB)
|
|
- Files are stored in Supabase Storage with RLS policies
|
|
- Always sanitize file names before storage (already implemented)
|
|
|
|
---
|
|
|
|
## 10. Next Steps (Optional Improvements)
|
|
|
|
Not included in this PR, but consider for future:
|
|
|
|
1. **Add amount verification in webhook:**
|
|
```typescript
|
|
// In pakasir-webhook/index.ts
|
|
if (payload.amount !== order.total_amount) {
|
|
return new Response(JSON.stringify({ error: "Amount mismatch" }), { status: 400 });
|
|
}
|
|
```
|
|
|
|
2. **Implement scheduled expiry checker:**
|
|
- Create cron job to automatically cancel expired consulting orders
|
|
- Release slots back to available pool
|
|
- Send notification emails to users
|
|
|
|
3. **Add email notifications:**
|
|
- QR code expiry warning (15 min before)
|
|
- Payment confirmation email
|
|
- Consultation booking reminder
|
|
|
|
4. **Add analytics:**
|
|
- Track QR regeneration rate
|
|
- Monitor expired vs paid order ratio
|
|
- Identify problematic payment flows
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
This deployment requires:
|
|
- ✅ Edge function deployment (1 function: `pakasir-webhook`)
|
|
- ✅ Verify storage bucket exists (`content`)
|
|
- ✅ Configure Pakasir webhook URL
|
|
- ✅ No database schema changes required (optional improvements only)
|
|
- ✅ Frontend automatically deploys via CI/CD
|
|
|
|
All features are backward compatible and safe to deploy to production.
|