feat(mealPlan) Add meal plan feature #3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "meal-plan"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Introduces the full meal plan feature: CRUD for plans, days, dishes, and share-based access control. Also adds dish sort order and a database naming strategy.
Meal plan feature
POST /meal-plan/save-or-update,POST /meal-plan/:id/load,DELETE /meal-plan/:idreadonly,read_write, orfullaccess to other users; share management is its own sub-resourceMealPlanHandler.loadWithPermission(); each write operation uses an explicit allowlist so future permission levels are denied by defaultSee
docs/adr/2026-05-31-meal-plan.mdfor the full design rationale anddocs/architecture.mdfor the updated architecture overview.Dish sort order
Adds a
sort_ordercolumn tomeal_plan_day_dish(migration 005). The value is client-managed; the backend stores, returns, and orders by it. Enables the frontend to present dishes in a stable, user-defined sequence and support drag-and-drop reordering.Snake case naming strategy
Adds
SnakeCaseNamingStrategyto the TypeORMAppDataSource. Without it, every camelCase entity property mapping to a multi-word column required an explicitnameoption in its@Columndecorator — omitting it caused TypeORM to use the camelCase name literally in SQL. The strategy converts property names automatically; explicitnameoptions still take precedence.Bug fixes
findCompactForUserpassed two parameters for a single$1placeholder — fixed to[userId]mps.permissionin the UNION was a nativemeal_plan_permissionenum; PostgreSQL tried to cast the literal string'owner'into it and failed — fixed with::textcastfindByIdWithDaysQueryBuilder used plain property paths ("shares","days.dishes") where TypeORM requires alias-qualified paths ("meal_plan.shares","day.dishes") — fixed and documented in CLAUDE.mdMigrations
meal_plantablemeal_plan_daytablemeal_plan_day_dishtablemeal_plan_permissionenum +meal_plan_sharetablesort_ordercolumn onmeal_plan_day_dishRun via
npx typeorm migration:run -d ./build/data-source.jsafter deploying.Test plan
sortOrdervalues) and confirm the load response reflects the new orderThe leftJoinAndSelect for SHARES used alias "share" but the subsequent nested join SHARES_SHARED_WITH_USER ("shares.sharedWithUser") expected TypeORM to resolve an alias named "shares". Renaming the alias to "shares" makes the two consistent and eliminates the TypeORMError "shares alias was not found". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Add a note to the repository conventions section explaining that TypeORM QueryBuilder leftJoinAndSelect requires alias-qualified paths ("alias.relation"), which are incompatible with the plain property paths used in findOne/find relations arrays. Repositories that use both must keep them in separate QB_-prefixed constants. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>meal-planto feat(mealPlan) Add meal plan feature