Prolo — RFQ Matching AWS Architecture (Stages 5–6)

AWS services behind the matching + submission tail: from the ExtractedQuote already in RDS (the ingestion handoff) → matched to a customer RFQ → submitted to the core system. Even tighter posture than ingestion — matching talks only to internal systems (RDS, Bedrock via endpoint, procurement API via private link), so no public ingress and no internet egress at all (no NAT). Ingestion (Stages 1–4) is in ingestion/aws-architecture.html. Yellow = AI.

flowchart TB
    subgraph CORE["🏢 Prolo core — reached via PrivateLink / VPC peering (private)"]
        PROC["Internal Procurement API
RFQs · submit / update quote"] end subgraph VPC["🔒 AWS VPC — private · no public ingress · no internet egress"] direction TB subgraph PRIV["Private subnets · multi-AZ · no public IPs"] SYNC["λ Lambda · RFQ sync
pull RFQs → read-model"] M1["Fargate · 1 RFQ MATCHING
pgvector kNN → rerank → LLM"] S2["λ Lambda · 2 SUBMIT TO CORE
submit / update quote"] RDS[("RDS Postgres + pgvector
quotes · RFQ read-model · matches")] end subgraph VPE["AWS services · via VPC Endpoints (PrivateLink)"] SCH["EventBridge Scheduler"] MQ(["SQS · to-match"]) SUBQ(["SQS · to-submit"]) HRQ(["SQS · human review"]) DLQ(["SQS · DLQ"]) BR["Bedrock
embeddings + rerank/LLM disambiguation"] SEC["Secrets Manager"] CW["CloudWatch"] SNS["SNS · alarm topic"] end end subgraph OC["🔔 On-call — external"] PD["PagerDuty"] SLACK["Slack / ticket"] end %% handoff from ingestion ING["Ingestion · Stage 4
ExtractedQuote in RDS"] ==>|"on P1 write → enqueue"| MQ --> M1 %% RFQ read-model sync SCH ==>|periodic| SYNC SYNC <-->|"read RFQs (private link)"| PROC SYNC -.->|"embed RFQ lines"| BR SYNC -->|"upsert RFQ read-model + embeddings"| RDS %% matching RDS -->|"quote + RFQ line embeddings (kNN)"| M1 M1 <-->|"rerank / LLM disambiguate"| BR M1 -->|"MatchedQuote: +rfq_id, matchEvidence"| RDS M1 -->|matched| SUBQ --> S2 M1 -.no/ambiguous match.-> HRQ %% submit (P2) S2 <-->|"submit / update (private link)"| PROC S2 -->|status = SUBMITTED| RDS S2 -.rejected.-> HRQ %% platform + alerting SUBQ -.poison.-> DLQ SEC -.creds.-> SYNC & M1 & S2 SYNC & M1 & S2 -.metrics/logs.-> CW DLQ -.depth alarm.-> CW CW -->|alarms| SNS SNS ==>|"critical → page"| PD SNS -.->|warning| SLACK classDef ai fill:#fde047,stroke:#ca8a04,color:#000 class M1,BR ai %% zone fills — distinct colours per zone style CORE fill:#f2f0ff,stroke:#8250df,stroke-width:2px,color:#1f2328 style VPC fill:#eef4ff,stroke:#2f6fd6,stroke-width:2px,color:#1f2328 style PRIV fill:#e2ecff,stroke:#3b7ddd,stroke-width:1.5px,color:#1f2328 style VPE fill:#fff4e6,stroke:#e8992e,stroke-width:2px,color:#1f2328 style OC fill:#fdeef0,stroke:#d1242f,stroke-width:1.5px,color:#1f2328
Prolo core (private link / peering) AWS VPC (private compute) AWS services · VPC Endpoints On-call · PagerDuty / Slack Yellow = AI (matching · Bedrock)