2026-08-15 - 2026-09-15

Overview

175 Active Pull Requests
156 Active Issues
Excluding merges, 1 author has pushed 5 commits to main and 333 commits to all branches. On main, 31 files have changed and there have been 1593 additions and 1120 deletions.

174 Pull requests merged by 1 user

Merged #356 docs(auth): correct the claim that QA could never run Google sign-in 2026-09-11 15:16:29 -05:00

Merged #355 chore(qa): read the Google credentials from the stack, like every other secret 2026-09-11 14:19:21 -05:00

Merged #354 fix(auth): offer Google on the sign-up tab, not only on Log In (#345) 2026-09-11 10:06:55 -05:00

Merged #353 fix(e2e): match an email template tab on its whole name, not a prefix 2026-09-11 10:04:43 -05:00

Merged #352 feat(auth): offer Google sign-in on the login form (#345) 2026-09-10 16:47:30 -05:00

Merged #351 feat(auth): the routes that assumed every customer has a password (#344) 2026-09-10 15:05:47 -05:00

Merged #350 feat(auth): link a Google identity to an account that already exists (#343) 2026-09-10 14:00:44 -05:00

Merged #349 feat(auth): create an account from a Google identity, then ask about consent (#342) 2026-09-10 10:11:18 -05:00

Merged #348 fix(local): install dependencies when the lockfile changes, not only when node_modules is absent 2026-09-10 10:07:00 -05:00

Merged #347 feat(auth): the Google sign-in round trip (#341) 2026-09-10 08:53:01 -05:00

Merged #346 feat(auth): groundwork for signing in with Google (#340) 2026-09-10 08:39:22 -05:00

Merged #339 fix(ci): the cleanup script forced TLS onto a plaintext endpoint (#324) 2026-09-10 07:19:47 -05:00

Merged #338 feat(admin): move a customer's account to an address they can reach (#337) 2026-09-09 16:38:35 -05:00

Merged #336 feat(passkeys): a password reset takes the passkeys with it (#42) 2026-09-09 16:22:13 -05:00

Merged #335 feat(passkeys): offer passkey sign-in on the login form (#41) 2026-09-09 15:53:20 -05:00

Merged #334 feat(passkeys): list, add and revoke from the account page (#40) 2026-09-09 15:44:49 -05:00

Merged #333 feat(passkeys): authentication ceremony (#39) 2026-09-09 14:32:26 -05:00

Merged #331 feat(passkeys): registration ceremony (#38) 2026-09-09 14:21:49 -05:00

Merged #330 feat(passkeys): schema, dependency and per-environment Relying Party (#37) 2026-09-09 14:08:29 -05:00

Merged #329 docs(ops): feature flags are not worth a manager here (#318) 2026-09-09 13:39:22 -05:00

Merged #328 fix(admin): refetch Inventory when its tab becomes visible (#327) 2026-09-09 13:32:36 -05:00

Merged #326 test(ci): record which Postgres actually answered (#154) 2026-09-09 10:49:04 -05:00

Merged #325 chore(ci): a manually-run workflow to delete old Actions runs (#324) 2026-09-09 10:48:29 -05:00

Merged #323 fix(tests): the error-handling suite would not compile, and nothing local said so (#307) 2026-09-09 08:51:34 -05:00

Merged #322 fix(items): read the id strictly, and stop the error test needing a route that does not (#307) 2026-09-08 16:00:45 -05:00

Merged #321 fix(tests): regenerate the schema mirror and name the controls #56 moved (#320) 2026-09-08 15:33:04 -05:00

Merged #319 test(e2e): make the resend allowance failure say why (#257) 2026-09-08 14:01:10 -05:00

Merged #317 feat(analytics): report consenting customers' activity to Brevo (#56) 2026-09-08 12:41:51 -05:00

Merged #316 fix(admin): keep a modal's controls on screen on a phone (#314) 2026-09-06 10:04:31 -05:00

Merged #315 docs(ops): the free tier cannot be applied to this hostname (#285) 2026-09-06 10:02:27 -05:00

Merged #312 fix(tests): close the route guard's factory hole and two regex warnings (#307) 2026-09-05 08:26:22 -05:00

Merged #310 docs(scripts): record the Node pin decision at the constant (#208) 2026-09-05 08:25:11 -05:00

Merged #309 Feature/308 kysely dynamic queries 2026-09-04 17:47:42 -05:00

Merged #306 Feature/305 kysely swap 2026-09-04 16:08:50 -05:00

Merged #304 docs(db): weigh Kysely against the Drizzle decision (#297) 2026-09-04 14:40:34 -05:00

Merged #303 Feature/301 rotate photos 2026-09-04 14:17:13 -05:00

Merged #302 fix(uploads): apply the EXIF orientation before discarding it (#300) 2026-09-04 13:30:05 -05:00

Merged #299 fix(lint): bring the backend test suites into scope (#298) 2026-09-04 12:58:13 -05:00

Merged #296 Feature/293 remove backgrounds from inventory 2026-09-04 12:20:01 -05:00

Merged #295 chore(sonarqube): keep interpolation out of query call sites (#294) 2026-09-04 09:36:40 -05:00

Merged #292 Feature/260 email the upload link 2026-09-03 18:50:37 -05:00

Merged #291 fix(scripts): make the database the e2e suite reads a recorded fact (#273) 2026-09-03 16:59:17 -05:00

Merged #290 fix(admin): let a setting whose default is empty actually be cleared (#280) 2026-09-03 16:53:45 -05:00

Merged #289 fix(admin): answer 404 for an unreadable id instead of 500 (#207) 2026-09-03 16:47:33 -05:00

Merged #288 fix(ci): give the end-to-end backend a REMBG_URL so its controls render (#287) 2026-09-03 16:37:32 -05:00

Merged #286 Feature/269 paginate catalogue 2026-09-03 16:29:42 -05:00

Merged #284 Feature/281 background removal plan 2026-09-03 14:09:52 -05:00

Merged #283 docs(intake): design background removal for submitted photos (#281) 2026-09-03 10:51:58 -05:00

Merged #282 chore: clear the six code smells SonarQube reported (#181) 2026-09-03 10:50:51 -05:00

Merged #279 docs(ops): setup notes for the rembg background-removal sidecar 2026-09-03 09:05:45 -05:00

Merged #278 test(integration): say so when the database loses its schema (#154) 2026-09-02 18:43:55 -05:00

Merged #277 feat(build): pass the commit to the image as a build arg (#248) 2026-09-02 18:37:03 -05:00

Merged #276 Fix/271 anthropic workspace id 2026-09-02 17:25:05 -05:00

Merged #275 chore(sonar): name the findings instead of counting them (#181) 2026-09-02 17:21:45 -05:00

Merged #274 fix(scripts): refuse to reuse a backend that is serving the previous database (#257) 2026-09-02 17:11:37 -05:00

Merged #270 test(e2e): give the suite a throwaway database of its own (#186) 2026-09-02 11:06:05 -05:00

Merged #268 test(uploads): stop the cleanup assertions racing the cleanup (#228) 2026-09-02 10:00:29 -05:00

Merged #267 Fix/197 restrict scan publishing 2026-09-02 09:33:13 -05:00

Merged #266 Feature/227 submission ceiling 2026-09-02 09:07:12 -05:00

Merged #265 Feature/224 notification impl 2026-09-01 15:47:28 -05:00

