revert(collections): a saved place carries no price, website or phone again

Takes back the editable price, currency, website and phone on collection
places from 0df82185b and its review follow-up in a910c2a83. Costs are kept
inside a trip only; a collection does not carry them, and #2471 is a
feature request rather than a bug. The collection files are back to how
they were before, including the dimmed save button from f16698bdb, which
only mattered for the price field.
This commit is contained in:
Maurice
2026-09-23 20:32:41 +02:00
parent f16698bdb1
commit a1d6348c5f
40 changed files with 25 additions and 937 deletions
@@ -337,86 +337,6 @@ describe('status + updatePlace move', () => {
expect((await svc.updatePlace(u.id, p.id, { name: 'Trattoria da Enzo' })).address).toBe('Via Vechia 1');
});
// #2471: price, currency, website and phone were stored on save and carried into
// a trip on copy, but the UPDATE set never named them, so none could be edited.
it('COLLECTIONS-SVC-128: updatePlace writes price, currency, website and phone', async () => {
const u = createUser(testDb).user;
const col = svc.createCollection(u.id, { name: 'Zurich' });
const p = svc.savePlace(u.id, { collection_id: col.id, name: 'Kunsthaus' }).place!;
const updated = await svc.updatePlace(u.id, p.id, {
price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44 253 84 84',
});
expect(updated).toMatchObject({ price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44 253 84 84' });
expect(testDb.prepare('SELECT price, currency, website, phone FROM collection_places WHERE id = ?').get(p.id)).toEqual({
price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44 253 84 84',
});
});
it('COLLECTIONS-SVC-129: null clears each of the four', async () => {
const u = createUser(testDb).user;
const col = svc.createCollection(u.id, { name: 'Zurich' });
const p = svc.savePlace(u.id, {
collection_id: col.id, name: 'Kunsthaus', price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44',
}).place!;
const cleared = await svc.updatePlace(u.id, p.id, { price: null, currency: null, website: null, phone: null });
expect(cleared).toMatchObject({ price: null, currency: null, website: null, phone: null });
});
it('COLLECTIONS-SVC-130: an update that leaves them out keeps the stored values', async () => {
const u = createUser(testDb).user;
const col = svc.createCollection(u.id, { name: 'Zurich' });
const p = svc.savePlace(u.id, {
collection_id: col.id, name: 'Kunsthaus', price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44',
}).place!;
const renamed = await svc.updatePlace(u.id, p.id, { name: 'Kunsthaus Zürich' });
expect(renamed).toMatchObject({ name: 'Kunsthaus Zürich', price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44' });
});
// A list has no base currency, so a bare amount would be read in every
// viewer's own default currency. The service refuses it for REST and MCP alike.
it('COLLECTIONS-SVC-132: a price without a currency on a place that has none is a 400 and changes nothing', async () => {
const u = createUser(testDb).user;
const col = svc.createCollection(u.id, { name: 'Zurich' });
const p = svc.savePlace(u.id, { collection_id: col.id, name: 'Kunsthaus' }).place!;
await expect(svc.updatePlace(u.id, p.id, { price: 14 })).rejects.toMatchObject({ status: 400, message: expect.stringMatching(/currency/) });
await expect(svc.updatePlace(u.id, p.id, { price: 14, currency: null })).rejects.toMatchObject({ status: 400 });
expect(testDb.prepare('SELECT price, currency FROM collection_places WHERE id = ?').get(p.id)).toEqual({ price: null, currency: null });
});
it('COLLECTIONS-SVC-133: a price alone keeps the stored currency, a zero price needs none, and a priced place cannot lose its currency', async () => {
const u = createUser(testDb).user;
const col = svc.createCollection(u.id, { name: 'Zurich' });
const priced = svc.savePlace(u.id, { collection_id: col.id, name: 'Kunsthaus', price: 10, currency: 'CHF' }).place!;
const free = svc.savePlace(u.id, { collection_id: col.id, name: 'Lake shore' }).place!;
expect(await svc.updatePlace(u.id, priced.id, { price: 24.5 })).toMatchObject({ price: 24.5, currency: 'CHF' });
expect(await svc.updatePlace(u.id, free.id, { price: 0 })).toMatchObject({ price: 0, currency: null });
await expect(svc.updatePlace(u.id, priced.id, { currency: null })).rejects.toMatchObject({ status: 400 });
expect(await svc.updatePlace(u.id, priced.id, { price: null, currency: null })).toMatchObject({ price: null, currency: null });
});
it('COLLECTIONS-SVC-131: copyToTrip carries the edited price, currency, website and phone into the trip place', async () => {
const u = createUser(testDb).user;
const trip = createTrip(testDb, u.id);
const col = svc.createCollection(u.id, { name: 'Zurich' });
const p = svc.savePlace(u.id, { collection_id: col.id, name: 'Kunsthaus', price: 10, currency: 'EUR' }).place!;
await svc.updatePlace(u.id, p.id, { price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44' });
expect(svc.copyToTrip(u.id, { trip_id: trip.id, place_ids: [p.id] }).copied).toBe(1);
expect(testDb.prepare("SELECT price, currency, website, phone FROM places WHERE trip_id = ? AND name = 'Kunsthaus'").get(trip.id)).toEqual({
price: 24.5, currency: 'CHF', website: 'https://kunsthaus.example', phone: '+41 44',
});
});
});
// ── copy to trip ─────────────────────────────────────────────────────────────