omnix-sopiga/docs/quick_start.md

319 lines
8.0 KiB
Markdown
Raw Permalink Normal View History

# Quick Start Guide
## Gadai Mulia Collection Broadcast Integration
---
## ⚡ 5-Minute Setup
### Prerequisites
- PostgreSQL database access
- Sopiga API credentials (token)
- Go 1.16+ (for worker deployment)
### Step 1: Create Database Schema (2 minutes)
```bash
# Run SQL schema
psql -U postgres -h localhost -d gadai_mulia < gadai_collection_broadcast_simplified_schema.sql
```
Verify schema created:
```sql
\dt collection_broadcasts.*
-- Should show: sopiga_template_config, template_variable_mapping, sopiga_collar_config, broadcast_staging, etc
```
### Step 2: Setup Sopiga Template (2 minutes)
**In Sopiga UI or API:**
```bash
# Create template
curl -X POST https://omnix.promas.site/api/client/template \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template_name": "Collection Invoice",
"channel": "waba",
"variables": [
{"name": "Nama", "type": "string"},
{"name": "TotalTagihan", "type": "integer"},
{"name": "TanggalJatuhTempo", "type": "date"}
]
}'
# Response: {"data": {"id": 2}}
# Create collar
curl -X POST https://omnix.promas.site/api/client/collar \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"judul_broadcast": "Invoice May 2026",
"template_id": 2
}'
# Response: {"data": {"id": 70}}
```
Note down:
- `template_id = 2`
- `collar_id = 70`
### Step 3: Register in Database (1 minute)
**Connect to PostgreSQL:**
```bash
psql -U postgres -h localhost -d gadai_mulia
```
**Insert template:**
```sql
INSERT INTO collection_broadcasts.sopiga_template_config
(template_name, sopiga_template_id, channel, template_type, description)
VALUES
('Collection Invoice May 2026', 2, 'waba', 'utility', 'Invoice bulanan untuk collection');
```
**Insert variable mappings (URUTAN PENTING!):**
```sql
INSERT INTO collection_broadcasts.template_variable_mapping
(sopiga_template_id, variable_order, sopiga_variable_name, variable_type, db_field_source, is_required, example_value)
VALUES
(2, 1, 'Nama', 'string', 'nasabah_nama', TRUE, 'Budi Santoso'),
(2, 2, 'TotalTagihan', 'integer', 'nominal_tagihan', TRUE, '1500000'),
(2, 3, 'TanggalJatuhTempo', 'date', 'tanggal_tempo', TRUE, '2026-06-30');
```
**Insert collar config:**
```sql
INSERT INTO collection_broadcasts.sopiga_collar_config
(broadcast_name, sopiga_collar_id, sopiga_template_id, status, description)
VALUES
('Collection Invoices May 2026', 70, 2, 'open', 'Broadcast collar untuk collection invoice bulanan Mei 2026');
```
**Verify setup:**
```sql
SELECT * FROM collection_broadcasts.v_template_variables_ordered
WHERE sopiga_template_id = 2;
-- Should show 3 rows with order 1, 2, 3
```
### Step 4: Deploy Worker (1 minute)
```bash
# Build
go build -o collection_broadcast_worker collection_broadcast_worker_simplified.go
# Run with environment variables
export DB_HOST=localhost
export DB_PORT=5432
export DB_NAME=gadai_mulia
export DB_USER=postgres
export DB_PASSWORD=xxx
export SOPIGA_BASE_URL=https://omnix.promas.site
export SOPIGA_TOKEN=your_api_token
./collection_broadcast_worker
# Output: Collection Broadcast Worker started
```
---
## 🧪 Test It
### Insert Test Record
```sql
-- Insert to broadcast_staging
INSERT INTO collection_broadcasts.broadcast_staging
(sopiga_collar_id, sopiga_template_id, message_payload, status)
VALUES
(
70,
2,
'{"nasabah_nama": "Budi Santoso", "nasabah_phone": "6281234567890", "nominal_tagihan": 1500000, "tanggal_tempo": "2026-06-30", "invoice_pdf_url": "https://storage.gadai.com/invoices/inv-001.pdf"}',
'pending'
);
-- Check it's pending
SELECT id, status, created_at FROM collection_broadcasts.broadcast_staging WHERE status='pending';
```
### Wait 30 seconds
Worker polls every 30 seconds. Check status:
```sql
SELECT id, status, sopiga_recipient_detail_id, dispatched_at, error_message
FROM collection_broadcasts.broadcast_staging
WHERE id = 1;
-- Should show: status='dispatched', sopiga_recipient_detail_id=512
```
### Check WhatsApp Delivery
After 5 minutes, check sync job:
```sql
SELECT id, status, last_status_from_sopiga, delivered_at
FROM collection_broadcasts.broadcast_staging
WHERE id = 1;
-- Should show: status='delivered', delivered_at=<timestamp>
```
---
## 📊 Monitor
### Check Delivery Rate
```sql
SELECT * FROM collection_broadcasts.v_delivery_rate_24h;
-- delivery_rate_percent should be > 95%
```
### Check Failed Records
```sql
SELECT * FROM collection_broadcasts.v_failed_records_24h;
-- Should be empty or < 5%
```
### Check Collar Summary
```sql
SELECT * FROM collection_broadcasts.v_collar_summary;
-- See totals per collar, delivery rates
```
---
## Add New Template (5 minutes)
When Sopiga template changes (e.g., add `NoKontrak` field):
### 1. Create in Sopiga
```bash
# template_id = 3, collar_id = 71
```
### 2. Register in Database
```sql
-- Template
INSERT INTO sopiga_template_config (template_name, sopiga_template_id, ...)
VALUES ('Collection Invoice Extended', 3, ...);
-- Variables (URUTAN PENTING!)
INSERT INTO template_variable_mapping
(sopiga_template_id, variable_order, sopiga_variable_name, variable_type, db_field_source, is_required)
VALUES
(3, 1, 'Nama', 'string', 'nasabah_nama', TRUE),
(3, 2, 'NoKontrak', 'string', 'contract_no', TRUE), ← NEW
(3, 3, 'TotalTagihan', 'integer', 'nominal_tagihan', TRUE),
(3, 4, 'TanggalJatuhTempo', 'date', 'tanggal_tempo', TRUE);
-- Collar
INSERT INTO sopiga_collar_config (broadcast_name, sopiga_collar_id, sopiga_template_id, status)
VALUES ('Collection Invoices June 2026', 71, 3, 'open');
```
### 3. NO code redeploy needed ✅
Worker automatically picks up new template on next poll.
---
## 🚀 Gadai Service Integration
**How Gadai calls this:**
```go
import "database/sql"
import "encoding/json"
db, _ := sql.Open("postgres", "postgres://user:pass@localhost/gadai_mulia")
payload := map[string]interface{}{
"nasabah_nama": "Budi Santoso",
"nasabah_phone": "6281234567890",
"nominal_tagihan": 1500000.0,
"tanggal_tempo": "2026-06-30",
"invoice_pdf_url": "https://storage.gadai.com/invoices/inv-001.pdf",
"contract_no": "GAD-2026-001",
}
payloadJSON, _ := json.Marshal(payload)
db.Exec(`
INSERT INTO collection_broadcasts.broadcast_staging
(sopiga_collar_id, sopiga_template_id, message_payload, status)
VALUES ($1, $2, $3, 'pending')
`, 70, 2, payloadJSON)
// Done! Worker picks it up automatically
```
---
## 🐛 Troubleshooting
### "Message format wrong"
→ Check template variable order matches Sopiga:
```sql
SELECT variable_order, sopiga_variable_name FROM template_variable_mapping
WHERE sopiga_template_id=2 ORDER BY variable_order;
```
### "Record stuck in pending"
→ Check worker logs:
```bash
# Look for errors in stdout/stderr
# Check DB connection
psql -U postgres -h localhost -d gadai_mulia -c "SELECT 1;"
```
### "Sopiga API errors"
→ Check token and URL:
```bash
curl -X GET https://omnix.promas.site/api/client/collar/list \
-H "Authorization: Bearer YOUR_TOKEN"
```
---
## ✅ Checklist
- [ ] Schema created
- [ ] Sopiga template created (note template_id)
- [ ] Sopiga collar created (note collar_id)
- [ ] Database populated with template_id, collar_id
- [ ] Variable mappings inserted (check order!)
- [ ] Worker deployed and running
- [ ] Test record inserted
- [ ] Record moved to 'dispatched' after 30s
- [ ] Record moved to 'delivered' after 5 min
- [ ] WhatsApp message received on test phone
---
## 📞 Quick Reference
**Database:**
- Schema: `collection_broadcasts`
- Main table: `broadcast_staging`
- Config tables: `sopiga_template_config`, `template_variable_mapping`, `sopiga_collar_config`
**Sopiga URLs:**
- Base: `https://omnix.promas.site`
- Create template: POST `/api/client/template`
- Create collar: POST `/api/client/collar`
- Add recipient: POST `/api/client/collar/add-recipient`
- Get recipient detail: GET `/api/client/collar/add-recipient/{id}/detail`
**Worker:**
- Poll interval: 30 seconds (pending records)
- Status sync: 5 minutes (delivery status)
- Max retries: 3 (exponential backoff: 1s, 2s, 4s)
---
**Ready to go! 🚀**