beers routing - BevvyTech/BrewskiDocs GitHub Wiki

Beers Route Architecture

This document captures the post-refactor structure for beer endpoints. It is the canonical reference for where handlers live, the shared helpers they depend on, and cross-cutting behaviours (auth, logging, storage) that any future changes must preserve.

Directory Layout

  • API/src/routes/beers/index.ts—Fastify plugin registrar that wires the feature-specific sub-plugins.
  • API/src/routes/beers/*.ts—Scoped route handlers grouped by responsibility (list, stock, create, detail, update).
  • API/src/routes/beers/gallery/*—Gallery upload/list/update/delete routes.
  • API/src/routes/beers/badge-image/*—Badge upload, AI generation, serving, and deletion endpoints.
  • API/src/modules/beers/—Shared utilities extracted from the former monolithic route:
    • activity.service.ts — wraps activity log writes for consistent metadata.
    • badge-schema.ts / badge.service.ts — validation and OpenAI integration.
    • constants.ts / schemas.ts — Zod schemas and cross-route enums.
    • access.ts — shared authentication helpers (ensureAuthenticated, ensureTeamMembership, ensureBeerAccess) to keep route files lean.
    • file-upload.ts / media.service.ts — MIME detection, Sharp transforms, and multipart helpers.
    • inventory.ts / mappers.ts — helper mappers and stock key generation.

Route Plugin Summary

File HTTP Surface Notes
list.ts GET /beers Pagination, multipack enrichment (uses computeBeerContainerAvailability).
stock.ts GET /beers/stock Collates packaged lots per container with availability rollups.
create.ts POST /beers Validates operating mode constraints and logs beer.created.
detail.ts GET /beers/:beerId Retrieves a single beer record after membership verification.
update.ts PATCH /beers/:beerId Applies partial updates, tracks changed fields, logs beer.updated.
gallery/list.ts GET /beers/:beerId/gallery Summary toggle plus uploader metadata.
gallery/create.ts POST /beers/:beerId/gallery Validates uploads, creates variants, keeps positions dense.
gallery/update.ts PATCH /beers/:beerId/gallery/:imageId Caption/position/tag updates with reordering logic.
gallery/remove.ts DELETE /beers/:beerId/gallery/:imageId Deletes files + records beer.gallery.removed.
badge-image/serve.ts GET /beers/:beerId/image Returns stored badge URLs (icon + original).
badge-image/upload.ts POST /beers/:beerId/image Handles manual uploads, variant generation, cleans old assets.
badge-image/generate.ts POST /beers/:beerId/image/generate Orchestrates OpenAI flow, persists usage + storage.
badge-image/remove.ts DELETE /beers/:beerId/image Idempotent removal of badge files + metadata.

Every handler:

  • Enforces authentication and team membership before performing work.
  • Delegates persistence to Prisma models (beer, beerGalleryImage, aiActionLog, etc.).
  • Emits activity entries so the operations timeline stays intact.
  • Returns minimal, well-typed payloads that the admin UI already expects.

Media & Storage Notes

  • File uploads are limited to PNG/JPG/WebP with explicit byte caps (3.5 MB badge, 3 MB gallery). Both the declared MIME type and the detected content type must agree.
  • Gallery uploads generate an original plus thumbnail variant; badge uploads generate original + 100 px icon.
  • Cloud storage interaction is centralised through services/image-storage, keeping the routes thin.

OpenAI Badge Generation

  • badge-image/generate.ts relies on env.OPENAI_API_KEY; missing keys short-circuit with 503.
  • Generated prompts flow through badge.service.ts, which formats beer/team context and manages request retries.
  • AiActionLog entries (success + failure) are recorded for observability and billing; image usage is persisted to ai_image_usage.

Implementation Guard Rails

  • Keep route files well under 500 lines—new functionality should live in helper modules.
  • Update Docs/api/Beers.md and this file whenever endpoints or shared behaviours change.
  • When new consumers need beer data, depend on modules/beers/* helpers instead of duplicating mapping logic.
⚠️ **GitHub.com Fallback** ⚠️