v0.73.0: remove new-package toast notifications
CI / build + unit + e2e (pull_request) Successful in 13m31s
CI / build + unit + e2e (pull_request) Successful in 13m31s
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
# Changelog
|
||||
|
||||
## v0.73.0 — 2026-09-24 12:24
|
||||
- **New-package toasts removed.** The client-side snapshot diff in `lib/deriveEvents.ts` no longer emits "New package available" info toasts when a contract appears (the user was spammed by them); the first-snapshot guard and every other event type — delivered, expired, landed, bought, sold — are unchanged.
|
||||
|
||||
## v0.72.0 — 2026-09-24 11:44
|
||||
- **Admin login fixed.** The seeded admin's scrypt digest in `lib/db/client.ts` was computed with different parameters than the verifier (`verifyPassword()` passes the salt as a plain string to `scryptSync(pw, saltHex, 32)`), so real logins failed with 401 "invalid credentials" since v0.71.0. The seed now carries a digest produced by exactly that call (the plaintext still exists nowhere in code, tests or comments). Because the seed is `INSERT … WHERE NOT EXISTS`, pre-existing databases keep their old row — so every `open()` also runs an idempotent rotation (`UPDATE users SET password_hash = ? WHERE id = 'admin-kamilkrzywda' AND password_hash != ?`): a no-op once healed, it repairs legacy rows at boot and is durable on the next persist. Unit tests cover the fresh seed with the new digest plus the rotate-on-open path (legacy file heals to the current digest; second open is a no-op).
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ describe('diffSnapshots', () => {
|
||||
expect(diffSnapshots(prev, next)).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns [] for the first snapshot (no baseline — no "new package" spam on page load)', () => {
|
||||
it('returns [] for the first snapshot (no baseline to diff against)', () => {
|
||||
const next = snapshot({ packages: [basePackage('pkg-1'), basePackage('pkg-2')] });
|
||||
expect(diffSnapshots(null, next)).toEqual([]);
|
||||
});
|
||||
@@ -113,14 +113,6 @@ describe('diffSnapshots', () => {
|
||||
expect(fromLoaded).toEqual([{ kind: 'info', message: 'Package expired: Frankfurt → Madrid–Barajas' }]);
|
||||
});
|
||||
|
||||
it('emits a new-package event for ids only in the next snapshot', () => {
|
||||
const prev = snapshot({ packages: [basePackage('pkg-1')] });
|
||||
const next = snapshot({ packages: [basePackage('pkg-1'), basePackage('pkg-2')] });
|
||||
expect(diffSnapshots(prev, next)).toEqual([
|
||||
{ kind: 'info', message: 'New package available: Frankfurt → Madrid–Barajas' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('emits bought/sold events when the plane id set changes (with the model name)', () => {
|
||||
const bought = diffSnapshots(
|
||||
snapshot(),
|
||||
|
||||
+4
-9
@@ -15,8 +15,7 @@ export interface GameEvent {
|
||||
const planeName = (model: string): string => PLANE_TYPES[model]?.name ?? model;
|
||||
|
||||
export function diffSnapshots(prev: StateSnapshot | null, next: StateSnapshot): GameEvent[] {
|
||||
// No baseline yet (first snapshot after load) — nothing to compare against. Emitting a
|
||||
// "new package" event for every existing row would spam the stack on page load.
|
||||
// No baseline yet (first snapshot after load) — nothing to diff against, so no events.
|
||||
if (prev === null) return [];
|
||||
|
||||
const events: GameEvent[] = [];
|
||||
@@ -40,16 +39,12 @@ export function diffSnapshots(prev: StateSnapshot | null, next: StateSnapshot):
|
||||
}
|
||||
}
|
||||
|
||||
// Packages: delivered (loaded → delivered, reward paid out in the same tick), expired
|
||||
// (open|loaded → expired), newly appeared (id only in next — terminal packages are never
|
||||
// deleted, so an id appearing is always a genuinely new one).
|
||||
// Packages: delivered (loaded → delivered, reward paid out in the same tick) and expired
|
||||
// (open|loaded → expired). Ids that appear for the first time emit nothing.
|
||||
const prevPackages = new Map(prev.packages.map((p) => [p.id, p]));
|
||||
for (const pkg of next.packages) {
|
||||
const before = prevPackages.get(pkg.id);
|
||||
if (!before) {
|
||||
events.push({ kind: 'info', message: `New package available: ${pkg.originName} → ${pkg.destName}` });
|
||||
continue;
|
||||
}
|
||||
if (!before) continue;
|
||||
if (before.status === 'loaded' && pkg.status === 'delivered') {
|
||||
events.push({ kind: 'info', message: `Package delivered: +${formatCash(pkg.reward)}` });
|
||||
} else if ((before.status === 'open' || before.status === 'loaded') && pkg.status === 'expired') {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "flight-ops",
|
||||
"version": "0.72.0",
|
||||
"version": "0.73.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3000",
|
||||
|
||||
Reference in New Issue
Block a user