"& note over a, b" does not work (vs "& note over a" - does work) ┌─┐ ║"│ └┬┘ ┌┼┐ │ | ,-. ┌──────────┐ ┌┴┐ ┌────────────┐ +--{ ) ┌──────────┐ ┌──────────────────┐ ┌──────────────────────┐ │apiClient │ Sales │Sales System│ | `-' │Controller│ │SignedUrlGenerator│ │ProjectDataTransformer│ │api-client│ Co-worker └──────┬─────┘ Endpoint └─────┬────┘ └─────────┬────────┘ └───────────┬──────────┘ └──────────┘ │ Selects a │ │ │ │ │ │ │ kitchen drawing │ ╔═══════════════════╗ │ │ │ │ │ │ for import │ ║e g //ProjectID// ░║ │ │ │ │ │ │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ >│ ╚═══════════════════╝ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╔════════════════════════╧════════════════════════╗ │ │ │ │ │ │ ║controller also gets: apiClient, translations, ░║ │ │ │ │ │ │ ║protocol, host, app.locals.secrets. ║ │ │ │ │ │ │ ║ IMAGE_PROXY_SECRET, ║ │ │ │ │ │ │ ║plannerUrl ║ │ │ │ │ │ │ ╚════════════════════════╤════════════════════════╝ │ │ │ │ │ProjectId, RetailUnit, │ │ │ │ │ │ │Language, APIKey, │ │ │ │ │ │ │Secret, MessageSignature │ │ │ │ │ │ │────────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ │ │exportProject( projectId, │ │ │ │ │ │ │retU, language, ... ) │ │ │ │ │ │ │──────────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ getProject(projectId), │ │ │ │ │ │ │ getMetadata(projectId) │ │ │ │ │ │───────────────────────────────────────────────────────────────────────────────────────>│ │ │ │ │ │ │ │ │ │ ╔═════╧═════════════════════════╗ │ │ project data, │ │ │ │ ║**metadata**=bom, wallpanel, ░║ │ │ project metadata │ │ │ │ ║worktop, wallEdgeStrip ║ │<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│ │ │ ╚═════╤═════════════════════════╝ │ │ │ │ │ │ │ │ │ ╔═════════╧════════════════════════════╧═════════╗ │ │ │ │ │ ║both calls (getProject & getMetadata) are ░║ │ │ │ │ │ ║asynchronous & parallel ║ │ │ │ │ │ ╚═════════╤════════════════════════════╤═════════╝ │ │ │ │ │ │ │