|
| 1 | +# OASIS Visualizer Troubleshooting & Implementation Guide |
| 2 | + |
| 3 | +## Overview |
| 4 | +This document covers the issues encountered while integrating the holonic visualizer with the local OASIS API and how they were resolved. |
| 5 | + |
| 6 | +## Project Location |
| 7 | +``` |
| 8 | +/Volumes/Storage/OASIS_CLEAN/holonic-visualizer/ |
| 9 | +``` |
| 10 | + |
| 11 | +## Local OASIS API Configuration |
| 12 | + |
| 13 | +### Base URL |
| 14 | +- **HTTP**: `http://localhost:5003` (for local development) |
| 15 | +- **HTTPS**: `https://localhost:5004` (causes HTTP/2 protocol errors in browsers) |
| 16 | + |
| 17 | +### Authentication |
| 18 | +- **Username**: `OASIS_ADMIN` |
| 19 | +- **Password**: `Uppermall1!` |
| 20 | +- **Endpoint**: `POST /api/avatar/authenticate` |
| 21 | +- **Token Expiry**: 15 minutes |
| 22 | + |
| 23 | +## Issues Encountered & Solutions |
| 24 | + |
| 25 | +### Issue 1: HTTP/2 Protocol Errors |
| 26 | +**Problem**: `ERR_HTTP2_PROTOCOL_ERROR 200 (OK)` when using HTTPS on localhost |
| 27 | + |
| 28 | +**Solution**: |
| 29 | +- Use HTTP (`http://localhost:5003`) instead of HTTPS |
| 30 | +- Disabled HTTPS redirection in `Startup.cs` for Development environment |
| 31 | +- Added URL rewriting in `OASISClient.js` to force HTTP for localhost requests |
| 32 | + |
| 33 | +**Files Modified**: |
| 34 | +- `/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI/Startup.cs` |
| 35 | +- `/holonic-visualizer/src/api/OASISClient.js` |
| 36 | + |
| 37 | +### Issue 2: CORS Preflight Failures |
| 38 | +**Problem**: `Redirect is not allowed for a preflight request` - CORS preflight (OPTIONS) requests were being redirected by HTTPS redirection middleware |
| 39 | + |
| 40 | +**Solution**: |
| 41 | +- Conditionally disable `app.UseHttpsRedirection()` in Development environment |
| 42 | +- Ensure CORS middleware is registered before HTTPS redirection |
| 43 | +- Skip subscription checks for OPTIONS requests and authentication endpoints |
| 44 | + |
| 45 | +**Files Modified**: |
| 46 | +- `/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI/Startup.cs` |
| 47 | +- `/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI/Middleware/SubscriptionMiddleware.cs` |
| 48 | + |
| 49 | +### Issue 3: HolonType Must Be Integer Enum |
| 50 | +**Problem**: `400 Bad Request` - `"The JSON value could not be converted to NextGenSoftware.OASIS.API.Core.Enums.HolonType"` |
| 51 | + |
| 52 | +**Root Cause**: The API expects `HolonType` as an integer enum value, not a string. |
| 53 | + |
| 54 | +**Solution**: |
| 55 | +- Use integer enum values: |
| 56 | + - `74` for OAPP (not `"OAPP"`) |
| 57 | + - `3` for Avatar (not `"Avatar"`) |
| 58 | + - `0` for default/regular holons (not `"Mission"`, `"NFT"`, etc.) |
| 59 | +- Store the type name in `MetaData.holonTypeName` for reference |
| 60 | + |
| 61 | +**Example**: |
| 62 | +```javascript |
| 63 | +// ❌ WRONG |
| 64 | +{ |
| 65 | + HolonType: "OAPP" // String - will fail |
| 66 | +} |
| 67 | + |
| 68 | +// ✅ CORRECT |
| 69 | +{ |
| 70 | + HolonType: 74, // Integer enum value |
| 71 | + MetaData: { |
| 72 | + holonTypeName: "OAPP" // Store name for reference |
| 73 | + } |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +**Files Modified**: |
| 78 | +- `/holonic-visualizer/src/utils/seedOASISData.js` |
| 79 | + |
| 80 | +### Issue 4: ProviderMetaData Validation Error |
| 81 | +**Problem**: `400 Bad Request` - `"The JSON value could not be converted to NextGenSoftware.OASIS.API.Core.Enums.ProviderType"` for `ProviderMetaData.collection` |
| 82 | + |
| 83 | +**Root Cause**: `ProviderMetaData.collection` was being interpreted as a `ProviderType` enum, not a string. |
| 84 | + |
| 85 | +**Solution**: Removed `ProviderMetaData` entirely - it's optional and the API will use default MongoDB collection based on `ProviderKey: 'MongoOASIS'`. |
| 86 | + |
| 87 | +**Files Modified**: |
| 88 | +- `/holonic-visualizer/src/utils/seedOASISData.js` |
| 89 | + |
| 90 | +### Issue 5: Request Body Property Casing |
| 91 | +**Problem**: `400 Bad Request` when saving holons |
| 92 | + |
| 93 | +**Root Cause**: C# API expects PascalCase property names in request body. |
| 94 | + |
| 95 | +**Solution**: Use PascalCase for all request body properties: |
| 96 | +```javascript |
| 97 | +{ |
| 98 | + Holon: { ... }, // Not "holon" |
| 99 | + SaveChildren: false, // Not "saveChildren" |
| 100 | + Recursive: false, // Not "recursive" |
| 101 | + MaxChildDepth: 0, // Not "maxChildDepth" |
| 102 | + ContinueOnError: true, // Not "continueOnError" |
| 103 | + ShowDetailedSettings: false // Not "showDetailedSettings" |
| 104 | +} |
| 105 | +``` |
| 106 | + |
| 107 | +**Files Modified**: |
| 108 | +- `/holonic-visualizer/src/utils/seedOASISData.js` |
| 109 | + |
| 110 | +### Issue 6: ERR_INCOMPLETE_CHUNKED_ENCODING |
| 111 | +**Problem**: When loading OAPPs, the response is too large because it includes all child holons (1200+ holons) |
| 112 | + |
| 113 | +**Root Cause**: GET request to `/api/data/load-all-holons/74` loads OAPPs with all their children by default. |
| 114 | + |
| 115 | +**Solution**: |
| 116 | +- Use POST request with `LoadChildren: false` to load only OAPPs without children |
| 117 | +- Created `getAllHolonsWithOptions()` method that always uses POST with options |
| 118 | +- Load OAPPs, Avatars, and regular holons separately |
| 119 | + |
| 120 | +**Files Modified**: |
| 121 | +- `/holonic-visualizer/src/api/OASISClient.js` - Added `getAllHolonsWithOptions()` |
| 122 | +- `/holonic-visualizer/src/main.js` - Updated to use POST with `LoadChildren: false` |
| 123 | + |
| 124 | +### Issue 7: String Enum Values Return 0 Results |
| 125 | +**Problem**: Loading holons with string `'OAPP'` or `'Avatar'` returns 0 results |
| 126 | + |
| 127 | +**Root Cause**: API only accepts integer enum values in URL path or request body. |
| 128 | + |
| 129 | +**Solution**: |
| 130 | +- Try integer enum values first (74, 3, 0) |
| 131 | +- Fallback to strings only if needed (though strings don't work for this API) |
| 132 | + |
| 133 | +**Files Modified**: |
| 134 | +- `/holonic-visualizer/src/main.js` |
| 135 | +- `/holonic-visualizer/src/api/OASISClient.js` |
| 136 | + |
| 137 | +## Current Working Configuration |
| 138 | + |
| 139 | +### API Endpoints |
| 140 | + |
| 141 | +#### Save Holon |
| 142 | +```http |
| 143 | +POST /api/data/save-holon |
| 144 | +Authorization: Bearer {jwtToken} |
| 145 | +Content-Type: application/json |
| 146 | +
|
| 147 | +{ |
| 148 | + "Holon": { |
| 149 | + "Name": "Holon Name", |
| 150 | + "Description": "Description", |
| 151 | + "HolonType": 74, // Integer enum (74=OAPP, 3=Avatar, 0=Default) |
| 152 | + "ProviderKey": "MongoOASIS", |
| 153 | + "MetaData": { |
| 154 | + "createdBy": "script", |
| 155 | + "createdDate": "2025-12-15T..." |
| 156 | + } |
| 157 | + }, |
| 158 | + "SaveChildren": false, |
| 159 | + "Recursive": false, |
| 160 | + "MaxChildDepth": 0, |
| 161 | + "ContinueOnError": true, |
| 162 | + "ShowDetailedSettings": false |
| 163 | +} |
| 164 | +``` |
| 165 | + |
| 166 | +#### Load All Holons (with options) |
| 167 | +```http |
| 168 | +POST /api/data/load-all-holons |
| 169 | +Authorization: Bearer {jwtToken} |
| 170 | +Content-Type: application/json |
| 171 | +
|
| 172 | +{ |
| 173 | + "HolonType": 74, // Integer enum or "All" |
| 174 | + "LoadChildren": false, // IMPORTANT: Set to false to avoid large responses |
| 175 | + "Recursive": false, |
| 176 | + "MaxChildDepth": 0, |
| 177 | + "ContinueOnError": true, |
| 178 | + "Version": 0, |
| 179 | + "ProviderKey": "MongoOASIS" |
| 180 | +} |
| 181 | +``` |
| 182 | + |
| 183 | +### Response Structure |
| 184 | +```javascript |
| 185 | +{ |
| 186 | + result: { |
| 187 | + result: [ // Array of holons |
| 188 | + { |
| 189 | + id: "guid", |
| 190 | + Name: "Holon Name", |
| 191 | + HolonType: 74, |
| 192 | + MetaData: { ... }, |
| 193 | + // ... other properties |
| 194 | + } |
| 195 | + ], |
| 196 | + isError: false, |
| 197 | + message: "" |
| 198 | + } |
| 199 | +} |
| 200 | +``` |
| 201 | + |
| 202 | +## Data Seeding |
| 203 | + |
| 204 | +### How to Seed Sample Data |
| 205 | + |
| 206 | +1. **Start the OASIS API** (if not already running): |
| 207 | + ```bash |
| 208 | + cd /Volumes/Storage/OASIS_CLEAN/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI |
| 209 | + dotnet run |
| 210 | + ``` |
| 211 | + |
| 212 | +2. **Open the visualizer**: |
| 213 | + ```bash |
| 214 | + cd /Volumes/Storage/OASIS_CLEAN/holonic-visualizer |
| 215 | + npm run dev |
| 216 | + ``` |
| 217 | + |
| 218 | +3. **Click "Seed Sample Data"** button in the UI |
| 219 | + |
| 220 | +4. **Wait for completion** - You should see: |
| 221 | + - ✅ Created 5 OAPPs |
| 222 | + - ✅ Created holons across all OAPPs (1200+ holons) |
| 223 | + - ✅ Created 50 unassigned holons |
| 224 | + |
| 225 | +### What Gets Created |
| 226 | + |
| 227 | +- **5 OAPPs** (HolonType: 74): |
| 228 | + - Star Navigation System (300 holons) |
| 229 | + - Planet Explorer (150 holons) |
| 230 | + - Moon Base Manager (50 holons) |
| 231 | + - Galaxy Tracker (500 holons) |
| 232 | + - Solar System Simulator (200 holons) |
| 233 | + |
| 234 | +- **1200+ Regular Holons** (HolonType: 0): |
| 235 | + - Assigned to OAPPs via `MetaData.oappId` |
| 236 | + - Types stored in `MetaData.holonTypeName` (Mission, NFT, Wallet, etc.) |
| 237 | + |
| 238 | +- **50 Unassigned Holons** (HolonType: 0): |
| 239 | + - No `oappId` in metadata |
| 240 | + |
| 241 | +## Loading Data |
| 242 | + |
| 243 | +### Current Status |
| 244 | +- ✅ **Seeding works** - Can create OAPPs and holons successfully |
| 245 | +- ⚠️ **Loading in progress** - Working on loading holons without chunked encoding errors |
| 246 | + |
| 247 | +### How to Load Data |
| 248 | + |
| 249 | +1. Click **"Load All from OASIS"** button |
| 250 | +2. The system will: |
| 251 | + - Authenticate with OASIS API |
| 252 | + - Load OAPPs (without children) using POST with `LoadChildren: false` |
| 253 | + - Load Avatars (without children) |
| 254 | + - Load regular holons separately |
| 255 | + - Transform and visualize the data |
| 256 | + |
| 257 | +### Expected Console Output |
| 258 | +``` |
| 259 | +✅ Authenticated with OASIS API |
| 260 | +Loading OAPPs... |
| 261 | +getAllHolonsWithOptions('74') returned 5 holons from data.result.result |
| 262 | +Loaded 5 OAPPs |
| 263 | +Loading Avatars... |
| 264 | +getAllHolonsWithOptions('3') returned X holons from data.result.result |
| 265 | +Loaded X Avatars |
| 266 | +Loading regular holons... |
| 267 | +getAllHolonsWithOptions('0') returned X holons from data.result.result |
| 268 | +Loaded X regular holons |
| 269 | +Found X regular holons, X avatars, X OAPPs |
| 270 | +``` |
| 271 | + |
| 272 | +## Key Files |
| 273 | + |
| 274 | +### Frontend (Visualizer) |
| 275 | +- `/holonic-visualizer/src/main.js` - Main orchestration |
| 276 | +- `/holonic-visualizer/src/api/OASISClient.js` - API client with authentication |
| 277 | +- `/holonic-visualizer/src/utils/seedOASISData.js` - Data seeding script |
| 278 | +- `/holonic-visualizer/src/data/OASISDataTransformer.js` - Data transformation |
| 279 | + |
| 280 | +### Backend (API) |
| 281 | +- `/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI/Startup.cs` - API configuration |
| 282 | +- `/ONODE/NextGenSoftware.OASIS.API.ONODE.WebAPI/Middleware/SubscriptionMiddleware.cs` - Middleware for request handling |
| 283 | + |
| 284 | +## Best Practices |
| 285 | + |
| 286 | +1. **Always use integer enum values** for `HolonType` (74, 3, 0) |
| 287 | +2. **Use POST with `LoadChildren: false`** when loading OAPPs to avoid large responses |
| 288 | +3. **Store type names in metadata** for reference (e.g., `MetaData.holonTypeName`) |
| 289 | +4. **Use PascalCase** for all request body properties when calling C# API |
| 290 | +5. **Handle chunked encoding errors** gracefully - they indicate responses are too large |
| 291 | +6. **Load data in smaller batches** if you encounter size issues |
| 292 | + |
| 293 | +## Common Errors & Fixes |
| 294 | + |
| 295 | +| Error | Cause | Fix | |
| 296 | +|-------|-------|-----| |
| 297 | +| `400 Bad Request - HolonType conversion` | Using string instead of integer | Use `74` not `"OAPP"` | |
| 298 | +| `400 Bad Request - ProviderMetaData.collection` | ProviderMetaData structure issue | Remove ProviderMetaData | |
| 299 | +| `ERR_INCOMPLETE_CHUNKED_ENCODING` | Response too large | Use POST with `LoadChildren: false` | |
| 300 | +| `CORS preflight redirect error` | HTTPS redirection on OPTIONS | Disable HTTPS redirection in Development | |
| 301 | +| `0 holons loaded` | String enum in URL | Use integer enum values (74, 3, 0) | |
| 302 | + |
| 303 | +## Next Steps |
| 304 | + |
| 305 | +1. ✅ Seeding works - Can create OAPPs and holons |
| 306 | +2. 🔄 Loading works - Need to verify `getAllHolonsWithOptions()` works correctly |
| 307 | +3. ⏳ Load child holons separately - After OAPPs load, load their holons individually |
| 308 | +4. ⏳ Visualize data - Ensure visualizer displays loaded data correctly |
| 309 | + |
| 310 | +## Testing Checklist |
| 311 | + |
| 312 | +- [x] Authentication works |
| 313 | +- [x] Can save OAPPs (HolonType: 74) |
| 314 | +- [x] Can save regular holons (HolonType: 0) |
| 315 | +- [x] Can save holons with metadata |
| 316 | +- [ ] Can load OAPPs without children |
| 317 | +- [ ] Can load Avatars |
| 318 | +- [ ] Can load regular holons |
| 319 | +- [ ] Can visualize loaded data |
| 320 | +- [ ] Can load child holons for each OAPP |
0 commit comments