Remove all references to nutrient targets.

Commit
03e1a1e6eac97f8d24ba36d7235d375331d11de1
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
db/migrations.rkt
index a0d7b9e0..71296f78 100644..100644
@@ -62,36 +62,25 @@
62 62 #:if-not-exists nutrient_value_sets
63 63 #:columns [id integer #:not-null]
64 64 [nutrient_measurement_id integer]
65 Removed: [nutrient_target_id integer]
66 65 [crop_requirement_id integer]
67 66 [fertilizer_product_id integer]
68 67 #:constraints (primary-key id)
69 68 (foreign-key nutrient_measurement_id #:references (nutrient_measurements id) #:on-delete #:cascade)
70 Removed: (foreign-key nutrient_target_id #:references (nutrient_targets id) #:on-delete #:cascade)
71 69 (foreign-key crop_requirement_id #:references (crop_requirements id) #:on-delete #:cascade)
72 70 (foreign-key fertilizer_product_id #:references (fertilizer_products id) #:on-delete #:cascade)
73 71 (unique nutrient_measurement_id)
74 Removed: (unique nutrient_target_id)
75 72 (unique crop_requirement_id)
76 73 (unique fertilizer_product_id)
77 74 (check (or (and (is-not-null nutrient_measurement_id)
78 Removed: (is-null nutrient_target_id)
79 75 (is-null crop_requirement_id)
80 76 (is-null fertilizer_product_id))
81 77 (and (is-null nutrient_measurement_id)
82 Removed: (is-not-null nutrient_target_id)
83 78 (is-null crop_requirement_id)
84 79 (is-null fertilizer_product_id))
85 80 (and (is-null nutrient_measurement_id)
86 Removed: (is-null nutrient_target_id)
87 81 (is-not-null crop_requirement_id)
88 Removed: (is-null fertilizer_product_id))
89 Removed: (and (is-null nutrient_measurement_id)
90 Removed: (is-null nutrient_target_id)
91 Removed: (is-null crop_requirement_id)
92 Removed: (is-not-null fertilizer_product_id)))))
82 Added: (is-null fertilizer_product_id)))))
93 83 "CREATE INDEX IF NOT EXISTS idx_nvs_meas ON nutrient_value_sets(nutrient_measurement_id)"
94 Removed: "CREATE INDEX IF NOT EXISTS idx_nvs_targ ON nutrient_value_sets(nutrient_target_id)"
95 84 "CREATE INDEX IF NOT EXISTS idx_nvs_crop ON nutrient_value_sets(crop_requirement_id)"
96 85 "CREATE INDEX IF NOT EXISTS idx_nvs_prod ON nutrient_value_sets(fertilizer_product_id)"))
97 86
@@ -115,13 +104,6 @@
115 104 #:constraints (primary-key id)
116 105 (unique measurement_date))))
117 106
118 Removed: (define-migration "create table nutrient_targets"
119 Removed: (list (create-table #:if-not-exists nutrient_targets
120 Removed: #:columns [id integer #:not-null]
121 Removed: ;; ISO8601 date
122 Removed: [target_date text #:not-null]
123 Removed: #:constraints (primary-key id)
124 Removed: (unique target_date))))
125 107
126 108 ;;;;;;;;
127 109 ;; CROPS
handlers.rkt
index bcd81c74..3798ca27 100644..100644
@@ -32,7 +32,7 @@
32 32 [("ferti" "measurement" "create") #:method "post" create-measurement]
33 33 [("ferti" "measurement" (integer-arg)) #:method "get" show-measurement]
34 34 [("ferti" "measurement" "destroy" (integer-arg)) #:method "get" destroy-measurement]
35 Removed: ;; Nutrient targets
35 Added: ;; Crop rotations
36 36 [("ferti" "rotation" "new") #:method "get" new-rotation]
37 37 [("ferti" "rotation" "new" (string-arg)) #:method "get" new-rotation-for-date]
38 38 [("ferti" "rotation" "create") #:method "post" create-rotation]
models/crop-rotation.rkt
index 37c242f3..630e493d 100644..100644
@@ -101,7 +101,7 @@
101 101 (match grouped-rows
102 102 ['() #f]
103 103 [(list grouped-row) (grouped-row->crop-rotation grouped-row)]
104 Removed: [many (error 'get-crop-rotation "expected 1 nutrient target, got ~a" (length many))]))
104 Added: [many (error 'get-crop-rotation "expected 1 crop rotation, got ~a" (length many))]))
105 105
106 106 (define (get-latest-crop-rotation)
107 107 (define rotations (get-crop-rotations))
models/nutrient-target.rkt
index bb89273b..00000000 100644..000000
@@ -1,239 +0,0 @@
1 Removed: #lang racket
2 Removed:
3 Removed: (provide nutrient-target
4 Removed: nutrient-target?
5 Removed: nutrient-target-id
6 Removed: (rename-out [nutrient-target-target-date nutrient-target-date]
7 Removed: [nutrient-target-nutrient-values nutrient-target-values])
8 Removed: (contract-out
9 Removed: [create-nutrient-target! (-> string? nutrient-value-hash/c nutrient-target?)]
10 Removed: [get-nutrient-targets (-> (listof nutrient-target?))]
11 Removed: [get-nutrient-target
12 Removed: (->* () (#:id exact-nonnegative-integer? #:date string?) (or/c nutrient-target? #f))]
13 Removed: [get-nutrient-target-values (-> nutrient-target-or-id/c nutrient-value-hash/c)]
14 Removed: [get-nutrient-target-value (-> nutrient-target-or-id/c nutrient? maybe-nutrient-value?)]
15 Removed: [get-latest-nutrient-target-value (-> nutrient? maybe-nutrient-value?)]
16 Removed: [get-latest-nutrient-target-values (-> nutrient-value-hash/c)]
17 Removed: [delete-nutrient-target! (-> nutrient-target-or-id/c void?)]))
18 Removed:
19 Removed: (require racket/contract
20 Removed: db
21 Removed: sql
22 Removed: "../db/conn.rkt"
23 Removed: "nutrient.rkt")
24 Removed:
25 Removed: (struct nutrient-target (id target-date nutrient-values)
26 Removed: #:transparent
27 Removed: #:property prop:custom-write
28 Removed: (λ (v out _)
29 Removed: (fprintf out "Target #~a on ~a\n" (nutrient-target-id v) (nutrient-target-target-date v))
30 Removed: (for ([(n v) (in-hash (nutrient-target-nutrient-values v))])
31 Removed: (fprintf out
32 Removed: "~a ~a\n"
33 Removed: (~a (nutrient-canonical-name n) #:min-width 14)
34 Removed: (~a v #:max-width 6 #:align 'right)))))
35 Removed:
36 Removed: (define nutrient-target-id? exact-nonnegative-integer?)
37 Removed: (define nutrient-target-or-id/c (or/c nutrient-target? nutrient-target-id?))
38 Removed:
39 Removed: (define (->nt-id nt-or-id)
40 Removed: (match nt-or-id
41 Removed: [(? nutrient-target-id? id) id]
42 Removed: [(nutrient-target id _ _) id]))
43 Removed:
44 Removed: ;; CREATE
45 Removed:
46 Removed: (define (create-nutrient-target! target-date nutrient-values)
47 Removed: (or (get-nutrient-target #:date target-date)
48 Removed: (with-tx
49 Removed: (query-exec (current-conn) (insert #:into nutrient_targets #:set [target_date ,target-date]))
50 Removed: (define nt-id
51 Removed: (query-value (current-conn)
52 Removed: (select id #:from nutrient_targets #:where (= target_date ,target-date))))
53 Removed: (query-exec (current-conn)
54 Removed: (insert #:into nutrient_value_sets #:set [nutrient_target_id ,nt-id]))
55 Removed: (define nvs-id
56 Removed: (query-value (current-conn)
57 Removed: (select id #:from nutrient_value_sets #:where (= nutrient_target_id ,nt-id))))
58 Removed: (for ([(n v) (in-hash nutrient-values)])
59 Removed: (query-exec (current-conn)
60 Removed: (insert #:into nutrient_values
61 Removed: #:set [value_set_id ,nvs-id]
62 Removed: [nutrient_id ,(nutrient-id n)]
63 Removed: [value_ppm ,v])))
64 Removed: (get-nutrient-target #:date target-date))))
65 Removed:
66 Removed: ;; READ
67 Removed:
68 Removed: (define joined
69 Removed: (table-expr-qq (inner-join (inner-join (inner-join (as nutrient_targets nt)
70 Removed: (as nutrient_value_sets nvs)
71 Removed: #:on (= nvs.nutrient_target_id nt.id))
72 Removed: (as nutrient_values nv)
73 Removed: #:on (= nv.value_set_id nvs.id))
74 Removed: (as nutrients n)
75 Removed: #:on (= n.id nv.nutrient_id))))
76 Removed:
77 Removed: (define (grouped-row->nutrient-target grouped-row)
78 Removed: (match-define (vector nt-id target-date residuals) grouped-row)
79 Removed: (nutrient-target nt-id target-date (residuals->nutrient-value-hash residuals)))
80 Removed:
81 Removed: (define (get-nutrient-targets)
82 Removed: (define grouped-rows
83 Removed: (query-rows (current-conn)
84 Removed: (select nt.id
85 Removed: nt.target_date
86 Removed: n.id
87 Removed: n.canonical_name
88 Removed: n.french_name
89 Removed: n.formula
90 Removed: nv.value_ppm
91 Removed: #:from (TableExpr:AST ,joined)
92 Removed: #:order-by nt.target_date
93 Removed: #:desc)
94 Removed: #:group '#(0 1)))
95 Removed: (map grouped-row->nutrient-target grouped-rows))
96 Removed:
97 Removed: (define (get-nutrient-target #:id [nt-id #f] #:date [target-date #f])
98 Removed: (define where
99 Removed: (cond
100 Removed: [(and nt-id target-date)
101 Removed: (scalar-expr-qq (and (= nt.id ,nt-id) (= nt.target_date ,target-date)))]
102 Removed: [nt-id (scalar-expr-qq (= nt.id ,nt-id))]
103 Removed: [target-date (scalar-expr-qq (= nt.target_date ,target-date))]
104 Removed: [else (error 'get-nutrient-target "either #:id or #:date must be provided")]))
105 Removed: (define grouped-rows
106 Removed: (query-rows (current-conn)
107 Removed: (select nt.id
108 Removed: nt.target_date
109 Removed: n.id
110 Removed: n.canonical_name
111 Removed: n.french_name
112 Removed: n.formula
113 Removed: nv.value_ppm
114 Removed: #:from (TableExpr:AST ,joined)
115 Removed: #:where (ScalarExpr:AST ,where)
116 Removed: #:order-by nt.target_date
117 Removed: #:desc)
118 Removed: #:group '#(0 1)))
119 Removed: (match grouped-rows
120 Removed: ['() #f]
121 Removed: [(list grouped-row) (grouped-row->nutrient-target grouped-row)]
122 Removed: [many (error 'get-nutrient-target "expected 1 nutrient target, got ~a" (length many))]))
123 Removed:
124 Removed: (define (get-nutrient-target-values nt-or-id)
125 Removed: (for/hash ([(nutrient-id canonical-name french-name formula value_ppm)
126 Removed: (in-query (current-conn)
127 Removed: (select n.id
128 Removed: n.canonical_name
129 Removed: n.french_name
130 Removed: n.formula
131 Removed: nv.value_ppm
132 Removed: #:from (TableExpr:AST ,joined)
133 Removed: #:where (= nt.id ,(->nt-id nt-or-id))))])
134 Removed: (values (nutrient nutrient-id canonical-name french-name formula) value_ppm)))
135 Removed:
136 Removed: (define (get-nutrient-target-value nt-or-id nutrient)
137 Removed: (query-maybe-value (current-conn)
138 Removed: (select value_ppm
139 Removed: #:from (TableExpr:AST ,joined)
140 Removed: #:where (and (= nt.id ,(->nt-id nt-or-id))
141 Removed: (= nv.nutrient_id ,(nutrient-id nutrient))))))
142 Removed:
143 Removed: (define (get-latest-nutrient-target-value nutrient)
144 Removed: (query-maybe-value (current-conn)
145 Removed: (select value_ppm
146 Removed: #:from (TableExpr:AST ,joined)
147 Removed: #:where (= nv.nutrient_id ,(nutrient-id nutrient))
148 Removed: #:order-by nt.target_date
149 Removed: #:desc
150 Removed: #:limit 1)))
151 Removed:
152 Removed: (define (get-latest-nutrient-target-values)
153 Removed: (define grouped-rows
154 Removed: (query-rows (current-conn)
155 Removed: (select n.id
156 Removed: n.canonical_name
157 Removed: n.french_name
158 Removed: n.formula
159 Removed: nt.target_date
160 Removed: nv.value_ppm
161 Removed: #:from (TableExpr:AST ,joined)
162 Removed: #:order-by nt.target_date
163 Removed: #:desc)
164 Removed: #:group '(#(0 1 2 3))))
165 Removed: (for/hash ([row grouped-rows])
166 Removed: (match-define (vector n-id n-canonical-name n-french-name n-formula residual-rows) row)
167 Removed: ;; residual-rows is a non-empty list of vectors: #(target_date value_ppm)
168 Removed: (match-define (vector _ value-ppm) (first residual-rows))
169 Removed: (values (nutrient n-id n-canonical-name n-french-name n-formula) value-ppm)))
170 Removed:
171 Removed: ;; UPDATE
172 Removed:
173 Removed: ;; DELETE
174 Removed:
175 Removed: (define (delete-nutrient-target! nt-or-id)
176 Removed: (query-exec (current-conn) (delete #:from nutrient_targets #:where (= id ,(->nt-id nt-or-id)))))
177 Removed:
178 Removed: (module+ test
179 Removed: (require rackunit
180 Removed: rackunit/text-ui
181 Removed: "../db/conn.rkt"
182 Removed: "../db/migrations.rkt"
183 Removed: "../models/nutrient.rkt")
184 Removed:
185 Removed: (define target-date "2025-09-01")
186 Removed:
187 Removed: (run-tests
188 Removed: (test-suite "Nutrient target model"
189 Removed: #:before (λ ()
190 Removed: (connect! #:path 'memory)
191 Removed: (migrate-all!)
192 Removed: (create-nutrient! "Nitrogen" "" "N")
193 Removed: (create-nutrient! "Phosphorus" "" "P")
194 Removed: (create-nutrient! "Potassium" "" "K"))
195 Removed: #:after (λ () (disconnect!))
196 Removed:
197 Removed: (test-case "Create target with date and values"
198 Removed: (define nitrogen (get-nutrient #:name "Nitrogen"))
199 Removed: (define phosphorus (get-nutrient #:name "Phosphorus"))
200 Removed: (create-nutrient-target! target-date (hash nitrogen 12.3 phosphorus 4.5))
201 Removed: (check-equal? (length (get-nutrient-targets)) 1)
202 Removed: (define nt (get-nutrient-target #:date target-date))
203 Removed: (check-true (nutrient-target? nt))
204 Removed: (check-equal? (nutrient-target-target-date nt) target-date))
205 Removed:
206 Removed: (test-case "Check all target values"
207 Removed: (define nitrogen (get-nutrient #:name "Nitrogen"))
208 Removed: (define phosphorus (get-nutrient #:name "Phosphorus"))
209 Removed:
210 Removed: (define nt (get-nutrient-target #:date target-date))
211 Removed: (check-equal? (get-nutrient-target-value nt nitrogen) 12.3)
212 Removed: (check-equal? (get-nutrient-target-value nt phosphorus) 4.5)
213 Removed:
214 Removed: (define ntv (nutrient-target-nutrient-values nt))
215 Removed: (check-equal?
216 Removed: (get-nutrient-target-values nt)
217 Removed: ntv
218 Removed: "return value of get-nutrient-target-values ≠ nutrient-target-values struct accessor")
219 Removed: (check-equal? (hash-count ntv) 2)
220 Removed: (check-equal? (hash-ref ntv nitrogen) 12.3)
221 Removed: (check-equal? (hash-ref ntv phosphorus) 4.5))
222 Removed:
223 Removed: (test-case "Retrieve latest target values"
224 Removed: (define nitrogen (get-nutrient #:name "Nitrogen"))
225 Removed: (define phosphorus (get-nutrient #:name "Phosphorus"))
226 Removed: (define second-target-date "2025-09-02")
227 Removed: (create-nutrient-target! second-target-date (hash nitrogen 6.7 phosphorus 8.9))
228 Removed:
229 Removed: (check-equal? (get-latest-nutrient-target-value nitrogen) 6.7)
230 Removed: (check-equal? (get-latest-nutrient-target-value phosphorus) 8.9))
231 Removed:
232 Removed: (test-case "Delete target and cascade to target values"
233 Removed: (define nt (get-nutrient-target #:date target-date))
234 Removed: (delete-nutrient-target! nt)
235 Removed: (check-false (get-nutrient-target #:id (nutrient-target-id nt)))
236 Removed: (check-equal? (length (get-nutrient-targets))
237 Removed: 1
238 Removed: "wrong number of nutrient targets were deleted")
239 Removed: (check-true (hash-empty? (get-nutrient-target-values nt)))))))
views.rkt
index 130b98d7..ee807202 100644..100644
@@ -134,29 +134,6 @@
134 134 "Ajouter un relevé"))
135 135 ,table)))
136 136
137 Removed: #;
138 Removed: (define (ferti-targets-page latest-measurement-hash latest-target-hash)
139 Removed: (define table
140 Removed: `(table ((class "table"))
141 Removed: (thead (tr (th "Nutriment")
142 Removed: (th ((class "text-end")) "Dernier Relevé")
143 Removed: (th ((class "text-end")) "Dernière Cible")))
144 Removed: (tbody ,@(for/list ([n (get-nutrients)])
145 Removed: (define latest-measurement (hash-ref latest-measurement-hash n #f))
146 Removed: (define latest-target (hash-ref latest-target-hash n #f))
147 Removed: `(tr (td ,(nutrient-french-name n))
148 Removed: (td ((class "text-end font-monospace"))
149 Removed: ,(if latest-measurement
150 Removed: (round 2 latest-measurement)
151 Removed: "—"))
152 Removed: (td ((class "text-end font-monospace"))
153 Removed: ,(if latest-target
154 Removed: (round 2 latest-target)
155 Removed: "—")))))))
156 Removed: (ferti-template `((h2 () "Dernière Cible")
157 Removed: (a ((class "btn btn-primary mb-3") [href "/ferti/target/new"]) "Créer une cible")
158 Removed: ,table)))
159 Removed:
160 137 (define (ferti-recipe-page recipe-date fertilizer-recipe)
161 138 (define table
162 139 `(table ((class "table"))