|
10 | 10 | 3. [AWS SSO Setup](#aws-sso-setup) |
11 | 11 | 4. [Other helpful commands](#other-helpful-commands) |
12 | 12 | 2. [Tests](#tests) |
13 | | -3. [pytest tests](#pytest-tests) |
14 | | -4. [End-to-End feature tests](#end-to-end-feature-tests) |
15 | | -5. [Generate the Feature Test Postman collection](#generate-the-feature-test-postman-collection) |
16 | | -6. [Workflow](#workflow) |
17 | | -7. [Swagger](#swagger) |
18 | | -8. [ETL](#etl) |
| 13 | + 1. [pytest tests](#pytest-tests) |
| 14 | + 2. [End-to-End feature tests](#end-to-end-feature-tests) |
| 15 | + 3. [Generate the Feature Test Postman collection](#generate-the-feature-test-postman-collection) |
| 16 | +3. [Data modelling](#data-modelling) |
| 17 | + 1. [Domain models](#domain-models) |
| 18 | + 2. [Database models](#database-models) |
| 19 | + 3. [Response models](#response-models) |
| 20 | + 4. [Request models](#request-models) |
| 21 | +4. [Workflow](#workflow) |
| 22 | +5. [Swagger](#swagger) |
| 23 | +6. [ETL](#etl) |
19 | 24 |
|
20 | 25 | --- |
21 | 26 |
|
@@ -273,6 +278,53 @@ in the environment (but these are filled out already if generated with the integ |
273 | 278 |
|
274 | 279 | 💡 **The feature tests are only guaranteed to work out-of-the-box with an empty database** |
275 | 280 |
|
| 281 | +## Data modelling |
| 282 | + |
| 283 | +Modelling in Connecting Party Manager is split into four partially-decoupled components: |
| 284 | + |
| 285 | +- Domain models: The conceptual entities of Connecting Party Manager, without any reference to database indexing, and request / response syntax. |
| 286 | +- Database models: A wrapper on the domain models that we persist to database (DynamoDB), indicating write-integrity (primary keys) and a read/search interface (indexing). |
| 287 | +- Response models: Deviations from the domain model (error handling, search result wrapping, private field exclusion, etc) |
| 288 | +- Request models: API-specific models indicating the expected request bodies of create/update/search operations. |
| 289 | + |
| 290 | +### Domain models |
| 291 | + |
| 292 | +TBC |
| 293 | + |
| 294 | +### Database models |
| 295 | + |
| 296 | +#### Write-integrity (primary keys) |
| 297 | + |
| 298 | +The Partition Key (`pk`) that we use for all objects\* in the database is a unique combination of prefix (aligned with the object type, e.g. `D#` for `Device`) and identifier (generally a UUID). The Sort Key (`sk`) that we use is always exactly equal to the Partition Key. This is opposed to having fully denormalised objects so that attributes are nested under their own `sk`. The reason for doing this is to limit multiple read operations for a given object, and also save I/O in our ETL process by reducing the number of database transactions required per object. |
| 299 | + |
| 300 | +Objects can additionally be indexed by any keys (see [Domain models](#domain-models)) that they have. For every key in an domain object, |
| 301 | +a copy is made in the database with the index being that key, rather |
| 302 | +than the object's identifier. Such copies are referred to as non-root |
| 303 | +objects, whereas the "original" (indexed by identifier) is referred to |
| 304 | +as the root object. |
| 305 | + |
| 306 | +\* In the case of `Device` tags, which sit outside of the standard database model, `pk` is equal to a query string and `sk` is equal to `pk` of the object that is referred to. A tag-indexed `Device` is otherwise a copy of the root `Device`. |
| 307 | + |
| 308 | +#### Read/search interface |
| 309 | + |
| 310 | +We have implemented a Global Secondary Index (GSI) for attributes named `pk_read` and `sk_read`. The pattern that is place is as follows: |
| 311 | + |
| 312 | +- `pk_read`: A concatenation of parent `pk` values (joined with `#`, e.g. `PT#<product_team_id>#P<product_id>`) |
| 313 | +- `sk_read`: Equal to the `pk` of the object itself. |
| 314 | + |
| 315 | +We refer to this as an "ownership" model, as it allows for reads to be |
| 316 | +executed in a way that mirrors the API read operations (GET `grandparent/parent/child`), whilst also giving us the ability to return all objects owned by the object indicated in the `pk_read` - which is a common operation for us. |
| 317 | + |
| 318 | +A `read` and `search` is available on all `Repository` patterns (almost) for free (the base `_read` and `_search` require a shallow wrapper, but most of the work is done for you). |
| 319 | + |
| 320 | +### Response models |
| 321 | + |
| 322 | +TBC |
| 323 | + |
| 324 | +### Request models |
| 325 | + |
| 326 | +TBC |
| 327 | + |
276 | 328 | ## Workflow |
277 | 329 |
|
278 | 330 | In order to create new branches, use the commands listed below. Note that the commands will throw an error if |
|
0 commit comments