diff --git a/hub/blueprint/bp-ai-assistant-platform.radical b/hub/blueprint/bp-ai-assistant-platform.radical index b3c52cf..0c4a045 100644 --- a/hub/blueprint/bp-ai-assistant-platform.radical +++ b/hub/blueprint/bp-ai-assistant-platform.radical @@ -404,6 +404,45 @@ "decision": "Keep the base model frozen and push knowledge updates through the retrieval index rather than fine-tuning on new content.", "consequences": "Knowledge freshness becomes index-refresh latency instead of training-cycle latency, but overall answer quality is now capped by retrieval quality, not just model quality.", "alternatives": "1. Periodic fine-tuning on new knowledge — keeps knowledge \"in\" the model, but the feedback loop is slow and risks catastrophic forgetting of earlier knowledge. 2. Retrieval only (chosen). 3. Retrieval plus light fine-tuning for tone and format only — a reasonable hybrid, at the cost of a second training pipeline. 4. Stuffing all knowledge into the prompt without retrieval — doesn't scale past a small, static document set." + }, + { + "id": "mockup-support-chat", + "type": "mockup", + "label": "Support Chat", + "description": "Customer-facing chat: the assistant answers with cited sources when it can ground the answer and hands off to a person when it cannot.", + "x": 0, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "chat widget", + "wireframe": "" + }, + { + "id": "mockup-escalation-queue", + "type": "mockup", + "label": "Escalation Queue", + "description": "Human agents pick up escalated cases oldest-first; each case must be picked up within {{ESCALATION_SLA_MIN}} minutes.", + "x": 320, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/console/queue", + "wireframe": "" + }, + { + "id": "mockup-case-review", + "type": "mockup", + "label": "Case Review", + "description": "The assistant's proposed action with its confidence, per-field extraction confidence (below {{EXTRACTION_REVIEW_THRESHOLD_PCT}}% needs review) and the sources it used.", + "x": 640, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/console/cases/:id", + "wireframe": "" } ], "relations": [ @@ -571,6 +610,61 @@ "sourceId": "req-case-audit-trail", "targetId": "adr-confidence-gated-autonomy", "relationType": "traces-to" + }, + { + "id": "mockup-support-chat--req-escalation-pickup", + "sourceId": "mockup-support-chat", + "targetId": "req-escalation-pickup", + "relationType": "illustrates" + }, + { + "id": "mockup-support-chat--source-channel", + "sourceId": "mockup-support-chat", + "targetId": "source-channel", + "relationType": "presented-by" + }, + { + "id": "mockup-escalation-queue--req-escalation-pickup", + "sourceId": "mockup-escalation-queue", + "targetId": "req-escalation-pickup", + "relationType": "illustrates" + }, + { + "id": "mockup-escalation-queue--req-extraction-review", + "sourceId": "mockup-escalation-queue", + "targetId": "req-extraction-review", + "relationType": "illustrates" + }, + { + "id": "mockup-escalation-queue--agent-console", + "sourceId": "mockup-escalation-queue", + "targetId": "agent-console", + "relationType": "presented-by" + }, + { + "id": "mockup-escalation-queue--mockup-case-review", + "sourceId": "mockup-escalation-queue", + "targetId": "mockup-case-review", + "relationType": "navigates-to", + "label": "Pick up" + }, + { + "id": "mockup-case-review--req-extraction-review", + "sourceId": "mockup-case-review", + "targetId": "req-extraction-review", + "relationType": "illustrates" + }, + { + "id": "mockup-case-review--req-case-audit-trail", + "sourceId": "mockup-case-review", + "targetId": "req-case-audit-trail", + "relationType": "illustrates" + }, + { + "id": "mockup-case-review--agent-console", + "sourceId": "mockup-case-review", + "targetId": "agent-console", + "relationType": "presented-by" } ], "sequences": [ diff --git a/hub/blueprint/bp-analytical-data-platform.radical b/hub/blueprint/bp-analytical-data-platform.radical index 69bc63f..3398bba 100644 --- a/hub/blueprint/bp-analytical-data-platform.radical +++ b/hub/blueprint/bp-analytical-data-platform.radical @@ -369,6 +369,45 @@ "decision": "All curated-zone transformations are dbt models with at least one test and a description; Spark is reserved for raw ingestion and feature engineering.", "consequences": "Version control, testing and documentation by default; CI/CD required for model deployment; learning curve for SQL-only teams.", "alternatives": "1. Spark jobs only — flexible, no conventions for tests or lineage. 2. Stored procedures — vendor-coupled and hard to review." + }, + { + "id": "mockup-sales-dashboard", + "type": "mockup", + "label": "Sales Dashboard", + "description": "Self-service dashboard showing how fresh the data is; restricted columns are masked for users whose role does not allow them.", + "x": 0, + "y": 1534, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/dashboards/sales", + "wireframe": "" + }, + { + "id": "mockup-dataset-lineage", + "type": "mockup", + "label": "Dataset & Lineage", + "description": "Catalogue page for a curated dataset with owner, classification and column-level lineage from source to dashboard.", + "x": 320, + "y": 1534, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/datasets/:name/lineage", + "wireframe": "" + }, + { + "id": "mockup-quality-runs", + "type": "mockup", + "label": "Data Quality Runs", + "description": "Run results with the quality gate applied: failing records are quarantined, the affected models fail and the dataset owner is notified before anything reaches consumers.", + "x": 640, + "y": 1534, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/runs", + "wireframe": "" } ], "relations": [ @@ -506,6 +545,62 @@ "sourceId": "ff-quality", "targetId": "adr-dbt", "relationType": "implements" + }, + { + "id": "mockup-sales-dashboard--req-rls", + "sourceId": "mockup-sales-dashboard", + "targetId": "req-rls", + "relationType": "illustrates" + }, + { + "id": "mockup-sales-dashboard--req-freshness", + "sourceId": "mockup-sales-dashboard", + "targetId": "req-freshness", + "relationType": "illustrates" + }, + { + "id": "mockup-sales-dashboard--bi", + "sourceId": "mockup-sales-dashboard", + "targetId": "bi", + "relationType": "presented-by" + }, + { + "id": "mockup-sales-dashboard--mockup-dataset-lineage", + "sourceId": "mockup-sales-dashboard", + "targetId": "mockup-dataset-lineage", + "relationType": "navigates-to", + "label": "View dataset" + }, + { + "id": "mockup-dataset-lineage--req-lineage", + "sourceId": "mockup-dataset-lineage", + "targetId": "req-lineage", + "relationType": "illustrates" + }, + { + "id": "mockup-dataset-lineage--catalog", + "sourceId": "mockup-dataset-lineage", + "targetId": "catalog", + "relationType": "presented-by" + }, + { + "id": "mockup-dataset-lineage--mockup-quality-runs", + "sourceId": "mockup-dataset-lineage", + "targetId": "mockup-quality-runs", + "relationType": "navigates-to", + "label": "Quality" + }, + { + "id": "mockup-quality-runs--req-quality-gate", + "sourceId": "mockup-quality-runs", + "targetId": "req-quality-gate", + "relationType": "illustrates" + }, + { + "id": "mockup-quality-runs--orchestrator", + "sourceId": "mockup-quality-runs", + "targetId": "orchestrator", + "relationType": "presented-by" } ] } diff --git a/hub/blueprint/bp-ecommerce-platform.radical b/hub/blueprint/bp-ecommerce-platform.radical index 7eb5ed4..ec639df 100644 --- a/hub/blueprint/bp-ecommerce-platform.radical +++ b/hub/blueprint/bp-ecommerce-platform.radical @@ -492,6 +492,45 @@ "decision": "Each service owns its store; other services get data through APIs or events, never through the database.", "consequences": "Independent deployment and scaling; cross-service reports require projections or a data platform; joins across services are not possible in SQL.", "alternatives": "1. Shared database — simple joins, tight coupling. 2. Shared schema with per-service tables — coupling through migrations remains." + }, + { + "id": "mockup-product-page", + "type": "mockup", + "label": "Product Page", + "description": "Product detail with live availability from the catalogue; \"Add to cart\" leads into checkout.", + "x": 0, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/products/:slug", + "wireframe": "" + }, + { + "id": "mockup-checkout", + "type": "mockup", + "label": "Checkout", + "description": "Final checkout step. Card fields are the provider's hosted fields, so card data never touches platform services; every step must answer within {{CHECKOUT_P95_MS}} ms at p95.", + "x": 320, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/checkout", + "wireframe": "" + }, + { + "id": "mockup-order-confirmation", + "type": "mockup", + "label": "Order Confirmation", + "description": "Shown once payment is captured. Refreshing or retrying never charges again — capture is keyed by the order id — and stock stays reserved for the order.", + "x": 640, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/orders/:id", + "wireframe": "" } ], "relations": [ @@ -715,6 +754,62 @@ "sourceId": "req-pci-scope", "targetId": "adr-hosted-payments", "relationType": "traces-to" + }, + { + "id": "mockup-product-page--storefront", + "sourceId": "mockup-product-page", + "targetId": "storefront", + "relationType": "presented-by" + }, + { + "id": "mockup-product-page--mockup-checkout", + "sourceId": "mockup-product-page", + "targetId": "mockup-checkout", + "relationType": "navigates-to", + "label": "Checkout" + }, + { + "id": "mockup-checkout--req-checkout-latency", + "sourceId": "mockup-checkout", + "targetId": "req-checkout-latency", + "relationType": "illustrates" + }, + { + "id": "mockup-checkout--req-pci-scope", + "sourceId": "mockup-checkout", + "targetId": "req-pci-scope", + "relationType": "illustrates" + }, + { + "id": "mockup-checkout--storefront", + "sourceId": "mockup-checkout", + "targetId": "storefront", + "relationType": "presented-by" + }, + { + "id": "mockup-checkout--mockup-order-confirmation", + "sourceId": "mockup-checkout", + "targetId": "mockup-order-confirmation", + "relationType": "navigates-to", + "label": "Pay" + }, + { + "id": "mockup-order-confirmation--req-payment-once", + "sourceId": "mockup-order-confirmation", + "targetId": "req-payment-once", + "relationType": "illustrates" + }, + { + "id": "mockup-order-confirmation--req-stock-reservation", + "sourceId": "mockup-order-confirmation", + "targetId": "req-stock-reservation", + "relationType": "illustrates" + }, + { + "id": "mockup-order-confirmation--storefront", + "sourceId": "mockup-order-confirmation", + "targetId": "storefront", + "relationType": "presented-by" } ] } diff --git a/hub/blueprint/bp-fintech-ledger-platform.radical b/hub/blueprint/bp-fintech-ledger-platform.radical index 307e04c..a63b174 100644 --- a/hub/blueprint/bp-fintech-ledger-platform.radical +++ b/hub/blueprint/bp-fintech-ledger-platform.radical @@ -392,6 +392,45 @@ "decision": "The internal journal is the source of truth for what the product shows the customer; the bank feed is an input reconciled against it, not the other way round.", "consequences": "A balance can update the instant a posting is accepted, before the bank settles — which means \"posted\" and \"reconciled\" must be visibly different states, or a customer or support agent will confuse a provisional balance with a settled one.", "alternatives": "1. Bank/processor as source of truth, product waits for their confirmation — correct by construction, but the customer's balance now lags the actual action by the settlement delay. 2. Internal ledger as source of truth (chosen). 3. Dual-write both, resolve conflicts on read — no clear authority, hardest of the three to reason about when they disagree." + }, + { + "id": "mockup-statement", + "type": "mockup", + "label": "Account Statement", + "description": "Customer statement generated strictly from balances replayed through a fixed cut-off; each line links to a dispute.", + "x": 0, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/accounts/:id/statement", + "wireframe": "" + }, + { + "id": "mockup-dispute", + "type": "mockup", + "label": "Dispute a Transaction", + "description": "Opens an investigation the moment it is submitted; the customer gets a resolution or explanation within {{DISPUTE_INVESTIGATION_DAYS}} days.", + "x": 320, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/disputes/new", + "wireframe": "" + }, + { + "id": "mockup-reconciliation-exceptions", + "type": "mockup", + "label": "Reconciliation Exceptions", + "description": "Finance Ops queue of settlement events not matched within {{RECONCILIATION_LAG_MIN}} minutes. Corrections are compensating entries that must balance before they can be submitted — the journal itself is never edited.", + "x": 640, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/ops/exceptions", + "wireframe": "" } ], "relations": [ @@ -552,6 +591,55 @@ "sourceId": "adr-ledger-as-system-of-record", "targetId": "balance-projector", "relationType": "constrains" + }, + { + "id": "mockup-statement--req-statement-accuracy-cutoff", + "sourceId": "mockup-statement", + "targetId": "req-statement-accuracy-cutoff", + "relationType": "illustrates" + }, + { + "id": "mockup-statement--statement-service", + "sourceId": "mockup-statement", + "targetId": "statement-service", + "relationType": "presented-by" + }, + { + "id": "mockup-statement--mockup-dispute", + "sourceId": "mockup-statement", + "targetId": "mockup-dispute", + "relationType": "navigates-to", + "label": "Dispute" + }, + { + "id": "mockup-dispute--req-dispute-investigation-sla", + "sourceId": "mockup-dispute", + "targetId": "req-dispute-investigation-sla", + "relationType": "illustrates" + }, + { + "id": "mockup-dispute--statement-service", + "sourceId": "mockup-dispute", + "targetId": "statement-service", + "relationType": "presented-by" + }, + { + "id": "mockup-reconciliation-exceptions--req-reconciliation-freshness", + "sourceId": "mockup-reconciliation-exceptions", + "targetId": "req-reconciliation-freshness", + "relationType": "illustrates" + }, + { + "id": "mockup-reconciliation-exceptions--req-balanced-entry-enforcement", + "sourceId": "mockup-reconciliation-exceptions", + "targetId": "req-balanced-entry-enforcement", + "relationType": "illustrates" + }, + { + "id": "mockup-reconciliation-exceptions--finance-ops-console", + "sourceId": "mockup-reconciliation-exceptions", + "targetId": "finance-ops-console", + "relationType": "presented-by" } ], "sequences": [ diff --git a/hub/blueprint/bp-marketplace-platform.radical b/hub/blueprint/bp-marketplace-platform.radical index cc04e7f..abe62fc 100644 --- a/hub/blueprint/bp-marketplace-platform.radical +++ b/hub/blueprint/bp-marketplace-platform.radical @@ -414,6 +414,45 @@ "decision": "Suspend first on a high-confidence signal — hide from search, freeze payouts — then investigate and either reinstate or ban, rather than investigating first and acting after.", "consequences": "Buyers are protected as fast as the platform can detect a problem; the investigation SLA becomes a trust-critical metric in its own right, since it's now the only thing standing between a wrongly-flagged seller and lost income.", "alternatives": "1. Investigate first, act after — protects sellers from false positives, but a genuine bad actor keeps selling and collecting funds during the investigation window. 2. Suspend first, investigate after (chosen). 3. Community reporting only, no proactive detection — cheapest, but slowest and worst for buyer trust. 4. Permanent ban on first signal, no reinstatement path — fastest, but the harshest possible cost of a false positive." + }, + { + "id": "mockup-new-listing", + "type": "mockup", + "label": "New Listing", + "description": "Seller creates a listing; it goes into review and only appears in search once approved (within {{LISTING_REVIEW_SLA_HOURS}} h).", + "x": 0, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/sell/listings/new", + "wireframe": "" + }, + { + "id": "mockup-listing-review-queue", + "type": "mockup", + "label": "Listing Review Queue", + "description": "Trust & Safety queue sorted by time left on the review SLA. Rejecting a listing or suspending a seller removes it from search within {{SUPPRESSION_MINUTES}} minutes.", + "x": 320, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/trust/listings", + "wireframe": "" + }, + { + "id": "mockup-order-dispute", + "type": "mockup", + "label": "Order & Buyer Protection", + "description": "Buyer view of an order: funds stay held for {{DISPUTE_WINDOW_DAYS}} days after delivery, and opening a dispute freezes the payout.", + "x": 640, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/orders/:id", + "wireframe": "" } ], "relations": [ @@ -574,6 +613,48 @@ "sourceId": "adr-suspend-first-moderation", "targetId": "trust-safety-console", "relationType": "constrains" + }, + { + "id": "mockup-new-listing--req-listing-moderation", + "sourceId": "mockup-new-listing", + "targetId": "req-listing-moderation", + "relationType": "illustrates" + }, + { + "id": "mockup-new-listing--listings-service", + "sourceId": "mockup-new-listing", + "targetId": "listings-service", + "relationType": "presented-by" + }, + { + "id": "mockup-listing-review-queue--req-listing-moderation", + "sourceId": "mockup-listing-review-queue", + "targetId": "req-listing-moderation", + "relationType": "illustrates" + }, + { + "id": "mockup-listing-review-queue--req-delisting-suppression", + "sourceId": "mockup-listing-review-queue", + "targetId": "req-delisting-suppression", + "relationType": "illustrates" + }, + { + "id": "mockup-listing-review-queue--trust-safety-console", + "sourceId": "mockup-listing-review-queue", + "targetId": "trust-safety-console", + "relationType": "presented-by" + }, + { + "id": "mockup-order-dispute--req-dispute-window-hold", + "sourceId": "mockup-order-dispute", + "targetId": "req-dispute-window-hold", + "relationType": "illustrates" + }, + { + "id": "mockup-order-dispute--order-checkout-service", + "sourceId": "mockup-order-dispute", + "targetId": "order-checkout-service", + "relationType": "presented-by" } ], "sequences": [ diff --git a/hub/blueprint/bp-realtime-collaboration.radical b/hub/blueprint/bp-realtime-collaboration.radical index 299769e..571ab96 100644 --- a/hub/blueprint/bp-realtime-collaboration.radical +++ b/hub/blueprint/bp-realtime-collaboration.radical @@ -357,6 +357,45 @@ "decision": "Gateways hold no document state themselves; they publish and subscribe to operations through a shared broadcast bus, so any instance can serve any client.", "consequences": "Gateway instances scale and restart freely with no handoff logic, but every operation takes an extra hop through the bus, adding a small amount of latency to the common case.", "alternatives": "1. Sticky sessions routing all of a document's clients to one gateway instance — lower latency per operation, but that instance becomes a single point of failure and a hot-spot for popular documents. 2. Shared broadcast bus (chosen). 3. Peer-to-peer mesh between clients — no server bottleneck, but NAT traversal and offline persistence become much harder to get right." + }, + { + "id": "mockup-document-editor", + "type": "mockup", + "label": "Document Editor", + "description": "Everyone edits a local replica: changes apply instantly, keep working offline (up to {{OFFLINE_GRACE_HOURS}} h) and merge on reconnect; presence shows up to {{MAX_DOC_COLLABORATORS}} collaborators.", + "x": 0, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/d/:docId", + "wireframe": "" + }, + { + "id": "mockup-share-dialog", + "type": "mockup", + "label": "Share & Access", + "description": "Workspace admins manage who can open the document; removing someone disconnects their live session instead of waiting for it to expire.", + "x": 320, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/d/:docId/share", + "wireframe": "" + }, + { + "id": "mockup-version-history", + "type": "mockup", + "label": "Version History", + "description": "Browse and restore any earlier state of the document, reconstructed from snapshots plus the operation log.", + "x": 640, + "y": 2084, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/d/:docId/history", + "wireframe": "" } ], "relations": [ @@ -496,6 +535,62 @@ "sourceId": "req-room-capacity", "targetId": "adr-stateless-gateway-fleet", "relationType": "traces-to" + }, + { + "id": "mockup-document-editor--req-offline-merge", + "sourceId": "mockup-document-editor", + "targetId": "req-offline-merge", + "relationType": "illustrates" + }, + { + "id": "mockup-document-editor--req-room-capacity", + "sourceId": "mockup-document-editor", + "targetId": "req-room-capacity", + "relationType": "illustrates" + }, + { + "id": "mockup-document-editor--editor-client", + "sourceId": "mockup-document-editor", + "targetId": "editor-client", + "relationType": "presented-by" + }, + { + "id": "mockup-document-editor--mockup-share-dialog", + "sourceId": "mockup-document-editor", + "targetId": "mockup-share-dialog", + "relationType": "navigates-to", + "label": "Share" + }, + { + "id": "mockup-document-editor--mockup-version-history", + "sourceId": "mockup-document-editor", + "targetId": "mockup-version-history", + "relationType": "navigates-to", + "label": "History" + }, + { + "id": "mockup-share-dialog--req-access-revocation", + "sourceId": "mockup-share-dialog", + "targetId": "req-access-revocation", + "relationType": "illustrates" + }, + { + "id": "mockup-share-dialog--editor-client", + "sourceId": "mockup-share-dialog", + "targetId": "editor-client", + "relationType": "presented-by" + }, + { + "id": "mockup-version-history--req-snapshot-recovery", + "sourceId": "mockup-version-history", + "targetId": "req-snapshot-recovery", + "relationType": "illustrates" + }, + { + "id": "mockup-version-history--editor-client", + "sourceId": "mockup-version-history", + "targetId": "editor-client", + "relationType": "presented-by" } ], "sequences": [ diff --git a/hub/blueprint/bp-saas-b2b-platform.radical b/hub/blueprint/bp-saas-b2b-platform.radical index a3123f4..6f84d19 100644 --- a/hub/blueprint/bp-saas-b2b-platform.radical +++ b/hub/blueprint/bp-saas-b2b-platform.radical @@ -440,6 +440,45 @@ "decision": "After a successful SSO handshake, the gateway issues its own short-lived, tenant-scoped JWT. The IdP is the source of truth for the identity; the platform never stores the tenant's SSO credentials.", "consequences": "A tenant revoking a user at their IdP takes effect on the token's next short expiry, not instantly, which is an accepted trade-off; token issuance adds one extra hop to first login.", "alternatives": "Storing IdP session cookies directly was rejected — it would tie the platform's session lifetime to each IdP's own cookie semantics and leak IdP-specific state into the app tier." + }, + { + "id": "mockup-signup", + "type": "mockup", + "label": "Sign Up", + "description": "Self-serve sign-up; the new tenant gets an isolated, ready-to-use workspace within {{PROVISION_MINUTES}} minutes.", + "x": 0, + "y": 2324, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/signup", + "wireframe": "" + }, + { + "id": "mockup-workspace-dashboard", + "type": "mockup", + "label": "Workspace Dashboard", + "description": "Tenant home. When a payment fails the workspace turns read-only — data stays visible, writes are blocked — until billing is fixed.", + "x": 320, + "y": 2324, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/", + "wireframe": "" + }, + { + "id": "mockup-billing-usage", + "type": "mockup", + "label": "Billing & Usage", + "description": "Tenant admin view of plan, metered usage and invoices; usage figures are recorded exactly once and reconciled against source logs.", + "x": 640, + "y": 2324, + "width": 220, + "height": 190, + "collapsed": false, + "screen": "/settings/billing", + "wireframe": "" } ], "relations": [ @@ -561,6 +600,62 @@ "targetId": "email-provider", "label": "Sends transactional email", "technology": "HTTPS" + }, + { + "id": "mockup-signup--req-tenant-provisioning-time", + "sourceId": "mockup-signup", + "targetId": "req-tenant-provisioning-time", + "relationType": "illustrates" + }, + { + "id": "mockup-signup--webapp", + "sourceId": "mockup-signup", + "targetId": "webapp", + "relationType": "presented-by" + }, + { + "id": "mockup-signup--mockup-workspace-dashboard", + "sourceId": "mockup-signup", + "targetId": "mockup-workspace-dashboard", + "relationType": "navigates-to", + "label": "Create workspace" + }, + { + "id": "mockup-workspace-dashboard--req-subscription-enforcement", + "sourceId": "mockup-workspace-dashboard", + "targetId": "req-subscription-enforcement", + "relationType": "illustrates" + }, + { + "id": "mockup-workspace-dashboard--webapp", + "sourceId": "mockup-workspace-dashboard", + "targetId": "webapp", + "relationType": "presented-by" + }, + { + "id": "mockup-workspace-dashboard--mockup-billing-usage", + "sourceId": "mockup-workspace-dashboard", + "targetId": "mockup-billing-usage", + "relationType": "navigates-to", + "label": "Update billing" + }, + { + "id": "mockup-billing-usage--req-usage-metering-accuracy", + "sourceId": "mockup-billing-usage", + "targetId": "req-usage-metering-accuracy", + "relationType": "illustrates" + }, + { + "id": "mockup-billing-usage--req-subscription-enforcement", + "sourceId": "mockup-billing-usage", + "targetId": "req-subscription-enforcement", + "relationType": "illustrates" + }, + { + "id": "mockup-billing-usage--webapp", + "sourceId": "mockup-billing-usage", + "targetId": "webapp", + "relationType": "presented-by" } ] } diff --git a/src/renderer/src/components/HubImportModal.tsx b/src/renderer/src/components/HubImportModal.tsx index f8fc2d1..70d6c0a 100644 --- a/src/renderer/src/components/HubImportModal.tsx +++ b/src/renderer/src/components/HubImportModal.tsx @@ -5,6 +5,7 @@ import { useDiagramStore } from '../store/diagramStore' import type { C4Node, C4Relation, C4ElementType, DiagramSequence } from '../types/c4' import { NODE_SIZES } from '../types/c4' import { isParentAllowed } from '../types/metamodel' +import { nodeTypeTheme } from '../types/hubTheme' // ─── Props ────────────────────────────────────────────────────────────────── @@ -979,11 +980,12 @@ export function HubImportModal({ open, onClose, preselectedIds }: Props): React. component: 'Components', database: 'Databases', webapp: 'Web Apps', queue: 'Queues', domain: 'Domains', group: 'Groups', adr: 'ADRs', 'fitness-fn': 'Fitness Functions', requirement: 'Requirements', + person: 'People', } return Object.entries(grouped).filter(([type]) => type !== 'blueprint').map(([type, nodes]) => (