omnix-sopiga/docs/quick_start.md
2026-08-07 12:21:42 +07:00

319 lines
8.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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! 🚀**