@la-main-verte/shared-types 1.0.88 → 1.0.89

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@la-main-verte/shared-types",
3
- "version": "1.0.88",
3
+ "version": "1.0.89",
4
4
  "description": "Shared TypeScript interfaces for frontend of la-main-verte app",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
package/src/audience.d.ts CHANGED
@@ -1,86 +1,93 @@
1
- /**
2
- * Audience targeting shared types
3
- * -------------------------------
4
- * An Audience is a reusable, named set of targeting criteria. Membership is
5
- * precomputed into a join table, so these shapes describe the *definition* of
6
- * an audience, not its resolved members.
7
- *
8
- * Criteria are heterogeneous and open-ended: each `type` has its own `params`.
9
- * The canonical runtime validation lives in the zod discriminated union at
10
- * `server/domains/audience/criterion.schema.ts`; keep these types in sync with it.
11
- */
12
-
13
- /** How an audience combines its criteria. */
14
- export type AudienceCombinator = 'all' | 'any'
15
-
16
- /** Member within `radiusKm` of a point. `label` is a human-readable origin (e.g. a city name). */
17
- export interface GeoRadiusCriterion {
18
- type: 'geo_radius'
19
- params: {
20
- latitude: number
21
- longitude: number
22
- radiusKm: number
23
- label?: string
24
- }
25
- }
26
-
27
- /**
28
- * Member whose `countryCode` matches (ISO 3166-1 alpha-2, e.g. "CA", "US", "FR").
29
- * @see documentation/geographic-targeting.md
30
- */
31
- export interface CountryCriterion {
32
- type: 'country'
33
- params: { countryCode: string }
34
- }
35
-
36
- /**
37
- * Member whose `provinceCode` matches (ISO 3166-2 subdivision code, e.g. "CA-QC", "US-CA", "FR-IDF").
38
- * @see documentation/geographic-targeting.md
39
- */
40
- export interface ProvinceCriterion {
41
- type: 'province'
42
- params: { provinceCode: string }
43
- }
44
-
45
- /** Member whose `city` matches (case-insensitive). */
46
- export interface CityCriterion {
47
- type: 'city'
48
- params: { cityName: string }
49
- }
50
-
51
- /** Member owns at least one GardenMap of the given category (e.g. "greenhouse"). */
52
- export interface GardenMapCategoryCriterion {
53
- type: 'garden_map_category'
54
- params: { category: string }
55
- }
56
-
57
- /**
58
- * Behavioral: member who was active on at least `minDistinctDays` distinct
59
- * calendar days (counted from SessionEvents) within the last `windowDays`.
60
- * Time-relative evaluated at recompute time, so the daily refresh cron keeps
61
- * the trailing window honest.
62
- */
63
- export interface ActivityDistinctDaysCriterion {
64
- type: 'activity_distinct_days'
65
- params: { minDistinctDays: number; windowDays: number }
66
- }
67
-
68
- export type AudienceCriterion =
69
- | GeoRadiusCriterion
70
- | CountryCriterion
71
- | ProvinceCriterion
72
- | CityCriterion
73
- | GardenMapCategoryCriterion
74
- | ActivityDistinctDaysCriterion
75
-
76
- export type AudienceCriterionType = AudienceCriterion['type']
77
-
78
- export interface AudienceI {
79
- id: number
80
- name: string
81
- description: string | null
82
- combinator: AudienceCombinator
83
- criteria: AudienceCriterion[]
84
- createdAt: Date
85
- updatedAt: Date
86
- }
1
+ /**
2
+ * Audience targeting shared types
3
+ * -------------------------------
4
+ * An Audience is a reusable, named set of targeting criteria. Membership is
5
+ * precomputed into a join table, so these shapes describe the *definition* of
6
+ * an audience, not its resolved members.
7
+ *
8
+ * Criteria are heterogeneous and open-ended: each `type` has its own `params`.
9
+ * The canonical runtime validation lives in the zod discriminated union at
10
+ * `server/domains/audience/criterion.schema.ts`; keep these types in sync with it.
11
+ */
12
+
13
+ /** How an audience combines its criteria. */
14
+ export type AudienceCombinator = 'all' | 'any'
15
+
16
+ /** Member within `radiusKm` of a point. `label` is a human-readable origin (e.g. a city name). */
17
+ export interface GeoRadiusCriterion {
18
+ type: 'geo_radius'
19
+ params: {
20
+ latitude: number
21
+ longitude: number
22
+ radiusKm: number
23
+ label?: string
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Member whose `countryCode` matches (ISO 3166-1 alpha-2, e.g. "CA", "US", "FR").
29
+ * @see documentation/geographic-targeting.md
30
+ */
31
+ export interface CountryCriterion {
32
+ type: 'country'
33
+ params: { countryCode: string }
34
+ }
35
+
36
+ /**
37
+ * Member whose `provinceCode` matches (ISO 3166-2 subdivision code, e.g. "CA-QC", "US-CA", "FR-IDF").
38
+ * @see documentation/geographic-targeting.md
39
+ */
40
+ export interface ProvinceCriterion {
41
+ type: 'province'
42
+ params: { provinceCode: string }
43
+ }
44
+
45
+ /** Member whose `city` matches (case-insensitive). */
46
+ export interface CityCriterion {
47
+ type: 'city'
48
+ params: { cityName: string }
49
+ }
50
+
51
+ /** Member owns at least one GardenMap of the given category (e.g. "greenhouse"). */
52
+ export interface GardenMapCategoryCriterion {
53
+ type: 'garden_map_category'
54
+ params: { category: string }
55
+ }
56
+
57
+ /** Member has the given plant placed in at least one non-deleted garden zone culture. */
58
+ export interface PlantInGardenCriterion {
59
+ type: 'plant_in_garden'
60
+ params: { plantSlug: string }
61
+ }
62
+
63
+ /**
64
+ * Behavioral: member who was active on at least `minDistinctDays` distinct
65
+ * calendar days (counted from SessionEvents) within the last `windowDays`.
66
+ * Time-relative — evaluated at recompute time, so the daily refresh cron keeps
67
+ * the trailing window honest.
68
+ */
69
+ export interface ActivityDistinctDaysCriterion {
70
+ type: 'activity_distinct_days'
71
+ params: { minDistinctDays: number; windowDays: number }
72
+ }
73
+
74
+ export type AudienceCriterion =
75
+ | GeoRadiusCriterion
76
+ | CountryCriterion
77
+ | ProvinceCriterion
78
+ | CityCriterion
79
+ | GardenMapCategoryCriterion
80
+ | PlantInGardenCriterion
81
+ | ActivityDistinctDaysCriterion
82
+
83
+ export type AudienceCriterionType = AudienceCriterion['type']
84
+
85
+ export interface AudienceI {
86
+ id: number
87
+ name: string
88
+ description: string | null
89
+ combinator: AudienceCombinator
90
+ criteria: AudienceCriterion[]
91
+ createdAt: Date
92
+ updatedAt: Date
93
+ }
@@ -1,55 +1,67 @@
1
- export interface FertilizerI {
2
- id: number
3
- name: string
4
- slug: string
5
- azotePercentage: number
6
- phosphorePercentage: number
7
- potassiumPercentage: number
8
- /**
9
- * The real azote percentage is the azote percentage multiplied by the azote efficiency.
10
- */
11
- realAzotePercentage: number
12
- /**
13
- * Nitrogen mineralization rate, between 0 and 1 (e.g. 0.9 for 90%).
14
- */
15
- nitrogenMineralizationRate: number | null
16
- imageLocation: string
17
- imageURL: string
18
- quantitySuggested: string
19
- /**
20
- * Blend composition when this fertilizer is a combination of two products.
21
- * Null for single fertilizers.
22
- * When populated, contains the IDs and ratios (as percentages) of the primary and secondary fertilizers.
23
- * The NPK values should be calculated by fetching each fertilizer and applying the weighted average.
24
- *
25
- * @example
26
- * // For a blend:
27
- * {
28
- * "primary_fertilizer_id": 1, // Acti-Sol (70%)
29
- * "primary_fertilizer_ratio": 70,
30
- * "secondary_fertilizer_id": 12, // Bionik (30%)
31
- * "secondary_fertilizer_ratio": 30
32
- * }
33
- *
34
- * // For a single fertilizer:
35
- * {}
36
- */
37
- combination_details: BlendCompositionI | null
38
- }
39
-
40
- interface BlendCompositionI {
41
- primary_fertilizer_id: number
42
- primary_fertilizer_ratio: number
43
- secondary_fertilizer_id: number
44
- secondary_fertilizer_ratio: number
45
- }
46
-
47
- export interface FertilizerSectionI {
48
- sectionTitle: string
49
- sectionSubtitle: string
50
- fertilizers: FertilizerI[]
51
- }
52
-
53
- export interface FertilizersInGridI {
54
- fertilizerSection: FertilizerSectionI[]
55
- }
1
+ export interface FertilizerI {
2
+ id: number
3
+ name: string
4
+ slug: string
5
+ azotePercentage: number
6
+ phosphorePercentage: number
7
+ potassiumPercentage: number
8
+ /**
9
+ * The real azote percentage is the azote percentage multiplied by the azote efficiency.
10
+ */
11
+ realAzotePercentage: number
12
+ /**
13
+ * Nitrogen mineralization rate, between 0 and 1 (e.g. 0.9 for 90%).
14
+ */
15
+ nitrogenMineralizationRate: number | null
16
+ imageLocation: string
17
+ imageURL: string
18
+ quantitySuggested: string
19
+ /**
20
+ * Blend composition when this fertilizer is a combination of two products.
21
+ * Null for single fertilizers.
22
+ * When populated, contains the IDs and ratios (as percentages) of the primary and secondary fertilizers.
23
+ * The NPK values should be calculated by fetching each fertilizer and applying the weighted average.
24
+ *
25
+ * @example
26
+ * // For a blend:
27
+ * {
28
+ * "primary_fertilizer_id": 1, // Acti-Sol (70%)
29
+ * "primary_fertilizer_ratio": 70,
30
+ * "secondary_fertilizer_id": 12, // Bionik (30%)
31
+ * "secondary_fertilizer_ratio": 30
32
+ * }
33
+ *
34
+ * // For a single fertilizer:
35
+ * {}
36
+ */
37
+ combination_details: BlendCompositionI | null
38
+ /**
39
+ * Bulk density in kg/L, used to convert quantities to litres or cubic yards.
40
+ * Null for fertilizers without a known density.
41
+ */
42
+ volumetricDensity: number | null
43
+ /**
44
+ * Controls how the quantity is displayed in the garden overview.
45
+ * - `'weight'`: kg/g, plus cubic yards if ≥ 1 yd³ (default for most bulk organics)
46
+ * - `'litre'`: solid products sold by volume (e.g. bagged compost) — L for small, yd³ for large
47
+ * - `'liquid'`: true liquid products (e.g. liquid seaweed) — L or mL only, never cubic yards
48
+ */
49
+ presentationMode: 'weight' | 'litre' | 'liquid'
50
+ }
51
+
52
+ interface BlendCompositionI {
53
+ primary_fertilizer_id: number
54
+ primary_fertilizer_ratio: number
55
+ secondary_fertilizer_id: number
56
+ secondary_fertilizer_ratio: number
57
+ }
58
+
59
+ export interface FertilizerSectionI {
60
+ sectionTitle: string
61
+ sectionSubtitle: string
62
+ fertilizers: FertilizerI[]
63
+ }
64
+
65
+ export interface FertilizersInGridI {
66
+ fertilizerSection: FertilizerSectionI[]
67
+ }