Merged #263 Feature/224 intake notification 2026-09-01 15:08:49 -05:00

Merged #262 chore(sonar): remove the rejected Tinqer spike, clear the lint debt, and report measures in CI (#261) 2026-09-01 13:41:58 -05:00

Merged #259 build(qa): take the SMTP host, port and TLS flag from QA_ stack variables (#258) 2026-09-01 11:51:15 -05:00

Merged #256 fix(e2e): match the modal OK button exactly so a random suffix cannot collide (#253) 2026-09-01 09:42:37 -05:00

Merged #255 fix(e2e): restore the frontend build by typing the responses findOrFail searches (#254) 2026-09-01 09:33:15 -05:00

Merged #251 Feature/223 drafting worker 2026-09-01 08:32:44 -05:00

Merged #252 Fix/241 e2e isolation part2 2026-09-01 08:32:15 -05:00

Merged #250 feat(intake): issue named upload links and accept photo submissions (#222) 2026-08-31 15:47:10 -05:00

Merged #249 chore(ci): remove the registry spike workflow (#237) 2026-08-31 15:40:35 -05:00

Merged #247 test(e2e): design, plan, and the find-or-fail helper (#241) 2026-08-31 14:44:14 -05:00

Merged #246 test(e2e): skip the admin save happy-path test while #241 stands (#245) 2026-08-30 16:36:13 -05:00

Merged #243 test(perf): stop hashing test passwords at production cost (#242) 2026-08-30 13:32:15 -05:00

Merged #240 fix(test): correct the sold-filter tally assertion stranded by #188 (#239) 2026-08-29 19:22:13 -05:00

Merged #238 spike(ci): probe whether the runner can build and push an image (#237) 2026-08-29 18:37:44 -05:00

Merged #236 fix(build): stop the version stamp from breaking every Portainer deploy (#235) 2026-08-29 17:07:38 -05:00

Merged #234 feat(admin): show the deployed commit and build time in the admin (#233) 2026-08-29 15:45:56 -05:00

Merged #232 fix(uploads): ship the image backfill script in the container image (#231) 2026-08-29 15:10:06 -05:00

Merged #229 fix(uploads): re-encode uploaded images to strip EXIF and cut stored bytes (#226) 2026-08-29 14:17:44 -05:00

Merged #230 spike(db): evaluate Drizzle and Tinqer against the hardest query we have (#216) 2026-08-29 14:04:46 -05:00

Merged #221 docs(intake): design and implementation plans for the intake pipeline (#220) 2026-08-29 10:32:49 -05:00

Merged #214 fix(cart): say what the demo button does rather than what the shop does (#203) 2026-08-28 14:05:22 -05:00

Merged #212 docs(security): put the SQL injection invariant where it is enforced (#202) 2026-08-28 14:04:22 -05:00

Merged #211 fix(email): stop a demo purchase telling real customers an item sold (#206) 2026-08-28 14:02:08 -05:00

Merged #210 docs(ops): stop the compose header contradicting itself, and name the four variables step 2 dropped (#204) 2026-08-28 14:01:30 -05:00

Merged #209 fix(orders): mark a demo order in the history rather than leaving it to read as real (#205) 2026-08-28 14:00:53 -05:00

Merged #201 fix(scripts): switch Node to a pinned version rather than asking nvm for latest (#198) 2026-08-27 17:05:49 -05:00

Merged #200 fix(cart): say it is a demo where the customer can see it (#195) 2026-08-27 17:03:58 -05:00

Merged #199 docs(ops): make the cutover runbook agree with the compose file about DEMO_MODE (#196) 2026-08-27 17:02:53 -05:00

Merged #193 Feature/192 backup directories 2026-08-26 10:58:15 -05:00

Merged #192 Feature/191 production demo mode interim 2026-08-26 09:17:22 -05:00

Merged #191 docs(ops): name the crash loop the cutover runbook was most likely to cause (#175) 2026-08-26 08:41:27 -05:00

Merged #189 Feature/188 filter dimensions 2026-08-25 16:25:22 -05:00

Merged #187 feat(filters): show a tag's own colour on its active filter chip (#185) 2026-08-25 14:05:34 -05:00

Merged #184 refactor: remove the duplicated blocks SonarQube found (#182) 2026-08-25 13:13:29 -05:00

Merged #183 fix(security): stop refused uploads accumulating on the volume, and record the hotspot review (#180) 2026-08-25 11:50:28 -05:00

Merged #179 fix(ci): stop the test summarisers failing the job on an unreadable results file (#178) 2026-08-25 11:49:12 -05:00

Merged #177 docs(ops): write down how to cut production over to the committed compose file (#175) 2026-08-25 09:16:15 -05:00

Merged #176 ci: fail at the end rather than part way through, so the scan still runs (#174) 2026-08-25 09:15:26 -05:00

Merged #173 feat(security): stop the app origin serving anything it does not recognise, and make the uploads origin configurable (#103) 2026-08-24 17:39:00 -05:00

Merged #172 test(perf): measure what concurrent hashing actually costs a bystander request (#163) 2026-08-24 17:02:53 -05:00

Merged #171 Feature/169 admin filter flyout 2026-08-24 16:46:53 -05:00

Merged #168 feat(admin): make the placeholder chips insert at the cursor (#143) 2026-08-24 15:48:42 -05:00

Merged #167 refactor: turn on noUncheckedIndexedAccess in both workspaces (#101) 2026-08-24 15:30:29 -05:00

Merged #165 refactor(backend): type the remaining query results (#159) 2026-08-24 15:03:50 -05:00

Merged #166 docs(ci): correct the #154 hypothesis — the database is wiped before the tests start (#154) 2026-08-24 15:03:09 -05:00

Merged #164 refactor(backend): type the admin item queries, and fix the stale status union (#159) 2026-08-24 14:45:30 -05:00

Merged #162 refactor(backend): type the customer query results (#159) 2026-08-24 13:23:30 -05:00

Merged #161 refactor(backend): type the cart and checkout query results (#159) 2026-08-24 13:13:13 -05:00

Merged #160 refactor(backend): type the item query results (#159) 2026-08-24 13:01:48 -05:00

Merged #158 refactor(frontend): triage the setState-in-effect sites (#99) 2026-08-24 12:19:51 -05:00

Merged #157 refactor(frontend): declare props read-only, and drop the deprecated antd prop (#100) 2026-08-24 12:01:54 -05:00

Merged #156 feat(ops): schedule database and uploads backups, and document the restore (#147) 2026-08-24 11:30:37 -05:00

Merged #155 ci: let the summarisers summarise and the gate do the failing (#142) 2026-08-24 09:51:51 -05:00

Merged #153 refactor(storefront): extract the catalogue machine from App.tsx as useCatalogue (#98) 2026-08-24 09:05:16 -05:00

Merged #152 fix(cart): make the reservation countdown tick, and warn against the real hold (#97) 2026-08-24 09:03:26 -05:00

Merged #151 Feature/137 convert account specs 2026-08-23 19:36:18 -05:00

Merged #150 test(e2e): convert the auth specs onto page objects (#137) 2026-08-23 17:36:31 -05:00

Merged #149 test(e2e): add page objects, fixtures and a typed test build (#137) 2026-08-23 17:19:50 -05:00

