feat(rezepte)!: liturgical-aware seasonality via date ranges
CI / update (push) Successful in 3m31s

Replace season: number[] (months 1-12) on Recipe with seasonRanges, a
list of date ranges where each endpoint is either a fixed MM-DD or a
movable liturgical anchor (Easter, Ash Wednesday, Palm Sunday,
Pentecost, Advent I) plus a day offset. The old month list couldn't
express liturgical seasons whose boundaries shift each year (Advent,
Lent, Easter Octave, Christmas Octave) nor sub-month windows.

The shared evaluator resolves anchors against [Y-1, Y, Y+1] so spans
that wrap the calendar year boundary (e.g. christmas + 0 to
christmas + 7) match correctly on both sides. SeasonSelect was
rewritten as a controlled bind:ranges editor with a
fixed/liturgical kind toggle, anchor + offset inputs, per-row
resolved-this-year preview, and preset chips.

Run the one-time migration before deploying:
  pnpm exec vite-node scripts/migrate-season-to-ranges.ts

It coalesces contiguous month runs into single fixed ranges and
merges Dec/Jan wrap into one wrapping range; the new code does not
read the legacy season field, so order matters.
This commit is contained in:
2026-05-02 17:53:27 +02:00
parent 68b078c146
commit 096d6e2868
38 changed files with 692 additions and 295 deletions
+20 -2
View File
@@ -17,7 +17,25 @@ const RecipeSchema = new mongoose.Schema(
description: {type: String, required: true},
note: {type: String},
tags : [String],
season : [Number],
seasonRanges: [{
_id: false,
start: {
_id: false,
kind: { type: String, enum: ['fixed', 'liturgical'], required: true },
m: { type: Number },
d: { type: Number },
anchor: { type: String, enum: ['easter', 'ash-wednesday', 'palm-sunday', 'pentecost', 'advent-i'] },
offsetDays: { type: Number, default: 0 },
},
end: {
_id: false,
kind: { type: String, enum: ['fixed', 'liturgical'], required: true },
m: { type: Number },
d: { type: Number },
anchor: { type: String, enum: ['easter', 'ash-wednesday', 'palm-sunday', 'pentecost', 'advent-i'] },
offsetDays: { type: Number, default: 0 },
},
}],
baking: { temperature: {type:String, default: ""},
length: {type:String, default: ""},
mode: {type:String, default: ""},
@@ -198,7 +216,7 @@ const RecipeSchema = new mongoose.Schema(
// Indexes for efficient querying
RecipeSchema.index({ short_name: 1 });
RecipeSchema.index({ season: 1 });
RecipeSchema.index({ 'seasonRanges.start.anchor': 1 });
RecipeSchema.index({ "translations.en.short_name": 1 });
RecipeSchema.index({ "translations.en.translationStatus": 1 });