@simonarcher/fika-types 1.6.0 → 2.0.0-rc.1

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.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Bag-scan event design surface (FIK-124 P1).
3
+ *
4
+ * NOTE: the `bean_scans` table is **not yet migrated**. This file is the
5
+ * type contract for the future bag-scan project — see
6
+ * `plans/bean-schema-redesign.md` (P1 — Bag-scan ready surface) for the SQL
7
+ * DDL and rationale.
8
+ *
9
+ * New types in this package use ISO string timestamps (Supabase / Postgres
10
+ * convention). Firebase-era types like `CoffeeBean` retain `Timestamp` for
11
+ * back-compat during the Firestore→Supabase migration window.
12
+ */
13
+ /**
14
+ * What the user did with the scan after seeing the candidates.
15
+ *
16
+ * - `pending` — scan ingested, no user action yet
17
+ * - `saved` — user kept the matched bean (e.g. added to a list)
18
+ * - `tried` — user marked having drunk this bean
19
+ * - `rejected` — user said the match was wrong
20
+ * - `created_new` — user created a new bean record from this scan
21
+ */
22
+ export type BeanScanAction = "pending" | "saved" | "tried" | "rejected" | "created_new";
23
+ /**
24
+ * One row per user scan event. Powers the bag-scan loop: photograph →
25
+ * OCR + photo similarity → top-N candidate beans → user picks (or rejects).
26
+ */
27
+ export interface BeanScan {
28
+ id: string;
29
+ userId?: string;
30
+ photoUrl: string;
31
+ ocrText?: string;
32
+ /**
33
+ * Top-N matcher candidates as inline jsonb. Promoted to a dedicated
34
+ * `bean_scan_candidates` table only when cross-scan analytics warrant it.
35
+ */
36
+ candidates?: Array<{
37
+ beanId: string;
38
+ score: number;
39
+ source: "ocr" | "vector" | "hybrid";
40
+ }>;
41
+ matchedBeanId?: string;
42
+ action: BeanScanAction;
43
+ deviceMeta?: Record<string, unknown>;
44
+ createdAt: string;
45
+ resolvedAt?: string;
46
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Bag-scan event design surface (FIK-124 P1).
4
+ *
5
+ * NOTE: the `bean_scans` table is **not yet migrated**. This file is the
6
+ * type contract for the future bag-scan project — see
7
+ * `plans/bean-schema-redesign.md` (P1 — Bag-scan ready surface) for the SQL
8
+ * DDL and rationale.
9
+ *
10
+ * New types in this package use ISO string timestamps (Supabase / Postgres
11
+ * convention). Firebase-era types like `CoffeeBean` retain `Timestamp` for
12
+ * back-compat during the Firestore→Supabase migration window.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/coffee.d.ts CHANGED
@@ -126,16 +126,31 @@ export type DecafMethod = "Swiss Water" | "Sugarcane / Ethyl Acetate" | "Carbon
126
126
  export declare const DECAF_METHODS: readonly ["Swiss Water", "Sugarcane / Ethyl Acetate", "Carbon Dioxide (CO₂)", "Methylene Chloride", "Mountain Water", "Unknown"];
127
127
  export type CoffeeProcessingMethod = "Washed (Wet)" | "Natural (Dry)" | "Honey" | "Anaerobic Fermentation" | "Carbonic Maceration" | "Wet-Hulled" | "Semi-Washed" | "Experimental / Other" | "Unknown";
128
128
  export type RoastLevel = "Light" | "Medium" | "Dark" | "Medium-Dark" | "Medium-Light" | "Espresso";
129
+ /**
130
+ * Per-origin row on a bean. Mirrors `coffee_bean_origins`.
131
+ * Multiple origins = blend (use `blendPercentage` when documented).
132
+ */
129
133
  export interface Origin {
130
134
  countryCode: string;
131
135
  countryName?: string;
132
136
  region?: string;
133
137
  subregion?: string;
134
- elevationMinMeters?: number;
135
- elevationMaxMeters?: number;
138
+ altitudeMinM?: number;
139
+ altitudeMaxM?: number;
140
+ farmId?: string;
141
+ farmNameUnverified?: string;
142
+ producerName?: string;
143
+ tradeProgram?: string;
144
+ blendPercentage?: number;
136
145
  }
146
+ /**
147
+ * Recipe-level bean record. Flat fields mirror `coffee_beans`; per-origin detail
148
+ * lives in `origins[]` (joined from `coffee_bean_origins`).
149
+ *
150
+ * Note: `varieties` here is recipe-level (what the roaster shipped). Farm-level
151
+ * varieties (what the farm grows) live on `Farm.varieties`.
152
+ */
137
153
  export interface CoffeeBean {
138
- active: boolean;
139
154
  id: string;
140
155
  name: string;
141
156
  description?: string;
@@ -146,9 +161,10 @@ export interface CoffeeBean {
146
161
  origins?: Origin[];
147
162
  varieties?: string[];
148
163
  harvestYear?: number;
164
+ harvestPeriod?: string;
149
165
  lotName?: string;
150
166
  scaScore?: number;
151
- roastLevel?: "Light" | "Medium-Light" | "Medium" | "Medium-Dark" | "Dark";
167
+ roastLevel?: RoastLevel;
152
168
  processing?: CoffeeProcessingMethod;
153
169
  processingDetails?: string;
154
170
  tastingNotes?: string[];
@@ -160,10 +176,16 @@ export interface CoffeeBean {
160
176
  farmerStory?: string;
161
177
  impactNotes?: string;
162
178
  awards?: string[];
179
+ certifications?: string[];
163
180
  limitedEdition?: boolean;
181
+ active: boolean;
164
182
  createdAt?: Timestamp;
165
183
  updatedAt?: Timestamp;
166
184
  }
185
+ /**
186
+ * Submission payload for a proposed bean. Origins ride along via `submission_origins`
187
+ * once accepted; the server promotes them to `coffee_bean_origins` on approval.
188
+ */
167
189
  export interface SubmissionCoffeeBeanData {
168
190
  name: string;
169
191
  description?: string;
@@ -23,7 +23,6 @@ export interface CoffeeShopEvent extends NewCoffeeShopEvent {
23
23
  createdAt: Date;
24
24
  updatedAt: Date;
25
25
  eventType: CoffeeShopEventType;
26
- rewardStickerId?: string | null;
27
26
  }
28
27
  export interface EventAttendee {
29
28
  userId: string;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './shop';
2
2
  export * from './coffee';
3
+ export * from './bean-scans';
3
4
  export * from './farm';
4
5
  export * from './user';
5
6
  export * from './userList';
package/dist/index.js CHANGED
@@ -16,8 +16,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  // Export all shop-related types
18
18
  __exportStar(require("./shop"), exports);
19
- // Export all coffee-related types
19
+ // Export all coffee-related types
20
20
  __exportStar(require("./coffee"), exports);
21
+ // Export bag-scan types (design surface; bean_scans table not yet migrated)
22
+ __exportStar(require("./bean-scans"), exports);
21
23
  // Export all farm-related types
22
24
  __exportStar(require("./farm"), exports);
23
25
  // Export all user-related types
package/dist/shop.d.ts CHANGED
@@ -256,21 +256,7 @@ export type ShopData = {
256
256
  completedAt?: AdminTimestamp;
257
257
  lastUpdated?: AdminTimestamp;
258
258
  };
259
- ownerSectionVerifications?: OwnerSectionVerifications;
260
259
  };
261
- /** Stable section keys exposed in the owner portal and surfaced as "verified
262
- * by owner" badges on user-facing apps. */
263
- export type OwnerSectionKey = 'hours' | 'about' | 'photos' | 'contact' | 'socials' | 'brew_methods' | 'roasters' | 'amenities' | 'specialties' | 'specialty_flags';
264
- export interface OwnerSectionVerification {
265
- /** ISO-8601 timestamp of when the owner last attested this section. */
266
- verifiedAt: string;
267
- /** staff_invites.id of the token used (null if attributed to the
268
- * signed-in accepted_by user, post-claim). */
269
- tokenId: string | null;
270
- /** Email captured from the invite at attestation time. */
271
- actorEmail: string | null;
272
- }
273
- export type OwnerSectionVerifications = Partial<Record<OwnerSectionKey, OwnerSectionVerification>>;
274
260
  export interface ShopCommunityStats {
275
261
  totalCheckIns: number;
276
262
  uniqueVisitors: number;
@@ -298,10 +284,6 @@ export interface DailyVisitorStats {
298
284
  updatedAt: AdminTimestamp;
299
285
  }
300
286
  export interface ShopInfo {
301
- /** FIKA-curated public description. Mirrored to top-level `shop.about`. */
302
- description?: string | null;
303
- /** Owner-authored public note, edited through the owner portal. */
304
- ownerDescription?: string | null;
305
287
  features: Partial<Record<ShopFeatureKey, boolean | null>> & Record<string, boolean | null>;
306
288
  wifiDetails?: {
307
289
  name?: string;
@@ -319,17 +301,6 @@ export interface ShopContactDetails {
319
301
  contactNumber: string;
320
302
  email: string;
321
303
  website: string;
322
- /**
323
- * Social media handles. Stored alongside other contact data so a shop has a
324
- * single source of truth for "how to reach this place". Bare handles only —
325
- * no `@` prefix, no URL — clients construct platform URLs at render time.
326
- * Optional/nullable to keep records sparse for shops that don't publish a
327
- * given platform.
328
- */
329
- instagram?: string | null;
330
- facebook?: string | null;
331
- tiktok?: string | null;
332
- twitter?: string | null;
333
304
  address: {
334
305
  formattedAddress: string;
335
306
  shortFormattedAddress: string;
@@ -342,18 +313,9 @@ export interface ShopContactDetails {
342
313
  };
343
314
  updatedAt?: Date;
344
315
  }
345
- export type ShopFeatureKey = 'powerOutlets' | 'laptopFriendly' | 'outdoorSeating' | 'indoorSeating' | 'accessibility' | 'alcohol' | 'breakfast' | 'lunch' | 'vegetarian' | 'petFriendly' | 'kidFriendly' | 'restrooms' | 'parking' | 'wifi' | 'acceptsCash' | 'acceptsCreditCards' | 'acceptsNfc' | 'discountOnReusableCup' | 'glutenFree' | 'loyaltyCard' | 'takeaway' | 'delivery' | 'walkInOnly';
346
- export type FeatureGroupKey = 'Space & Seating' | 'Work & Facilities' | 'Food & Drink' | 'Service' | 'Payment';
347
- /** Maps each feature key to its display group. Single source of truth for admin and mobile. */
348
- export declare const featureGroupMap: Record<ShopFeatureKey, FeatureGroupKey>;
349
- /** Display labels for each feature key. Single source of truth for admin and mobile. */
350
- export declare const featureLabelMap: Record<ShopFeatureKey, string>;
351
- export type ShopSpecialtyKey = 'inHouseRoastery' | 'pourOverSpecialty' | 'espressoExpert' | 'singleOriginFocus' | 'rotatingRoasters' | 'tastingNotesOnMenu' | 'naturalFermentedFocus' | 'cuppingAndEducation' | 'cozyAmbiance' | 'bustlingEnergy' | 'espressoBarStanding' | 'vinylRecords' | 'uniqueExperience' | 'inHouseBakery' | 'freshPastries' | 'localBakeryPartner' | 'dessertDestination' | 'lgbtqFriendly' | 'womenOwned' | 'zeroWasteFocus' | 'communityHub' | 'laptopWelcome' | 'fastWifi' | 'longStayOk';
352
- export type SpecialtyCategoryKey = 'Coffee' | 'Atmosphere' | 'Food & Treats' | 'Identity & Values' | 'Workspace';
353
- /** Maps each specialty key to its category. Single source of truth for admin and mobile. */
354
- export declare const specialtyCategoryMap: Record<ShopSpecialtyKey, SpecialtyCategoryKey>;
355
- /** Display labels for each specialty key. Single source of truth for admin and mobile. */
356
- export declare const specialtyLabelMap: Record<ShopSpecialtyKey, string>;
316
+ export type ShopFeatureKey = 'powerOutlets' | 'laptopFriendly' | 'outdoorSeating' | 'indoorSeating' | 'accessibility' | 'alcohol' | 'breakfast' | 'lunch' | 'vegetarian' | 'petFriendly' | 'restrooms' | 'parking' | 'wifi' | 'acceptsCash' | 'acceptsCreditCards' | 'acceptsNfc' | 'discountOnReusableCup' | 'glutenFree' | 'loyaltyCard' | 'takeaway' | 'delivery';
317
+ export type ShopSpecialtyKey = 'pourOverSpecialty' | 'espressoExpert' | 'singleOriginFocus' | 'localRoaster' | 'brewingEducation' | 'cuppingEvents' | 'matchaSpecialty' | 'decafSpecialty' | 'inHouseRoastery' | 'relaxingVibes' | 'bustlingEnergy' | 'quietStudySpace' | 'uniqueExperience' | 'instagramWorthy' | 'cozyAmbiance' | 'freshPastries' | 'homemadeTreats' | 'artisanBread' | 'localBakery' | 'healthyOptions' | 'dessertDestination' | 'inHouseBakery' | 'signatureBakedGoods' | 'lgbtqFriendly' | 'womenOwned' | 'familyOwned' | 'communityHub' | 'sociallyConscious' | 'localArtSupport' | 'liveMusic' | 'localArt' | 'bookExchange' | 'boardGames' | 'culturalEvents' | 'workshopSpace' | 'laptopFriendlyPro' | 'meetingSpaceAvailable' | 'quietZones' | 'fastWifi' | 'longStayWelcome' | 'coworkingVibes';
318
+ export type SpecialtyCategoryKey = 'Coffee Excellence' | 'Atmosphere' | 'Food & Treats' | 'Community & Values' | 'Entertainment' | 'Work & Study';
357
319
  export interface ShopSpecialties {
358
320
  highlighted: ShopSpecialtyKey[];
359
321
  additional: ShopSpecialtyKey[];
package/dist/shop.js CHANGED
@@ -1,129 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.specialtyLabelMap = exports.specialtyCategoryMap = exports.featureLabelMap = exports.featureGroupMap = void 0;
4
- /** Maps each feature key to its display group. Single source of truth for admin and mobile. */
5
- exports.featureGroupMap = {
6
- // Space & Seating
7
- indoorSeating: 'Space & Seating',
8
- outdoorSeating: 'Space & Seating',
9
- petFriendly: 'Space & Seating',
10
- kidFriendly: 'Space & Seating',
11
- // Work & Facilities
12
- wifi: 'Work & Facilities',
13
- powerOutlets: 'Work & Facilities',
14
- laptopFriendly: 'Work & Facilities',
15
- restrooms: 'Work & Facilities',
16
- parking: 'Work & Facilities',
17
- accessibility: 'Work & Facilities',
18
- // Food & Drink
19
- breakfast: 'Food & Drink',
20
- lunch: 'Food & Drink',
21
- vegetarian: 'Food & Drink',
22
- glutenFree: 'Food & Drink',
23
- alcohol: 'Food & Drink',
24
- // Service
25
- takeaway: 'Service',
26
- delivery: 'Service',
27
- loyaltyCard: 'Service',
28
- discountOnReusableCup: 'Service',
29
- walkInOnly: 'Service',
30
- // Payment
31
- acceptsCash: 'Payment',
32
- acceptsCreditCards: 'Payment',
33
- acceptsNfc: 'Payment',
34
- };
35
- /** Display labels for each feature key. Single source of truth for admin and mobile. */
36
- exports.featureLabelMap = {
37
- // Space & Seating
38
- indoorSeating: 'Indoor Seating',
39
- outdoorSeating: 'Outdoor Seating',
40
- petFriendly: 'Pet Friendly',
41
- kidFriendly: 'Kid Friendly',
42
- // Work & Facilities
43
- wifi: 'Free WiFi',
44
- powerOutlets: 'Power Outlets',
45
- laptopFriendly: 'Laptop Friendly',
46
- restrooms: 'Restrooms',
47
- parking: 'Parking',
48
- accessibility: 'Wheelchair Accessible',
49
- // Food & Drink
50
- breakfast: 'Serves Breakfast',
51
- lunch: 'Serves Lunch',
52
- vegetarian: 'Vegetarian Options',
53
- glutenFree: 'Gluten-Free Options',
54
- alcohol: 'Serves Alcohol',
55
- // Service
56
- takeaway: 'Takeaway',
57
- delivery: 'Delivery',
58
- loyaltyCard: 'Loyalty Card',
59
- discountOnReusableCup: 'Discount for Reusable Cup',
60
- walkInOnly: 'Walk-In Only',
61
- // Payment
62
- acceptsCash: 'Cash Payments',
63
- acceptsCreditCards: 'Card Payments',
64
- acceptsNfc: 'Contactless / NFC',
65
- };
66
- /** Maps each specialty key to its category. Single source of truth for admin and mobile. */
67
- exports.specialtyCategoryMap = {
68
- // Coffee
69
- inHouseRoastery: 'Coffee',
70
- pourOverSpecialty: 'Coffee',
71
- espressoExpert: 'Coffee',
72
- singleOriginFocus: 'Coffee',
73
- rotatingRoasters: 'Coffee',
74
- tastingNotesOnMenu: 'Coffee',
75
- naturalFermentedFocus: 'Coffee',
76
- cuppingAndEducation: 'Coffee',
77
- // Atmosphere
78
- cozyAmbiance: 'Atmosphere',
79
- bustlingEnergy: 'Atmosphere',
80
- espressoBarStanding: 'Atmosphere',
81
- vinylRecords: 'Atmosphere',
82
- uniqueExperience: 'Atmosphere',
83
- // Food & Treats
84
- inHouseBakery: 'Food & Treats',
85
- freshPastries: 'Food & Treats',
86
- localBakeryPartner: 'Food & Treats',
87
- dessertDestination: 'Food & Treats',
88
- // Identity & Values
89
- lgbtqFriendly: 'Identity & Values',
90
- womenOwned: 'Identity & Values',
91
- zeroWasteFocus: 'Identity & Values',
92
- communityHub: 'Identity & Values',
93
- // Workspace
94
- laptopWelcome: 'Workspace',
95
- fastWifi: 'Workspace',
96
- longStayOk: 'Workspace',
97
- };
98
- /** Display labels for each specialty key. Single source of truth for admin and mobile. */
99
- exports.specialtyLabelMap = {
100
- // Coffee
101
- inHouseRoastery: 'In-House Roastery',
102
- pourOverSpecialty: 'Pour-Over / Filter Focus',
103
- espressoExpert: 'Espresso Specialists',
104
- singleOriginFocus: 'Single Origin Focus',
105
- rotatingRoasters: 'Rotating / Guest Roasters',
106
- tastingNotesOnMenu: 'Tasting Notes on Menu',
107
- naturalFermentedFocus: 'Natural & Fermented Coffees',
108
- cuppingAndEducation: 'Cuppings & Education',
109
- // Atmosphere
110
- cozyAmbiance: 'Cosy & Welcoming',
111
- bustlingEnergy: 'Lively Atmosphere',
112
- espressoBarStanding: 'Espresso Bar / Standing Only',
113
- vinylRecords: 'Vinyl Records',
114
- uniqueExperience: 'Unique Concept',
115
- // Food & Treats
116
- inHouseBakery: 'In-House Bakery',
117
- freshPastries: 'Fresh Pastries',
118
- localBakeryPartner: 'Local Bakery Partner',
119
- dessertDestination: 'Dessert Destination',
120
- // Identity & Values
121
- lgbtqFriendly: 'LGBTQ+ Friendly',
122
- womenOwned: 'Women Owned & Led',
123
- zeroWasteFocus: 'Zero Waste Focused',
124
- communityHub: 'Community Hub',
125
- // Workspace
126
- laptopWelcome: 'Laptop Welcome',
127
- fastWifi: 'Fast WiFi',
128
- longStayOk: 'Long Stay OK',
129
- };
@@ -20,11 +20,12 @@ export type DbFarm = Tables<"farms">;
20
20
  export type DbFranchise = Tables<"franchises">;
21
21
  export type DbCoffeeBean = Tables<"coffee_beans">;
22
22
  export type DbShopRoaster = Tables<"shop_roasters">;
23
- export type DbRoasterFarm = Tables<"roaster_farms">;
24
23
  export type DbFranchiseRoaster = Tables<"franchise_roasters">;
25
24
  export type DbShopBean = Tables<"shop_beans">;
26
25
  export type DbUserFollower = Tables<"user_followers">;
27
26
  export type DbShopFavourite = Tables<"shop_favourites">;
27
+ export type DbCoffeeBeanOrigin = Tables<"coffee_bean_origins">;
28
+ export type DbSubmissionOrigin = Tables<"submission_origins">;
28
29
  export type DbAction = Tables<"actions">;
29
30
  export type DbPoints = Tables<"points">;
30
31
  export type DbReward = Tables<"rewards">;
@@ -77,11 +78,12 @@ export type NewFarm = TablesInsert<"farms">;
77
78
  export type NewFranchise = TablesInsert<"franchises">;
78
79
  export type NewCoffeeBean = TablesInsert<"coffee_beans">;
79
80
  export type NewShopRoaster = TablesInsert<"shop_roasters">;
80
- export type NewRoasterFarm = TablesInsert<"roaster_farms">;
81
81
  export type NewFranchiseRoaster = TablesInsert<"franchise_roasters">;
82
82
  export type NewShopBean = TablesInsert<"shop_beans">;
83
83
  export type NewUserFollower = TablesInsert<"user_followers">;
84
84
  export type NewShopFavourite = TablesInsert<"shop_favourites">;
85
+ export type NewCoffeeBeanOrigin = TablesInsert<"coffee_bean_origins">;
86
+ export type NewSubmissionOrigin = TablesInsert<"submission_origins">;
85
87
  export type NewAction = TablesInsert<"actions">;
86
88
  export type NewPoints = TablesInsert<"points">;
87
89
  export type NewReward = TablesInsert<"rewards">;
@@ -133,6 +135,8 @@ export type CoffeeBeanUpdate = TablesUpdate<"coffee_beans">;
133
135
  export type ActionUpdate = TablesUpdate<"actions">;
134
136
  export type PointsUpdate = TablesUpdate<"points">;
135
137
  export type RewardUpdate = TablesUpdate<"rewards">;
138
+ export type CoffeeBeanOriginUpdate = TablesUpdate<"coffee_bean_origins">;
139
+ export type SubmissionOriginUpdate = TablesUpdate<"submission_origins">;
136
140
  export type ReviewUpdate = TablesUpdate<"reviews">;
137
141
  export type VoteUpdate = TablesUpdate<"votes">;
138
142
  export type AssertionUpdate = TablesUpdate<"assertions">;
@@ -270,22 +270,80 @@ export type Database = {
270
270
  }
271
271
  ];
272
272
  };
273
+ coffee_bean_origins: {
274
+ Row: {
275
+ altitude_max_m: number | null;
276
+ altitude_min_m: number | null;
277
+ bean_id: string;
278
+ blend_percentage: number | null;
279
+ country_code: string;
280
+ country_name: string | null;
281
+ farm_id: string | null;
282
+ farm_name_unverified: string | null;
283
+ ordinal: number;
284
+ producer_name: string | null;
285
+ region: string | null;
286
+ subregion: string | null;
287
+ trade_program: string | null;
288
+ };
289
+ Insert: {
290
+ altitude_max_m?: number | null;
291
+ altitude_min_m?: number | null;
292
+ bean_id: string;
293
+ blend_percentage?: number | null;
294
+ country_code: string;
295
+ country_name?: string | null;
296
+ farm_id?: string | null;
297
+ farm_name_unverified?: string | null;
298
+ ordinal: number;
299
+ producer_name?: string | null;
300
+ region?: string | null;
301
+ subregion?: string | null;
302
+ trade_program?: string | null;
303
+ };
304
+ Update: {
305
+ altitude_max_m?: number | null;
306
+ altitude_min_m?: number | null;
307
+ bean_id?: string;
308
+ blend_percentage?: number | null;
309
+ country_code?: string;
310
+ country_name?: string | null;
311
+ farm_id?: string | null;
312
+ farm_name_unverified?: string | null;
313
+ ordinal?: number;
314
+ producer_name?: string | null;
315
+ region?: string | null;
316
+ subregion?: string | null;
317
+ trade_program?: string | null;
318
+ };
319
+ Relationships: [
320
+ {
321
+ foreignKeyName: "coffee_bean_origins_bean_id_fkey";
322
+ columns: ["bean_id"];
323
+ isOneToOne: false;
324
+ referencedRelation: "coffee_beans";
325
+ referencedColumns: ["id"];
326
+ },
327
+ {
328
+ foreignKeyName: "coffee_bean_origins_farm_id_fkey";
329
+ columns: ["farm_id"];
330
+ isOneToOne: false;
331
+ referencedRelation: "farms";
332
+ referencedColumns: ["id"];
333
+ }
334
+ ];
335
+ };
273
336
  coffee_bean_submissions: {
274
337
  Row: {
275
338
  active: boolean | null;
276
- approved_bean_id: string | null;
277
339
  bean_id: string | null;
278
- bean_name: string | null;
279
340
  country: string | null;
280
341
  created_at: string | null;
281
342
  decaf_method: string | null;
282
343
  id: string;
283
344
  image: string | null;
284
- image_url: string | null;
285
345
  is_decaf: boolean | null;
286
346
  name: string | null;
287
- origin: string | null;
288
- process: string | null;
289
347
  processing: string | null;
290
348
  review_notes: string | null;
291
349
  reviewed_at: string | null;
@@ -300,19 +358,14 @@ export type Database = {
300
358
  };
301
359
  Insert: {
302
360
  active?: boolean | null;
303
- approved_bean_id?: string | null;
304
361
  bean_id?: string | null;
305
- bean_name?: string | null;
306
362
  country?: string | null;
307
363
  created_at?: string | null;
308
364
  decaf_method?: string | null;
309
365
  id?: string;
310
366
  image?: string | null;
311
- image_url?: string | null;
312
367
  is_decaf?: boolean | null;
313
368
  name?: string | null;
314
- origin?: string | null;
315
- process?: string | null;
316
369
  processing?: string | null;
317
370
  review_notes?: string | null;
318
371
  reviewed_at?: string | null;
@@ -327,19 +380,14 @@ export type Database = {
327
380
  };
328
381
  Update: {
329
382
  active?: boolean | null;
330
- approved_bean_id?: string | null;
331
383
  bean_id?: string | null;
332
- bean_name?: string | null;
333
384
  country?: string | null;
334
385
  created_at?: string | null;
335
386
  decaf_method?: string | null;
336
387
  id?: string;
337
388
  image?: string | null;
338
- image_url?: string | null;
339
389
  is_decaf?: boolean | null;
340
390
  name?: string | null;
341
- origin?: string | null;
342
- process?: string | null;
343
391
  processing?: string | null;
344
392
  review_notes?: string | null;
345
393
  reviewed_at?: string | null;
@@ -357,66 +405,90 @@ export type Database = {
357
405
  coffee_beans: {
358
406
  Row: {
359
407
  active: boolean | null;
360
- country: string | null;
408
+ awards: string[] | null;
409
+ brew_recommendations: string[] | null;
410
+ certifications: string[] | null;
361
411
  created_at: string | null;
412
+ cup_profile: string | null;
362
413
  decaf_method: string | null;
363
414
  description: string | null;
364
- elevation: number | null;
365
415
  farm_id: string | null;
416
+ farmer_story: string | null;
417
+ harvest_period: string | null;
418
+ harvest_year: number | null;
366
419
  id: string;
367
420
  image: string | null;
421
+ impact_notes: string | null;
368
422
  is_decaf: boolean | null;
369
423
  limited_edition: boolean | null;
424
+ lot_name: string | null;
370
425
  name: string | null;
371
- origin: string | null;
372
- origins: Json | null;
373
426
  processing: string | null;
374
- region: string | null;
427
+ processing_details: string | null;
428
+ roast_level: string | null;
375
429
  roaster_id: string | null;
430
+ sca_score: number | null;
376
431
  tasting_notes: string[] | null;
377
432
  updated_at: string | null;
433
+ varieties: string[] | null;
378
434
  };
379
435
  Insert: {
380
436
  active?: boolean | null;
381
- country?: string | null;
437
+ awards?: string[] | null;
438
+ brew_recommendations?: string[] | null;
439
+ certifications?: string[] | null;
382
440
  created_at?: string | null;
441
+ cup_profile?: string | null;
383
442
  decaf_method?: string | null;
384
443
  description?: string | null;
385
- elevation?: number | null;
386
444
  farm_id?: string | null;
445
+ farmer_story?: string | null;
446
+ harvest_period?: string | null;
447
+ harvest_year?: number | null;
387
448
  id: string;
388
449
  image?: string | null;
450
+ impact_notes?: string | null;
389
451
  is_decaf?: boolean | null;
390
452
  limited_edition?: boolean | null;
453
+ lot_name?: string | null;
391
454
  name?: string | null;
392
- origin?: string | null;
393
- origins?: Json | null;
394
455
  processing?: string | null;
395
- region?: string | null;
456
+ processing_details?: string | null;
457
+ roast_level?: string | null;
396
458
  roaster_id?: string | null;
459
+ sca_score?: number | null;
397
460
  tasting_notes?: string[] | null;
398
461
  updated_at?: string | null;
462
+ varieties?: string[] | null;
399
463
  };
400
464
  Update: {
401
465
  active?: boolean | null;
402
- country?: string | null;
466
+ awards?: string[] | null;
467
+ brew_recommendations?: string[] | null;
468
+ certifications?: string[] | null;
403
469
  created_at?: string | null;
470
+ cup_profile?: string | null;
404
471
  decaf_method?: string | null;
405
472
  description?: string | null;
406
- elevation?: number | null;
407
473
  farm_id?: string | null;
474
+ farmer_story?: string | null;
475
+ harvest_period?: string | null;
476
+ harvest_year?: number | null;
408
477
  id?: string;
409
478
  image?: string | null;
479
+ impact_notes?: string | null;
410
480
  is_decaf?: boolean | null;
411
481
  limited_edition?: boolean | null;
482
+ lot_name?: string | null;
412
483
  name?: string | null;
413
- origin?: string | null;
414
- origins?: Json | null;
415
484
  processing?: string | null;
416
- region?: string | null;
485
+ processing_details?: string | null;
486
+ roast_level?: string | null;
417
487
  roaster_id?: string | null;
488
+ sca_score?: number | null;
418
489
  tasting_notes?: string[] | null;
419
490
  updated_at?: string | null;
491
+ varieties?: string[] | null;
420
492
  };
421
493
  Relationships: [
422
494
  {
@@ -2777,36 +2849,6 @@ export type Database = {
2777
2849
  }
2778
2850
  ];
2779
2851
  };
2780
- roaster_farms: {
2781
- Row: {
2782
- farm_id: string;
2783
- roaster_id: string;
2784
- };
2785
- Insert: {
2786
- farm_id: string;
2787
- roaster_id: string;
2788
- };
2789
- Update: {
2790
- farm_id?: string;
2791
- roaster_id?: string;
2792
- };
2793
- Relationships: [
2794
- {
2795
- foreignKeyName: "roaster_farms_farm_id_fkey";
2796
- columns: ["farm_id"];
2797
- isOneToOne: false;
2798
- referencedRelation: "farms";
2799
- referencedColumns: ["id"];
2800
- },
2801
- {
2802
- foreignKeyName: "roaster_farms_roaster_id_fkey";
2803
- columns: ["roaster_id"];
2804
- isOneToOne: false;
2805
- referencedRelation: "roasters";
2806
- referencedColumns: ["id"];
2807
- }
2808
- ];
2809
- };
2810
2852
  roaster_submissions: {
2811
2853
  Row: {
2812
2854
  about: string | null;
@@ -3860,6 +3902,69 @@ export type Database = {
3860
3902
  };
3861
3903
  Relationships: [];
3862
3904
  };
3905
+ submission_origins: {
3906
+ Row: {
3907
+ altitude_max_m: number | null;
3908
+ altitude_min_m: number | null;
3909
+ blend_percentage: number | null;
3910
+ country_code: string;
3911
+ country_name: string | null;
3912
+ farm_id: string | null;
3913
+ farm_name_unverified: string | null;
3914
+ ordinal: number;
3915
+ producer_name: string | null;
3916
+ region: string | null;
3917
+ submission_id: string;
3918
+ subregion: string | null;
3919
+ trade_program: string | null;
3920
+ };
3921
+ Insert: {
3922
+ altitude_max_m?: number | null;
3923
+ altitude_min_m?: number | null;
3924
+ blend_percentage?: number | null;
3925
+ country_code: string;
3926
+ country_name?: string | null;
3927
+ farm_id?: string | null;
3928
+ farm_name_unverified?: string | null;
3929
+ ordinal: number;
3930
+ producer_name?: string | null;
3931
+ region?: string | null;
3932
+ submission_id: string;
3933
+ subregion?: string | null;
3934
+ trade_program?: string | null;
3935
+ };
3936
+ Update: {
3937
+ altitude_max_m?: number | null;
3938
+ altitude_min_m?: number | null;
3939
+ blend_percentage?: number | null;
3940
+ country_code?: string;
3941
+ country_name?: string | null;
3942
+ farm_id?: string | null;
3943
+ farm_name_unverified?: string | null;
3944
+ ordinal?: number;
3945
+ producer_name?: string | null;
3946
+ region?: string | null;
3947
+ submission_id?: string;
3948
+ subregion?: string | null;
3949
+ trade_program?: string | null;
3950
+ };
3951
+ Relationships: [
3952
+ {
3953
+ foreignKeyName: "submission_origins_farm_id_fkey";
3954
+ columns: ["farm_id"];
3955
+ isOneToOne: false;
3956
+ referencedRelation: "farms";
3957
+ referencedColumns: ["id"];
3958
+ },
3959
+ {
3960
+ foreignKeyName: "submission_origins_submission_id_fkey";
3961
+ columns: ["submission_id"];
3962
+ isOneToOne: false;
3963
+ referencedRelation: "coffee_bean_submissions";
3964
+ referencedColumns: ["id"];
3965
+ }
3966
+ ];
3967
+ };
3863
3968
  submissions: {
3864
3969
  Row: {
3865
3970
  active: boolean | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonarcher/fika-types",
3
- "version": "1.6.0",
3
+ "version": "2.0.0-rc.1",
4
4
  "description": "Shared TypeScript types for Fika projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",