|
| 1 | +# Mapping Rules |
| 2 | + |
| 3 | +This document explains how to create mappings for the web3-adapter system, which enables data exchange between different platforms using a universal ontology. |
| 4 | + |
| 5 | +## Basic Structure |
| 6 | + |
| 7 | +A mapping file defines how local database fields map to global ontology fields. The structure is: |
| 8 | + |
| 9 | +```json |
| 10 | +{ |
| 11 | + "tableName": "local_table_name", |
| 12 | + "schemaId": "global_schema_uuid", |
| 13 | + "ownerEnamePath": "path_to_owner_ename", |
| 14 | + "ownedJunctionTables": ["junction_table1", "junction_table2"], |
| 15 | + "localToUniversalMap": { |
| 16 | + "localField": "globalField", |
| 17 | + "localRelation": "tableName(relationPath),globalAlias" |
| 18 | + } |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | +## Field Mapping |
| 23 | + |
| 24 | +### Direct Field Mapping |
| 25 | + |
| 26 | +```json |
| 27 | +"localField": "globalField" |
| 28 | +``` |
| 29 | + |
| 30 | +Maps a local field directly to a global field with the same name. |
| 31 | + |
| 32 | +### Relation Mapping |
| 33 | + |
| 34 | +```json |
| 35 | +"localRelation": "tableName(relationPath),globalAlias" |
| 36 | +``` |
| 37 | + |
| 38 | +Maps a local relation to a global field, where: |
| 39 | + |
| 40 | +- `tableName` is the referenced table name |
| 41 | +- `relationPath` is the path to the relation data |
| 42 | +- `globalAlias` is the target global field name |
| 43 | + |
| 44 | +### Array Relation Mapping |
| 45 | + |
| 46 | +```json |
| 47 | +"participants": "users(participants[].id),participantIds" |
| 48 | +``` |
| 49 | + |
| 50 | +Maps an array of relations: |
| 51 | + |
| 52 | +- `participants[].id` extracts the `id` field from each item in the `participants` array |
| 53 | +- `users()` resolves each ID to a global user reference |
| 54 | +- `participantIds` is the target global field name |
| 55 | + |
| 56 | +## Special Functions |
| 57 | + |
| 58 | +### Date Conversion (`__date`) |
| 59 | + |
| 60 | +Converts various timestamp formats to ISO string format. |
| 61 | + |
| 62 | +```json |
| 63 | +"createdAt": "__date(createdAt)" |
| 64 | +"timestamp": "__date(calc(timestamp * 1000))" |
| 65 | +``` |
| 66 | + |
| 67 | +**Supported input formats:** |
| 68 | + |
| 69 | +- Unix timestamp (number) |
| 70 | +- Firebase v8 timestamp (`{_seconds: number}`) |
| 71 | +- Firebase v9+ timestamp (`{seconds: number}`) |
| 72 | +- Firebase Timestamp objects |
| 73 | +- Date objects |
| 74 | +- UTC strings |
| 75 | + |
| 76 | +### Calculation (`__calc`) |
| 77 | + |
| 78 | +Performs mathematical calculations using field values. |
| 79 | + |
| 80 | +```json |
| 81 | +"total": "__calc(quantity * price)" |
| 82 | +"average": "__calc((score1 + score2 + score3) / 3)" |
| 83 | +``` |
| 84 | + |
| 85 | +**Features:** |
| 86 | + |
| 87 | +- Supports basic arithmetic operations (+, -, \*, /, etc.) |
| 88 | +- Can reference other fields in the same entity |
| 89 | +- Automatically resolves field values before calculation |
| 90 | + |
| 91 | +## Owner Path |
| 92 | + |
| 93 | +The `ownerEnamePath` defines how to determine which eVault owns the data: |
| 94 | + |
| 95 | +```json |
| 96 | +"ownerEnamePath": "ename" // Direct field |
| 97 | +"ownerEnamePath": "users(createdBy.ename)" // Nested via relation |
| 98 | +"ownerEnamePath": "users(participants[].ename)" // Array relation |
| 99 | +``` |
| 100 | + |
| 101 | +## Junction Tables |
| 102 | + |
| 103 | +Junction tables (many-to-many relationships) can be marked as owned: |
| 104 | + |
| 105 | +```json |
| 106 | +"ownedJunctionTables": [ |
| 107 | + "user_followers", |
| 108 | + "user_following" |
| 109 | +] |
| 110 | +``` |
| 111 | + |
| 112 | +When junction table data changes, it triggers updates to the parent entity. |
| 113 | + |
| 114 | +## Examples |
| 115 | + |
| 116 | +### User Mapping |
| 117 | + |
| 118 | +```json |
| 119 | +{ |
| 120 | + "tableName": "users", |
| 121 | + "schemaId": "550e8400-e29b-41d4-a716-446655440000", |
| 122 | + "ownerEnamePath": "ename", |
| 123 | + "ownedJunctionTables": ["user_followers", "user_following"], |
| 124 | + "localToUniversalMap": { |
| 125 | + "handle": "username", |
| 126 | + "name": "displayName", |
| 127 | + "description": "bio", |
| 128 | + "avatarUrl": "avatarUrl", |
| 129 | + "ename": "ename", |
| 130 | + "followers": "followers", |
| 131 | + "following": "following" |
| 132 | + } |
| 133 | +} |
| 134 | +``` |
| 135 | + |
| 136 | +### Group with Relations |
| 137 | + |
| 138 | +```json |
| 139 | +{ |
| 140 | + "tableName": "groups", |
| 141 | + "schemaId": "550e8400-e29b-41d4-a716-446655440003", |
| 142 | + "ownerEnamePath": "users(participants[].ename)", |
| 143 | + "localToUniversalMap": { |
| 144 | + "name": "name", |
| 145 | + "description": "description", |
| 146 | + "owner": "owner", |
| 147 | + "admins": "users(admins),admins", |
| 148 | + "participants": "users(participants[].id),participantIds", |
| 149 | + "createdAt": "__date(createdAt)", |
| 150 | + "updatedAt": "__date(updatedAt)" |
| 151 | + } |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +## Best Practices |
| 156 | + |
| 157 | +1. **Use descriptive global field names** that match the ontology schema |
| 158 | +2. **Handle timestamps consistently** using `__date()` function |
| 159 | +3. **Map relations properly** using the `tableName(relationPath)` syntax |
| 160 | +4. **Use aliases** when the global field name differs from the local field |
| 161 | +5. **Test mappings** with sample data to ensure proper conversion |
| 162 | +6. **Document complex mappings** with comments explaining the logic |
| 163 | + |
| 164 | +## Troubleshooting |
| 165 | + |
| 166 | +### Common Issues |
| 167 | + |
| 168 | +1. **Missing relations**: Ensure the referenced table has a mapping |
| 169 | +2. **Invalid paths**: Check that the relation path matches your entity structure |
| 170 | +3. **Type mismatches**: Use `__date()` for timestamps, `__calc()` for calculations |
| 171 | +4. **Circular references**: Avoid mapping entities that reference each other infinitely |
| 172 | + |
| 173 | +### Debug Tips |
| 174 | + |
| 175 | +- Check the console for mapping errors |
| 176 | +- Verify that all referenced tables have mappings |
| 177 | +- Test with simple data first, then add complexity |
| 178 | +- Use the `__calc()` function to debug field values |
| 179 | + |
0 commit comments