Files
WooNooW/ADDON_BRIDGE_PATTERN.md
dwindown 0c1f5d5047 docs: Critical audit and strategy documents
## Point 1: Addon Bridge Pattern 

Created ADDON_BRIDGE_PATTERN.md documenting:
- WooNooW Core = Zero addon dependencies
- Bridge snippet pattern for Rajaongkir compatibility
- Proper addon development approach
- Hook system usage

**Key Decision:**
-  No Rajaongkir integration in core
-  Provide bridge snippets for compatibility
-  Encourage proper WooNooW addons
-  Keep core clean and maintainable

---

## Point 2: Calculation Efficiency Audit 🚨 CRITICAL

Created CALCULATION_EFFICIENCY_AUDIT.md revealing:

**BLOATED Implementation Found:**
- 2 separate API calls (/shipping/calculate + /orders/preview)
- Cart initialized TWICE
- Shipping calculated TWICE
- Taxes calculated TWICE
- ~1000ms total time

**Recommended Solution:**
- Single /orders/calculate endpoint
- ONE cart initialization
- ONE calculation
- ~300ms total time (70% faster!)
- 50% fewer requests
- 50% less server load

**This is exactly what we discussed at the beginning:**
> "WooCommerce is bloated because of separate requests. We need efficient flow that handles everything at once."

**Current implementation repeats WooCommerce's mistake!**

**Status:**  NOT IMPLEMENTED YET
**Priority:** 🚨 CRITICAL
**Impact:** 🔥 HIGH - Performance bottleneck

---

## Point 3: Settings Placement Strategy 

Created SETTINGS_PLACEMENT_STRATEGY.md proposing:

**No separate "WooNooW Settings" page.**

Instead:
- Store Logo → WooCommerce > Settings > General
- Order Format → WooCommerce > Settings > Orders
- Product Settings → WooCommerce > Settings > Products
- UI Settings → WooCommerce > Settings > Admin UI (new tab)

**Benefits:**
- Contextual placement
- Familiar to users
- No clutter
- Seamless integration
- Feels native to WooCommerce

**Philosophy:**
WooNooW should feel like a native part of WooCommerce, not a separate plugin.

---

## Summary

**Point 1:**  Documented addon bridge pattern
**Point 2:** 🚨 CRITICAL - Current calculation is bloated, needs refactoring
**Point 3:**  Settings placement strategy documented

**Next Action Required:**
Implement unified /orders/calculate endpoint to fix performance bottleneck.
2025-11-10 20:24:23 +07:00

326 lines
8.4 KiB
Markdown

