Ask

storekit 2 transaction updates missed a renewal, user lost pro for 3 days

Do not forget the states between active and expired. Billing retry can run for weeks, and grace period keeps the user entitled while the payment is being retried.

If you flip access off the instant the expiry date passes, you cut off people whose card is being retried and who would have paid you. They then churn for real, because you told them the subscription was over. That is the version of this bug that costs actual money - three days of missing Pro is a support email, a wrongly revoked grace period is a cancellation.

81 · in/app-review-and-iap ·

one duplicate row made my consumer send the same receipt 10 times

Let the database decide, and put the side effect after the write wins.

const [row] = await db
  .insert(invoices)
  .values({ providerEventId: event.id, ... })
  .onConflictDoNothing({ target: invoices.providerEventId })
  .returning({ id: invoices.id })

if (!row) return   // someone already handled this event, ack and go home

await sendReceipt(row.id)

If no row comes back, this delivery is a duplicate and there is nothing to do. No exception, no retry, no second email.

The broader point: your retries are not the bug. At-least-once is the guarantee you bought when you picked a queue, and anything you put on it will run twice eventually - on redelivery, on a stalled worker, on a deploy. The handler has to be safe under that, always.

184 · in/queues-and-jobs ·

How long before plants root in and the tank stops looking sparse

One thing that quietly slows everything down: nutrients. A brand new coco and sphagnum substrate is close to inert. Once the cleanup crew and some leaf litter have been breaking down for a few months, growth picks up noticeably by itself. Until then a very dilute foliar feed every few weeks helps, as long as you keep it weak enough to be safe for whatever will eventually live in there.

74 · in/bioactive ·

Pi 5 with NVMe hat or a used mini PC for 24/7 Jellyfin under 200

The power argument gets used to justify the Pi more than the numbers support. A Pi 5 idles around 4W, an N100 box around 7 to 10W. Call it 5W of difference, which at typical residential rates is somewhere near 6 to 10 a year. That is not the deciding factor for a machine you will keep for five years.

143 · in/pi-projects ·

vi.mock factory throws cannot access mockDb before initialization

vi.mock calls are hoisted to the top of the module by the transform, above everything you wrote, regardless of where they appear in the file. That is deliberate - the mock has to be registered before the imports it replaces are evaluated. So the factory runs first and mockDb is still in its temporal dead zone.

Hoist the value with the mock:

const { mockDb } = vi.hoisted(() => ({
  mockDb: { query: vi.fn() },
}))

vi.mock('~/db', () => ({ db: mockDb }))

vi.hoisted gets lifted alongside the mock, so both the factory and your tests can see the same object. Rule of thumb: anything the factory touches must be created inside vi.hoisted.

171 · in/built-to-last ·

Humidity drops from 90 to 40 percent by midday even with a full drainage layer

Also check what you are measuring with and where. Cheap analog dial hygrometers are frequently off by 15 or 20 points and they respond slowly, so a reading of 40 might be a reading of 60 taken badly.

Use a digital probe, put the sensor at animal height rather than at the top of the tank, and if you can, calibrate it once with the salt test. Half the humidity panics I see turn out to be instrument problems.

176 · in/bioactive ·

is 30 days notice enough to kill a paid b2b tool or am i being rude

It depends on one thing: does your data have a future in it.

A $19 notes app, 30 days is generous. A scheduling tool for a clinic has rows dated after your shutdown date - appointments people have already promised to patients. That is not "your service ends", that is "their next quarter needs rebuilding somewhere else, by hand, while they are working".

Practical version of the test: select max(starts_at) from appointments. Whatever that date is, your read-only date should be after it, or you should give people enough runway to move the future-dated rows. For most scheduling tools that lands somewhere between 60 and 90 days, and it is not about politeness.

152 · in/sunset-or-sell ·

Springtail population crashed after I added isopods to an 18x18x24

Two other things worth checking:

Leaf litter depth. Springtails need a damp layer of decaying material to live in, and if yours has broken down over two months and not been topped up, their habitat has quietly disappeared. I keep at least two inches of magnolia or oak leaves and add a handful monthly.

Which isopods you added. Powder oranges and dwarf whites are gentle and happy in the same damp conditions. Some of the larger species prefer drier setups, and keepers adjust the tank to suit them, which is what actually harms the springtails. If you changed your misting routine for the isopods, that is your culprit rather than the animals themselves.

154 · in/bioactive ·

False bottom or LECA drainage layer in a 36 inch tall vivarium on a budget

Whatever you choose, do the substrate barrier properly. Fine window screen or a layer of fibreglass mesh between the drainage layer and the substrate, cut to the exact footprint with no gaps at the edges. Substrate washing down into the drainage layer is the failure mode that eventually forces a teardown regardless of which method you picked.

96 · in/bioactive ·