No description
Find a file
jableader b08561c9bb
Some checks failed
CI / build-test (push) Has been cancelled
Squashed commit of the following:
commit 594a14009096f7321ff92638e05cfa7c5ae6ca07
Author: jableader <jacobdunk@gmail.com>
Date:   Sat Nov 1 12:20:33 2025 +1100

    API update - avoid optional arrays

commit 85787384cfc24dc28953ebb4630fe7614cb0ead1
Author: jableader <jacobdunk@gmail.com>
Date:   Sat Nov 1 10:14:51 2025 +1100

    refactor(types): add NonNullableArrays and apply to Meal arrays; test: add shopping mapper boundary tests; all checks green

commit 1c50b7e23585cd4a34b5a691ffbf87d6d123f474
Author: jableader <jacobdunk@gmail.com>
Date:   Sun Oct 26 15:30:45 2025 +1100

    Use discriminated unions and overloads
2025-11-01 12:22:52 +11:00
.github/workflows Squashed commit of the following: 2025-10-20 00:12:40 +11:00
.husky Refactor #6.1 2025-10-18 13:06:25 +11:00
public Refactor #6.2 autoformat 2025-10-18 13:08:22 +11:00
scripts Squashed commit of the following: 2025-10-20 00:12:40 +11:00
src Squashed commit of the following: 2025-11-01 12:22:52 +11:00
tests Squashed commit of the following: 2025-11-01 12:22:52 +11:00
.editorconfig Refactor #3 2025-10-18 12:42:23 +11:00
.env.example Autoformat 2025-10-18 14:16:34 +11:00
.gitignore init 2024-01-07 13:40:35 +11:00
.prettierignore Refactor #6.1 2025-10-18 13:06:25 +11:00
.prettierrc.json Refactor #3 2025-10-18 12:42:23 +11:00
babel.config.js Refactor #6.2 autoformat 2025-10-18 13:08:22 +11:00
CONTRIBUTING.md Squashed commit of the following: 2025-10-20 00:12:40 +11:00
jsconfig.json Refactor #6.2 autoformat 2025-10-18 13:08:22 +11:00
package-lock.json pruning (#3) 2025-10-25 02:18:30 +00:00
package.json pruning (#3) 2025-10-25 02:18:30 +00:00
README.md Stricter api changes 2025-10-26 15:13:33 +11:00
tsconfig.eslint.json Squashed commit of the following: 2025-10-20 00:12:40 +11:00
tsconfig.json pruning (#3) 2025-10-25 02:18:30 +00:00
vitest.config.js pruning (#3) 2025-10-25 02:18:30 +00:00
vue.config.js Squashed commit of the following: 2025-10-20 00:12:40 +11:00

Munch Ease — Plan, Cook, Shop, Repeat

Munch Ease is a snappy Vue 3 app that helps you plan meals, manage recipes, and turn plans into stress-free shopping lists. Search and save recipes, build your weekly meal plan, and seamlessly check items off your shopping list—everything stays in sync so you can focus on whats cooking.

Built with modern Vue patterns, a clean API layer, and lightweight tests, the project is easy to extend and fun to work on.


Quick start

  1. Install dependencies
npm install
  1. Run the dev server
npm run serve
  1. Run unit tests (Vitest)
npm run test
  1. Build for production
npm run build

Environment


Architecture and conventions

Strict TypeScript, Vue 3 Composition API, and a single typed API boundary.

Key axioms

  • OpenAPI (generated src/api/types.ts) is the single source of truth for shapes.
  • SDK (src/api/sdk.ts) is the only data access surface; UI uses domain types from src/domain/types.ts.
  • Domain normalization is minimal in src/domain/decoders.ts (e.g., date strings → Date).
  • No casts (as, angle brackets) and no any/unknown in app code. Generated files are exempt.
  • Arrays that are required in OpenAPI are non-nullable in domain types (e.g., Meal.recipes).
  • Disallow runtime type checks in app code; acceptable exceptions: DOM event narrowing, error/env handling in the boundary.

Layout

  • src/api/ — Typed client and SDK boundary
  • src/domain/ — Domain types and decoders
  • src/composables/ — Reusable app logic (auth, meals, shopping, pagination, alert)
  • src/components/ — UI components and pages
  • src/router/ — Routes and helpers (parseRouteId, parseQueryString)

Testing and tooling

  • Vitest + MSW under tests/
  • ESLint (type-aware) + Prettier + Volar

Development tips

  • Prefer composables for shared logic; keep components thin.
  • Use computed for derived values; avoid mutating props directly.
  • Use discriminated unions for UI-only shapes when helpful (e.g., shopping Group).
  • Add/adjust tests when changing behavior.

Troubleshooting

  • API errors: verify VUE_APP_API_BASE is set and reachable.
  • Type/IDE help: ensure Volar is enabled and ESLint is not conflicting with Prettier.
  • Build issues: this project uses Vue CLI 5. If migrating to Vite, update scripts and configs accordingly.

Type checking and codegen

  • Type check (TS strict + vue-tsc):
npm run typecheck
  • Generate API types (consumed by SDK):
npm run codegen

Environment

  • VUE_APP_API_BASE (Vue CLI) or VITE_API_BASE_URL (Vite) for API base URL

Testing

  • Unit tests use MSW; the client defaults to a localhost base in tests for easy mocking

CurrentShoppingList item kinds

The OpenAPI spec models current shopping list items as distinct kinds:

  • outstandingItems: ListIngredientItem[]
  • requestedMeals: RequestedMealItem[]
  • purchasedItems: ListIngredientItem[]

The SDK maps these to a domain DTO (CurrentShoppingListDTO) and may attach refs (ingredient, recipe, meal, list) for convenience. UI code should:

  • Prefer stable IDs (ingredientId, mealId, recipeId, listId) for actions and lookups
  • Treat attached refs as optional view helpers (never required)
  • Keep all normalization at the boundary (decoders); avoid casts and runtime type checks in app code