# Addon Bridge Pattern - Rajaongkir Example
## Philosophy
**WooNooW Core = Zero Addon Dependencies**
We don't integrate specific addons into WooNooW core. Instead, we provide:
1. **Hook system** for addons to extend functionality
2. **Bridge snippets** for compatibility with existing plugins
3. **Addon development guide** for building proper WooNooW addons
---
## Problem: Rajaongkir Plugin
Rajaongkir is a WooCommerce plugin that:
- Removes standard address fields (city, state)
- Adds custom destination dropdown
- Stores data in WooCommerce session
- Works on WooCommerce checkout page
**It doesn't work with WooNooW OrderForm because:**
- OrderForm uses standard WooCommerce fields
- Rajaongkir expects session-based destination
- No destination = No shipping calculation
---
## Solution: Bridge Snippet (Not Core Integration!)
### Option A: Standalone Bridge Plugin
Create a tiny bridge plugin that makes Rajaongkir work with WooNooW:
```php
<?php
/**
* Plugin Name: WooNooW Rajaongkir Bridge
* Description: Makes Rajaongkir plugin work with WooNooW OrderForm
* Version: 1.0.0
* Requires: WooNooW, Rajaongkir Official
*/
// Hook into WooNooW's shipping calculation
add_filter('woonoow_before_shipping_calculate', function($shipping_data) {
// If Indonesia and has city, convert to Rajaongkir destination
if ($shipping_data['country'] === 'ID' && !empty($shipping_data['city'])) {
// Search Rajaongkir API for destination
$api = Cekongkir_API::get_instance();
$results = $api->search_destination_api($shipping_data['city']);
if (!empty($results[0])) {
// Set Rajaongkir session data
WC()->session->set('selected_destination_id', $results[0]['id']);
WC()->session->set('selected_destination_label', $results[0]['text']);
}
}
return $shipping_data;
});
// Add Rajaongkir destination field to OrderForm via hook system
add_action('wp_enqueue_scripts', function() {
if (!is_admin()) return;
wp_enqueue_script(
'woonoow-rajaongkir-bridge',
plugin_dir_url(__FILE__) . 'dist/bridge.js',
['woonoow-admin'],
'1.0.0',
true
);
});
```
**Frontend (bridge.js):**
```typescript
import { addonLoader, addFilter } from '@woonoow/hooks';
addonLoader.register({
id: 'rajaongkir-bridge',
name: 'Rajaongkir Bridge',
version: '1.0.0',
init: () => {
// Add destination search field after shipping address
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
// Only for Indonesia
if (formData.shipping?.country !== 'ID') return content;
return (
<>
{content}
<div className="border rounded-lg p-4 mt-4">
<h3 className="font-medium mb-3">📍 Shipping Destination</h3>
<RajaongkirDestinationSearch
value={formData.shipping?.destination_id}
onChange={(id, label) => {
setFormData({
...formData,
shipping: {
...formData.shipping,
destination_id: id,
destination_label: label,
}
});
}}
/>
</div>
</>
);
});
}
});
```
### Option B: Code Snippet (No Plugin)
For users who don't want a separate plugin, provide a code snippet:
```php
// Add to theme's functions.php or custom plugin
// Bridge Rajaongkir with WooNooW
add_filter('woonoow_shipping_data', function($data) {
if ($data['country'] === 'ID' && !empty($data['city'])) {
// Auto-search and set destination
$api = Cekongkir_API::get_instance();
$results = $api->search_destination_api($data['city']);
if (!empty($results[0])) {
WC()->session->set('selected_destination_id', $results[0]['id']);
}
}
return $data;
});
```
---
## Proper Solution: Build WooNooW Addon
Instead of bridging Rajaongkir, build a proper WooNooW addon:
**WooNooW Indonesia Shipping Addon**
```php
<?php
/**
* Plugin Name: WooNooW Indonesia Shipping
* Description: Indonesia shipping with Rajaongkir API
* Version: 1.0.0
* Requires: WooNooW 1.0.0+
*/
// Register addon
add_filter('woonoow/addon_registry', function($addons) {
$addons['indonesia-shipping'] = [
'id' => 'indonesia-shipping',
'name' => 'Indonesia Shipping',
'version' => '1.0.0',
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
'dependencies' => ['woocommerce' => '8.0'],
];
return $addons;
});
// Add API endpoints
add_action('rest_api_init', function() {
register_rest_route('woonoow/v1', '/indonesia/search-destination', [
'methods' => 'GET',
'callback' => function($req) {
$query = $req->get_param('query');
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
return $api->searchDestination($query);
},
]);
register_rest_route('woonoow/v1', '/indonesia/calculate-shipping', [
'methods' => 'POST',
'callback' => function($req) {
$origin = $req->get_param('origin');
$destination = $req->get_param('destination');
$weight = $req->get_param('weight');
$api = new RajaongkirAPI(get_option('rajaongkir_api_key'));
return $api->calculateShipping($origin, $destination, $weight);
},
]);
});
```
**Frontend:**
```typescript
// dist/addon.ts
import { addonLoader, addFilter } from '@woonoow/hooks';
import { DestinationSearch } from './components/DestinationSearch';
addonLoader.register({
id: 'indonesia-shipping',
name: 'Indonesia Shipping',
version: '1.0.0',
init: () => {
// Add destination field
addFilter('woonoow_order_form_after_shipping', (content, formData, setFormData) => {
if (formData.shipping?.country !== 'ID') return content;
return (
<>
{content}
<DestinationSearch
value={formData.shipping?.destination_id}
onChange={(id, label) => {
setFormData({
...formData,
shipping: { ...formData.shipping, destination_id: id, destination_label: label }
});
}}
/>
</>
);
});
// Add validation
addFilter('woonoow_order_form_validation', (errors, formData) => {
if (formData.shipping?.country === 'ID' && !formData.shipping?.destination_id) {
errors.destination = 'Please select shipping destination';
}
return errors;
});
}
});
```
---
## Comparison
### Bridge Snippet (Quick Fix)
✅ Works immediately
✅ No new plugin needed
✅ Minimal code
❌ Depends on Rajaongkir plugin
❌ Limited features
❌ Not ideal UX
### Proper WooNooW Addon (Best Practice)
✅ Native WooNooW integration
✅ Better UX
✅ More features
✅ Independent of Rajaongkir plugin
✅ Can use any shipping API
❌ More development effort
❌ Separate plugin to maintain
---
## Recommendation
**For WooNooW Core:**
- ❌ Don't integrate Rajaongkir
- ✅ Provide hook system
- ✅ Document bridge pattern
- ✅ Provide code snippets
**For Users:**
- **Quick fix:** Use bridge snippet
- **Best practice:** Build proper addon or use community addon
**For Community:**
- Build "WooNooW Indonesia Shipping" addon
- Publish on WordPress.org
- Support Rajaongkir, Biteship, and other Indonesian shipping APIs
---
## Hook Points Needed in WooNooW Core
To support addons like this, WooNooW core should provide:
```php
// Before shipping calculation
apply_filters('woonoow_before_shipping_calculate', $shipping_data);
// After shipping calculation
apply_filters('woonoow_after_shipping_calculate', $rates, $shipping_data);
// Modify shipping data
apply_filters('woonoow_shipping_data', $data);
```
```typescript
// Frontend hooks
'woonoow_order_form_after_shipping'
'woonoow_order_form_shipping_fields'
'woonoow_order_form_validation'
'woonoow_order_form_submit'
```
**These hooks already exist in our addon system!**
---
## Conclusion
**WooNooW Core = Zero addon dependencies**
Instead of integrating Rajaongkir into core:
1. Provide hook system ✅ (Already done)
2. Document bridge pattern ✅ (This document)
3. Encourage community addons ✅
This keeps WooNooW core:
- Clean
- Maintainable
- Flexible
- Extensible
Users can choose:
- Bridge snippet (quick fix)
- Proper addon (best practice)
- Build their own
**No bloat in core!**