Merged #148 fix(deploy): run the image QA reviewed rather than rebuilding production (#146) 2026-08-23 16:52:26 -05:00

Merged #145 fix(deploy): commit production's compose and bring it under the drift guard (#118) 2026-08-23 16:15:15 -05:00

Merged #144 feat(scripts): switch Node automatically, and add a test runner (#140) 2026-08-23 09:36:41 -05:00

Merged #141 feat(admin): make the token lifetimes, cart hold and greeting configurable (#136) 2026-08-23 08:55:54 -05:00

Merged #138 feat(admin): give the customer emails a tab of their own (#135) 2026-08-23 08:21:41 -05:00

Merged #134 feat(admin): filter inventory by status directly, so Published and Unpublished are reachable (#132) 2026-08-23 07:22:15 -05:00

Merged #133 feat(admin): use the item description's markdown editor for email templates (#131) 2026-08-23 07:21:30 -05:00

Merged #130 feat: let a customer resend their own verification email (#110) 2026-08-22 12:59:10 -05:00

Merged #129 feat: filter by Sold / Not sold / All on the storefront and the admin (#105) 2026-08-22 12:58:34 -05:00

Merged #128 feat: tabs and a rendered preview for the email templates (#119) 2026-08-22 12:57:31 -05:00

Merged #127 ci: fold the Tests workflow into SonarQube Analysis and delete it (#123) 2026-08-22 11:13:06 -05:00

Merged #126 feat(scripts): a PowerShell script to start the local environment (#125) 2026-08-22 11:12:17 -05:00

Merged #124 feat(frontend): give order history a page of its own (#121) 2026-08-22 10:58:02 -05:00

Merged #122 docs: design for moving Order History onto its own page (#121) 2026-08-22 10:42:17 -05:00

Merged #120 feat(frontend): let a customer change their own name, password and email (#111) 2026-08-22 10:23:50 -05:00

Merged #114 ci: give linting its own workflow (#113) 2026-08-22 09:29:16 -05:00

Merged #113 feat(backend): let a customer change their own name, password and email (#111) 2026-08-22 09:27:35 -05:00

Merged #112 Feature/92 editable email templates 2026-08-22 08:35:24 -05:00

Merged #109 Feature/106 customer first last name 2026-08-21 18:42:00 -05:00

Merged #108 Feature/107 compose required env 2026-08-21 17:39:30 -05:00

Merged #104 feat(backend): accept only real images in the inventory upload (#95) 2026-08-21 16:46:03 -05:00

Merged #102 refactor: standardise antd imports and remove the avoidable any (#65) 2026-08-21 16:15:18 -05:00

Merged #96 feat(backend): check the environment at boot instead of discovering it later (#64) 2026-08-21 15:30:12 -05:00

Merged #94 Feature/63 admin gate 2026-08-21 13:44:16 -05:00

Merged #93 feat: stage new items as pending until an admin publishes them (#90) 2026-08-21 12:46:29 -05:00

Merged #91 feat(frontend): preview an inventory item as a customer sees it (#89) 2026-08-21 11:46:54 -05:00

Merged #88 feat: let QA send real email, guarded by a recipient allowlist (#87) 2026-08-21 09:40:53 -05:00

Merged #86 Feature/84 ipv6 rate limit key 2026-08-20 18:44:49 -05:00

Merged #85 Feature/62 error boundary 2026-08-20 18:32:28 -05:00

Merged #83 docs: design for React error boundaries (#62) 2026-08-20 17:46:27 -05:00

Merged #82 Feature/81 technical debt 2026-08-20 15:08:20 -05:00

Merged #80 chore(ci): declare sonar.projectVersion so the new-code period means something (#79) 2026-08-20 13:19:36 -05:00

Merged #78 docs: require an issue behind every branch and PR (#77) 2026-08-20 11:10:26 -05:00

Merged #75 feat(frontend): show the RD mark beside the storefront wordmark 2026-08-20 11:00:18 -05:00

Merged #73 Feature/61 coverage import 2026-08-20 10:30:30 -05:00

Merged #70 feat(frontend): add an RD monogram app icon 2026-08-20 09:01:28 -05:00

Merged #69 fix(ci): make SonarQube actually analyse the frontend (#61) 2026-08-19 14:52:09 -05:00

Merged #68 Feature/60 eslint 2026-08-19 14:42:20 -05:00

Merged #66 Feature/59 wrap async routes 2026-08-19 13:19:33 -05:00

Merged #58 Feature/50 auth modal routes 2026-08-18 17:27:53 -05:00

Merged #57 48 my account modal 2026-08-18 16:39:08 -05:00

Merged #55 Feature/favorites filter issue #35 2026-08-18 15:17:34 -05:00

Merged #54 feat: tell favoriters when an item is withdrawn (#34) 2026-08-18 14:40:17 -05:00

Merged #53 feat: favorite items and notify when a favorite is sold (#34) 2026-08-18 13:51:20 -05:00

Merged #47 feat(admin): disable and re-enable customer accounts (#33) 2026-08-18 11:05:43 -05:00

Merged #46 ci: run backend integration tests as a separate manual workflow 2026-08-18 09:04:06 -05:00

Merged #45 ci: distinguish between missing secrets and variables in QA build 2026-08-18 08:21:41 -05:00

Merged #44 ci: distinguish why the QA build daemon is unreachable (#25) 2026-08-18 08:18:43 -05:00

Merged #43 feat: customer password reset via email round-trip (#32) 2026-08-17 19:15:58 -05:00

Merged #30 fix(admin): theme, American English, and inventory/reservation tooling (#27) 2026-08-17 15:57:00 -05:00

Merged #29 docs: make QA review a standing step in the change checklist 2026-08-17 14:28:33 -05:00

Merged #28 fix: reset the header and return home when a customer logs out (#21) 2026-08-17 14:07:11 -05:00

Merged #26 Fix/deploy migration safety 2026-08-17 12:31:45 -05:00

Merged #24 Feature/categories and tags 2026-08-17 09:49:37 -05:00

Merged #22 test: disambiguate the Email locator in auth.spec 2026-08-15 18:37:39 -05:00

Merged #20 fix: add the missing /verify-email page 2026-08-15 18:23:15 -05:00

1 Pull request proposed by 1 user

154 Issues closed from 1 user

Closed #332 feat(auth): sign in with Google, and decide whether Apple follows 2026-09-11 08:50:44 -05:00

Closed #345 Google 6: the button, and the domain cutover 2026-09-10 16:47:30 -05:00

Closed #344 Google 5: life without a password 2026-09-10 15:05:48 -05:00

Closed #343 Google 4: linking a Google identity to an existing account 2026-09-10 14:00:45 -05:00

Closed #342 Google 3: new accounts, and the consent problem 2026-09-10 10:11:18 -05:00

Closed #341 Google 2: the OAuth round trip 2026-09-10 08:53:01 -05:00

Closed #340 Google 1: groundwork — nullable password hash, identities table, config 2026-09-10 08:39:22 -05:00

Closed #337 Admin: change a customer's email address, for the locked-out case 2026-09-09 16:38:35 -05:00

Closed #42 Passkeys 6: account recovery and interaction with password reset 2026-09-09 16:22:13 -05:00

Closed #41 Passkeys 5: login page integration and unsupported-browser fallback 2026-09-09 15:53:20 -05:00

Closed #40 Passkeys 4: manage and revoke passkeys from the account page 2026-09-09 15:44:50 -05:00

