@purveyors/cli 0.1.0 → 0.3.0

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.
Files changed (86) hide show
  1. package/README.md +23 -23
  2. package/dist/commands/auth.js +4 -4
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/catalog.d.ts +5 -57
  5. package/dist/commands/catalog.d.ts.map +1 -1
  6. package/dist/commands/catalog.js +15 -82
  7. package/dist/commands/catalog.js.map +1 -1
  8. package/dist/commands/inventory.d.ts +3 -26
  9. package/dist/commands/inventory.d.ts.map +1 -1
  10. package/dist/commands/inventory.js +53 -153
  11. package/dist/commands/inventory.js.map +1 -1
  12. package/dist/commands/roast.d.ts +3 -42
  13. package/dist/commands/roast.d.ts.map +1 -1
  14. package/dist/commands/roast.js +144 -131
  15. package/dist/commands/roast.js.map +1 -1
  16. package/dist/commands/sales.d.ts +3 -11
  17. package/dist/commands/sales.d.ts.map +1 -1
  18. package/dist/commands/sales.js +35 -114
  19. package/dist/commands/sales.js.map +1 -1
  20. package/dist/commands/tasting.d.ts +5 -39
  21. package/dist/commands/tasting.d.ts.map +1 -1
  22. package/dist/commands/tasting.js +21 -111
  23. package/dist/commands/tasting.js.map +1 -1
  24. package/dist/index.js +23 -23
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/artisan/db.d.ts +37 -0
  27. package/dist/lib/artisan/db.d.ts.map +1 -0
  28. package/dist/lib/artisan/db.js +51 -0
  29. package/dist/lib/artisan/db.js.map +1 -0
  30. package/dist/lib/artisan/import.d.ts +16 -0
  31. package/dist/lib/artisan/import.d.ts.map +1 -0
  32. package/dist/lib/artisan/import.js +447 -0
  33. package/dist/lib/artisan/import.js.map +1 -0
  34. package/dist/lib/artisan/index.d.ts +9 -0
  35. package/dist/lib/artisan/index.d.ts.map +1 -0
  36. package/dist/lib/artisan/index.js +7 -0
  37. package/dist/lib/artisan/index.js.map +1 -0
  38. package/dist/lib/artisan/parser.d.ts +19 -0
  39. package/dist/lib/artisan/parser.d.ts.map +1 -0
  40. package/dist/lib/artisan/parser.js +376 -0
  41. package/dist/lib/artisan/parser.js.map +1 -0
  42. package/dist/lib/artisan/temperature.d.ts +52 -0
  43. package/dist/lib/artisan/temperature.d.ts.map +1 -0
  44. package/dist/lib/artisan/temperature.js +101 -0
  45. package/dist/lib/artisan/temperature.js.map +1 -0
  46. package/dist/lib/artisan/types.d.ts +195 -0
  47. package/dist/lib/artisan/types.d.ts.map +1 -0
  48. package/dist/lib/artisan/types.js +35 -0
  49. package/dist/lib/artisan/types.js.map +1 -0
  50. package/dist/lib/artisan/validator.d.ts +14 -0
  51. package/dist/lib/artisan/validator.d.ts.map +1 -0
  52. package/dist/lib/artisan/validator.js +228 -0
  53. package/dist/lib/artisan/validator.js.map +1 -0
  54. package/dist/lib/catalog.d.ts +87 -0
  55. package/dist/lib/catalog.d.ts.map +1 -0
  56. package/dist/lib/catalog.js +111 -0
  57. package/dist/lib/catalog.js.map +1 -0
  58. package/dist/lib/config.d.ts +1 -0
  59. package/dist/lib/config.d.ts.map +1 -1
  60. package/dist/lib/config.js +20 -2
  61. package/dist/lib/config.js.map +1 -1
  62. package/dist/lib/errors.js +2 -2
  63. package/dist/lib/errors.js.map +1 -1
  64. package/dist/lib/index.d.ts +6 -0
  65. package/dist/lib/index.d.ts.map +1 -0
  66. package/dist/lib/index.js +11 -0
  67. package/dist/lib/index.js.map +1 -0
  68. package/dist/lib/inventory.d.ts +80 -0
  69. package/dist/lib/inventory.d.ts.map +1 -0
  70. package/dist/lib/inventory.js +205 -0
  71. package/dist/lib/inventory.js.map +1 -0
  72. package/dist/lib/roast.d.ts +127 -0
  73. package/dist/lib/roast.d.ts.map +1 -0
  74. package/dist/lib/roast.js +284 -0
  75. package/dist/lib/roast.js.map +1 -0
  76. package/dist/lib/sales.d.ts +53 -0
  77. package/dist/lib/sales.d.ts.map +1 -0
  78. package/dist/lib/sales.js +155 -0
  79. package/dist/lib/sales.js.map +1 -0
  80. package/dist/lib/supabase.js +2 -2
  81. package/dist/lib/supabase.js.map +1 -1
  82. package/dist/lib/tasting.d.ts +76 -0
  83. package/dist/lib/tasting.d.ts.map +1 -0
  84. package/dist/lib/tasting.js +136 -0
  85. package/dist/lib/tasting.js.map +1 -0
  86. package/package.json +24 -13
