Skip to content

System architecture

Golfer client (web / iOS / Android / watch)
|
v
Azure API Management / App Service-hosted API
|
+--> Application services and orchestration
| +--> Foundry agents / fallback recommendation logic
| +--> OpenGolf integration
| +--> Speech synthesis
|
+--> PostgreSQL (system of record)
|
+--> Blob storage (image/avatar bytes only)
  • Clients own capture, immediate presentation, and platform-native UX concerns.
  • The API owns validation, persistence, orchestration, and integration boundaries.
  • PostgreSQL stores structured entities and relationships.
  • Blob storage stores binary assets only.
  • AI Foundry is treated as an orchestrated pipeline, not a single monolithic step.
  1. A client posts multipart/form-data to POST /api/photos/upload.
  2. PhotosController validates the request, resolves user ownership, and derives optional location context.
  3. PhotoService saves the image and metadata.
  4. ShotAnalysisPipeline loads swing averages, attempts Foundry lie analysis, loads profile personalization, and requests stance guidance.
  5. If agent calls fail, built-in fallback recommendation logic still returns a usable answer.
  6. The API updates the photo’s analysis and returns the full photo payload.
  1. The client requests GET /api/photos/{id}/speech.
  2. The API builds a spoken summary from the shot analysis.
  3. SpeechSynthesisService renders MP3 audio.
  4. The client plays the result immediately.
  • Microsoft Entra External ID is the main golfer identity source.
  • Azure API Management validates tokens at the edge.
  • The API still configures bearer authentication so application code can resolve the current caller.
  • Development auth can impersonate a test user only in development.

Each golfer’s data is scoped by a canonical user id derived from authentication. Controllers and repositories preserve per-user separation so one golfer cannot read another golfer’s uploads or profile data by id alone.