B[Auth: extract org_id from JWT] B --> C[Save to temp file] C --> D[extract_text_from_pdf/docx] D --> E1[extract_structured_data\nAnthropic Claude] D --> E2[extract_name_from_cv\nAnthropic Claude] D --> E3[extract_contact_info\nAnthropic Claude + regex] D --> E4[get_embedding\nOpenAI ada-002\n→ 1536-dim vector] E1 & E2 & E3 & E4 --> F[Assemble metadata\nname, level, skills,\nexperience, industries,\nt-shape, contact info] F --> G1[INSERT INTO documents\nid, content, metadata,\norganization_id] F --> G2[INSERT INTO embeddings\nid, vector 1536,\ndocument_id] G1 & G2 --> H[UPDATE users\nSET profile_id = doc_id] H --> I[Invalidate cache\nuser_profile / user_profiles] end subgraph MATCH["šŸ” MATCHING — POST /api/profiles/match"] J[User"> B[Auth: extract org_id from JWT] B --> C[Save to temp file] C --> D[extract_text_from_pdf/docx] D --> E1[extract_structured_data\nAnthropic Claude] D --> E2[extract_name_from_cv\nAnthropic Claude] D --> E3[extract_contact_info\nAnthropic Claude + regex] D --> E4[get_embedding\nOpenAI ada-002\n→ 1536-dim vector] E1 & E2 & E3 & E4 --> F[Assemble metadata\nname, level, skills,\nexperience, industries,\nt-shape, contact info] F --> G1[INSERT INTO documents\nid, content, metadata,\norganization_id] F --> G2[INSERT INTO embeddings\nid, vector 1536,\ndocument_id] G1 & G2 --> H[UPDATE users\nSET profile_id = doc_id] H --> I[Invalidate cache\nuser_profile / user_profiles] end subgraph MATCH["šŸ” MATCHING — POST /api/profiles/match"] J[User"> B[Auth: extract org_id from JWT] B --> C[Save to temp file] C --> D[extract_text_from_pdf/docx] D --> E1[extract_structured_data\nAnthropic Claude] D --> E2[extract_name_from_cv\nAnthropic Claude] D --> E3[extract_contact_info\nAnthropic Claude + regex] D --> E4[get_embedding\nOpenAI ada-002\n→ 1536-dim vector] E1 & E2 & E3 & E4 --> F[Assemble metadata\nname, level, skills,\nexperience, industries,\nt-shape, contact info] F --> G1[INSERT INTO documents\nid, content, metadata,\norganization_id] F --> G2[INSERT INTO embeddings\nid, vector 1536,\ndocument_id] G1 & G2 --> H[UPDATE users\nSET profile_id = doc_id] H --> I[Invalidate cache\nuser_profile / user_profiles] end subgraph MATCH["šŸ” MATCHING — POST /api/profiles/match"] J[User">
  flowchart TD
      subgraph UPLOAD["šŸ“¤ CV UPLOAD  —  POST /api/profiles/upload"]
          A[User uploads PDF/DOCX] --> B[Auth: extract org_id from JWT]
          B --> C[Save to temp file]
          C --> D[extract_text_from_pdf/docx]

          D --> E1[extract_structured_data\nAnthropic Claude]
          D --> E2[extract_name_from_cv\nAnthropic Claude]
          D --> E3[extract_contact_info\nAnthropic Claude + regex]
          D --> E4[get_embedding\nOpenAI ada-002\n→ 1536-dim vector]

          E1 & E2 & E3 & E4 --> F[Assemble metadata\nname, level, skills,\nexperience, industries,\nt-shape, contact info]

          F --> G1[INSERT INTO documents\nid, content, metadata,\norganization_id]
          F --> G2[INSERT INTO embeddings\nid, vector 1536,\ndocument_id]

          G1 & G2 --> H[UPDATE users\nSET profile_id = doc_id]
          H --> I[Invalidate cache\nuser_profile / user_profiles]
      end

      subgraph MATCH["šŸ” MATCHING  —  POST /api/profiles/match"]
          J[User submits project description] --> K[Auth: extract org_id from JWT]
          K --> L[Embed project description\nOpenAI ada-002]

          L --> M[Vector search pgvector\nSELECT … ORDER BY\nembedding <-> query_vec\nLIMIT 10\nWHERE org_id = …]

          M --> N{level filter?}
          N -->|yes| O[Keep matching level only]
          N -->|no| P

          O --> P{start_date?}
          P -->|yes| Q[AvailabilityDB lookup\nFilter by ISO week]
          P -->|no| R

          Q --> R[Multi-dimensional scoring\n30% vector similarity\n25% experience relevance\n20% industry alignment\n15% level match\n10% competency match]

          R --> S[Top 4 candidates →\nLLM deep analysis\nAnthropic claude-haiku\nstrengths, gaps, score]

          S --> T[LRU cache result\nsize 1000]
          T --> U[Log to match_queries\n+ match_results tables]
          U --> V[Return ranked matches\nto client]
      end

      I -.->|profile now findable| M