This repository contains shared models and types used across the Recipe Management platform services.
The shared models provide a consistent interface for recipe data exchange between:
- Frontend (React/TypeScript)
- AI Service (Spring Boot/Java)
- Storage Service (Spring Boot/Java)
The core Recipe model includes all recipe-related fields with consistent naming and types across services.
recipeName: Recipe title (consistent naming)ingredients: List of ingredient strings with quantitiesinstructions: Step-by-step cooking instructionsservings: Number of servingsnutritionalInfo: Structured nutritional datatips: Recipe tips and additional informationsource: Origin of recipe ("ai-generated", "manual", etc.)
prepTimeMinutes/cookTimeMinutes: Integer minutesprepTime/cookTime: Human-readable strings (e.g., "15 minutes")totalTimeMinutes: Calculated total time
In addition to core persistence models, shared response DTOs are available for service API boundaries in both TypeScript and Java:
RecipeResponse: Enriched API response payload containing the core recipe fields plus author metadata (authorDisplayName,authorAvatarUrl,author) and social interaction state (likeCount,isLikedByCurrentUser,isSavedByCurrentUser).AuthorDto: Author profile information (uid,displayName,avatarUrl).PagedRecipeResponse: Standard paginated wrapper containingrecipes,size,totalCount, andnextPageToken.
To support backward compatibility across services:
- Core
Recipeentities standardize onrecipeName. RecipeResponseemits bothrecipeNameandtitle(or supports payloads specifying either key), allowing existing consumers expectingtitleand updated consumers expectingrecipeNameto consume responses without breaking.
import { Recipe, RecipeResponse, PagedRecipeResponse, AuthorDto, NutritionalInfo, RecipeTips } from '@recipe-management/shared';
// Use the shared types
const recipe: Recipe = {
recipeName: "Spaghetti Carbonara",
ingredients: ["400g spaghetti", "200g pancetta"],
instructions: ["Boil pasta", "Fry pancetta"],
servings: 4,
source: "manual"
};import com.recipe.shared.model.Recipe;
import com.recipe.shared.model.RecipeResponse;
import com.recipe.shared.model.PagedRecipeResponse;
import com.recipe.shared.model.AuthorDto;
import com.recipe.shared.model.NutritionalInfo;
// Use the shared models
Recipe recipe = Recipe.builder()
.recipeName("Spaghetti Carbonara")
.ingredients(Arrays.asList("400g spaghetti", "200g pancetta"))
.instructions(Arrays.asList("Boil pasta", "Fry pancetta"))
.servings(4)
.source("manual")
.build();Replace the existing Recipe interface in src/types/nutrition.ts with:
import { Recipe, RecipeResponse } from '@recipe-management/shared';Replace RecipeDTO with the shared Recipe model. Key mapping:
recipeName→recipeName(already consistent)estimatedTimeMinutes→totalTimeMinutesestimatedTime→totalTime
Replace the existing Recipe entity with the shared model. Key mapping:
title→recipeNamein core persistence (Recipe)- API endpoints returning
RecipeResponseprovide bothrecipeNameandtitlealiases for backward compatibility. nutrition(Map) →nutritionalInfo(NutritionalInfo)tips(Map) →tips(RecipeTips)
npm run build:tsmvn compilenpm run build # Builds both TypeScript and Java# Publish TypeScript package to npm
npm publish
# Publish Java package to Maven repository
mvn deployThe shared models are designed to be backward compatible where possible, with utility methods for data conversion between old and new formats.
When adding new fields to the Recipe model:
- Update both TypeScript and Java versions
- Ensure backward compatibility
- Update this README
- Add conversion utilities if needed# Test commit