Closed #39 Passkeys 3: authentication ceremony 2026-09-09 14:32:26 -05:00

Closed #38 Passkeys 2: registration ceremony 2026-09-09 14:21:49 -05:00

Closed #37 Passkeys 1: schema, dependency, and per-environment RP configuration 2026-09-09 14:08:30 -05:00

Closed #318 spike(ops): is a feature flag manager worth adopting, and is a free one viable here 2026-09-09 13:39:06 -05:00

Closed #327 fix(admin): a published item does not appear in Inventory until the page is reloaded 2026-09-09 13:32:40 -05:00

Closed #324 chore(ci): a manually-run workflow to delete old Actions runs 2026-09-09 10:48:29 -05:00

Closed #307 chore(sonar): clean up after the rotation and Kysely branches 2026-09-09 09:23:23 -05:00

Closed #257 e2e: the resend-verification allowance test fails intermittently in full runs but never in isolation 2026-09-09 09:23:04 -05:00

Closed #320 fix(tests): #56 left main red — the schema mirror and three positional locators 2026-09-08 15:33:04 -05:00

Closed #56 Implement the Brevo Tracker 2026-09-08 12:41:52 -05:00

Closed #314 fix(admin): the item editor modal cannot be closed on a phone 2026-09-06 10:04:31 -05:00

Closed #285 spike(ops): what Cloudflare's free tier would and would not do for us 2026-09-05 17:36:39 -05:00

Closed #208 fix(scripts): the Node pin left three docs stale, and the alias check still fails open 2026-09-05 08:22:47 -05:00

Closed #197 fix(ci): every pull request scan overwrites the dashboard's picture of main 2026-09-04 19:12:08 -05:00

Closed #308 refactor(db): convert the two dynamic queries to Kysely and retire the S2077 hotspots 2026-09-04 17:47:44 -05:00

Closed #297 spike(db): finish the Drizzle conversion of the dynamic queries, or reconsider the builder 2026-09-04 16:11:08 -05:00

Closed #305 refactor(db): swap the query builder from Drizzle to Kysely 2026-09-04 16:08:53 -05:00

Closed #301 feat(admin): rotate a photo from the review queue and the inventory editor 2026-09-04 14:52:17 -05:00

Closed #300 fix(uploads): the EXIF strip rotates every photo that was taken in portrait 2026-09-04 13:30:05 -05:00

Closed #298 fix(lint): backend test files are never linted 2026-09-04 12:58:14 -05:00

Closed #293 feat(admin): remove an image's background from the inventory item editor 2026-09-04 12:22:05 -05:00

Closed #294 chore(sonarqube): keep interpolation out of query call sites, and clear the last hotspot 2026-09-04 09:36:40 -05:00

Closed #260 Upload links should require an email address and send the link to it on creation 2026-09-04 09:06:20 -05:00

Closed #269 feat(storefront): paginate the catalogue instead of rendering all of it 2026-09-04 09:06:14 -05:00

Closed #287 fix(ci): three background-removal e2e tests fail because CI never sets REMBG_URL 2026-09-04 09:06:08 -05:00

Closed #273 fix(scripts): the e2e helper connects to a different database than the app under test 2026-09-03 16:59:17 -05:00

Closed #280 fix(admin): a text setting that is meant to be empty cannot be cleared 2026-09-03 16:53:48 -05:00

Closed #207 fix(admin): PUT /admin/items/:id returns 200 with an empty body for an id that does not exist 2026-09-03 16:47:33 -05:00

Closed #217 feat(db): land the Drizzle schema, config and conventions 2026-09-03 15:52:38 -05:00

Closed #223 feat(intake): draft a listing from the submitted photos 2026-09-03 15:52:38 -05:00

Closed #227 feat(intake): global submission ceiling with an abuse alert 2026-09-03 15:52:38 -05:00

Closed #248 feat(build): pass the commit to the image as a build arg 2026-09-03 15:52:38 -05:00

Closed #186 Two e2e tests now fail every run locally: the storefront renders 1,662 items unpaginated 2026-09-03 15:52:37 -05:00

Closed #181 Clear the five code smells, which are the 21 minutes of new technical debt 2026-09-03 15:51:34 -05:00

Closed #272 fix(intake): Regenerate re-queues the draft but never wakes the worker 2026-09-03 15:51:18 -05:00

Closed #271 fix(intake): identity-linked Anthropic keys need a workspace id, and drafting has no way to send one 2026-09-03 15:51:07 -05:00

Closed #281 feat(intake): remove the background from submitted photos 2026-09-03 14:09:57 -05:00

Closed #116 The e2e suite and the backend integration suite share one database, and the integration suite truncates it 2026-09-02 18:27:35 -05:00

Closed #241 test(e2e): specs are not isolated — parallel runs interfere through one shared database 2026-09-02 11:07:20 -05:00

Closed #228 test(uploads): upload cleanup assertions race the cleanup they assert on 2026-09-02 10:00:29 -05:00

Closed #219 decide: whether generated Drizzle migrations replace node-pg-migrate 2026-09-02 09:04:58 -05:00

Closed #218 feat(db): convert routes/adminCategories.ts to Drizzle, and measure the real per-site cost 2026-09-02 09:04:10 -05:00

Closed #220 feat(intake): shared upload links, AI-drafted listings, and an admin review queue 2026-09-01 16:14:08 -05:00

Closed #245 test(e2e): admin-save-failures happy-path test is skipped and needs restoring 2026-09-01 16:13:42 -05:00

Closed #224 feat(intake): notify the admin with signed action links 2026-09-01 16:13:21 -05:00

Closed #225 feat(intake): review queue for drafted items 2026-09-01 15:18:35 -05:00

Closed #261 SonarQube cleanup: remove the rejected Tinqer spike, clear the lint debt, dedupe the extension map, and report measures in CI 2026-09-01 13:41:58 -05:00

Closed #258 QA_SMTP_HOST, QA_SMTP_PORT and QA_SMTP_SECURE are set on the stack but nothing reads them 2026-09-01 11:51:15 -05:00

Closed #253 e2e: name: 'OK' matches as a substring, so random test data can collide with the modal button 2026-09-01 09:42:38 -05:00

Closed #254 The frontend build fails on main, breaking QA and production deploys (regression from #241) 2026-09-01 09:33:15 -05:00

Closed #222 feat(intake): issue named upload links and accept photo submissions 2026-08-31 15:47:10 -05:00

Closed #237 spike: can the runner build and push an image, and can Portainer pull it? 2026-08-31 15:40:35 -05:00

Closed #242 test(perf): bcrypt cost 12 in tests makes the integration suite slow and timeout-flaky 2026-08-30 13:32:15 -05:00

Closed #239 fix(test): sold-filter tally assertion has been failing since #188 2026-08-29 19:22:16 -05:00

Closed #235 fix(build): COPY .git breaks the Portainer build — the version stamp stops deploys 2026-08-29 17:07:46 -05:00

Closed #233 feat(admin): show the deployed commit and build time in the admin 2026-08-29 15:45:58 -05:00

Closed #231 fix(uploads): the image backfill script does not ship in the container image 2026-08-29 15:10:07 -05:00

Closed #226 fix(uploads): re-encode uploaded images to strip EXIF and cut stored bytes 2026-08-29 14:17:44 -05:00