@@ -3,11 +3,10 @@ import { createAuthenticatedClient } from '../lib/supabase.js';
3
3
  import { outputData, info, success } from '../lib/output.js';
4
4
  import { withErrorHandling, AuthError, PrvrsError } from '../lib/errors.js';
5
5
  import { confirm, todayIso } from '../lib/prompts.js';
6
- // ─── Shared select columns ────────────────────────────────────────────────────
7
- const SALE_SELECT = 'id, roast_id, oz_sold, sale_price, buyer, sell_date, user, last_updated';
6
+ import { listSales, recordSale, updateSale, deleteSale } from '../lib/sales.js';
8
7
  // ─── Command builder ──────────────────────────────────────────────────────────
9
8
  /**
10
- * `prvrs sales` — Record and manage coffee sales.
9
+ * `purvey sales` — Record and manage coffee sales.
11
10
  * Requires authentication.
12
11
  */
13
12
  export function buildSalesCommand() {
@@ -22,19 +21,12 @@ export function buildSalesCommand() {
22
21
  const supabase = await createAuthenticatedClient();
23
22
  const { data: { user }, } = await supabase.auth.getUser();
24
23
  if (!user) {
25
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
24
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
26
25
  }
27
- const limit = Math.max(1, parseInt(opts.limit, 10));
28
- // Join with roast_profiles to surface coffee name
29
- const { data, error } = await supabase
30
- .from('sales')
31
- .select(`${SALE_SELECT}, roast_profiles!roast_id (batch_name, coffee_name)`)
32
- .eq('user', user.id)
33
- .order('sell_date', { ascending: false })
34
- .limit(limit);
35
- if (error)
36
- throw error;
37
- if (!data || data.length === 0) {
26
+ const data = await listSales(supabase, user.id, {
27
+ limit: Math.max(1, parseInt(opts.limit, 10)),
28
+ });
29
+ if (data.length === 0) {
38
30
  info('No sales found.');
39
31
  return;
40
32
  }
@@ -54,7 +46,7 @@ export function buildSalesCommand() {
54
46
  const supabase = await createAuthenticatedClient();
55
47
  const { data: { user }, } = await supabase.auth.getUser();
56
48
  if (!user) {
57
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
49
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
58
50
  }
59
51
  const roastId = parseInt(opts.roastId, 10);
60
52
  if (isNaN(roastId)) {
@@ -68,42 +60,14 @@ export function buildSalesCommand() {
68
60
  if (isNaN(price) || price < 0) {
69
61
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid --price: "${opts.price}". Must be a non-negative number.`);
70
62
  }
71
- // Verify the roast profile belongs to the user
72
- const { data: roastExists, error: roastError } = await supabase
73
- .from('roast_profiles')
74
- .select('roast_id')
75
- .eq('roast_id', roastId)
76
- .eq('user', user.id)
77
- .single();
78
- if (roastError || !roastExists) {
79
- throw new AuthError(`Roast profile ${roastId} not found or does not belong to you.`);
80
- }
81
- const insertPayload = {
82
- user: user.id,
83
- roast_id: roastId,
84
- oz_sold: oz,
85
- sale_price: price,
86
- sell_date: opts.sellDate ?? todayIso(),
87
- };
88
- if (opts.buyer !== undefined) {
89
- insertPayload.buyer = opts.buyer;
90
- }
91
- const { data: inserted, error: insertError } = await supabase
92
- .from('sales')
93
- .insert(insertPayload)
94
- .select('id')
95
- .single();
96
- if (insertError)
97
- throw insertError;
98
- // Re-fetch the full row with roast join
99
- const { data, error } = await supabase
100
- .from('sales')
101
- .select(`${SALE_SELECT}, roast_profiles!roast_id (batch_name, coffee_name)`)
102
- .eq('id', inserted.id)
103
- .single();
104
- if (error)
105
- throw error;
106
- success(`Sale ${inserted.id} recorded.`);
63
+ const data = await recordSale(supabase, user.id, {
64
+ roastId,
65
+ oz,
66
+ price,
67
+ buyer: opts.buyer,
68
+ sellDate: opts.sellDate ?? todayIso(),
69
+ });
70
+ success(`Sale ${data.id} recorded.`);
107
71
  outputData(data, globalOpts);
108
72
  }));
109
73
  // ── sales update <id> ─────────────────────────────────────────────────────
@@ -119,60 +83,36 @@ export function buildSalesCommand() {
119
83
  const supabase = await createAuthenticatedClient();
120
84
  const { data: { user }, } = await supabase.auth.getUser();
121
85
  if (!user) {
122
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
86
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
123
87
  }
124
88
  const saleId = parseInt(id, 10);
125
89
  if (isNaN(saleId)) {
126
90
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid sale ID: "${id}".`);
127
91
  }
128
- // Verify ownership
129
- const { data: existing, error: fetchError } = await supabase
130
- .from('sales')
131
- .select('id')
132
- .eq('id', saleId)
133
- .eq('user', user.id)
134
- .single();
135
- if (fetchError || !existing) {
136
- throw new AuthError(`Sale ${id} not found or does not belong to you.`);
137
- }
138
- // Build partial update
139
- const updates = {};
92
+ let oz;
140
93
  if (opts.oz !== undefined) {
141
- const oz = parseFloat(opts.oz);
94
+ oz = parseFloat(opts.oz);
142
95
  if (isNaN(oz) || oz <= 0)
143
96
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid --oz: "${opts.oz}".`);
144
- updates.oz_sold = oz;
145
97
  }
98
+ let price;
146
99
  if (opts.price !== undefined) {
147
- const price = parseFloat(opts.price);
100
+ price = parseFloat(opts.price);
148
101
  if (isNaN(price) || price < 0)
149
102
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid --price: "${opts.price}".`);
150
- updates.sale_price = price;
151
103
  }
152
- if (opts.buyer !== undefined) {
153
- updates.buyer = opts.buyer;
154
- }
155
- if (opts.sellDate !== undefined) {
156
- updates.sell_date = opts.sellDate;
157
- }
158
- if (Object.keys(updates).length === 0) {
104
+ if (oz === undefined &&
105
+ price === undefined &&
106
+ opts.buyer === undefined &&
107
+ opts.sellDate === undefined) {
159
108
  throw new PrvrsError('INVALID_ARGUMENT', 'No update fields provided. Pass at least one of: --oz, --price, --buyer, --sell-date.');
160
109
  }
161
- const { error: updateError } = await supabase
162
- .from('sales')
163
- .update(updates)
164
- .eq('id', saleId)
165
- .eq('user', user.id);
166
- if (updateError)
167
- throw updateError;
168
- // Re-fetch the updated row
169
- const { data, error } = await supabase
170
- .from('sales')
171
- .select(`${SALE_SELECT}, roast_profiles!roast_id (batch_name, coffee_name)`)
172
- .eq('id', saleId)
173
- .single();
174
- if (error)
175
- throw error;
110
+ const data = await updateSale(supabase, user.id, saleId, {
111
+ oz,
112
+ price,
113
+ buyer: opts.buyer,
114
+ sellDate: opts.sellDate,
115
+ });
176
116
  success(`Sale ${saleId} updated.`);
177
117
  outputData(data, globalOpts);
178
118
  }));
@@ -182,43 +122,24 @@ export function buildSalesCommand() {
182
122
  .description('Delete a sale (must be yours)')
183
123
  .option('-y, --yes', 'Skip confirmation prompt')
184
124
  .action(withErrorHandling(async (id, opts, cmd) => {
185
- void cmd; // global opts not needed for delete
125
+ void cmd;
186
126
  const supabase = await createAuthenticatedClient();
187
127
  const { data: { user }, } = await supabase.auth.getUser();
188
128
  if (!user) {
189
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
129
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
190
130
  }
191
131
  const saleId = parseInt(id, 10);
192
132
  if (isNaN(saleId)) {
193
133
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid sale ID: "${id}".`);
194
134
  }
195
- // Verify ownership
196
- const { data: existing, error: fetchError } = await supabase
197
- .from('sales')
198
- .select('id, sell_date, oz_sold')
199
- .eq('id', saleId)
200
- .eq('user', user.id)
201
- .single();
202
- if (fetchError || !existing) {
203
- throw new AuthError(`Sale ${id} not found or does not belong to you.`);
204
- }
205
135
  if (!opts.yes) {
206
- const label = existing.sell_date
207
- ? `from ${existing.sell_date} (${existing.oz_sold} oz)`
208
- : `#${saleId}`;
209
- const ok = await confirm(`Delete sale ${label}?`);
136
+ const ok = await confirm(`Delete sale #${saleId}?`);
210
137
  if (!ok) {
211
138
  info('Aborted.');
212
139
  return;
213
140
  }
214
141
  }
215
- const { error: deleteError } = await supabase
216
- .from('sales')
217
- .delete()
218
- .eq('id', saleId)
219
- .eq('user', user.id);
220
- if (deleteError)
221
- throw deleteError;
142
+ await deleteSale(supabase, user.id, saleId);
222
143
  success(`Sale ${saleId} deleted.`);
223
144
  }));
224
145
  return sales;
@@ -1 +1 @@
1
- {"version":3,"file":"sales.js","sourceRoot":"","sources":["../../src/commands/sales.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sales.js","sourceRoot":"","sources":["../../src/commands/sales.ts"],"names":[],"mappings":"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"}
@@ -1,44 +1,10 @@
1
1
  import { Command } from 'commander';
2
- export type TastingFilter = 'user' | 'supplier' | 'both';
3
- export interface SupplierTastingNotes {
4
- source: 'supplier';
5
- catalogId: number;
6
- name: string | null;
7
- processing: string | null;
8
- region: string | null;
9
- cupping_notes: string | null;
10
- ai_tasting_notes: unknown | null;
11
- ai_description: string | null;
12
- }
13
- export interface UserTastingNotes {
14
- source: 'user';
15
- inventoryId: number;
16
- catalogId: number | null;
17
- cupping_notes: string | null;
18
- notes: string | null;
19
- }
20
- export interface TastingResult {
21
- beanId: number;
22
- filter: TastingFilter;
23
- supplier: SupplierTastingNotes | null;
24
- user: UserTastingNotes | null;
25
- }
26
- export interface CuppingNotes {
27
- aroma?: number;
28
- body?: number;
29
- acidity?: number;
30
- sweetness?: number;
31
- aftertaste?: number;
32
- brew_method?: string;
33
- notes?: string;
34
- rated_at?: string;
35
- }
36
- /** Validate a cupping score is an integer in [1, 5]. */
37
- export declare function isValidCuppingScore(value: number): boolean;
38
- /** Parse and validate a cupping score flag value. */
39
- export declare function parseCuppingScore(raw: string, flag: string): number;
2
+ import { isValidCuppingScore, parseCuppingScore } from '../lib/tasting.js';
3
+ import type { TastingFilter, TastingData, CuppingNotes } from '../lib/tasting.js';
4
+ export type { TastingFilter, TastingData, CuppingNotes };
5
+ export { isValidCuppingScore, parseCuppingScore };
40
6
  /**
41
- * `prvrs tasting` — View and record tasting notes for a bean.
7
+ * `purvey tasting` — View and record tasting notes for a bean.
42
8
  * Combines supplier notes from coffee_catalog with user notes from green_coffee_inv.
43
9
  * Requires authentication.
44
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tasting.d.ts","sourceRoot":"","sources":["../../src/commands/tasting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CASnE;AAID;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAyM7C"}
1
+ {"version":3,"file":"tasting.d.ts","sourceRoot":"","sources":["../../src/commands/tasting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAGL,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIlF,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAIlD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CA8G7C"}
@@ -2,22 +2,11 @@ import { Command } from 'commander';
2
2
  import { createAuthenticatedClient } from '../lib/supabase.js';
3
3
  import { outputData, info, success } from '../lib/output.js';
4
4
  import { withErrorHandling, AuthError, PrvrsError } from '../lib/errors.js';
5
- // ─── Validation helpers ───────────────────────────────────────────────────────
6
- /** Validate a cupping score is an integer in [1, 5]. */
7
- export function isValidCuppingScore(value) {
8
- return Number.isInteger(value) && value >= 1 && value <= 5;
9
- }
10
- /** Parse and validate a cupping score flag value. */
11
- export function parseCuppingScore(raw, flag) {
12
- const n = parseInt(raw, 10);
13
- if (isNaN(n) || !isValidCuppingScore(n)) {
14
- throw new PrvrsError('INVALID_ARGUMENT', `--${flag} must be an integer between 1 and 5 (got "${raw}").`);
15
- }
16
- return n;
17
- }
5
+ import { getTastingNotes, rateCoffee, isValidCuppingScore, parseCuppingScore, } from '../lib/tasting.js';
6
+ export { isValidCuppingScore, parseCuppingScore };
18
7
  // ─── Command builder ──────────────────────────────────────────────────────────
19
8
  /**
20
- * `prvrs tasting` — View and record tasting notes for a bean.
9
+ * `purvey tasting` — View and record tasting notes for a bean.
21
10
  * Combines supplier notes from coffee_catalog with user notes from green_coffee_inv.
22
11
  * Requires authentication.
23
12
  */
@@ -41,61 +30,9 @@ export function buildTastingCommand() {
41
30
  const supabase = await createAuthenticatedClient();
42
31
  const { data: { user }, } = await supabase.auth.getUser();
43
32
  if (!user) {
44
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
45
- }
46
- const result = {
47
- beanId: catalogId,
48
- filter,
49
- supplier: null,
50
- user: null,
51
- };
52
- // ── Supplier notes (from coffee_catalog) ─────────────────────────
53
- if (filter === 'supplier' || filter === 'both') {
54
- const { data: catalogRow, error: catalogError } = await supabase
55
- .from('coffee_catalog')
56
- .select('id, name, processing, region, source, cupping_notes, ai_tasting_notes, ai_description')
57
- .eq('id', catalogId)
58
- .single();
59
- if (catalogError && catalogError.code !== 'PGRST116') {
60
- throw catalogError;
61
- }
62
- if (catalogRow) {
63
- result.supplier = {
64
- source: 'supplier',
65
- catalogId: catalogRow.id,
66
- name: catalogRow.name ?? null,
67
- processing: catalogRow.processing ?? null,
68
- region: catalogRow.region ?? null,
69
- cupping_notes: catalogRow.cupping_notes ?? null,
70
- ai_tasting_notes: catalogRow.ai_tasting_notes ?? null,
71
- ai_description: catalogRow.ai_description ?? null,
72
- };
73
- }
74
- }
75
- // ── User notes (from green_coffee_inv) ───────────────────────────
76
- if (filter === 'user' || filter === 'both') {
77
- // A user might have multiple inventory items from the same catalog entry
78
- const { data: invRows, error: invError } = await supabase
79
- .from('green_coffee_inv')
80
- .select('id, catalog_id, cupping_notes, notes')
81
- .eq('catalog_id', catalogId)
82
- .eq('user', user.id)
83
- .order('id', { ascending: false })
84
- .limit(1);
85
- if (invError)
86
- throw invError;
87
- if (invRows && invRows.length > 0) {
88
- const row = invRows[0];
89
- result.user = {
90
- source: 'user',
91
- inventoryId: row.id,
92
- catalogId: row.catalog_id ?? null,
93
- cupping_notes: row.cupping_notes ?? null,
94
- notes: row.notes ?? null,
95
- };
96
- }
33
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
97
34
  }
98
- // If nothing found at all, let the user know
35
+ const result = await getTastingNotes(supabase, user.id, catalogId, filter);
99
36
  if (result.supplier === null && result.user === null) {
100
37
  info(`No tasting notes found for bean ID ${catalogId} (filter: ${filter}).`);
101
38
  return;
@@ -119,53 +56,26 @@ export function buildTastingCommand() {
119
56
  if (isNaN(inventoryId)) {
120
57
  throw new PrvrsError('INVALID_ARGUMENT', `Invalid bean ID: "${beanId}". Pass a green_coffee_inv ID.`);
121
58
  }
122
- // Parse and validate all scores
123
- const cupping = {
124
- aroma: parseCuppingScore(opts.aroma, 'aroma'),
125
- body: parseCuppingScore(opts.body, 'body'),
126
- acidity: parseCuppingScore(opts.acidity, 'acidity'),
127
- sweetness: parseCuppingScore(opts.sweetness, 'sweetness'),
128
- aftertaste: parseCuppingScore(opts.aftertaste, 'aftertaste'),
129
- rated_at: new Date().toISOString(),
130
- };
131
- if (opts.brewMethod !== undefined) {
132
- cupping.brew_method = opts.brewMethod;
133
- }
134
- if (opts.notes !== undefined) {
135
- cupping.notes = opts.notes;
136
- }
59
+ // Parse and validate all scores (CLI strings → numbers)
60
+ const aroma = parseCuppingScore(opts.aroma, 'aroma');
61
+ const body = parseCuppingScore(opts.body, 'body');
62
+ const acidity = parseCuppingScore(opts.acidity, 'acidity');
63
+ const sweetness = parseCuppingScore(opts.sweetness, 'sweetness');
64
+ const aftertaste = parseCuppingScore(opts.aftertaste, 'aftertaste');
137
65
  const supabase = await createAuthenticatedClient();
138
66
  const { data: { user }, } = await supabase.auth.getUser();
139
67
  if (!user) {
140
- throw new AuthError('Not logged in. Run `prvrs auth login` first.');
141
- }
142
- // Verify ownership of the inventory item
143
- const { data: existing, error: fetchError } = await supabase
144
- .from('green_coffee_inv')
145
- .select('id, catalog_id')
146
- .eq('id', inventoryId)
147
- .eq('user', user.id)
148
- .single();
149
- if (fetchError || !existing) {
150
- throw new AuthError(`Inventory item ${inventoryId} not found or does not belong to you.`);
68
+ throw new AuthError('Not logged in. Run `purvey auth login` first.');
151
69
  }
152
- // Update the cupping_notes JSONB field
153
- const { error: updateError } = await supabase
154
- .from('green_coffee_inv')
155
- // Pass object directly — Supabase JS serializes JSONB columns correctly
156
- .update({ cupping_notes: cupping })
157
- .eq('id', inventoryId)
158
- .eq('user', user.id);
159
- if (updateError)
160
- throw updateError;
161
- // Re-fetch the updated row
162
- const { data, error } = await supabase
163
- .from('green_coffee_inv')
164
- .select('id, catalog_id, cupping_notes, notes, last_updated')
165
- .eq('id', inventoryId)
166
- .single();
167
- if (error)
168
- throw error;
70
+ const data = await rateCoffee(supabase, user.id, inventoryId, {
71
+ aroma,
72
+ body,
73
+ acidity,
74
+ sweetness,
75
+ aftertaste,
76
+ brewMethod: opts.brewMethod,
77
+ notes: opts.notes,
78
+ });
169
79
  success(`Cupping notes saved for inventory item ${inventoryId}.`);
170
80
  outputData(data, globalOpts);
171
81
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"tasting.js","sourceRoot":"","sources":["../../src/commands/tasting.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasting.js","sourceRoot":"","sources":["../../src/commands/tasting.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -22,36 +22,36 @@ catch {
22
22
  }
23
23
  const program = new Command();
24
24
  program
25
- .name('prvrs')
25
+ .name('purvey')
26
26
  .description('The official CLI for purveyors.io — coffee intelligence from your terminal')
27
27
  .version(version, '-v, --version', 'Print version')
28
28
  .option('--pretty', 'Pretty-print JSON output with colors')
29
29
  .option('--csv', 'Output results as CSV (useful for piping to spreadsheets)')
30
30
  .addHelpText('after', `
31
31
  Examples:
32
- $ prvrs auth login # Authenticate via Google
33
- $ prvrs auth status # Check login state
34
- $ prvrs catalog search --origin Ethiopia --stocked
35
- $ prvrs catalog get 42
36
- $ prvrs catalog stats
37
- $ prvrs inventory list --stocked
38
- $ prvrs inventory get 7
39
- $ prvrs inventory add --catalog-id 42 --qty 5 --cost 28.50
40
- $ prvrs inventory update 7 --stocked true
41
- $ prvrs inventory delete 7
42
- $ prvrs roast list --limit 5
43
- $ prvrs roast get 123 --include-temps
44
- $ prvrs roast create --coffee-id 7 --batch-name "Ethiopia Guji" --oz-in 16
45
- $ prvrs roast delete 123
46
- $ prvrs sales list
47
- $ prvrs sales record --roast-id 123 --oz 12 --price 22.00
48
- $ prvrs sales update 5 --price 24.00
49
- $ prvrs sales delete 5
50
- $ prvrs tasting get 42 --filter both
51
- $ prvrs tasting rate 7 --aroma 4 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
52
- $ prvrs --help # Show this help
32
+ $ purvey auth login # Authenticate via Google
33
+ $ purvey auth status # Check login state
34
+ $ purvey catalog search --origin Ethiopia --stocked
35
+ $ purvey catalog get 42
36
+ $ purvey catalog stats
37
+ $ purvey inventory list --stocked
38
+ $ purvey inventory get 7
39
+ $ purvey inventory add --catalog-id 42 --qty 5 --cost 28.50
40
+ $ purvey inventory update 7 --stocked true
41
+ $ purvey inventory delete 7
42
+ $ purvey roast list --limit 5
43
+ $ purvey roast get 123 --include-temps
44
+ $ purvey roast create --coffee-id 7 --batch-name "Ethiopia Guji" --oz-in 16
45
+ $ purvey roast delete 123
46
+ $ purvey sales list
47
+ $ purvey sales record --roast-id 123 --oz 12 --price 22.00
48
+ $ purvey sales update 5 --price 24.00
49
+ $ purvey sales delete 5
50
+ $ purvey tasting get 42 --filter both
51
+ $ purvey tasting rate 7 --aroma 4 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
52
+ $ purvey --help # Show this help
53
53
 
54
- Docs: https://purveyors.io/docs/cli
54
+ Docs: https://github.com/reedwhetstone/purveyors-cli
55
55
  `);
56
56
  // Register subcommands
57
57
  program.addCommand(buildAuthCommand());
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,4CAA4C;AAC5C,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAAC,MAAM,CAAC;IACP,gCAAgC;AAClC,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,4EAA4E,CAAC;KACzF,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC;KAClD,MAAM,CAAC,UAAU,EAAE,sCAAsC,CAAC;KAC1D,MAAM,CAAC,OAAO,EAAE,2DAA2D,CAAC;KAC5E,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;CAyBH,CACE,CAAC;AAEJ,uBAAuB;AACvB,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAE1C,qBAAqB;AACrB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,4CAA4C;AAC5C,IAAI,OAAO,GAAG,OAAO,CAAC;AACtB,IAAI,CAAC;IACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;AACnC,CAAC;AAAC,MAAM,CAAC;IACP,gCAAgC;AAClC,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,4EAA4E,CAAC;KACzF,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,eAAe,CAAC;KAClD,MAAM,CAAC,UAAU,EAAE,sCAAsC,CAAC;KAC1D,MAAM,CAAC,OAAO,EAAE,2DAA2D,CAAC;KAC5E,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;CAyBH,CACE,CAAC;AAEJ,uBAAuB;AACvB,OAAO,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACvC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC1C,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAE1C,qBAAqB;AACrB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { SupabaseClient } from '@supabase/supabase-js';
2
+ export interface TemperatureRow {
3
+ roast_id: number;
4
+ time_seconds: number;
5
+ bean_temp?: number | null;
6
+ environmental_temp?: number | null;
7
+ ambient_temp?: number | null;
8
+ ror_bean_temp?: number | null;
9
+ data_source: string;
10
+ }
11
+ export interface EventRow {
12
+ roast_id: number;
13
+ time_seconds: number;
14
+ event_type: number;
15
+ event_value: string | null;
16
+ event_string: string;
17
+ category: string;
18
+ subcategory: string;
19
+ user_generated: boolean;
20
+ automatic: boolean;
21
+ notes?: string;
22
+ }
23
+ export declare const BATCH_SIZE = 100;
24
+ /**
25
+ * Clear existing roast data scoped to artisan_import source.
26
+ * Deletes temperature rows by data_source and event rows by category.
27
+ */
28
+ export declare function clearRoastData(supabase: SupabaseClient, roastId: number, source: 'artisan_import' | 'live'): Promise<void>;
29
+ /**
30
+ * Batch-insert temperature rows into roast_temperatures.
31
+ */
32
+ export declare function insertTemperatures(supabase: SupabaseClient, entries: TemperatureRow[]): Promise<void>;
33
+ /**
34
+ * Batch-insert event rows into roast_events.
35
+ */
36
+ export declare function insertEvents(supabase: SupabaseClient, entries: EventRow[]): Promise<void>;
37
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/lib/artisan/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,eAAO,MAAM,UAAU,MAAM,CAAC;AAI9B;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAChC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,cAAc,EAAE,GACxB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/F"}