@la-main-verte/shared-types 1.0.90 → 1.0.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/plant.d.ts CHANGED
@@ -1,201 +1,201 @@
1
- import type { TaxonFamilyI } from './taxonFamily'
2
- import type { SeedingInfoI } from './pages.api'
3
- import type { PlantFilterI } from './plantFilters'
4
- import type { RotationGroup } from './rotationGroup'
5
- /**
6
- * Range filter value for min/max filters
7
- */
8
- export interface RangeFilterValueI {
9
- min: number
10
- max: number
11
- }
12
-
13
- /**
14
- * Plant filter value types
15
- * Represents the possible values for a single filter
16
- */
17
- export type PlantFilterValueI = string | string[] | number | boolean | RangeFilterValueI
18
-
19
- /**
20
- * Plant attributes for filtering
21
- * Used in JSONB field and as query parameters
22
- * Supports multiple value types for different filter types
23
- */
24
- /**
25
- * A group of related attribute values, used for nested attribute objects.
26
- * Ex: { growth: { type: 'déterminée' }}
27
- */
28
- export type PlantAttributeGroupI = Record<string, PlantFilterValueI>
29
-
30
- /**
31
- * Plant attributes for filtering
32
- * Used in JSONB field and as query parameters
33
- * Supports flat values and one level of nested groups.
34
- */
35
- export type PlantAttributesI = Record<string, PlantFilterValueI | PlantAttributeGroupI>
36
-
37
- export interface PlantI {
38
- id: number
39
- name: string
40
- slug: string
41
- description: string
42
- descriptionSource?: string
43
- female: boolean
44
- family?: string | null
45
- isFamily: boolean
46
- taxonFamilyId?: number | null
47
- spaceBetweenSeedMin: number
48
- spaceBetweenSeedMax: number
49
- spaceBetweenAlleyMin: number
50
- spaceBetweenAlleyMax: number
51
- weeksInTransplant: number
52
- weeksDuringWhichYouCanSeedOutdoor: number
53
- weeksToMaturity: number
54
- daysToMaturity: number | null
55
- weeksToWaitAfterFreezingDate: number
56
- weeksToHarvest: number
57
- indoorSeeding: boolean
58
- outdoorSeeding: boolean
59
- azoteNeedsKgPerHa: number
60
- hibernate: boolean
61
- germinationTemperature: number | null
62
- minGerminationTemperature: number | null
63
- germinationNumberOfDays: string | null
64
- germinationSeedDepth: string | null
65
- cultivationInfo: string | null
66
- parentId: number | null
67
- memberId?: number
68
- memberFirstName?: string | null
69
- shared: boolean
70
- hexColor: string | null
71
- sunRequirements: 'partialShade' | 'fullSun' | 'fullShade' | null
72
- isHardy: boolean | null
73
- quantityForFiveInJardinVivrier?: number | null
74
- imageURL: string
75
- /**
76
- * Filename of the plant's 3D mesh asset stored on S3.
77
- * - Ideally a `.webp` file (e.g. `ail.webp`).
78
- * - Stored in S3 under the `images/meshes/` folder.
79
- * - By default named after the `Plant.slug` (e.g. `ail.webp` for the garlic plant).
80
- * - Only the filename is persisted; the public URL is exposed through the
81
- * virtual `meshURL` field.
82
- */
83
- meshFilename: string | null
84
- /**
85
- * Public ImageKit URL to the plant's 3D mesh asset.
86
- * Virtual field computed from `meshFilename`. The underlying file is
87
- * stored on S3 at `images/meshes/{meshFilename}` and rewritten to
88
- * ImageKit for CDN delivery and transformations.
89
- *
90
- * Falls back to `imageURL` when `meshFilename` is not set.
91
- *
92
- * Example: `https://ik.imagekit.io/lamainverte/meshes/ail.webp`
93
- */
94
- meshURL: string
95
- totalWeeksToMaturity: number
96
- hasNoInformation: boolean
97
- createdAt: Date
98
- updatedAt: Date
99
- translatedSunRequirements: 'Plein soleil' | 'Mi-ombre' | 'Ombre' | null
100
- parent?: PlantI
101
- children?: PlantI[]
102
- PlantInventories?: PlantInventoryI[]
103
- taggedItems?: TaggedItemI[]
104
- /**
105
- * List of selections that the plant is in.
106
- * --------------------------------------
107
- * Tends to be used for featured selections
108
- */
109
- Selections?: SelectionI[]
110
- tasks?: TaskI[]
111
- Images?: ImageI[]
112
- Member?: Partial<MemberI>
113
- notes?: NoteI[]
114
- /**
115
- * Nitrogen-derived rotation group enum (virtual field on the Plant model).
116
- * Source of truth for rotation classification — derived from
117
- * `azoteNeedsKgPerHa` plus the regenerative override on `taxonFamily`.
118
- */
119
- rotationGroup?: RotationGroup | null
120
- /**
121
- * French label of `rotationGroup`, ready for display.
122
- */
123
- translatedRotationGroup?: string | null
124
- taxonFamily?: TaxonFamilyI
125
- seedingInfo: SeedingInfoI
126
- /**
127
- * Contextual search text for recommended plants
128
- * Provides additional context when suggesting plants for specific garden zones
129
- */
130
- contextualSearchText?: string
131
- }
132
-
133
- interface PlantInventoryI {
134
- id: number
135
- plantId: number
136
- supplierName: string
137
- plantName: string
138
- supplierURL: string
139
- imageLocation: string
140
- description: string
141
- inStock: boolean
142
- }
143
-
144
- export type AvailableGrowingConditionsI = Record<string, string[]>
145
-
146
- /**
147
- * For each attribute filter key (e.g. "fruit.color"), the list of values that
148
- * still yield at least one match under the current search + active filters.
149
- * Consumed by the frontend to mark filter tags as "unavailable".
150
- */
151
- export type AvailableAttributesI = Record<string, string[]>
152
-
153
- /**
154
- * Which filter surface the frontend should render for the current search.
155
- * - `specific`: family-specific filters (e.g. tomate attributes)
156
- * - `general`: global growing-conditions filters
157
- *
158
- * Mutually exclusive by design — the two sets never appear together.
159
- */
160
- export type PlantFiltersModeI = 'specific' | 'general'
161
-
162
- /**
163
- * Backend-driven description of the filter UI for a given search response.
164
- * The frontend is a dumb renderer: it shows the filters listed here with the
165
- * given mode and marks tags whose value is not in `availability` as unavailable.
166
- */
167
- export interface PlantFiltersUII {
168
- mode: PlantFiltersModeI
169
- filters: PlantFilterI[]
170
- availability: Record<string, string[]>
171
- }
172
-
173
- export interface GrowingConditionsConfigI {
174
- filters: PlantFilterI[]
175
- }
176
-
177
- export interface GrowingConditionsFiltersI {
178
- sunRequirements?: 'partialShade' | 'fullShade'
179
- rotationGroup?: 'regenerative' | 'demanding' | 'moderately_demanding' | 'less_demanding'
180
- }
181
-
182
- export interface PlantSearchResultI {
183
- plants: PlantModelI[]
184
- selections: SelectionModelI[]
185
- total?: number
186
- familyName?: string
187
- filtersUI?: PlantFiltersUII
188
- }
189
-
190
- /**
191
- * Response shape for `GET /selections/:slug/gardenZones/:id/rotation-suggestions`.
192
- * - `advice`: short user-facing sentence explaining the recommendation
193
- * - `Plants`: parent plants matching the recommended rotation group, with
194
- * the avoided taxon families excluded. Empty when the zone has no usable
195
- * history yet.
196
- */
197
- export interface PlantRotationSuggestionsI {
198
- targetYear: number
199
- advice: string
200
- Plants: PlantI[]
201
- }
1
+ import type { TaxonFamilyI } from './taxonFamily'
2
+ import type { SeedingInfoI } from './pages.api'
3
+ import type { PlantFilterI } from './plantFilters'
4
+ import type { RotationGroup } from './rotationGroup'
5
+ /**
6
+ * Range filter value for min/max filters
7
+ */
8
+ export interface RangeFilterValueI {
9
+ min: number
10
+ max: number
11
+ }
12
+
13
+ /**
14
+ * Plant filter value types
15
+ * Represents the possible values for a single filter
16
+ */
17
+ export type PlantFilterValueI = string | string[] | number | boolean | RangeFilterValueI
18
+
19
+ /**
20
+ * Plant attributes for filtering
21
+ * Used in JSONB field and as query parameters
22
+ * Supports multiple value types for different filter types
23
+ */
24
+ /**
25
+ * A group of related attribute values, used for nested attribute objects.
26
+ * Ex: { growth: { type: 'déterminée' }}
27
+ */
28
+ export type PlantAttributeGroupI = Record<string, PlantFilterValueI>
29
+
30
+ /**
31
+ * Plant attributes for filtering
32
+ * Used in JSONB field and as query parameters
33
+ * Supports flat values and one level of nested groups.
34
+ */
35
+ export type PlantAttributesI = Record<string, PlantFilterValueI | PlantAttributeGroupI>
36
+
37
+ export interface PlantI {
38
+ id: number
39
+ name: string
40
+ slug: string
41
+ description: string
42
+ descriptionSource?: string
43
+ female: boolean
44
+ family?: string | null
45
+ isFamily: boolean
46
+ taxonFamilyId?: number | null
47
+ spaceBetweenSeedMin: number
48
+ spaceBetweenSeedMax: number
49
+ spaceBetweenAlleyMin: number
50
+ spaceBetweenAlleyMax: number
51
+ weeksInTransplant: number
52
+ weeksDuringWhichYouCanSeedOutdoor: number
53
+ weeksToMaturity: number
54
+ daysToMaturity: number | null
55
+ weeksToWaitAfterFreezingDate: number
56
+ weeksToHarvest: number
57
+ indoorSeeding: boolean
58
+ outdoorSeeding: boolean
59
+ azoteNeedsKgPerHa: number
60
+ hibernate: boolean
61
+ germinationTemperature: number | null
62
+ minGerminationTemperature: number | null
63
+ germinationNumberOfDays: string | null
64
+ germinationSeedDepth: string | null
65
+ cultivationInfo: string | null
66
+ parentId: number | null
67
+ memberId?: number
68
+ memberFirstName?: string | null
69
+ shared: boolean
70
+ hexColor: string | null
71
+ sunRequirements: 'partialShade' | 'fullSun' | 'fullShade' | null
72
+ isHardy: boolean | null
73
+ quantityForFiveInJardinVivrier?: number | null
74
+ imageURL: string
75
+ /**
76
+ * Filename of the plant's 3D mesh asset stored on S3.
77
+ * - Ideally a `.webp` file (e.g. `ail.webp`).
78
+ * - Stored in S3 under the `images/meshes/` folder.
79
+ * - By default named after the `Plant.slug` (e.g. `ail.webp` for the garlic plant).
80
+ * - Only the filename is persisted; the public URL is exposed through the
81
+ * virtual `meshURL` field.
82
+ */
83
+ meshFilename: string | null
84
+ /**
85
+ * Public ImageKit URL to the plant's 3D mesh asset.
86
+ * Virtual field computed from `meshFilename`. The underlying file is
87
+ * stored on S3 at `images/meshes/{meshFilename}` and rewritten to
88
+ * ImageKit for CDN delivery and transformations.
89
+ *
90
+ * Falls back to `imageURL` when `meshFilename` is not set.
91
+ *
92
+ * Example: `https://ik.imagekit.io/lamainverte/meshes/ail.webp`
93
+ */
94
+ meshURL: string
95
+ totalWeeksToMaturity: number
96
+ hasNoInformation: boolean
97
+ createdAt: Date
98
+ updatedAt: Date
99
+ translatedSunRequirements: 'Plein soleil' | 'Mi-ombre' | 'Ombre' | null
100
+ parent?: PlantI
101
+ children?: PlantI[]
102
+ PlantInventories?: PlantInventoryI[]
103
+ taggedItems?: TaggedItemI[]
104
+ /**
105
+ * List of selections that the plant is in.
106
+ * --------------------------------------
107
+ * Tends to be used for featured selections
108
+ */
109
+ Selections?: SelectionI[]
110
+ tasks?: TaskI[]
111
+ Images?: ImageI[]
112
+ Member?: Partial<MemberI>
113
+ notes?: NoteI[]
114
+ /**
115
+ * Nitrogen-derived rotation group enum (virtual field on the Plant model).
116
+ * Source of truth for rotation classification — derived from
117
+ * `azoteNeedsKgPerHa` plus the regenerative override on `taxonFamily`.
118
+ */
119
+ rotationGroup?: RotationGroup | null
120
+ /**
121
+ * French label of `rotationGroup`, ready for display.
122
+ */
123
+ translatedRotationGroup?: string | null
124
+ taxonFamily?: TaxonFamilyI
125
+ seedingInfo: SeedingInfoI
126
+ /**
127
+ * Contextual search text for recommended plants
128
+ * Provides additional context when suggesting plants for specific garden zones
129
+ */
130
+ contextualSearchText?: string
131
+ }
132
+
133
+ interface PlantInventoryI {
134
+ id: number
135
+ plantId: number
136
+ supplierName: string
137
+ plantName: string
138
+ supplierURL: string
139
+ imageLocation: string
140
+ description: string
141
+ inStock: boolean
142
+ }
143
+
144
+ export type AvailableGrowingConditionsI = Record<string, string[]>
145
+
146
+ /**
147
+ * For each attribute filter key (e.g. "fruit.color"), the list of values that
148
+ * still yield at least one match under the current search + active filters.
149
+ * Consumed by the frontend to mark filter tags as "unavailable".
150
+ */
151
+ export type AvailableAttributesI = Record<string, string[]>
152
+
153
+ /**
154
+ * Which filter surface the frontend should render for the current search.
155
+ * - `specific`: family-specific filters (e.g. tomate attributes)
156
+ * - `general`: global growing-conditions filters
157
+ *
158
+ * Mutually exclusive by design — the two sets never appear together.
159
+ */
160
+ export type PlantFiltersModeI = 'specific' | 'general'
161
+
162
+ /**
163
+ * Backend-driven description of the filter UI for a given search response.
164
+ * The frontend is a dumb renderer: it shows the filters listed here with the
165
+ * given mode and marks tags whose value is not in `availability` as unavailable.
166
+ */
167
+ export interface PlantFiltersUII {
168
+ mode: PlantFiltersModeI
169
+ filters: PlantFilterI[]
170
+ availability: Record<string, string[]>
171
+ }
172
+
173
+ export interface GrowingConditionsConfigI {
174
+ filters: PlantFilterI[]
175
+ }
176
+
177
+ export interface GrowingConditionsFiltersI {
178
+ sunRequirements?: 'partialShade' | 'fullShade'
179
+ rotationGroup?: 'regenerative' | 'demanding' | 'moderately_demanding' | 'less_demanding'
180
+ }
181
+
182
+ export interface PlantSearchResultI {
183
+ plants: PlantModelI[]
184
+ selections: SelectionModelI[]
185
+ total?: number
186
+ familyName?: string
187
+ filtersUI?: PlantFiltersUII
188
+ }
189
+
190
+ /**
191
+ * Response shape for `GET /selections/:slug/gardenZones/:id/rotation-suggestions`.
192
+ * - `advice`: short user-facing sentence explaining the recommendation
193
+ * - `Plants`: parent plants matching the recommended rotation group, with
194
+ * the avoided taxon families excluded. Empty when the zone has no usable
195
+ * history yet.
196
+ */
197
+ export interface PlantRotationSuggestionsI {
198
+ targetYear: number
199
+ advice: string
200
+ Plants: PlantI[]
201
+ }
@@ -0,0 +1,42 @@
1
+ import { GardenZoneI } from './gardenMap.d'
2
+ import { SelectionI } from './selection.d'
3
+
4
+ export namespace SELECTIONS {
5
+ export namespace ADD_PLANT {
6
+ export interface Request {
7
+ params: {
8
+ /**
9
+ * Slug of the selection to add the plant to, or the literal `default`
10
+ * to target the member's default selection.
11
+ */
12
+ slug: string
13
+ plantSlug: string
14
+ }
15
+ query?: {
16
+ /**
17
+ * Opt-in: also create a GardenZone (holding the plant's culture) on the
18
+ * selection's GardenMap. Only the plant search opened from the garden
19
+ * plan asks for this — adding from the calendar, the home screen or the
20
+ * explore screen just puts the plant in the selection.
21
+ *
22
+ * Opting in is a *request*, not a guarantee: see
23
+ * {@link ADD_PLANT.Response.autoCreatedGardenZone}.
24
+ */
25
+ autoCreateGardenZone?: boolean
26
+ }
27
+ }
28
+
29
+ export type Response = SelectionI & {
30
+ /**
31
+ * The GardenZone created for this plant, or `null` when none was.
32
+ *
33
+ * `null` even though `autoCreateGardenZone` was requested when the API
34
+ * legitimately declined: the selection has no GardenMap, the member is on
35
+ * the free tier and already reached the culture limit, or the plant
36
+ * already had a culture. Clients must therefore key their feedback off
37
+ * this field rather than off what they asked for.
38
+ */
39
+ autoCreatedGardenZone: GardenZoneI | null
40
+ }
41
+ }
42
+ }