Closed #216 spike: evaluate Drizzle for type-safe queries and generated migrations 2026-08-28 15:17:54 -05:00

Closed #203 fix(cart): the demo notice claims the shop is not taking payments, which is false when PayPal is configured 2026-08-28 14:05:22 -05:00

Closed #202 docs(security): the S2077 justification never reached main, and belongs beside the invariant it describes 2026-08-28 14:04:22 -05:00

Closed #206 fix(email): a demo purchase emails real customers to say an item sold, with no demo qualifier 2026-08-28 14:02:08 -05:00

Closed #204 docs(ops): the compose header contradicts itself, and step 2 drops four interpolated variables 2026-08-28 14:01:30 -05:00

Closed #205 fix(orders): a demo order is indistinguishable from a real one in order history 2026-08-28 14:00:53 -05:00

Closed #198 fix(scripts): start-local.ps1 asks nvm for a version it cannot have, then blames the wrong thing 2026-08-27 17:05:50 -05:00

Closed #195 fix(cart): production's demo checkout button is not labelled as a demo 2026-08-27 17:04:04 -05:00

Closed #196 docs(ops): the cutover runbook contradicts the compose file about DEMO_MODE 2026-08-27 17:02:53 -05:00

Closed #180 Review and clear the three security hotspots in routes/admin.ts 2026-08-27 11:29:52 -05:00

Closed #190 Production is in demo mode and taking no money — restore real payments 2026-08-26 09:17:06 -05:00

Closed #188 Make filtering one composable component both screens extend, rather than a shared drawer with per-screen flags 2026-08-26 08:10:43 -05:00

Closed #185 Active filter chips render tags without their colour, the only place that does 2026-08-25 14:05:34 -05:00

Closed #182 Remove the four duplicated blocks, one of which #139 introduced 2026-08-25 13:13:29 -05:00

Closed #178 The test summarisers fail the job on an unreadable results file, which is the one thing they exist not to do 2026-08-25 11:49:12 -05:00

Closed #175 There is no runbook for cutting production over to the committed compose file 2026-08-25 09:16:16 -05:00

Closed #174 A failing integration suite takes the SonarQube scan down with it, and four other steps can do the same 2026-08-25 09:15:26 -05:00

Closed #103 Serve user uploads from an origin of their own, not the app's 2026-08-24 17:39:00 -05:00

Closed #163 Concurrent password hashing adds tail latency — measured, and not worth acting on at this traffic 2026-08-24 17:04:33 -05:00

Closed #139 The storefront filter panel needs searchable multi-select for categories and tags 2026-08-24 17:03:31 -05:00

Closed #169 Admin inventory filtering should use the same flyout and controls as the storefront 2026-08-24 16:47:00 -05:00

Closed #143 Make the placeholder chips insert themselves at the cursor instead of only naming themselves 2026-08-24 15:48:43 -05:00

Closed #101 Turn on noUncheckedIndexedAccess once #65 has typed the query results 2026-08-24 15:30:29 -05:00

Closed #159 Query results are untyped, so strict: true stops at the database boundary 2026-08-24 15:03:51 -05:00

Closed #99 Eight setState-in-effect sites: triage which are derived state and which are legitimate 2026-08-24 12:19:52 -05:00

Closed #100 Seventeen components declare mutable props, and one antd prop is deprecated 2026-08-24 12:01:54 -05:00

Closed #147 Nothing backs up the production database 2026-08-24 11:31:26 -05:00

Closed #142 A failing e2e run is reported as a failure in the summary step, and the explicit gate never runs 2026-08-24 09:51:38 -05:00

Closed #98 App.tsx holds the whole catalogue-fetching machine — extract it as a useCatalogue hook 2026-08-24 09:05:58 -05:00

Closed #97 The cart's reservation countdown is frozen — it never ticks, and the expiry warning never appears 2026-08-24 09:05:47 -05:00

Closed #137 Refactor the Playwright suite onto page objects, shared fixtures, and a typed test build 2026-08-23 17:20:11 -05:00

Closed #118 The compose drift guard covers only ALWAYS_REQUIRED, and only QA — production is unguarded entirely 2026-08-23 17:06:41 -05:00

Closed #117 QA publishes port 32751 on every interface, not just to the proxy 2026-08-23 17:06:21 -05:00

Closed #146 Production rebuilds its own image rather than running the one QA tested, and the builds are not reproducible anyway 2026-08-23 17:05:21 -05:00

Closed #140 start-local should switch Node itself, and there should be a script for running the test suites 2026-08-23 09:36:50 -05:00

Closed #136 Make the email settings configurable: token lifetimes, cart hold, and the greeting 2026-08-23 08:55:54 -05:00

Closed #135 Email templates are buried in Settings and squeezed into 720px — give them their own Emails tab 2026-08-23 08:21:41 -05:00

Closed #132 Admin inventory needs to filter Published / Unpublished, so give it the status dimension directly 2026-08-23 07:22:16 -05:00

Closed #131 Use the item description's markdown editor for the email templates too 2026-08-23 07:21:32 -05:00

Closed #110 Let a customer resend their own verification email from My Account 2026-08-22 12:59:10 -05:00

Closed #105 Filter by Sold / Not Sold / All, on the storefront and the admin inventory 2026-08-22 12:58:34 -05:00

Closed #119 Email template editor: put the cards in tabs and show a rendered preview 2026-08-22 12:57:31 -05:00

Closed #123 tests.yml duplicates the suites sonarqube.yml already runs: fold its reporting in and delete it 2026-08-22 11:13:06 -05:00

Closed #125 A script to start the local environment for testing and review 2026-08-22 11:12:17 -05:00

Closed #121 Move Order History out of the My Account modal onto its own page 2026-08-22 10:58:02 -05:00

Closed #92 Make the password-reset email editable from Admin → Settings 2026-08-22 10:40:49 -05:00

Closed #111 A customer cannot change their own details — PUT /api/customers/me has no caller 2026-08-22 10:23:51 -05:00

Closed #115 Give linting its own workflow instead of a job inside tests.yml 2026-08-22 09:50:25 -05:00

Closed #106 Capture first and last name at registration, so emails can greet informally 2026-08-22 09:21:14 -05:00

Closed #95 The inventory image upload accepts any file type, in the picker and on the server 2026-08-22 08:40:36 -05:00

Closed #107 QA cannot start: UPLOADS_DIR became required in #64 but the compose file never set it 2026-08-21 17:50:04 -05:00

Closed #65 Import convention and avoidable any are inconsistent across the codebase 2026-08-21 16:46:50 -05:00

Closed #64 No boot-time validation of required environment variables 2026-08-21 15:32:47 -05:00

Closed #63 The admin API has no application-layer authorization — it depends entirely on one proxy regex 2026-08-21 13:55:12 -05:00

Closed #90 Add a Pending status so items are staged, not published the moment they are created 2026-08-21 13:55:01 -05:00

Closed #89 Preview an inventory item as a customer sees it, from the admin panel 2026-08-21 12:43:59 -05:00

Closed #84 IPv6 clients can bypass the password-reset rate limit, and express-rate-limit says so at every boot 2026-08-21 11:43:25 -05:00

Closed #87 QA cannot send email at all, so the four mail flows have never been regression tested 2026-08-21 11:40:19 -05:00

Closed #62 No React error boundary — one render error blanks the entire storefront 2026-08-20 18:38:36 -05:00

