This repository has been archived on 2026-10-08. You can view files and clone it, but cannot push or open issues or pull requests.
allotment/packages/server/db/models/Patch.schema.js

85 lines
3.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import mongoose from "mongoose";
import {
DEFAULT_PRODUCE_ICON,
PRODUCE_ICON_IDS,
} from "../../constants/produceIcons.js";
const SUNLIGHT_VALUES = ["fullSun", "partialShade", "fullShade"];
const WATER_NEEDS_VALUES = ["low", "medium", "high"];
const patchSchema = new mongoose.Schema(
{
deviceId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Device",
required: true,
index: true,
},
patchId: { type: String, required: true },
name: { type: String, default: "" },
description: { type: String, default: "" },
/** Produce icon id (basename under client assets/svg/produce). */
icon: {
type: String,
enum: PRODUCE_ICON_IDS,
default: DEFAULT_PRODUCE_ICON,
},
/** Plant grid rows on the bed visualisation. */
rows: { type: Number, default: 3, min: 1 },
/** Plant grid columns on the bed visualisation. */
columns: { type: Number, default: 8, min: 1 },
/** Growth stage passed to the plant Lottie (derived from lifecycle + time; not user-edited). */
currentGrowingPosition: { type: Number, default: 0 },
/** Withering tint 0–100 for plant Lottie (derived from lifecycle + time; not user-edited). */
currentWithering: { type: Number, default: 0 },
/** Visible leaf count 0–6 for plant Lottie (derived from lifecycle + time; not user-edited). */
currentLeaves: { type: Number, default: 0, min: 0, max: 6 },
/** Visible flower count 0–3 for plant Lottie (derived from lifecycle + time; not user-edited). */
currentFlowers: { type: Number, default: 0, min: 0, max: 3 },
/** Fruit development 0–100 for plant Lottie (derived from lifecycle + time; not user-edited). */
currentFruiting: { type: Number, default: 0, min: 0, max: 100 },
/** Active lifecycle phase name/index from last server-side recalculation. */
currentGrowingPhase: {
type: new mongoose.Schema(
{
name: { type: String, default: "" },
index: { type: Number, default: 0 },
},
{ _id: false },
),
default: null,
},
soilHumidity: { type: Number, default: 0 },
soilTemperature: { type: Number, default: 21 },
sunlight: {
type: String,
enum: SUNLIGHT_VALUES,
default: "fullSun",
},
soilPhMin: { type: Number, default: 5.5, min: 0, max: 14 },
soilPhMax: { type: Number, default: 6.5, min: 0, max: 14 },
waterNeeds: {
type: String,
enum: WATER_NEEDS_VALUES,
default: "medium",
},
/** Biennial: sow/plant date anchor for offset-based lifecycle (ISO date in API). */
plantedAt: { type: Date, default: null },
/**
* Biennial: { type, durationWeeks, phases[{ name, startOffsetWeeks, endOffsetWeeks, growingPosition 0–100, withering 0–100, leaves 0–6, flowers 0–3, fruiting 0–100 }] }
* Perennial: { type, recurring, phases[{ name, startWeek, endWeek, growingPosition 0–100, withering 0–100, leaves 0–6, flowers 0–3, fruiting 0–100 }] }
*/
lifecycle: { type: mongoose.Schema.Types.Mixed, default: undefined },
/** Ordered gallery image references (see `Image` model). */
images: {
type: [{ type: mongoose.Schema.Types.ObjectId, ref: "Image" }],
default: [],
},
},
{ timestamps: true },
);
patchSchema.index({ deviceId: 1, patchId: 1 }, { unique: true });
export const Patch = mongoose.model("Patch", patchSchema);