feat(public-berths): expose booleans, metric variants, timestamps

Bring the public berth feed to verbatim NocoDB parity (all fields
except Price, which is held pending an explicit policy decision per
the audit follow-ups Q4). Adds:

- Berth Approved (boolean)
- Water Depth (number)
- Width Is Minimum / Water Depth Is Minimum (boolean)
- Length / Width / Draft / Water Depth / Nominal Boat Size (Metric)
- CreatedAt / UpdatedAt (ISO strings, useful for cache invalidation)

Booleans pass through as nullable to preserve NocoDB's tri-state
checkbox semantics (true / false / unset). Test fixtures cover the
new fields end-to-end including the null-passthrough case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 04:16:42 +02:00
parent 8fdf7a92cf
commit 72ab7180cf
2 changed files with 48 additions and 0 deletions

View File

@@ -48,6 +48,17 @@ export interface PublicBerth {
'Bollard Capacity': string | null;
'Nominal Boat Size': number | null;
Access: string | null;
'Berth Approved': boolean | null;
'Water Depth': number | null;
'Width Is Minimum': boolean | null;
'Water Depth Is Minimum': boolean | null;
'Length (Metric)': number | null;
'Width (Metric)': number | null;
'Draft (Metric)': number | null;
'Water Depth (Metric)': number | null;
'Nominal Boat Size (Metric)': number | null;
CreatedAt: string;
UpdatedAt: string;
'Map Data'?: PublicMapData;
}
@@ -126,6 +137,17 @@ export function toPublicBerth(
'Bollard Capacity': toString(berth.bollardCapacity),
'Nominal Boat Size': toNumber(berth.nominalBoatSize),
Access: toString(berth.access),
'Berth Approved': berth.berthApproved,
'Water Depth': toNumber(berth.waterDepth),
'Width Is Minimum': berth.widthIsMinimum,
'Water Depth Is Minimum': berth.waterDepthIsMinimum,
'Length (Metric)': toNumber(berth.lengthM),
'Width (Metric)': toNumber(berth.widthM),
'Draft (Metric)': toNumber(berth.draftM),
'Water Depth (Metric)': toNumber(berth.waterDepthM),
'Nominal Boat Size (Metric)': toNumber(berth.nominalBoatSizeM),
CreatedAt: berth.createdAt.toISOString(),
UpdatedAt: berth.updatedAt.toISOString(),
...(mapMapData(mapData) ? { 'Map Data': mapMapData(mapData)! } : {}),
};
}

View File

@@ -105,6 +105,32 @@ describe('toPublicBerth', () => {
expect(out.Access).toBe('Car (3t) to Vessel');
});
it('exposes booleans + metric variants + timestamps for verbatim NocoDB parity', () => {
const out = toPublicBerth(makeBerth(), null, false);
expect(out['Berth Approved']).toBe(false);
expect(out['Water Depth']).toBe(16.08);
expect(out['Width Is Minimum']).toBe(false);
expect(out['Water Depth Is Minimum']).toBe(false);
expect(out['Length (Metric)']).toBe(63);
expect(out['Width (Metric)']).toBe(14.19);
expect(out['Draft (Metric)']).toBe(4.42);
expect(out['Water Depth (Metric)']).toBe(4.9);
expect(out['Nominal Boat Size (Metric)']).toBe(60.96);
expect(out.CreatedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
expect(out.UpdatedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
});
it('preserves null booleans (NocoDB checkbox-tri-state parity)', () => {
const out = toPublicBerth(
makeBerth({ berthApproved: null, widthIsMinimum: null, waterDepthIsMinimum: null }),
null,
false,
);
expect(out['Berth Approved']).toBeNull();
expect(out['Width Is Minimum']).toBeNull();
expect(out['Water Depth Is Minimum']).toBeNull();
});
it('inlines map data when present', () => {
const out = toPublicBerth(makeBerth(), makeMapData(), false);
expect(out['Map Data']).toEqual({