Closed #61 SonarQube analyses the code but imports no test coverage, so its quality gate is measuring nothing 2026-08-20 15:28:09 -05:00

Closed #60 No ESLint anywhere, so the React and SonarJS rules that would catch these problems never run 2026-08-20 15:28:06 -05:00

Closed #72 Keep the coverage pipeline honest: a frontend unit suite, and guards against silently-empty coverage 2026-08-20 15:23:58 -05:00

Closed #71 CI authenticates to SonarQube as admin rather than a restricted analysis account 2026-08-20 15:23:21 -05:00

Closed #81 Clear the 85 minutes of technical debt — four of the fourteen "smells" are real React defects 2026-08-20 15:22:41 -05:00

Closed #79 new_coverage is 71.2% against an 80% gate — and "new code" is silently the entire codebase 2026-08-20 15:22:01 -05:00

Closed #76 Show the RD monogram beside the wordmark in the storefront header 2026-08-20 15:21:01 -05:00

Closed #74 Review and disposition the 3 SQL-injection hotspots in admin.ts — they block the quality gate 2026-08-20 11:21:08 -05:00

Closed #77 Documented branch convention still permits branches with no issue behind them 2026-08-20 11:10:27 -05:00

Closed #67 SonarQube silently skips the entire frontend, and the scan still reports success 2026-08-19 14:51:32 -05:00

Closed #59 30 async route handlers still bypass the error middleware 2026-08-19 13:19:35 -05:00

Closed #52 Most pages outside the storefront are navigational dead ends 2026-08-19 10:42:44 -05:00

Closed #36 Passkey (WebAuthn) login for customers 2026-08-18 17:32:48 -05:00

Closed #50 Sign-in and registration exist twice, and neither route leads back to the shop 2026-08-18 17:27:56 -05:00

Closed #51 My Account should open as a modal and return the customer where they were 2026-08-18 16:38:33 -05:00

Closed #49 Pages reached from an email link or bookmark have no site chrome 2026-08-18 16:18:01 -05:00

Closed #48 My Account is a navigational dead end 2026-08-18 16:17:48 -05:00

Closed #35 Filter the storefront by favorited items 2026-08-18 15:52:36 -05:00

Closed #31 Initial Build UI issues and clean-up 2026-08-18 15:52:26 -05:00

Closed #34 Favorite items, with notification when a favorite sells 2026-08-18 15:52:10 -05:00

Closed #32 Customer password reset via email round-trip 2026-08-18 11:20:41 -05:00

Closed #33 Admin: disable a customer account 2026-08-18 11:20:29 -05:00

Closed #21 Home Page and Customer Reset when logging out. 2026-08-17 16:31:47 -05:00

Closed #23 Categories and tags 2026-08-17 16:31:27 -05:00

Closed #25 On-demand QA environment stack 2026-08-17 16:31:15 -05:00

Closed #27 Admin Category and Tag UI issues 2026-08-17 16:31:04 -05:00

156 Issues created by 1 user

Opened #21 Home Page and Customer Reset when logging out. 2026-08-15 18:27:49 -05:00

Opened #23 Categories and tags 2026-08-16 15:56:33 -05:00

Opened #25 On-demand QA environment stack 2026-08-17 11:10:01 -05:00

Opened #27 Admin Category and Tag UI issues 2026-08-17 13:49:12 -05:00

Opened #31 Initial Build UI issues and clean-up 2026-08-17 16:47:55 -05:00

Opened #32 Customer password reset via email round-trip 2026-08-17 17:09:32 -05:00

Opened #33 Admin: disable a customer account 2026-08-17 17:09:36 -05:00

Opened #34 Favorite items, with notification when a favorite sells 2026-08-17 17:09:53 -05:00

Opened #35 Filter the storefront by favorited items 2026-08-17 17:09:59 -05:00

Opened #36 Passkey (WebAuthn) login for customers 2026-08-17 17:10:23 -05:00

Opened #37 Passkeys 1: schema, dependency, and per-environment RP configuration 2026-08-17 17:14:01 -05:00

Opened #38 Passkeys 2: registration ceremony 2026-08-17 17:14:06 -05:00

Opened #39 Passkeys 3: authentication ceremony 2026-08-17 17:14:30 -05:00

Opened #40 Passkeys 4: manage and revoke passkeys from the account page 2026-08-17 17:14:59 -05:00

Opened #41 Passkeys 5: login page integration and unsupported-browser fallback 2026-08-17 17:15:11 -05:00

Opened #42 Passkeys 6: account recovery and interaction with password reset 2026-08-17 17:15:39 -05:00

Opened #48 My Account is a navigational dead end 2026-08-18 11:28:10 -05:00

Opened #49 Pages reached from an email link or bookmark have no site chrome 2026-08-18 11:28:36 -05:00

Opened #50 Sign-in and registration exist twice, and neither route leads back to the shop 2026-08-18 11:29:11 -05:00

Opened #51 My Account should open as a modal and return the customer where they were 2026-08-18 12:52:16 -05:00

Opened #52 Most pages outside the storefront are navigational dead ends 2026-08-18 12:52:43 -05:00

Opened #56 Implement the Brevo Tracker 2026-08-18 15:41:28 -05:00

Opened #59 30 async route handlers still bypass the error middleware 2026-08-19 11:03:57 -05:00

Opened #60 No ESLint anywhere, so the React and SonarJS rules that would catch these problems never run 2026-08-19 11:04:33 -05:00

Opened #61 SonarQube analyses the code but imports no test coverage, so its quality gate is measuring nothing 2026-08-19 11:05:02 -05:00

Opened #62 No React error boundary — one render error blanks the entire storefront 2026-08-19 11:05:27 -05:00

Opened #63 The admin API has no application-layer authorization — it depends entirely on one proxy regex 2026-08-19 11:06:01 -05:00

Opened #64 No boot-time validation of required environment variables 2026-08-19 11:06:29 -05:00

Opened #65 Import convention and avoidable any are inconsistent across the codebase 2026-08-19 11:07:00 -05:00

Opened #67 SonarQube silently skips the entire frontend, and the scan still reports success 2026-08-19 14:27:52 -05:00

Opened #71 CI authenticates to SonarQube as admin rather than a restricted analysis account 2026-08-20 10:15:12 -05:00

Opened #72 Keep the coverage pipeline honest: a frontend unit suite, and guards against silently-empty coverage 2026-08-20 10:15:56 -05:00

Opened #74 Review and disposition the 3 SQL-injection hotspots in admin.ts — they block the quality gate 2026-08-20 10:56:26 -05:00

Opened #76 Show the RD monogram beside the wordmark in the storefront header 2026-08-20 11:01:30 -05:00

Opened #77 Documented branch convention still permits branches with no issue behind them 2026-08-20 11:01:54 -05:00

Opened #79 new_coverage is 71.2% against an 80% gate — and "new code" is silently the entire codebase 2026-08-20 11:25:14 -05:00

Opened #81 Clear the 85 minutes of technical debt — four of the fourteen "smells" are real React defects 2026-08-20 13:52:30 -05:00

Opened #84 IPv6 clients can bypass the password-reset rate limit, and express-rate-limit says so at every boot 2026-08-20 18:30:13 -05:00

Opened #87 QA cannot send email at all, so the four mail flows have never been regression tested 2026-08-21 09:08:07 -05:00

Opened #89 Preview an inventory item as a customer sees it, from the admin panel 2026-08-21 11:32:34 -05:00

Opened #90 Add a Pending status so items are staged, not published the moment they are created 2026-08-21 11:33:01 -05:00

Opened #92 Make the password-reset email editable from Admin → Settings 2026-08-21 12:18:28 -05:00

Opened #95 The inventory image upload accepts any file type, in the picker and on the server 2026-08-21 13:51:06 -05:00

Opened #97 The cart's reservation countdown is frozen — it never ticks, and the expiry warning never appears 2026-08-21 15:56:31 -05:00

Opened #98 App.tsx holds the whole catalogue-fetching machine — extract it as a useCatalogue hook 2026-08-21 15:57:03 -05:00

Opened #99 Eight setState-in-effect sites: triage which are derived state and which are legitimate 2026-08-21 16:01:40 -05:00

Opened #100 Seventeen components declare mutable props, and one antd prop is deprecated 2026-08-21 16:02:14 -05:00

Opened #101 Turn on noUncheckedIndexedAccess once #65 has typed the query results 2026-08-21 16:02:53 -05:00

Opened #103 Serve user uploads from an origin of their own, not the app's 2026-08-21 16:24:20 -05:00

Opened #105 Filter by Sold / Not Sold / All, on the storefront and the admin inventory 2026-08-21 16:55:04 -05:00

Opened #106 Capture first and last name at registration, so emails can greet informally 2026-08-21 16:57:41 -05:00

Opened #107 QA cannot start: UPLOADS_DIR became required in #64 but the compose file never set it 2026-08-21 17:23:28 -05:00

Opened #110 Let a customer resend their own verification email from My Account 2026-08-21 18:58:59 -05:00

Opened #111 A customer cannot change their own details — PUT /api/customers/me has no caller 2026-08-21 18:59:31 -05:00

Opened #115 Give linting its own workflow instead of a job inside tests.yml 2026-08-22 09:49:38 -05:00

Opened #116 The e2e suite and the backend integration suite share one database, and the integration suite truncates it 2026-08-22 09:49:45 -05:00

Opened #117 QA publishes port 32751 on every interface, not just to the proxy 2026-08-22 09:49:54 -05:00

Opened #118 The compose drift guard covers only ALWAYS_REQUIRED, and only QA — production is unguarded entirely 2026-08-22 09:50:03 -05:00

Opened #119 Email template editor: put the cards in tabs and show a rendered preview 2026-08-22 09:50:10 -05:00

Opened #121 Move Order History out of the My Account modal onto its own page 2026-08-22 10:35:00 -05:00

Opened #123 tests.yml duplicates the suites sonarqube.yml already runs: fold its reporting in and delete it 2026-08-22 10:57:29 -05:00

Opened #125 A script to start the local environment for testing and review 2026-08-22 11:03:10 -05:00

Opened #131 Use the item description's markdown editor for the email templates too 2026-08-22 13:13:02 -05:00

Opened #132 Admin inventory needs to filter Published / Unpublished, so give it the status dimension directly 2026-08-22 17:07:11 -05:00

Opened #135 Email templates are buried in Settings and squeezed into 720px — give them their own Emails tab 2026-08-23 07:47:00 -05:00

Opened #136 Make the email settings configurable: token lifetimes, cart hold, and the greeting 2026-08-23 08:10:08 -05:00

Opened #137 Refactor the Playwright suite onto page objects, shared fixtures, and a typed test build 2026-08-23 08:16:21 -05:00

Opened #139 The storefront filter panel needs searchable multi-select for categories and tags 2026-08-23 08:53:54 -05:00

Opened #140 start-local should switch Node itself, and there should be a script for running the test suites 2026-08-23 08:54:21 -05:00

Opened #142 A failing e2e run is reported as a failure in the summary step, and the explicit gate never runs 2026-08-23 09:07:32 -05:00

Opened #143 Make the placeholder chips insert themselves at the cursor instead of only naming themselves 2026-08-23 09:10:13 -05:00

Opened #146 Production rebuilds its own image rather than running the one QA tested, and the builds are not reproducible anyway 2026-08-23 16:38:36 -05:00

Opened #147 Nothing backs up the production database 2026-08-23 16:38:59 -05:00

Opened #154 The integration suite's Postgres service loses its schema mid-run in CI, failing 12 of 17 suites 2026-08-24 09:33:36 -05:00

Opened #159 Query results are untyped, so strict: true stops at the database boundary 2026-08-24 12:19:36 -05:00

Opened #163 Concurrent password hashing adds tail latency — measured, and not worth acting on at this traffic 2026-08-24 14:08:18 -05:00

Opened #169 Admin inventory filtering should use the same flyout and controls as the storefront 2026-08-24 16:28:02 -05:00

Opened #174 A failing integration suite takes the SonarQube scan down with it, and four other steps can do the same 2026-08-25 08:40:18 -05:00

Opened #175 There is no runbook for cutting production over to the committed compose file 2026-08-25 08:49:25 -05:00

Opened #178 The test summarisers fail the job on an unreadable results file, which is the one thing they exist not to do 2026-08-25 09:18:54 -05:00

Opened #180 Review and clear the three security hotspots in routes/admin.ts 2026-08-25 11:34:02 -05:00

Opened #181 Clear the five code smells, which are the 21 minutes of new technical debt 2026-08-25 11:34:23 -05:00

Opened #182 Remove the four duplicated blocks, one of which #139 introduced 2026-08-25 11:34:48 -05:00

Opened #185 Active filter chips render tags without their colour, the only place that does 2026-08-25 13:12:37 -05:00

Opened #186 Two e2e tests now fail every run locally: the storefront renders 1,662 items unpaginated 2026-08-25 13:21:01 -05:00

Opened #188 Make filtering one composable component both screens extend, rather than a shared drawer with per-screen flags 2026-08-25 14:35:10 -05:00

Opened #190 Production is in demo mode and taking no money — restore real payments 2026-08-26 08:38:36 -05:00

Opened #195 fix(cart): production's demo checkout button is not labelled as a demo 2026-08-27 11:07:29 -05:00

Opened #196 docs(ops): the cutover runbook contradicts the compose file about DEMO_MODE 2026-08-27 11:07:42 -05:00

Opened #197 fix(ci): every pull request scan overwrites the dashboard's picture of main 2026-08-27 11:20:33 -05:00

Opened #198 fix(scripts): start-local.ps1 asks nvm for a version it cannot have, then blames the wrong thing 2026-08-27 11:36:23 -05:00

Opened #202 docs(security): the S2077 justification never reached main, and belongs beside the invariant it describes 2026-08-28 11:39:23 -05:00

Opened #203 fix(cart): the demo notice claims the shop is not taking payments, which is false when PayPal is configured 2026-08-28 11:39:39 -05:00

Opened #204 docs(ops): the compose header contradicts itself, and step 2 drops four interpolated variables 2026-08-28 11:51:43 -05:00

Opened #205 fix(orders): a demo order is indistinguishable from a real one in order history 2026-08-28 11:54:03 -05:00

Opened #206 fix(email): a demo purchase emails real customers to say an item sold, with no demo qualifier 2026-08-28 11:54:11 -05:00

Opened #207 fix(admin): PUT /admin/items/:id returns 200 with an empty body for an id that does not exist 2026-08-28 11:54:25 -05:00

Opened #208 fix(scripts): the Node pin left three docs stale, and the alias check still fails open 2026-08-28 11:54:46 -05:00

Opened #216 spike: evaluate Drizzle for type-safe queries and generated migrations 2026-08-28 14:38:19 -05:00

Opened #217 feat(db): land the Drizzle schema, config and conventions 2026-08-28 15:17:15 -05:00

Opened #218 feat(db): convert routes/adminCategories.ts to Drizzle, and measure the real per-site cost 2026-08-28 15:17:24 -05:00

Opened #219 decide: whether generated Drizzle migrations replace node-pg-migrate 2026-08-28 15:17:42 -05:00

Opened #220 feat(intake): shared upload links, AI-drafted listings, and an admin review queue 2026-08-29 07:21:19 -05:00

Opened #222 feat(intake): issue named upload links and accept photo submissions 2026-08-29 08:09:57 -05:00

Opened #223 feat(intake): draft a listing from the submitted photos 2026-08-29 08:10:10 -05:00

Opened #224 feat(intake): notify the admin with signed action links 2026-08-29 08:10:23 -05:00

Opened #225 feat(intake): review queue for drafted items 2026-08-29 08:10:32 -05:00

Opened #226 fix(uploads): re-encode uploaded images to strip EXIF and cut stored bytes 2026-08-29 09:03:02 -05:00

Opened #227 feat(intake): global submission ceiling with an abuse alert 2026-08-29 09:03:12 -05:00

Opened #228 test(uploads): upload cleanup assertions race the cleanup they assert on 2026-08-29 11:54:51 -05:00

Opened #231 fix(uploads): the image backfill script does not ship in the container image 2026-08-29 14:56:03 -05:00

Opened #233 feat(admin): show the deployed commit and build time in the admin 2026-08-29 15:23:03 -05:00

Opened #235 fix(build): COPY .git breaks the Portainer build — the version stamp stops deploys 2026-08-29 15:49:35 -05:00

Opened #237 spike: can the runner build and push an image, and can Portainer pull it? 2026-08-29 18:29:42 -05:00

Opened #239 fix(test): sold-filter tally assertion has been failing since #188 2026-08-29 19:09:46 -05:00

Opened #241 test(e2e): specs are not isolated — parallel runs interfere through one shared database 2026-08-29 19:19:48 -05:00

Opened #242 test(perf): bcrypt cost 12 in tests makes the integration suite slow and timeout-flaky 2026-08-30 12:10:35 -05:00

Opened #245 test(e2e): admin-save-failures happy-path test is skipped and needs restoring 2026-08-30 16:18:20 -05:00

Opened #248 feat(build): pass the commit to the image as a build arg 2026-08-31 14:44:51 -05:00

Opened #253 e2e: name: 'OK' matches as a substring, so random test data can collide with the modal button 2026-09-01 08:57:08 -05:00

Opened #254 The frontend build fails on main, breaking QA and production deploys (regression from #241) 2026-09-01 09:08:40 -05:00

Opened #257 e2e: the resend-verification allowance test fails intermittently in full runs but never in isolation 2026-09-01 10:03:47 -05:00

Opened #258 QA_SMTP_HOST, QA_SMTP_PORT and QA_SMTP_SECURE are set on the stack but nothing reads them 2026-09-01 11:46:30 -05:00

Opened #260 Upload links should require an email address and send the link to it on creation 2026-09-01 12:22:19 -05:00

Opened #261 SonarQube cleanup: remove the rejected Tinqer spike, clear the lint debt, dedupe the extension map, and report measures in CI 2026-09-01 13:17:32 -05:00

Opened #269 feat(storefront): paginate the catalogue instead of rendering all of it 2026-09-02 10:57:21 -05:00

Opened #271 fix(intake): identity-linked Anthropic keys need a workspace id, and drafting has no way to send one 2026-09-02 16:53:39 -05:00

Opened #272 fix(intake): Regenerate re-queues the draft but never wakes the worker 2026-09-02 16:54:39 -05:00

Opened #273 fix(scripts): the e2e helper connects to a different database than the app under test 2026-09-02 17:11:18 -05:00

Opened #280 fix(admin): a text setting that is meant to be empty cannot be cleared 2026-09-03 09:16:00 -05:00

Opened #281 feat(intake): remove the background from submitted photos 2026-09-03 10:17:19 -05:00

Opened #285 spike(ops): what Cloudflare's free tier would and would not do for us 2026-09-03 15:47:02 -05:00

Opened #287 fix(ci): three background-removal e2e tests fail because CI never sets REMBG_URL 2026-09-03 16:33:25 -05:00

Opened #293 feat(admin): remove an image's background from the inventory item editor 2026-09-04 09:11:23 -05:00

Opened #294 chore(sonarqube): keep interpolation out of query call sites, and clear the last hotspot 2026-09-04 09:13:30 -05:00

Opened #297 spike(db): finish the Drizzle conversion of the dynamic queries, or reconsider the builder 2026-09-04 12:22:29 -05:00

Opened #298 fix(lint): backend test files are never linted 2026-09-04 12:22:46 -05:00

Opened #300 fix(uploads): the EXIF strip rotates every photo that was taken in portrait 2026-09-04 12:57:58 -05:00

Opened #301 feat(admin): rotate a photo from the review queue and the inventory editor 2026-09-04 12:58:22 -05:00

Opened #305 refactor(db): swap the query builder from Drizzle to Kysely 2026-09-04 14:52:33 -05:00

Opened #307 chore(sonar): clean up after the rotation and Kysely branches 2026-09-04 16:11:35 -05:00

Opened #308 refactor(db): convert the two dynamic queries to Kysely and retire the S2077 hotspots 2026-09-04 16:11:56 -05:00

Opened #313 chore(ops): move to a domain we control and proxy the origin through Cloudflare 2026-09-05 20:35:43 -05:00

Opened #314 fix(admin): the item editor modal cannot be closed on a phone 2026-09-06 07:35:02 -05:00

Opened #318 spike(ops): is a feature flag manager worth adopting, and is a free one viable here 2026-09-08 12:09:24 -05:00

Opened #320 fix(tests): #56 left main red — the schema mirror and three positional locators 2026-09-08 14:09:13 -05:00

Opened #324 chore(ci): a manually-run workflow to delete old Actions runs 2026-09-09 09:27:32 -05:00

Opened #327 fix(admin): a published item does not appear in Inventory until the page is reloaded 2026-09-09 11:58:56 -05:00

Opened #332 feat(auth): sign in with Google, and decide whether Apple follows 2026-09-09 14:19:28 -05:00

Opened #337 Admin: change a customer's email address, for the locked-out case 2026-09-09 16:04:31 -05:00

Opened #340 Google 1: groundwork — nullable password hash, identities table, config 2026-09-10 08:12:26 -05:00

Opened #341 Google 2: the OAuth round trip 2026-09-10 08:12:38 -05:00

Opened #342 Google 3: new accounts, and the consent problem 2026-09-10 08:12:48 -05:00

Opened #343 Google 4: linking a Google identity to an existing account 2026-09-10 08:12:57 -05:00

Opened #344 Google 5: life without a password 2026-09-10 08:13:08 -05:00

Opened #345 Google 6: the button, and the domain cutover 2026-09-10 08:13:21 -05:00