From e40b6c3d99629b4a48b9b8c7bd5e5a9e3287859c Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Sun, 3 May 2026 15:30:32 +0200 Subject: [PATCH 1/3] feat(berths): full NocoDB field parity, numeric types, sales edit access Aligns the berths schema with the 117 production rows in NocoDB and exposes every field for editing via the BerthForm sheet. Schema (migration 0020): - power_capacity / voltage / nominal_boat_size / nominal_boat_size_m: text -> numeric (NocoDB stores plain numbers; text was wrong shape and broke filter/sort) - ADD status_override_mode text (1/117 legacy rows have a value; carried forward for parity but not yet wired into the UI) - USING NULLIF(TRIM(...), '')::numeric so legacy whitespace and empty strings convert cleanly Validator + service: - updateBerthSchema / createBerthSchema use z.coerce.number() for the four numeric fields - berths.service stringifies numeric values for Drizzle's numeric type Form (src/components/berths/berth-form.tsx): - adds: nominal boat size (ft/m), water depth (ft/m) + "is minimum" flag, side pontoon, cleat type/capacity, bollard type/capacity, bow facing - converts to typed selects (with NocoDB option lists in src/lib/constants): area, side pontoon, mooring type, cleat type/capacity, bollard type/capacity, access - power capacity / voltage become numeric inputs (with kW / V hints) Permissions (seed.ts + dev DB): - sales_manager and sales_agent: berths.edit false -> true ("sales will sometimes have to update these and I cannot be the only one") - super_admin / director already had it; viewer stays read-only - dev DB updated in-place via UPDATE roles ... jsonb_set Verification: - pnpm exec vitest run: 858/858 passing - pnpm exec tsc --noEmit: same 36 errors as baseline (all pre-existing on feat/mobile-foundation, none introduced) - lint clean Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/berths/berth-detail-header.tsx | 11 + src/components/berths/berth-form.tsx | 289 +- src/lib/constants.ts | 43 + .../migrations/0020_medical_betty_brant.sql | 15 + src/lib/db/migrations/meta/0020_snapshot.json | 10246 ++++++++++++++++ src/lib/db/migrations/meta/_journal.json | 7 + src/lib/db/schema/berths.ts | 12 +- src/lib/db/seed.ts | 4 +- src/lib/services/berths.service.ts | 12 +- src/lib/validators/berths.ts | 12 +- 10 files changed, 10571 insertions(+), 80 deletions(-) create mode 100644 src/lib/db/migrations/0020_medical_betty_brant.sql create mode 100644 src/lib/db/migrations/meta/0020_snapshot.json diff --git a/src/components/berths/berth-detail-header.tsx b/src/components/berths/berth-detail-header.tsx index 9558c84..1c4500e 100644 --- a/src/components/berths/berth-detail-header.tsx +++ b/src/components/berths/berth-detail-header.tsx @@ -44,6 +44,17 @@ type BerthDetailData = { draftFt: string | null; draftM: string | null; widthIsMinimum: boolean | null; + nominalBoatSize: string | null; + nominalBoatSizeM: string | null; + waterDepth: string | null; + waterDepthM: string | null; + waterDepthIsMinimum: boolean | null; + sidePontoon: string | null; + cleatType: string | null; + cleatCapacity: string | null; + bollardType: string | null; + bollardCapacity: string | null; + bowFacing: string | null; price: string | null; priceCurrency: string; tenureType: string; diff --git a/src/components/berths/berth-form.tsx b/src/components/berths/berth-form.tsx index 430fec1..bbaf349 100644 --- a/src/components/berths/berth-form.tsx +++ b/src/components/berths/berth-form.tsx @@ -16,18 +16,22 @@ import { SelectTrigger, SelectValue, } from '@/components/ui/select'; -import { - Sheet, - SheetContent, - SheetHeader, - SheetTitle, - SheetFooter, -} from '@/components/ui/sheet'; +import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter } from '@/components/ui/sheet'; import { Separator } from '@/components/ui/separator'; import { Switch } from '@/components/ui/switch'; import { TagPicker } from '@/components/shared/tag-picker'; import { apiFetch } from '@/lib/api/client'; import { updateBerthSchema, type UpdateBerthInput } from '@/lib/validators/berths'; +import { + BERTH_AREAS, + BERTH_SIDE_PONTOON_OPTIONS, + BERTH_MOORING_TYPES, + BERTH_CLEAT_TYPES, + BERTH_CLEAT_CAPACITIES, + BERTH_BOLLARD_TYPES, + BERTH_BOLLARD_CAPACITIES, + BERTH_ACCESS_OPTIONS, +} from '@/lib/constants'; interface BerthFormProps { berth: { @@ -42,16 +46,27 @@ interface BerthFormProps { draftFt: string | null; draftM: string | null; widthIsMinimum: boolean | null; + nominalBoatSize: string | null; + nominalBoatSizeM: string | null; + waterDepth: string | null; + waterDepthM: string | null; + waterDepthIsMinimum: boolean | null; + sidePontoon: string | null; + powerCapacity: string | null; + voltage: string | null; + mooringType: string | null; + cleatType: string | null; + cleatCapacity: string | null; + bollardType: string | null; + bollardCapacity: string | null; + access: string | null; + bowFacing: string | null; price: string | null; priceCurrency: string; tenureType: string; tenureYears: number | null; tenureStartDate: string | null; tenureEndDate: string | null; - powerCapacity: string | null; - voltage: string | null; - mooringType: string | null; - access: string | null; berthApproved: boolean | null; tags: Array<{ id: string; name: string; color: string }>; }; @@ -59,10 +74,42 @@ interface BerthFormProps { onOpenChange: (open: boolean) => void; } +/** Optional select that allows clearing back to "no value". */ +function SelectOrEmpty({ + value, + onChange, + options, + placeholder = 'Select…', +}: { + value: string | undefined; + onChange: (next: string | undefined) => void; + options: readonly string[]; + placeholder?: string; +}) { + const NONE = '__none'; + return ( + + ); +} + export function BerthForm({ berth, open, onOpenChange }: BerthFormProps) { const queryClient = useQueryClient(); const [tagIds, setTagIds] = useState(berth.tags.map((t) => t.id)); + const numOrUndef = (v: string | null) => (v != null && v !== '' ? Number(v) : undefined); + const { register, handleSubmit, @@ -73,23 +120,34 @@ export function BerthForm({ berth, open, onOpenChange }: BerthFormProps) { resolver: zodResolver(updateBerthSchema), defaultValues: { area: berth.area ?? undefined, - lengthFt: berth.lengthFt ? Number(berth.lengthFt) : undefined, - lengthM: berth.lengthM ? Number(berth.lengthM) : undefined, - widthFt: berth.widthFt ? Number(berth.widthFt) : undefined, - widthM: berth.widthM ? Number(berth.widthM) : undefined, - draftFt: berth.draftFt ? Number(berth.draftFt) : undefined, - draftM: berth.draftM ? Number(berth.draftM) : undefined, + lengthFt: numOrUndef(berth.lengthFt), + lengthM: numOrUndef(berth.lengthM), + widthFt: numOrUndef(berth.widthFt), + widthM: numOrUndef(berth.widthM), + draftFt: numOrUndef(berth.draftFt), + draftM: numOrUndef(berth.draftM), widthIsMinimum: berth.widthIsMinimum ?? false, - price: berth.price ? Number(berth.price) : undefined, + nominalBoatSize: numOrUndef(berth.nominalBoatSize), + nominalBoatSizeM: numOrUndef(berth.nominalBoatSizeM), + waterDepth: numOrUndef(berth.waterDepth), + waterDepthM: numOrUndef(berth.waterDepthM), + waterDepthIsMinimum: berth.waterDepthIsMinimum ?? false, + sidePontoon: berth.sidePontoon ?? undefined, + powerCapacity: numOrUndef(berth.powerCapacity), + voltage: numOrUndef(berth.voltage), + mooringType: berth.mooringType ?? undefined, + cleatType: berth.cleatType ?? undefined, + cleatCapacity: berth.cleatCapacity ?? undefined, + bollardType: berth.bollardType ?? undefined, + bollardCapacity: berth.bollardCapacity ?? undefined, + access: berth.access ?? undefined, + bowFacing: berth.bowFacing ?? undefined, + price: numOrUndef(berth.price), priceCurrency: berth.priceCurrency, tenureType: berth.tenureType as 'permanent' | 'fixed_term', tenureYears: berth.tenureYears ?? undefined, tenureStartDate: berth.tenureStartDate ?? undefined, tenureEndDate: berth.tenureEndDate ?? undefined, - powerCapacity: berth.powerCapacity ?? undefined, - voltage: berth.voltage ?? undefined, - mooringType: berth.mooringType ?? undefined, - access: berth.access ?? undefined, berthApproved: berth.berthApproved ?? false, }, }); @@ -120,6 +178,14 @@ export function BerthForm({ berth, open, onOpenChange }: BerthFormProps) { } const tenureType = watch('tenureType'); + const area = watch('area'); + const sidePontoon = watch('sidePontoon'); + const mooringType = watch('mooringType'); + const cleatType = watch('cleatType'); + const cleatCapacity = watch('cleatCapacity'); + const bollardType = watch('bollardType'); + const bollardCapacity = watch('bollardCapacity'); + const access = watch('access'); return ( @@ -136,18 +202,18 @@ export function BerthForm({ berth, open, onOpenChange }: BerthFormProps) {
- - + + setValue('area', v)} + options={BERTH_AREAS} + />
- - + +
-
- - -
- +
- +
- +
- +
- +
- + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
-
- setValue('widthIsMinimum', v)} - /> - +
+
+ setValue('widthIsMinimum', v)} + /> + +
+
+ setValue('waterDepthIsMinimum', v)} + /> + +
+ {/* Mooring & Hardware */} +
+

+ Mooring & Hardware +

+
+ + setValue('sidePontoon', v)} + options={BERTH_SIDE_PONTOON_OPTIONS} + /> +
+
+ + setValue('mooringType', v)} + options={BERTH_MOORING_TYPES} + /> +
+
+
+ + setValue('cleatType', v)} + options={BERTH_CLEAT_TYPES} + /> +
+
+ + setValue('cleatCapacity', v)} + options={BERTH_CLEAT_CAPACITIES} + /> +
+
+ + setValue('bollardType', v)} + options={BERTH_BOLLARD_TYPES} + /> +
+
+ + setValue('bollardCapacity', v)} + options={BERTH_BOLLARD_CAPACITIES} + /> +
+
+
+ + + + {/* Power */} +
+

+ Power +

+
+
+ + +
+
+ + +
+
+
+ + + + {/* Access */} +
+

+ Access +

+ setValue('access', v)} + options={BERTH_ACCESS_OPTIONS} + /> +
+ + + {/* Price */}

@@ -262,25 +446,6 @@ export function BerthForm({ berth, open, onOpenChange }: BerthFormProps) { - {/* Infrastructure */} -
-

- Infrastructure -

-
-
- - -
-
- - -
-
-
- - - {/* Tags */}

diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 095ea71..8a31bf5 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -123,6 +123,49 @@ export const BERTH_STATUSES = ['available', 'under_offer', 'sold'] as const; export type BerthStatus = (typeof BERTH_STATUSES)[number]; +// ─── Berth single-select catalogues (mirror NocoDB) ────────────────────────── +// Stored as free text in the DB so legacy values still load, but the form +// presents only the canonical options below. + +export const BERTH_AREAS = ['A', 'B', 'C', 'D', 'E'] as const; + +export const BERTH_SIDE_PONTOON_OPTIONS = [ + 'No', + 'Quay SB', + 'Quay PT', + 'Quay SB, Yes PT', + 'Quay PT, Yes SB', + 'Yes SB', + 'Yes PT', + 'Yes SB, PT', + 'Finger SB', + 'Finger PT', +] as const; + +export const BERTH_MOORING_TYPES = [ + 'Side Pier / Med Mooring', + '2x Med Mooring', + 'Side Pier / Finger', + 'Finger / Med Mooring', + '2x Finger', +] as const; + +export const BERTH_CLEAT_TYPES = ['A3', 'A5'] as const; + +export const BERTH_CLEAT_CAPACITIES = ['10-14 ton break load', '20-24 ton break load'] as const; + +export const BERTH_BOLLARD_TYPES = ['Bull bollard type A', 'Bull bollard type B'] as const; + +export const BERTH_BOLLARD_CAPACITIES = ['20 ton break load', '40 ton break load'] as const; + +export const BERTH_ACCESS_OPTIONS = [ + 'Car to Vessel', + 'Car to Quai, Cart to Vessel', + 'Cart to Vessel', + 'Car (3t) to Vessel', + 'Car (3.5t) to Vessel', +] as const; + // ─── Lead Categories ───────────────────────────────────────────────────────── export const LEAD_CATEGORIES = ['general_interest', 'specific_qualified', 'hot_lead'] as const; diff --git a/src/lib/db/migrations/0020_medical_betty_brant.sql b/src/lib/db/migrations/0020_medical_betty_brant.sql new file mode 100644 index 0000000..cd2ce78 --- /dev/null +++ b/src/lib/db/migrations/0020_medical_betty_brant.sql @@ -0,0 +1,15 @@ +-- Convert text columns to numeric. NULLs survive; empty strings become NULL; +-- whitespace is trimmed before casting so legacy data with stray spaces converts cleanly. +ALTER TABLE "berths" + ALTER COLUMN "nominal_boat_size" SET DATA TYPE numeric + USING NULLIF(TRIM("nominal_boat_size"), '')::numeric;--> statement-breakpoint +ALTER TABLE "berths" + ALTER COLUMN "nominal_boat_size_m" SET DATA TYPE numeric + USING NULLIF(TRIM("nominal_boat_size_m"), '')::numeric;--> statement-breakpoint +ALTER TABLE "berths" + ALTER COLUMN "power_capacity" SET DATA TYPE numeric + USING NULLIF(TRIM("power_capacity"), '')::numeric;--> statement-breakpoint +ALTER TABLE "berths" + ALTER COLUMN "voltage" SET DATA TYPE numeric + USING NULLIF(TRIM("voltage"), '')::numeric;--> statement-breakpoint +ALTER TABLE "berths" ADD COLUMN "status_override_mode" text; \ No newline at end of file diff --git a/src/lib/db/migrations/meta/0020_snapshot.json b/src/lib/db/migrations/meta/0020_snapshot.json new file mode 100644 index 0000000..d134560 --- /dev/null +++ b/src/lib/db/migrations/meta/0020_snapshot.json @@ -0,0 +1,10246 @@ +{ + "id": "e0e6a819-cf9f-45d3-b65b-19da27890f0b", + "prevId": "6326a9a7-0b30-4647-bf86-b3d79e6a08bf", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.ai_usage_ledger": { + "name": "ai_usage_ledger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "feature": { + "name": "feature", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "output_tokens": { + "name": "output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "total_tokens": { + "name": "total_tokens", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ai_usage_port_created": { + "name": "idx_ai_usage_port_created", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ai_usage_port_feature_created": { + "name": "idx_ai_usage_port_feature_created", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "feature", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ai_usage_ledger_port_id_ports_id_fk": { + "name": "ai_usage_ledger_port_id_ports_id_fk", + "tableFrom": "ai_usage_ledger", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "ai_usage_ledger_user_id_user_id_fk": { + "name": "ai_usage_ledger_user_id_user_id_fk", + "tableFrom": "ai_usage_ledger", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_maintenance_log": { + "name": "berth_maintenance_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost": { + "name": "cost", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "cost_currency": { + "name": "cost_currency", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'USD'" + }, + "responsible_party": { + "name": "responsible_party", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "performed_date": { + "name": "performed_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "photo_file_ids": { + "name": "photo_file_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_bml_berth": { + "name": "idx_bml_berth", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_bml_port": { + "name": "idx_bml_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berth_maintenance_log_berth_id_berths_id_fk": { + "name": "berth_maintenance_log_berth_id_berths_id_fk", + "tableFrom": "berth_maintenance_log", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "berth_maintenance_log_port_id_ports_id_fk": { + "name": "berth_maintenance_log_port_id_ports_id_fk", + "tableFrom": "berth_maintenance_log", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_map_data": { + "name": "berth_map_data", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "svg_path": { + "name": "svg_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "x": { + "name": "x", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "y": { + "name": "y", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "transform": { + "name": "transform", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "font_size": { + "name": "font_size", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "extra_data": { + "name": "extra_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "berth_map_data_berth_id_idx": { + "name": "berth_map_data_berth_id_idx", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berth_map_data_berth_id_berths_id_fk": { + "name": "berth_map_data_berth_id_berths_id_fk", + "tableFrom": "berth_map_data", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "berth_map_data_berth_id_unique": { + "name": "berth_map_data_berth_id_unique", + "nullsNotDistinct": false, + "columns": ["berth_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_recommendations": { + "name": "berth_recommendations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "match_score": { + "name": "match_score", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "match_reasons": { + "name": "match_reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'ai'" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "berth_rec_interest_berth_idx": { + "name": "berth_rec_interest_berth_idx", + "columns": [ + { + "expression": "interest_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_br_interest": { + "name": "idx_br_interest", + "columns": [ + { + "expression": "interest_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berth_recommendations_berth_id_berths_id_fk": { + "name": "berth_recommendations_berth_id_berths_id_fk", + "tableFrom": "berth_recommendations", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_tags": { + "name": "berth_tags", + "schema": "", + "columns": { + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "berth_tags_berth_id_berths_id_fk": { + "name": "berth_tags_berth_id_berths_id_fk", + "tableFrom": "berth_tags", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "berth_tags_berth_id_tag_id_pk": { + "name": "berth_tags_berth_id_tag_id_pk", + "columns": ["berth_id", "tag_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_waiting_list": { + "name": "berth_waiting_list", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'normal'" + }, + "notify_pref": { + "name": "notify_pref", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'email'" + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "berth_waiting_list_berth_client_idx": { + "name": "berth_waiting_list_berth_client_idx", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_bwl_berth": { + "name": "idx_bwl_berth", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berth_waiting_list_berth_id_berths_id_fk": { + "name": "berth_waiting_list_berth_id_berths_id_fk", + "tableFrom": "berth_waiting_list", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "berth_waiting_list_client_id_clients_id_fk": { + "name": "berth_waiting_list_client_id_clients_id_fk", + "tableFrom": "berth_waiting_list", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berths": { + "name": "berths", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mooring_number": { + "name": "mooring_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "area": { + "name": "area", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'available'" + }, + "length_ft": { + "name": "length_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width_ft": { + "name": "width_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "draft_ft": { + "name": "draft_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "length_m": { + "name": "length_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width_m": { + "name": "width_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "draft_m": { + "name": "draft_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width_is_minimum": { + "name": "width_is_minimum", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "nominal_boat_size": { + "name": "nominal_boat_size", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "nominal_boat_size_m": { + "name": "nominal_boat_size_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "water_depth": { + "name": "water_depth", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "water_depth_m": { + "name": "water_depth_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "water_depth_is_minimum": { + "name": "water_depth_is_minimum", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "side_pontoon": { + "name": "side_pontoon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "power_capacity": { + "name": "power_capacity", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "voltage": { + "name": "voltage", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "mooring_type": { + "name": "mooring_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cleat_type": { + "name": "cleat_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cleat_capacity": { + "name": "cleat_capacity", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bollard_type": { + "name": "bollard_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bollard_capacity": { + "name": "bollard_capacity", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access": { + "name": "access", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "price_currency": { + "name": "price_currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'USD'" + }, + "bow_facing": { + "name": "bow_facing", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "berth_approved": { + "name": "berth_approved", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "tenure_type": { + "name": "tenure_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'permanent'" + }, + "tenure_years": { + "name": "tenure_years", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tenure_start_date": { + "name": "tenure_start_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "tenure_end_date": { + "name": "tenure_end_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "status_last_changed_by": { + "name": "status_last_changed_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_last_changed_reason": { + "name": "status_last_changed_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_last_modified": { + "name": "status_last_modified", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status_override_mode": { + "name": "status_override_mode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_berths_port": { + "name": "idx_berths_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_berths_status": { + "name": "idx_berths_status", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_berths_area": { + "name": "idx_berths_area", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "area", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_berths_mooring": { + "name": "idx_berths_mooring", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "mooring_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berths_port_id_ports_id_fk": { + "name": "berths_port_id_ports_id_fk", + "tableFrom": "berths", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_addresses": { + "name": "client_addresses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Primary'" + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subdivision_iso": { + "name": "subdivision_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country_iso": { + "name": "country_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ca_client": { + "name": "idx_ca_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ca_port": { + "name": "idx_ca_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ca_primary": { + "name": "idx_ca_primary", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"client_addresses\".\"is_primary\" = true", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "client_addresses_client_id_clients_id_fk": { + "name": "client_addresses_client_id_clients_id_fk", + "tableFrom": "client_addresses", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "client_addresses_port_id_ports_id_fk": { + "name": "client_addresses_port_id_ports_id_fk", + "tableFrom": "client_addresses", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_contacts": { + "name": "client_contacts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value_e164": { + "name": "value_e164", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "value_country": { + "name": "value_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_cc_client": { + "name": "idx_cc_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cc_email": { + "name": "idx_cc_email", + "columns": [ + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"client_contacts\".\"channel\" = 'email'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cc_phone": { + "name": "idx_cc_phone", + "columns": [ + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"client_contacts\".\"channel\" = 'phone'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "client_contacts_client_id_clients_id_fk": { + "name": "client_contacts_client_id_clients_id_fk", + "tableFrom": "client_contacts", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_merge_log": { + "name": "client_merge_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "surviving_client_id": { + "name": "surviving_client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "merged_client_id": { + "name": "merged_client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "merged_by": { + "name": "merged_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "merge_details": { + "name": "merge_details", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_cml_port": { + "name": "idx_cml_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "client_merge_log_port_id_ports_id_fk": { + "name": "client_merge_log_port_id_ports_id_fk", + "tableFrom": "client_merge_log", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "client_merge_log_surviving_client_id_clients_id_fk": { + "name": "client_merge_log_surviving_client_id_clients_id_fk", + "tableFrom": "client_merge_log", + "tableTo": "clients", + "columnsFrom": ["surviving_client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_notes": { + "name": "client_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mentions": { + "name": "mentions", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_locked": { + "name": "is_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_cn_client": { + "name": "idx_cn_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "client_notes_client_id_clients_id_fk": { + "name": "client_notes_client_id_clients_id_fk", + "tableFrom": "client_notes", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_relationships": { + "name": "client_relationships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_a_id": { + "name": "client_a_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_b_id": { + "name": "client_b_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "relationship_type": { + "name": "relationship_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_cr_port": { + "name": "idx_cr_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "client_relationships_port_id_ports_id_fk": { + "name": "client_relationships_port_id_ports_id_fk", + "tableFrom": "client_relationships", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "client_relationships_client_a_id_clients_id_fk": { + "name": "client_relationships_client_a_id_clients_id_fk", + "tableFrom": "client_relationships", + "tableTo": "clients", + "columnsFrom": ["client_a_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "client_relationships_client_b_id_clients_id_fk": { + "name": "client_relationships_client_b_id_clients_id_fk", + "tableFrom": "client_relationships", + "tableTo": "clients", + "columnsFrom": ["client_b_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.client_tags": { + "name": "client_tags", + "schema": "", + "columns": { + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "client_tags_client_id_clients_id_fk": { + "name": "client_tags_client_id_clients_id_fk", + "tableFrom": "client_tags", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "client_tags_client_id_tag_id_pk": { + "name": "client_tags_client_id_tag_id_pk", + "columns": ["client_id", "tag_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.clients": { + "name": "clients", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "full_name": { + "name": "full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "nationality_iso": { + "name": "nationality_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preferred_contact_method": { + "name": "preferred_contact_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preferred_language": { + "name": "preferred_language", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_details": { + "name": "source_details", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_clients_port": { + "name": "idx_clients_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_clients_name": { + "name": "idx_clients_name", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "full_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_clients_archived": { + "name": "idx_clients_archived", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "archived_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_clients_nationality_iso": { + "name": "idx_clients_nationality_iso", + "columns": [ + { + "expression": "nationality_iso", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "clients_port_id_ports_id_fk": { + "name": "clients_port_id_ports_id_fk", + "tableFrom": "clients", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.companies": { + "name": "companies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "legal_name": { + "name": "legal_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tax_id": { + "name": "tax_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registration_number": { + "name": "registration_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "incorporation_country_iso": { + "name": "incorporation_country_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "incorporation_subdivision_iso": { + "name": "incorporation_subdivision_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "incorporation_date": { + "name": "incorporation_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_companies_port": { + "name": "idx_companies_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_companies_name_unique": { + "name": "idx_companies_name_unique", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "lower(\"name\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_companies_taxid": { + "name": "idx_companies_taxid", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "tax_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"companies\".\"tax_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "companies_port_id_ports_id_fk": { + "name": "companies_port_id_ports_id_fk", + "tableFrom": "companies", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_addresses": { + "name": "company_addresses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'Primary'" + }, + "street_address": { + "name": "street_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subdivision_iso": { + "name": "subdivision_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "postal_code": { + "name": "postal_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country_iso": { + "name": "country_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_compa_company": { + "name": "idx_compa_company", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_compa_port": { + "name": "idx_compa_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_compa_primary": { + "name": "idx_compa_primary", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"company_addresses\".\"is_primary\" = true", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_addresses_company_id_companies_id_fk": { + "name": "company_addresses_company_id_companies_id_fk", + "tableFrom": "company_addresses", + "tableTo": "companies", + "columnsFrom": ["company_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "company_addresses_port_id_ports_id_fk": { + "name": "company_addresses_port_id_ports_id_fk", + "tableFrom": "company_addresses", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_memberships": { + "name": "company_memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_detail": { + "name": "role_detail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start_date": { + "name": "start_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_cm_company": { + "name": "idx_cm_company", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cm_client": { + "name": "idx_cm_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cm_active": { + "name": "idx_cm_active", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"company_memberships\".\"end_date\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "unique_cm_exact": { + "name": "unique_cm_exact", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_memberships_company_id_companies_id_fk": { + "name": "company_memberships_company_id_companies_id_fk", + "tableFrom": "company_memberships", + "tableTo": "companies", + "columnsFrom": ["company_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "company_memberships_client_id_clients_id_fk": { + "name": "company_memberships_client_id_clients_id_fk", + "tableFrom": "company_memberships", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_notes": { + "name": "company_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mentions": { + "name": "mentions", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_locked": { + "name": "is_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_compn_company": { + "name": "idx_compn_company", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "company_notes_company_id_companies_id_fk": { + "name": "company_notes_company_id_companies_id_fk", + "tableFrom": "company_notes", + "tableTo": "companies", + "columnsFrom": ["company_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.company_tags": { + "name": "company_tags", + "schema": "", + "columns": { + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "company_tags_company_id_companies_id_fk": { + "name": "company_tags_company_id_companies_id_fk", + "tableFrom": "company_tags", + "tableTo": "companies", + "columnsFrom": ["company_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "company_tags_company_id_tag_id_pk": { + "name": "company_tags_company_id_tag_id_pk", + "columns": ["company_id", "tag_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.crm_user_invites": { + "name": "crm_user_invites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_super_admin": { + "name": "is_super_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_crm_invites_token_hash": { + "name": "idx_crm_invites_token_hash", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_crm_invites_email": { + "name": "idx_crm_invites_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.document_events": { + "name": "document_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_data": { + "name": "event_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "signature_hash": { + "name": "signature_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_de_doc": { + "name": "idx_de_doc", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_de_dedup": { + "name": "idx_de_dedup", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "signature_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"document_events\".\"signature_hash\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_events_document_id_documents_id_fk": { + "name": "document_events_document_id_documents_id_fk", + "tableFrom": "document_events", + "tableTo": "documents", + "columnsFrom": ["document_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "document_events_signer_id_document_signers_id_fk": { + "name": "document_events_signer_id_document_signers_id_fk", + "tableFrom": "document_events", + "tableTo": "document_signers", + "columnsFrom": ["signer_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.document_signers": { + "name": "document_signers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_name": { + "name": "signer_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_email": { + "name": "signer_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_role": { + "name": "signer_role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signing_order": { + "name": "signing_order", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "signed_at": { + "name": "signed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "signing_url": { + "name": "signing_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "embedded_url": { + "name": "embedded_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ds_doc": { + "name": "idx_ds_doc", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_signers_document_id_documents_id_fk": { + "name": "document_signers_document_id_documents_id_fk", + "tableFrom": "document_signers", + "tableTo": "documents", + "columnsFrom": ["document_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.document_templates": { + "name": "document_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_type": { + "name": "template_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body_html": { + "name": "body_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "merge_fields": { + "name": "merge_fields", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "template_format": { + "name": "template_format", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'html'" + }, + "source_file_id": { + "name": "source_file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "documenso_template_id": { + "name": "documenso_template_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "field_mapping": { + "name": "field_mapping", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "overlay_positions": { + "name": "overlay_positions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "reminder_cadence_days": { + "name": "reminder_cadence_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_dt_port": { + "name": "idx_dt_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_dt_type": { + "name": "idx_dt_type", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "template_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_templates_port_id_ports_id_fk": { + "name": "document_templates_port_id_ports_id_fk", + "tableFrom": "document_templates", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "document_templates_source_file_id_files_id_fk": { + "name": "document_templates_source_file_id_files_id_fk", + "tableFrom": "document_templates", + "tableTo": "files", + "columnsFrom": ["source_file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.document_watchers": { + "name": "document_watchers", + "schema": "", + "columns": { + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "added_by": { + "name": "added_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "added_at": { + "name": "added_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_doc_watchers_doc": { + "name": "idx_doc_watchers_doc", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_doc_watchers_user": { + "name": "idx_doc_watchers_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "document_watchers_document_id_documents_id_fk": { + "name": "document_watchers_document_id_documents_id_fk", + "tableFrom": "document_watchers", + "tableTo": "documents", + "columnsFrom": ["document_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "document_watchers_document_id_user_id_pk": { + "name": "document_watchers_document_id_user_id_pk", + "columns": ["document_id", "user_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.documents": { + "name": "documents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reservation_id": { + "name": "reservation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "document_type": { + "name": "document_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "documenso_id": { + "name": "documenso_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "file_id": { + "name": "file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signed_file_id": { + "name": "signed_file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_manual_upload": { + "name": "is_manual_upload", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminders_disabled": { + "name": "reminders_disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "reminder_cadence_override": { + "name": "reminder_cadence_override", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_docs_port": { + "name": "idx_docs_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_docs_interest": { + "name": "idx_docs_interest", + "columns": [ + { + "expression": "interest_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_docs_client": { + "name": "idx_docs_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_documents_yacht": { + "name": "idx_documents_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_documents_company": { + "name": "idx_documents_company", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_docs_reservation": { + "name": "idx_docs_reservation", + "columns": [ + { + "expression": "reservation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_docs_type": { + "name": "idx_docs_type", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "document_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_docs_status_port": { + "name": "idx_docs_status_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "documents_port_id_ports_id_fk": { + "name": "documents_port_id_ports_id_fk", + "tableFrom": "documents", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "documents_client_id_clients_id_fk": { + "name": "documents_client_id_clients_id_fk", + "tableFrom": "documents", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "documents_file_id_files_id_fk": { + "name": "documents_file_id_files_id_fk", + "tableFrom": "documents", + "tableTo": "files", + "columnsFrom": ["file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "documents_signed_file_id_files_id_fk": { + "name": "documents_signed_file_id_files_id_fk", + "tableFrom": "documents", + "tableTo": "files", + "columnsFrom": ["signed_file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.files": { + "name": "files", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "company_id": { + "name": "company_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "original_name": { + "name": "original_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "storage_path": { + "name": "storage_path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_bucket": { + "name": "storage_bucket", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'crm-files'" + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploaded_by": { + "name": "uploaded_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_files_port": { + "name": "idx_files_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_files_client": { + "name": "idx_files_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_files_yacht": { + "name": "idx_files_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_files_company": { + "name": "idx_files_company", + "columns": [ + { + "expression": "company_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "files_port_id_ports_id_fk": { + "name": "files_port_id_ports_id_fk", + "tableFrom": "files", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "files_client_id_clients_id_fk": { + "name": "files_client_id_clients_id_fk", + "tableFrom": "files", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_submissions": { + "name": "form_submissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "form_template_id": { + "name": "form_template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefilled_data": { + "name": "prefilled_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "submitted_data": { + "name": "submitted_data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "submitted_at": { + "name": "submitted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_fs_token": { + "name": "idx_fs_token", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_submissions_form_template_id_form_templates_id_fk": { + "name": "form_submissions_form_template_id_form_templates_id_fk", + "tableFrom": "form_submissions", + "tableTo": "form_templates", + "columnsFrom": ["form_template_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "form_submissions_client_id_clients_id_fk": { + "name": "form_submissions_client_id_clients_id_fk", + "tableFrom": "form_submissions", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_submissions_token_unique": { + "name": "form_submissions_token_unique", + "nullsNotDistinct": false, + "columns": ["token"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_templates": { + "name": "form_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fields": { + "name": "fields", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "branding": { + "name": "branding", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ft_port": { + "name": "idx_ft_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_templates_port_id_ports_id_fk": { + "name": "form_templates_port_id_ports_id_fk", + "tableFrom": "form_templates", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_accounts": { + "name": "email_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_address": { + "name": "email_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "smtp_host": { + "name": "smtp_host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "smtp_port": { + "name": "smtp_port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "imap_host": { + "name": "imap_host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "imap_port": { + "name": "imap_port", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credentials_enc": { + "name": "credentials_enc", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_sync_at": { + "name": "last_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ea_user": { + "name": "idx_ea_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_ea_port": { + "name": "idx_ea_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_accounts_port_id_ports_id_fk": { + "name": "email_accounts_port_id_ports_id_fk", + "tableFrom": "email_accounts", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_messages": { + "name": "email_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id_header": { + "name": "message_id_header", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from_address": { + "name": "from_address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_addresses": { + "name": "to_addresses", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "cc_addresses": { + "name": "cc_addresses", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body_text": { + "name": "body_text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body_html": { + "name": "body_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "direction": { + "name": "direction", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "attachment_file_ids": { + "name": "attachment_file_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "raw_file_id": { + "name": "raw_file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_em_thread": { + "name": "idx_em_thread", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_em_message_id": { + "name": "idx_em_message_id", + "columns": [ + { + "expression": "message_id_header", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"email_messages\".\"message_id_header\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_messages_thread_id_email_threads_id_fk": { + "name": "email_messages_thread_id_email_threads_id_fk", + "tableFrom": "email_messages", + "tableTo": "email_threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_messages_raw_file_id_files_id_fk": { + "name": "email_messages_raw_file_id_files_id_fk", + "tableFrom": "email_messages", + "tableTo": "files", + "columnsFrom": ["raw_file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_threads": { + "name": "email_threads", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_et_client": { + "name": "idx_et_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_et_port": { + "name": "idx_et_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_threads_port_id_ports_id_fk": { + "name": "email_threads_port_id_ports_id_fk", + "tableFrom": "email_threads", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "email_threads_client_id_clients_id_fk": { + "name": "email_threads_client_id_clients_id_fk", + "tableFrom": "email_threads", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.expenses": { + "name": "expenses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "establishment_name": { + "name": "establishment_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount": { + "name": "amount", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'USD'" + }, + "amount_usd": { + "name": "amount_usd", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "exchange_rate": { + "name": "exchange_rate", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "payment_method": { + "name": "payment_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payer": { + "name": "payer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expense_date": { + "name": "expense_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "receipt_file_ids": { + "name": "receipt_file_ids", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "payment_status": { + "name": "payment_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'unpaid'" + }, + "payment_date": { + "name": "payment_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "payment_reference": { + "name": "payment_reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_notes": { + "name": "payment_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "duplicate_of": { + "name": "duplicate_of", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedup_scanned_at": { + "name": "dedup_scanned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "ocr_status": { + "name": "ocr_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'pending'" + }, + "ocr_raw": { + "name": "ocr_raw", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "ocr_confidence": { + "name": "ocr_confidence", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_expenses_port": { + "name": "idx_expenses_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_expenses_date": { + "name": "idx_expenses_date", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expense_date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_expenses_category": { + "name": "idx_expenses_category", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "category", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_expenses_dedup": { + "name": "idx_expenses_dedup", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "establishment_name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "amount", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expense_date", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "duplicate_of IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "expenses_port_id_ports_id_fk": { + "name": "expenses_port_id_ports_id_fk", + "tableFrom": "expenses", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "expenses_duplicate_of_expenses_id_fk": { + "name": "expenses_duplicate_of_expenses_id_fk", + "tableFrom": "expenses", + "tableTo": "expenses", + "columnsFrom": ["duplicate_of"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invoice_expenses": { + "name": "invoice_expenses", + "schema": "", + "columns": { + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expense_id": { + "name": "expense_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "invoice_expenses_invoice_id_invoices_id_fk": { + "name": "invoice_expenses_invoice_id_invoices_id_fk", + "tableFrom": "invoice_expenses", + "tableTo": "invoices", + "columnsFrom": ["invoice_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invoice_expenses_expense_id_expenses_id_fk": { + "name": "invoice_expenses_expense_id_expenses_id_fk", + "tableFrom": "invoice_expenses", + "tableTo": "expenses", + "columnsFrom": ["expense_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "invoice_expenses_invoice_id_expense_id_pk": { + "name": "invoice_expenses_invoice_id_expense_id_pk", + "columns": ["invoice_id", "expense_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invoice_line_items": { + "name": "invoice_line_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric", + "primaryKey": false, + "notNull": true, + "default": "'1'" + }, + "unit_price": { + "name": "unit_price", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "total": { + "name": "total", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_ili_invoice": { + "name": "idx_ili_invoice", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invoice_line_items_invoice_id_invoices_id_fk": { + "name": "invoice_line_items_invoice_id_invoices_id_fk", + "tableFrom": "invoice_line_items", + "tableTo": "invoices", + "columnsFrom": ["invoice_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invoices": { + "name": "invoices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_number": { + "name": "invoice_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_name": { + "name": "client_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "billing_entity_type": { + "name": "billing_entity_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'client'" + }, + "billing_entity_id": { + "name": "billing_entity_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_address": { + "name": "billing_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "due_date": { + "name": "due_date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "payment_terms": { + "name": "payment_terms", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'net30'" + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'USD'" + }, + "subtotal": { + "name": "subtotal", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "discount_pct": { + "name": "discount_pct", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": "'0'" + }, + "discount_amount": { + "name": "discount_amount", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": "'0'" + }, + "fee_pct": { + "name": "fee_pct", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": "'0'" + }, + "fee_amount": { + "name": "fee_amount", + "type": "numeric", + "primaryKey": false, + "notNull": false, + "default": "'0'" + }, + "total": { + "name": "total", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "payment_status": { + "name": "payment_status", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'unpaid'" + }, + "payment_date": { + "name": "payment_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "payment_method": { + "name": "payment_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_reference": { + "name": "payment_reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pdf_file_id": { + "name": "pdf_file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'general'" + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_invoices_number": { + "name": "idx_invoices_number", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "invoice_number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_invoices_port": { + "name": "idx_invoices_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_invoices_status": { + "name": "idx_invoices_status", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_invoices_billing_entity": { + "name": "idx_invoices_billing_entity", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "billing_entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "billing_entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_invoices_interest": { + "name": "idx_invoices_interest", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "interest_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invoices_port_id_ports_id_fk": { + "name": "invoices_port_id_ports_id_fk", + "tableFrom": "invoices", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "invoices_pdf_file_id_files_id_fk": { + "name": "invoices_pdf_file_id_files_id_fk", + "tableFrom": "invoices", + "tableTo": "files", + "columnsFrom": ["pdf_file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "invoices_interest_id_interests_id_fk": { + "name": "invoices_interest_id_interests_id_fk", + "tableFrom": "invoices", + "tableTo": "interests", + "columnsFrom": ["interest_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.gdpr_exports": { + "name": "gdpr_exports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "requested_by": { + "name": "requested_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size_bytes": { + "name": "size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_to": { + "name": "sent_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ready_at": { + "name": "ready_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "idx_gdpr_exports_client": { + "name": "idx_gdpr_exports_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_gdpr_exports_port_created": { + "name": "idx_gdpr_exports_port_created", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "gdpr_exports_port_id_ports_id_fk": { + "name": "gdpr_exports_port_id_ports_id_fk", + "tableFrom": "gdpr_exports", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "gdpr_exports_client_id_clients_id_fk": { + "name": "gdpr_exports_client_id_clients_id_fk", + "tableFrom": "gdpr_exports", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "gdpr_exports_requested_by_user_id_fk": { + "name": "gdpr_exports_requested_by_user_id_fk", + "tableFrom": "gdpr_exports", + "tableTo": "user", + "columnsFrom": ["requested_by"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ports": { + "name": "ports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo_url": { + "name": "logo_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "primary_color": { + "name": "primary_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_currency": { + "name": "default_currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'USD'" + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'America/Anguilla'" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "ports_slug_idx": { + "name": "ports_slug_idx", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.port_role_overrides": { + "name": "port_role_overrides", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "permission_overrides": { + "name": "permission_overrides", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "port_role_overrides_port_role_idx": { + "name": "port_role_overrides_port_role_idx", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "port_role_overrides_port_idx": { + "name": "port_role_overrides_port_idx", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "port_role_overrides_port_id_ports_id_fk": { + "name": "port_role_overrides_port_id_ports_id_fk", + "tableFrom": "port_role_overrides", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "port_role_overrides_role_id_roles_id_fk": { + "name": "port_role_overrides_role_id_roles_id_fk", + "tableFrom": "port_role_overrides", + "tableTo": "roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.roles": { + "name": "roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "permissions": { + "name": "permissions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "is_global": { + "name": "is_global", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "is_system": { + "name": "is_system", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sessions_token_idx": { + "name": "sessions_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_user_id_idx": { + "name": "sessions_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": ["token"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_port_roles": { + "name": "user_port_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "residential_access": { + "name": "residential_access", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "assigned_by": { + "name": "assigned_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_port_roles_user_port_role_idx": { + "name": "user_port_roles_user_port_role_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_upr_user": { + "name": "idx_upr_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_upr_port": { + "name": "idx_upr_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_port_roles_port_id_ports_id_fk": { + "name": "user_port_roles_port_id_ports_id_fk", + "tableFrom": "user_port_roles", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_port_roles_role_id_roles_id_fk": { + "name": "user_port_roles_role_id_roles_id_fk", + "tableFrom": "user_port_roles", + "tableTo": "roles", + "columnsFrom": ["role_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_profiles": { + "name": "user_profiles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_super_admin": { + "name": "is_super_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_login_at": { + "name": "last_login_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "preferences": { + "name": "preferences", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_profiles_user_id_idx": { + "name": "user_profiles_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_profiles_user_id_unique": { + "name": "user_profiles_user_id_unique", + "nullsNotDistinct": false, + "columns": ["user_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.yacht_notes": { + "name": "yacht_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mentions": { + "name": "mentions", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_locked": { + "name": "is_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_yn_yacht": { + "name": "idx_yn_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "yacht_notes_yacht_id_yachts_id_fk": { + "name": "yacht_notes_yacht_id_yachts_id_fk", + "tableFrom": "yacht_notes", + "tableTo": "yachts", + "columnsFrom": ["yacht_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.yacht_ownership_history": { + "name": "yacht_ownership_history", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "owner_type": { + "name": "owner_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_date": { + "name": "start_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "transfer_reason": { + "name": "transfer_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "transfer_notes": { + "name": "transfer_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_yoh_yacht": { + "name": "idx_yoh_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_yoh_active": { + "name": "idx_yoh_active", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"yacht_ownership_history\".\"end_date\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "yacht_ownership_history_yacht_id_yachts_id_fk": { + "name": "yacht_ownership_history_yacht_id_yachts_id_fk", + "tableFrom": "yacht_ownership_history", + "tableTo": "yachts", + "columnsFrom": ["yacht_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.yacht_tags": { + "name": "yacht_tags", + "schema": "", + "columns": { + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "yacht_tags_yacht_id_yachts_id_fk": { + "name": "yacht_tags_yacht_id_yachts_id_fk", + "tableFrom": "yacht_tags", + "tableTo": "yachts", + "columnsFrom": ["yacht_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "yacht_tags_yacht_id_tag_id_pk": { + "name": "yacht_tags_yacht_id_tag_id_pk", + "columns": ["yacht_id", "tag_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.yachts": { + "name": "yachts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hull_number": { + "name": "hull_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registration": { + "name": "registration", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "flag": { + "name": "flag", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "year_built": { + "name": "year_built", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "builder": { + "name": "builder", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hull_material": { + "name": "hull_material", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "length_ft": { + "name": "length_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width_ft": { + "name": "width_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "draft_ft": { + "name": "draft_ft", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "length_m": { + "name": "length_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "width_m": { + "name": "width_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "draft_m": { + "name": "draft_m", + "type": "numeric", + "primaryKey": false, + "notNull": false + }, + "current_owner_type": { + "name": "current_owner_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "current_owner_id": { + "name": "current_owner_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_yachts_port": { + "name": "idx_yachts_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_yachts_current_owner": { + "name": "idx_yachts_current_owner", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "current_owner_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "current_owner_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_yachts_name": { + "name": "idx_yachts_name", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_yachts_archived": { + "name": "idx_yachts_archived", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "archived_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "yachts_port_id_ports_id_fk": { + "name": "yachts_port_id_ports_id_fk", + "tableFrom": "yachts", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.interest_notes": { + "name": "interest_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "author_id": { + "name": "author_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mentions": { + "name": "mentions", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "is_locked": { + "name": "is_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_in_interest": { + "name": "idx_in_interest", + "columns": [ + { + "expression": "interest_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "interest_notes_interest_id_interests_id_fk": { + "name": "interest_notes_interest_id_interests_id_fk", + "tableFrom": "interest_notes", + "tableTo": "interests", + "columnsFrom": ["interest_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.interest_tags": { + "name": "interest_tags", + "schema": "", + "columns": { + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "interest_tags_interest_id_interests_id_fk": { + "name": "interest_tags_interest_id_interests_id_fk", + "tableFrom": "interest_tags", + "tableTo": "interests", + "columnsFrom": ["interest_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "interest_tags_interest_id_tag_id_pk": { + "name": "interest_tags_interest_id_tag_id_pk", + "columns": ["interest_id", "tag_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.interests": { + "name": "interests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pipeline_stage": { + "name": "pipeline_stage", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "lead_category": { + "name": "lead_category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "eoi_status": { + "name": "eoi_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "documenso_id": { + "name": "documenso_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contract_status": { + "name": "contract_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deposit_status": { + "name": "deposit_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reservation_status": { + "name": "reservation_status", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "date_first_contact": { + "name": "date_first_contact", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_last_contact": { + "name": "date_last_contact", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_eoi_sent": { + "name": "date_eoi_sent", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_eoi_signed": { + "name": "date_eoi_signed", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_contract_sent": { + "name": "date_contract_sent", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_contract_signed": { + "name": "date_contract_signed", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_deposit_received": { + "name": "date_deposit_received", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reminder_enabled": { + "name": "reminder_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "reminder_days": { + "name": "reminder_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reminder_last_fired": { + "name": "reminder_last_fired", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome_reason": { + "name": "outcome_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome_at": { + "name": "outcome_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_interests_port": { + "name": "idx_interests_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_client": { + "name": "idx_interests_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_berth": { + "name": "idx_interests_berth", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_yacht": { + "name": "idx_interests_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_stage": { + "name": "idx_interests_stage", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pipeline_stage", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_archived": { + "name": "idx_interests_archived", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "archived_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_interests_outcome": { + "name": "idx_interests_outcome", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "outcome", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "interests_port_id_ports_id_fk": { + "name": "interests_port_id_ports_id_fk", + "tableFrom": "interests", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "interests_client_id_clients_id_fk": { + "name": "interests_client_id_clients_id_fk", + "tableFrom": "interests", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.berth_reservations": { + "name": "berth_reservations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "yacht_id": { + "name": "yacht_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_date": { + "name": "start_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_date": { + "name": "end_date", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tenure_type": { + "name": "tenure_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'permanent'" + }, + "contract_file_id": { + "name": "contract_file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_br_berth": { + "name": "idx_br_berth", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_br_client": { + "name": "idx_br_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_br_yacht": { + "name": "idx_br_yacht", + "columns": [ + { + "expression": "yacht_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_br_port": { + "name": "idx_br_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_br_active": { + "name": "idx_br_active", + "columns": [ + { + "expression": "berth_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"berth_reservations\".\"status\" = 'active'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "berth_reservations_berth_id_berths_id_fk": { + "name": "berth_reservations_berth_id_berths_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "berths", + "columnsFrom": ["berth_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "berth_reservations_port_id_ports_id_fk": { + "name": "berth_reservations_port_id_ports_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "berth_reservations_client_id_clients_id_fk": { + "name": "berth_reservations_client_id_clients_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "berth_reservations_yacht_id_yachts_id_fk": { + "name": "berth_reservations_yacht_id_yachts_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "yachts", + "columnsFrom": ["yacht_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "berth_reservations_interest_id_interests_id_fk": { + "name": "berth_reservations_interest_id_interests_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "interests", + "columnsFrom": ["interest_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "berth_reservations_contract_file_id_files_id_fk": { + "name": "berth_reservations_contract_file_id_files_id_fk", + "tableFrom": "berth_reservations", + "tableTo": "files", + "columnsFrom": ["contract_file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.portal_auth_tokens": { + "name": "portal_auth_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "portal_user_id": { + "name": "portal_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_portal_tokens_hash_unique": { + "name": "idx_portal_tokens_hash_unique", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_portal_tokens_user": { + "name": "idx_portal_tokens_user", + "columns": [ + { + "expression": "portal_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "portal_auth_tokens_portal_user_id_portal_users_id_fk": { + "name": "portal_auth_tokens_portal_user_id_portal_users_id_fk", + "tableFrom": "portal_auth_tokens", + "tableTo": "portal_users", + "columnsFrom": ["portal_user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.portal_users": { + "name": "portal_users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_login_at": { + "name": "last_login_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_portal_users_email_unique": { + "name": "idx_portal_users_email_unique", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_portal_users_client": { + "name": "idx_portal_users_client", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_portal_users_port": { + "name": "idx_portal_users_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "portal_users_port_id_ports_id_fk": { + "name": "portal_users_port_id_ports_id_fk", + "tableFrom": "portal_users", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "portal_users_client_id_clients_id_fk": { + "name": "portal_users_client_id_clients_id_fk", + "tableFrom": "portal_users", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.residential_clients": { + "name": "residential_clients", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "full_name": { + "name": "full_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "phone_e164": { + "name": "phone_e164", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "phone_country": { + "name": "phone_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "nationality_iso": { + "name": "nationality_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "place_of_residence": { + "name": "place_of_residence", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "place_of_residence_country_iso": { + "name": "place_of_residence_country_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subdivision_iso": { + "name": "subdivision_iso", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preferred_contact_method": { + "name": "preferred_contact_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'prospect'" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_residential_clients_port": { + "name": "idx_residential_clients_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_clients_email": { + "name": "idx_residential_clients_email", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_clients_archived": { + "name": "idx_residential_clients_archived", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "archived_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "residential_clients_port_id_ports_id_fk": { + "name": "residential_clients_port_id_ports_id_fk", + "tableFrom": "residential_clients", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.residential_interests": { + "name": "residential_interests", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "residential_client_id": { + "name": "residential_client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pipeline_stage": { + "name": "pipeline_stage", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'new'" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "preferences": { + "name": "preferences", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "assigned_to": { + "name": "assigned_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "date_first_contact": { + "name": "date_first_contact", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "date_last_contact": { + "name": "date_last_contact", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_residential_interests_port": { + "name": "idx_residential_interests_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_interests_client": { + "name": "idx_residential_interests_client", + "columns": [ + { + "expression": "residential_client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_interests_stage": { + "name": "idx_residential_interests_stage", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pipeline_stage", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_interests_assigned": { + "name": "idx_residential_interests_assigned", + "columns": [ + { + "expression": "assigned_to", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_residential_interests_archived": { + "name": "idx_residential_interests_archived", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "archived_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "residential_interests_port_id_ports_id_fk": { + "name": "residential_interests_port_id_ports_id_fk", + "tableFrom": "residential_interests", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "residential_interests_residential_client_id_residential_clients_id_fk": { + "name": "residential_interests_residential_client_id_residential_clients_id_fk", + "tableFrom": "residential_interests", + "tableTo": "residential_clients", + "columnsFrom": ["residential_client_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.generated_reports": { + "name": "generated_reports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scheduled_report_id": { + "name": "scheduled_report_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "report_type": { + "name": "report_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "parameters": { + "name": "parameters", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "file_id": { + "name": "file_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_by": { + "name": "requested_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_gr_port_created": { + "name": "idx_gr_port_created", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_gr_port_status": { + "name": "idx_gr_port_status", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_gr_scheduled": { + "name": "idx_gr_scheduled", + "columns": [ + { + "expression": "scheduled_report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"generated_reports\".\"scheduled_report_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "generated_reports_port_id_ports_id_fk": { + "name": "generated_reports_port_id_ports_id_fk", + "tableFrom": "generated_reports", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "generated_reports_scheduled_report_id_scheduled_reports_id_fk": { + "name": "generated_reports_scheduled_report_id_scheduled_reports_id_fk", + "tableFrom": "generated_reports", + "tableTo": "scheduled_reports", + "columnsFrom": ["scheduled_report_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "generated_reports_file_id_files_id_fk": { + "name": "generated_reports_file_id_files_id_fk", + "tableFrom": "generated_reports", + "tableTo": "files", + "columnsFrom": ["file_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.google_calendar_cache": { + "name": "google_calendar_cache", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_crm_pushed": { + "name": "is_crm_pushed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "reminder_id": { + "name": "reminder_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fetched_at": { + "name": "fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "gcal_cache_user_event_idx": { + "name": "gcal_cache_user_event_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_gcal_cache_user": { + "name": "idx_gcal_cache_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "google_calendar_cache_reminder_id_reminders_id_fk": { + "name": "google_calendar_cache_reminder_id_reminders_id_fk", + "tableFrom": "google_calendar_cache", + "tableTo": "reminders", + "columnsFrom": ["reminder_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.google_calendar_tokens": { + "name": "google_calendar_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_expiry": { + "name": "token_expiry", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'primary'" + }, + "connected_at": { + "name": "connected_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_sync_at": { + "name": "last_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_enabled": { + "name": "sync_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "gcal_tokens_user_id_idx": { + "name": "gcal_tokens_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "google_calendar_tokens_user_id_unique": { + "name": "google_calendar_tokens_user_id_unique", + "nullsNotDistinct": false, + "columns": ["user_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "link": { + "name": "link", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_read": { + "name": "is_read", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "email_sent": { + "name": "email_sent", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_notif_user": { + "name": "idx_notif_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_read", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_notif_port": { + "name": "idx_notif_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_notifications_user_type": { + "name": "idx_notifications_user_type", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_port_id_ports_id_fk": { + "name": "notifications_port_id_ports_id_fk", + "tableFrom": "notifications", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reminders": { + "name": "reminders", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "due_at": { + "name": "due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "priority": { + "name": "priority", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'medium'" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "assigned_to": { + "name": "assigned_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "interest_id": { + "name": "interest_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "berth_id": { + "name": "berth_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auto_generated": { + "name": "auto_generated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "google_calendar_event_id": { + "name": "google_calendar_event_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "google_calendar_synced": { + "name": "google_calendar_synced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "snoozed_until": { + "name": "snoozed_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_reminders_port": { + "name": "idx_reminders_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reminders_assigned": { + "name": "idx_reminders_assigned", + "columns": [ + { + "expression": "assigned_to", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_reminders_due": { + "name": "idx_reminders_due", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reminders\".\"status\" IN ('pending', 'snoozed')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reminders_port_id_ports_id_fk": { + "name": "reminders_port_id_ports_id_fk", + "tableFrom": "reminders", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "reminders_client_id_clients_id_fk": { + "name": "reminders_client_id_clients_id_fk", + "tableFrom": "reminders", + "tableTo": "clients", + "columnsFrom": ["client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.report_recipients": { + "name": "report_recipients", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "report_id": { + "name": "report_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "report_recipients_report_email_idx": { + "name": "report_recipients_report_email_idx", + "columns": [ + { + "expression": "report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_rr_report": { + "name": "idx_rr_report", + "columns": [ + { + "expression": "report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "report_recipients_report_id_scheduled_reports_id_fk": { + "name": "report_recipients_report_id_scheduled_reports_id_fk", + "tableFrom": "report_recipients", + "tableTo": "scheduled_reports", + "columnsFrom": ["report_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduled_reports": { + "name": "scheduled_reports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "report_type": { + "name": "report_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "schedule": { + "name": "schedule", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_run_at": { + "name": "last_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_sr_port": { + "name": "idx_sr_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduled_reports_port_id_ports_id_fk": { + "name": "scheduled_reports_port_id_ports_id_fk", + "tableFrom": "scheduled_reports", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_logs": { + "name": "audit_logs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "field_changed": { + "name": "field_changed", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "old_value": { + "name": "old_value", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "new_value": { + "name": "new_value", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reverted_by": { + "name": "reverted_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reverted_at": { + "name": "reverted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revert_of": { + "name": "revert_of", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "search_text": { + "name": "search_text", + "type": "tsvector", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_al_port": { + "name": "idx_al_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_al_entity": { + "name": "idx_al_entity", + "columns": [ + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_al_user": { + "name": "idx_al_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_al_created": { + "name": "idx_al_created", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audit_logs_port_id_ports_id_fk": { + "name": "audit_logs_port_id_ports_id_fk", + "tableFrom": "audit_logs", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "audit_logs_revert_of_audit_logs_id_fk": { + "name": "audit_logs_revert_of_audit_logs_id_fk", + "tableFrom": "audit_logs", + "tableTo": "audit_logs", + "columnsFrom": ["revert_of"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.currency_rates": { + "name": "currency_rates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "base_currency": { + "name": "base_currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_currency": { + "name": "target_currency", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rate": { + "name": "rate", + "type": "numeric", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'frankfurter'" + }, + "fetched_at": { + "name": "fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "currency_rates_base_target_idx": { + "name": "currency_rates_base_target_idx", + "columns": [ + { + "expression": "base_currency", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_currency", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_field_definitions": { + "name": "custom_field_definitions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "field_name": { + "name": "field_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "field_label": { + "name": "field_label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "field_type": { + "name": "field_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "select_options": { + "name": "select_options", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_required": { + "name": "is_required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "cfd_port_entity_name_idx": { + "name": "cfd_port_entity_name_idx", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "field_name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cfd_port": { + "name": "idx_cfd_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "custom_field_definitions_port_id_ports_id_fk": { + "name": "custom_field_definitions_port_id_ports_id_fk", + "tableFrom": "custom_field_definitions", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_field_values": { + "name": "custom_field_values", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "field_id": { + "name": "field_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "cfv_field_entity_idx": { + "name": "cfv_field_entity_idx", + "columns": [ + { + "expression": "field_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_cfv_entity": { + "name": "idx_cfv_entity", + "columns": [ + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "custom_field_values_field_id_custom_field_definitions_id_fk": { + "name": "custom_field_values_field_id_custom_field_definitions_id_fk", + "tableFrom": "custom_field_values", + "tableTo": "custom_field_definitions", + "columnsFrom": ["field_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.saved_views": { + "name": "saved_views", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filters": { + "name": "filters", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "sort_config": { + "name": "sort_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "column_config": { + "name": "column_config", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_shared": { + "name": "is_shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_sv_user": { + "name": "idx_sv_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "saved_views_port_id_ports_id_fk": { + "name": "saved_views_port_id_ports_id_fk", + "tableFrom": "saved_views", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scratchpad_notes": { + "name": "scratchpad_notes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "linked_client_id": { + "name": "linked_client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "linked_at": { + "name": "linked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_sp_user": { + "name": "idx_sp_user", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scratchpad_notes_linked_client_id_clients_id_fk": { + "name": "scratchpad_notes_linked_client_id_clients_id_fk", + "tableFrom": "scratchpad_notes", + "tableTo": "clients", + "columnsFrom": ["linked_client_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.system_settings": { + "name": "system_settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_by": { + "name": "updated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "system_settings_key_port_idx": { + "name": "system_settings_key_port_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "system_settings_port_id_ports_id_fk": { + "name": "system_settings_port_id_ports_id_fk", + "tableFrom": "system_settings", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tags": { + "name": "tags", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'#6B7280'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tags_port_name_idx": { + "name": "tags_port_name_idx", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_tags_port": { + "name": "idx_tags_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "tags_port_id_ports_id_fk": { + "name": "tags_port_id_ports_id_fk", + "tableFrom": "tags", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_notification_preferences": { + "name": "user_notification_preferences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notification_type": { + "name": "notification_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "in_app": { + "name": "in_app", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "email": { + "name": "email", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + } + }, + "indexes": { + "unp_user_port_type_idx": { + "name": "unp_user_port_type_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "notification_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_notification_preferences_port_id_ports_id_fk": { + "name": "user_notification_preferences_port_id_ports_id_fk", + "tableFrom": "user_notification_preferences", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_deliveries": { + "name": "webhook_deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "webhook_id": { + "name": "webhook_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "response_status": { + "name": "response_status", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "response_body": { + "name": "response_body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempt": { + "name": "attempt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "delivered_at": { + "name": "delivered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_wd_webhook": { + "name": "idx_wd_webhook", + "columns": [ + { + "expression": "webhook_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_deliveries_webhook_id_webhooks_id_fk": { + "name": "webhook_deliveries_webhook_id_webhooks_id_fk", + "tableFrom": "webhook_deliveries", + "tableTo": "webhooks", + "columnsFrom": ["webhook_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhooks": { + "name": "webhooks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "events": { + "name": "events", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "idx_webhooks_port": { + "name": "idx_webhooks_port", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhooks_port_id_ports_id_fk": { + "name": "webhooks_port_id_ports_id_fk", + "tableFrom": "webhooks", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.alerts": { + "name": "alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rule_id": { + "name": "rule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "severity": { + "name": "severity", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "link": { + "name": "link", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "entity_id": { + "name": "entity_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fingerprint": { + "name": "fingerprint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fired_at": { + "name": "fired_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "dismissed_at": { + "name": "dismissed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dismissed_by": { + "name": "dismissed_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "acknowledged_at": { + "name": "acknowledged_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "acknowledged_by": { + "name": "acknowledged_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "idx_alerts_fingerprint_open": { + "name": "idx_alerts_fingerprint_open", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "fingerprint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "resolved_at IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_alerts_port_fired": { + "name": "idx_alerts_port_fired", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "fired_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "idx_alerts_port_severity_open": { + "name": "idx_alerts_port_severity_open", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "severity", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "resolved_at IS NULL AND dismissed_at IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "alerts_port_id_ports_id_fk": { + "name": "alerts_port_id_ports_id_fk", + "tableFrom": "alerts", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "alerts_dismissed_by_user_id_fk": { + "name": "alerts_dismissed_by_user_id_fk", + "tableFrom": "alerts", + "tableTo": "user", + "columnsFrom": ["dismissed_by"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "alerts_acknowledged_by_user_id_fk": { + "name": "alerts_acknowledged_by_user_id_fk", + "tableFrom": "alerts", + "tableTo": "user", + "columnsFrom": ["acknowledged_by"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.analytics_snapshots": { + "name": "analytics_snapshots", + "schema": "", + "columns": { + "port_id": { + "name": "port_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metric_id": { + "name": "metric_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "computed_at": { + "name": "computed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "idx_analytics_pk": { + "name": "idx_analytics_pk", + "columns": [ + { + "expression": "port_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "metric_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "analytics_snapshots_port_id_ports_id_fk": { + "name": "analytics_snapshots_port_id_ports_id_fk", + "tableFrom": "analytics_snapshots", + "tableTo": "ports", + "columnsFrom": ["port_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/src/lib/db/migrations/meta/_journal.json b/src/lib/db/migrations/meta/_journal.json index b559df0..a3fa3b8 100644 --- a/src/lib/db/migrations/meta/_journal.json +++ b/src/lib/db/migrations/meta/_journal.json @@ -141,6 +141,13 @@ "when": 1777671562738, "tag": "0019_lazy_vampiro", "breakpoints": true + }, + { + "idx": 20, + "version": "7", + "when": 1777814682110, + "tag": "0020_medical_betty_brant", + "breakpoints": true } ] } diff --git a/src/lib/db/schema/berths.ts b/src/lib/db/schema/berths.ts index 18b0bc9..d71d282 100644 --- a/src/lib/db/schema/berths.ts +++ b/src/lib/db/schema/berths.ts @@ -33,14 +33,15 @@ export const berths = pgTable( widthM: numeric('width_m'), draftM: numeric('draft_m'), widthIsMinimum: boolean('width_is_minimum').default(false), - nominalBoatSize: text('nominal_boat_size'), - nominalBoatSizeM: text('nominal_boat_size_m'), + // Numeric: ft (legacy NocoDB stored as plain numbers, no units in value). + nominalBoatSize: numeric('nominal_boat_size'), + nominalBoatSizeM: numeric('nominal_boat_size_m'), waterDepth: numeric('water_depth'), waterDepthM: numeric('water_depth_m'), waterDepthIsMinimum: boolean('water_depth_is_minimum').default(false), sidePontoon: text('side_pontoon'), - powerCapacity: text('power_capacity'), - voltage: text('voltage'), + powerCapacity: numeric('power_capacity'), // kW + voltage: numeric('voltage'), // V at 60Hz mooringType: text('mooring_type'), cleatType: text('cleat_type'), cleatCapacity: text('cleat_capacity'), @@ -58,6 +59,9 @@ export const berths = pgTable( statusLastChangedBy: text('status_last_changed_by'), // user ID statusLastChangedReason: text('status_last_changed_reason'), statusLastModified: timestamp('status_last_modified', { withTimezone: true }), + // Optional override flag carried over from NocoDB ("auto" or null in legacy data). + // Reserved for future "manual override" semantics; not surfaced in the UI today. + statusOverrideMode: text('status_override_mode'), createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(), updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(), }, diff --git a/src/lib/db/seed.ts b/src/lib/db/seed.ts index a313047..1a351d5 100644 --- a/src/lib/db/seed.ts +++ b/src/lib/db/seed.ts @@ -186,7 +186,7 @@ const SALES_MANAGER_PERMISSIONS: RolePermissions = { generate_eoi: true, export: true, }, - berths: { view: true, edit: false, import: false, manage_waiting_list: true }, + berths: { view: true, edit: true, import: false, manage_waiting_list: true }, documents: { view: true, create: true, @@ -260,7 +260,7 @@ const SALES_AGENT_PERMISSIONS: RolePermissions = { generate_eoi: true, export: true, }, - berths: { view: true, edit: false, import: false, manage_waiting_list: true }, + berths: { view: true, edit: true, import: false, manage_waiting_list: true }, documents: { view: true, create: true, diff --git a/src/lib/services/berths.service.ts b/src/lib/services/berths.service.ts index 92fe229..e938bb8 100644 --- a/src/lib/services/berths.service.ts +++ b/src/lib/services/berths.service.ts @@ -180,14 +180,14 @@ export async function updateBerth( draftFt: n(data.draftFt), draftM: n(data.draftM), widthIsMinimum: data.widthIsMinimum, - nominalBoatSize: data.nominalBoatSize, - nominalBoatSizeM: data.nominalBoatSizeM, + nominalBoatSize: n(data.nominalBoatSize), + nominalBoatSizeM: n(data.nominalBoatSizeM), waterDepth: n(data.waterDepth), waterDepthM: n(data.waterDepthM), waterDepthIsMinimum: data.waterDepthIsMinimum, sidePontoon: data.sidePontoon, - powerCapacity: data.powerCapacity, - voltage: data.voltage, + powerCapacity: n(data.powerCapacity), + voltage: n(data.voltage), mooringType: data.mooringType, cleatType: data.cleatType, cleatCapacity: data.cleatCapacity, @@ -481,8 +481,8 @@ export async function createBerth(portId: string, data: CreateBerthInput, meta: priceCurrency: data.priceCurrency ?? 'USD', tenureType: data.tenureType ?? 'permanent', mooringType: data.mooringType, - powerCapacity: data.powerCapacity, - voltage: data.voltage, + powerCapacity: data.powerCapacity?.toString(), + voltage: data.voltage?.toString(), access: data.access, bowFacing: data.bowFacing, sidePontoon: data.sidePontoon, diff --git a/src/lib/validators/berths.ts b/src/lib/validators/berths.ts index e4f3f7b..f5b7a67 100644 --- a/src/lib/validators/berths.ts +++ b/src/lib/validators/berths.ts @@ -18,8 +18,8 @@ export const createBerthSchema = z.object({ status: z.enum(BERTH_STATUSES).default('available'), tenureType: z.enum(['permanent', 'fixed_term']).optional(), mooringType: z.string().optional(), - powerCapacity: z.string().optional(), - voltage: z.string().optional(), + powerCapacity: z.coerce.number().optional(), // kW + voltage: z.coerce.number().optional(), // V at 60Hz access: z.string().optional(), bowFacing: z.string().optional(), sidePontoon: z.string().optional(), @@ -38,14 +38,14 @@ export const updateBerthSchema = z.object({ draftFt: z.coerce.number().optional(), draftM: z.coerce.number().optional(), widthIsMinimum: z.boolean().optional(), - nominalBoatSize: z.string().optional(), - nominalBoatSizeM: z.string().optional(), + nominalBoatSize: z.coerce.number().optional(), // ft + nominalBoatSizeM: z.coerce.number().optional(), // m waterDepth: z.coerce.number().optional(), waterDepthM: z.coerce.number().optional(), waterDepthIsMinimum: z.boolean().optional(), sidePontoon: z.string().optional(), - powerCapacity: z.string().optional(), - voltage: z.string().optional(), + powerCapacity: z.coerce.number().optional(), // kW + voltage: z.coerce.number().optional(), // V at 60Hz mooringType: z.string().optional(), cleatType: z.string().optional(), cleatCapacity: z.string().optional(), From c7ab816c99b64d2d6a3dc2f5f8e8d54a59d1d5f0 Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Sun, 3 May 2026 15:41:12 +0200 Subject: [PATCH 2/3] feat(seed): replace 12 hand-rolled berths with 117-row NocoDB snapshot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old seed only had 12 berths with made-up area names ("North Pier", "Central Basin", etc.) and placeholder dimensions. Devs now get the real 117 berths exported from the legacy NocoDB Berths table — every editable column populated with real production values. What's in the snapshot (src/lib/db/seed-data/berths.json): - 117 berths total (61 available / 45 under_offer / 11 sold) - Areas A through E (matches NocoDB single-select) - All numeric fields filled: length / width / draft (ft + m), water depth, nominal boat size, power capacity (kW), voltage (V) - All NocoDB single-selects filled where present: side pontoon, mooring type, cleat/bollard type+capacity, access - Bow facing, status_override_mode, berth_approved carried forward as-is - Status normalized to lowercase snake_case ("Under Offer" -> "under_offer") - Mooring numbers reformatted A1 -> A-01 to keep the existing "Letter-NN" convention used elsewhere in the codebase Pre-sorted to preserve seed semantics: idx 0..4 -> 5 available (small) -- "open" / "details_sent" interests idx 5..9 -> 5 under_offer (medium) -- "eoi_signed" / "deposit" / "contract" idx 10..11 -> 2 sold (large) -- "completed" interests This means existing interest/reservation seeds that index berthRows[0..11] keep their semantic alignment without code changes. End-to-end verified by clearing Marina Azzurra and re-seeding: Port "Marina Azzurra" -- 117 berths, 8 clients, 3 companies, 12 yachts, 15 interests, 8 reservations Future devs running `pnpm db:seed` on a fresh DB will now get realistic berth data automatically. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/lib/db/seed-data.ts | 208 +- src/lib/db/seed-data/berths.json | 3746 ++++++++++++++++++++++++++++++ 2 files changed, 3822 insertions(+), 132 deletions(-) create mode 100644 src/lib/db/seed-data/berths.json diff --git a/src/lib/db/seed-data.ts b/src/lib/db/seed-data.ts index 12312dd..e3f20de 100644 --- a/src/lib/db/seed-data.ts +++ b/src/lib/db/seed-data.ts @@ -4,7 +4,13 @@ * Exports `seedPortData(portId, portSlug)` — creates a realistic, * multi-cardinality data fixture for one port: * - * - 12 berths (5 available / 5 reserved-active / 2 sold) + * - 117 berths imported from a snapshot of the legacy NocoDB Berths + * table (`src/lib/db/seed-data/berths.json`). The snapshot is reordered + * so the first 12 entries satisfy the index assumptions used further + * down for interest/reservation linkage: + * idx 0..4 — available (small) + * idx 5..9 — under_offer (medium) + * idx 10..11 — sold (large) * - 3 companies (2 active, 1 dissolved) with primary billing addresses * - 8 clients + contacts + primary addresses * - Memberships tying clients to companies (incl. multi-company + ended) @@ -39,6 +45,44 @@ import { getStandardEoiTemplateHtml, STANDARD_EOI_MERGE_FIELDS, } from '@/lib/pdf/templates/eoi-standard-inapp'; +import berthSnapshot from './seed-data/berths.json'; + +// ─── Berth snapshot ────────────────────────────────────────────────────────── +// 117 rows imported from the legacy NocoDB Berths table on 2026-05-03. +// Refresh by re-running the snapshot script (see git history of this file). +type SeedBerth = { + legacyId: number; + mooringNumber: string; + legacyMooringNumber: string; + area: string | null; + status: 'available' | 'under_offer' | 'sold'; + lengthFt: number | null; + widthFt: number | null; + draftFt: number | null; + lengthM: number | null; + widthM: number | null; + draftM: number | null; + widthIsMinimum: boolean; + nominalBoatSize: number | null; + nominalBoatSizeM: number | null; + waterDepth: number | null; + waterDepthM: number | null; + waterDepthIsMinimum: boolean; + sidePontoon: string | null; + powerCapacity: number | null; + voltage: number | null; + mooringType: string | null; + cleatType: string | null; + cleatCapacity: string | null; + bollardType: string | null; + bollardCapacity: string | null; + access: string | null; + price: number | null; + bowFacing: string | null; + berthApproved: boolean; + statusOverrideMode: string | null; +}; +const BERTH_SNAPSHOT = berthSnapshot as SeedBerth[]; // ─── Tunables ──────────────────────────────────────────────────────────────── @@ -77,144 +121,44 @@ export async function seedPortData(portId: string, portSlug: string): Promise { // ── 1. Berths ────────────────────────────────────────────────────────── - // 12 berths: [0..4] available, [5..9] will be reserved-active, [10..11] sold. - // We mark 5..9 as 'under_offer' (closest to "reserved via active reservation") - // and 10..11 as 'sold'; 0..4 remain 'available'. - const BERTH_SPECS: Array<{ - mooring: string; - area: string; - lengthM: string; - widthM: string; - draftM: string; - price: string; - status: 'available' | 'under_offer' | 'sold'; - }> = [ - { - mooring: 'A-01', - area: 'North Pier', - lengthM: '15', - widthM: '5', - draftM: '2.5', - price: '250000', - status: 'available', - }, - { - mooring: 'A-02', - area: 'North Pier', - lengthM: '18', - widthM: '5.5', - draftM: '2.8', - price: '320000', - status: 'available', - }, - { - mooring: 'A-03', - area: 'North Pier', - lengthM: '20', - widthM: '6', - draftM: '3.0', - price: '420000', - status: 'available', - }, - { - mooring: 'B-01', - area: 'Central Basin', - lengthM: '25', - widthM: '7', - draftM: '3.5', - price: '580000', - status: 'available', - }, - { - mooring: 'B-02', - area: 'Central Basin', - lengthM: '30', - widthM: '8', - draftM: '4.0', - price: '780000', - status: 'available', - }, - { - mooring: 'B-03', - area: 'Central Basin', - lengthM: '35', - widthM: '8.5', - draftM: '4.2', - price: '950000', - status: 'under_offer', - }, - { - mooring: 'C-01', - area: 'South Marina', - lengthM: '40', - widthM: '9', - draftM: '4.5', - price: '1250000', - status: 'under_offer', - }, - { - mooring: 'C-02', - area: 'South Marina', - lengthM: '45', - widthM: '10', - draftM: '4.8', - price: '1600000', - status: 'under_offer', - }, - { - mooring: 'C-03', - area: 'South Marina', - lengthM: '50', - widthM: '11', - draftM: '5.0', - price: '2100000', - status: 'under_offer', - }, - { - mooring: 'D-01', - area: 'Superyacht Dock', - lengthM: '60', - widthM: '13', - draftM: '5.5', - price: '3200000', - status: 'under_offer', - }, - { - mooring: 'D-02', - area: 'Superyacht Dock', - lengthM: '70', - widthM: '14', - draftM: '6.0', - price: '4500000', - status: 'sold', - }, - { - mooring: 'D-03', - area: 'Superyacht Dock', - lengthM: '80', - widthM: '15', - draftM: '6.5', - price: '6800000', - status: 'sold', - }, - ]; - + // 117 berths seeded from the legacy NocoDB Berths snapshot. + // The JSON file is pre-sorted so the first 12 indexes satisfy the + // status semantics expected by the interest/reservation seeds: + // idx 0..4 available, idx 5..9 under_offer, idx 10..11 sold. const berthRows = await tx .insert(berths) .values( - BERTH_SPECS.map((b) => ({ + BERTH_SNAPSHOT.map((b) => ({ portId, - mooringNumber: b.mooring, + mooringNumber: b.mooringNumber, area: b.area, status: b.status, - lengthM: b.lengthM, - widthM: b.widthM, - draftM: b.draftM, - lengthFt: (Number(b.lengthM) * 3.28084).toFixed(2), - widthFt: (Number(b.widthM) * 3.28084).toFixed(2), - draftFt: (Number(b.draftM) * 3.28084).toFixed(2), - price: b.price, + lengthFt: b.lengthFt != null ? String(b.lengthFt) : null, + widthFt: b.widthFt != null ? String(b.widthFt) : null, + draftFt: b.draftFt != null ? String(b.draftFt) : null, + lengthM: b.lengthM != null ? String(b.lengthM) : null, + widthM: b.widthM != null ? String(b.widthM) : null, + draftM: b.draftM != null ? String(b.draftM) : null, + widthIsMinimum: b.widthIsMinimum, + nominalBoatSize: b.nominalBoatSize != null ? String(b.nominalBoatSize) : null, + nominalBoatSizeM: b.nominalBoatSizeM != null ? String(b.nominalBoatSizeM) : null, + waterDepth: b.waterDepth != null ? String(b.waterDepth) : null, + waterDepthM: b.waterDepthM != null ? String(b.waterDepthM) : null, + waterDepthIsMinimum: b.waterDepthIsMinimum, + sidePontoon: b.sidePontoon, + powerCapacity: b.powerCapacity != null ? String(b.powerCapacity) : null, + voltage: b.voltage != null ? String(b.voltage) : null, + mooringType: b.mooringType, + cleatType: b.cleatType, + cleatCapacity: b.cleatCapacity, + bollardType: b.bollardType, + bollardCapacity: b.bollardCapacity, + access: b.access, + price: b.price != null ? String(b.price) : null, priceCurrency: 'USD', + bowFacing: b.bowFacing, + berthApproved: b.berthApproved, + statusOverrideMode: b.statusOverrideMode, tenureType: 'permanent' as const, })), ) diff --git a/src/lib/db/seed-data/berths.json b/src/lib/db/seed-data/berths.json new file mode 100644 index 0000000..2dc7f78 --- /dev/null +++ b/src/lib/db/seed-data/berths.json @@ -0,0 +1,3746 @@ +[ + { + "legacyId": 85, + "mooringNumber": "E-02", + "legacyMooringNumber": "E2", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 86, + "mooringNumber": "E-03", + "legacyMooringNumber": "E3", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 87, + "mooringNumber": "E-04", + "legacyMooringNumber": "E4", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 88, + "mooringNumber": "E-05", + "legacyMooringNumber": "E5", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 89, + "mooringNumber": "E-06", + "legacyMooringNumber": "E6", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 99, + "mooringNumber": "E-16", + "legacyMooringNumber": "E16", + "area": "E", + "status": "under_offer", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 10.92, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": null, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 100, + "mooringNumber": "E-17", + "legacyMooringNumber": "E17", + "area": "E", + "status": "under_offer", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 10.92, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": null, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 68, + "mooringNumber": "D-19", + "legacyMooringNumber": "D19", + "area": "D", + "status": "under_offer", + "lengthFt": 51, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.5448, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 76, + "mooringNumber": "D-27", + "legacyMooringNumber": "D27", + "area": "D", + "status": "under_offer", + "lengthFt": 51, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.5448, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 11.17, + "waterDepthM": 3.404616, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 60, + "mooringNumber": "D-11", + "legacyMooringNumber": "D11", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 19.62, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.980176, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Quay PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Side Pier / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 30, + "mooringNumber": "B-20", + "legacyMooringNumber": "B20", + "area": "B", + "status": "sold", + "lengthFt": 157.5, + "widthFt": 37.73, + "draftFt": 14, + "lengthM": 48.006, + "widthM": 11.500104, + "draftM": 4.2672, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 28, + "mooringNumber": "B-18", + "legacyMooringNumber": "B18", + "area": "B", + "status": "sold", + "lengthFt": 157.48, + "widthFt": 36.92, + "draftFt": 14, + "lengthM": 47.999904, + "widthM": 11.253216, + "draftM": 4.2672, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": true, + "statusOverrideMode": null + }, + { + "legacyId": 1, + "mooringNumber": "A-01", + "legacyMooringNumber": "A1", + "area": "A", + "status": "under_offer", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14.5, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Quay PT", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "Side Pier / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3528000, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": "auto" + }, + { + "legacyId": 2, + "mooringNumber": "A-02", + "legacyMooringNumber": "A2", + "area": "A", + "status": "available", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14.5, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 3, + "mooringNumber": "A-03", + "legacyMooringNumber": "A3", + "area": "A", + "status": "available", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.2672, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 4, + "mooringNumber": "A-04", + "legacyMooringNumber": "A4", + "area": "A", + "status": "under_offer", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14.5, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 5, + "mooringNumber": "A-05", + "legacyMooringNumber": "A5", + "area": "A", + "status": "available", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14.5, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 6, + "mooringNumber": "A-06", + "legacyMooringNumber": "A6", + "area": "A", + "status": "available", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 14.5, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 7, + "mooringNumber": "A-07", + "legacyMooringNumber": "A7", + "area": "A", + "status": "under_offer", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 15.67, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 8, + "mooringNumber": "A-08", + "legacyMooringNumber": "A8", + "area": "A", + "status": "under_offer", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 15.67, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 9, + "mooringNumber": "A-09", + "legacyMooringNumber": "A9", + "area": "A", + "status": "under_offer", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 15.67, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3528000, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 10, + "mooringNumber": "A-10", + "legacyMooringNumber": "A10", + "area": "A", + "status": "available", + "lengthFt": 206.69, + "widthFt": 46.56, + "draftFt": 15.67, + "lengthM": 62.999112, + "widthM": 14.191488, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 200, + "nominalBoatSizeM": 60.96, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": false, + "sidePontoon": "No", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "2x Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 3920313, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 117, + "mooringNumber": "A-11", + "legacyMooringNumber": "A11", + "area": "A", + "status": "under_offer", + "lengthFt": 265, + "widthFt": 52.92, + "draftFt": 15.67, + "lengthM": 80.772, + "widthM": 16.130016, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 240, + "nominalBoatSizeM": 73.152, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Quay SB", + "powerCapacity": 330, + "voltage": 480, + "mooringType": "Side Pier / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3t) to Vessel", + "price": 5488439, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 11, + "mooringNumber": "B-01", + "legacyMooringNumber": "B1", + "area": "B", + "status": "sold", + "lengthFt": 104.33, + "widthFt": 29.52, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.997696, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Quay PT, Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Side Pier / Finger", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 12, + "mooringNumber": "B-02", + "legacyMooringNumber": "B2", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 13, + "mooringNumber": "B-03", + "legacyMooringNumber": "B3", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 14, + "mooringNumber": "B-04", + "legacyMooringNumber": "B4", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 15, + "mooringNumber": "B-05", + "legacyMooringNumber": "B5", + "area": "B", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 16, + "mooringNumber": "B-06", + "legacyMooringNumber": "B6", + "area": "B", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 17, + "mooringNumber": "B-07", + "legacyMooringNumber": "B7", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 18, + "mooringNumber": "B-08", + "legacyMooringNumber": "B8", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 26.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.129016, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 19, + "mooringNumber": "B-09", + "legacyMooringNumber": "B9", + "area": "B", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 20, + "mooringNumber": "B-10", + "legacyMooringNumber": "B10", + "area": "B", + "status": "under_offer", + "lengthFt": 157.48, + "widthFt": 37.73, + "draftFt": 14.5, + "lengthM": 47.999904, + "widthM": 11.500104, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Quay SB, Yes PT", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Side Pier / Finger", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 21, + "mooringNumber": "B-11", + "legacyMooringNumber": "B11", + "area": "B", + "status": "sold", + "lengthFt": 124.67, + "widthFt": 3081, + "draftFt": 13, + "lengthM": 37.999416, + "widthM": 939.0888, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 1680315, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 22, + "mooringNumber": "B-12", + "legacyMooringNumber": "B12", + "area": "B", + "status": "available", + "lengthFt": 157.48, + "widthFt": 36.92, + "draftFt": 14.5, + "lengthM": 47.999904, + "widthM": 11.253216, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 23, + "mooringNumber": "B-13", + "legacyMooringNumber": "B13", + "area": "B", + "status": "available", + "lengthFt": 124.67, + "widthFt": 30.81, + "draftFt": 13, + "lengthM": 37.999416, + "widthM": 9.390888, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 1680135, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 24, + "mooringNumber": "B-14", + "legacyMooringNumber": "B14", + "area": "B", + "status": "under_offer", + "lengthFt": 157.48, + "widthFt": 36.92, + "draftFt": 14, + "lengthM": 47.999904, + "widthM": 11.253216, + "draftM": 4.2672, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 25, + "mooringNumber": "B-15", + "legacyMooringNumber": "B15", + "area": "B", + "status": "under_offer", + "lengthFt": 124.67, + "widthFt": 30.81, + "draftFt": 13, + "lengthM": 37.999416, + "widthM": 9.390888, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 1680135, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 26, + "mooringNumber": "B-16", + "legacyMooringNumber": "B16", + "area": "B", + "status": "under_offer", + "lengthFt": 157.48, + "widthFt": 36.92, + "draftFt": 14.5, + "lengthM": 47.999904, + "widthM": 11.253216, + "draftM": 4.4196, + "widthIsMinimum": false, + "nominalBoatSize": 150, + "nominalBoatSizeM": 45.72, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 160, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type B", + "bollardCapacity": "40 ton break load", + "access": "Car (3.5t) to Vessel", + "price": 2310185, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 27, + "mooringNumber": "B-17", + "legacyMooringNumber": "B17", + "area": "B", + "status": "sold", + "lengthFt": 30, + "widthFt": 15.4, + "draftFt": 13, + "lengthM": 9.144, + "widthM": 4.69392, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 30, + "nominalBoatSizeM": 9.144, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB, PT", + "powerCapacity": 7, + "voltage": 120, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car (3.5t) to Vessel", + "price": 168013, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 29, + "mooringNumber": "B-19", + "legacyMooringNumber": "B19", + "area": "B", + "status": "sold", + "lengthFt": 30, + "widthFt": 15.4, + "draftFt": 13, + "lengthM": 9.144, + "widthM": 4.69392, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 30, + "nominalBoatSizeM": 9.144, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB, PT", + "powerCapacity": 7, + "voltage": 120, + "mooringType": "2x Finger", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car (3.5t) to Vessel", + "price": 168013, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 31, + "mooringNumber": "B-21", + "legacyMooringNumber": "B21", + "area": "B", + "status": "sold", + "lengthFt": 30, + "widthFt": 15.4, + "draftFt": 13, + "lengthM": 9.144, + "widthM": 4.69392, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 30, + "nominalBoatSizeM": 9.144, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB, PT", + "powerCapacity": 7, + "voltage": 120, + "mooringType": "2x Finger", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car (3.5t) to Vessel", + "price": 168013, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 33, + "mooringNumber": "B-23", + "legacyMooringNumber": "B23", + "area": "B", + "status": "sold", + "lengthFt": 30, + "widthFt": 15.4, + "draftFt": 13, + "lengthM": 9.144, + "widthM": 4.69392, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 30, + "nominalBoatSizeM": 9.144, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 7, + "voltage": 120, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car (3.5t) to Vessel", + "price": 168013, + "bowFacing": "East", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 35, + "mooringNumber": "C-01", + "legacyMooringNumber": "C1", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Quay SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Side Pier / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 36, + "mooringNumber": "C-02", + "legacyMooringNumber": "C2", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 37, + "mooringNumber": "C-03", + "legacyMooringNumber": "C3", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 38, + "mooringNumber": "C-04", + "legacyMooringNumber": "C4", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 39, + "mooringNumber": "C-05", + "legacyMooringNumber": "C5", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 40, + "mooringNumber": "C-06", + "legacyMooringNumber": "C6", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 41, + "mooringNumber": "C-07", + "legacyMooringNumber": "C7", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 42, + "mooringNumber": "C-08", + "legacyMooringNumber": "C8", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 43, + "mooringNumber": "C-09", + "legacyMooringNumber": "C9", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 44, + "mooringNumber": "C-10", + "legacyMooringNumber": "C10", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 12.8, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.90144, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 45, + "mooringNumber": "C-11", + "legacyMooringNumber": "C11", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 13, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 46, + "mooringNumber": "C-12", + "legacyMooringNumber": "C12", + "area": "C", + "status": "available", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 13, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 47, + "mooringNumber": "C-13", + "legacyMooringNumber": "C13", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 13, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 100, + "nominalBoatSizeM": 30.48, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1260100, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 48, + "mooringNumber": "C-14", + "legacyMooringNumber": "C14", + "area": "C", + "status": "under_offer", + "lengthFt": 104.33, + "widthFt": 27.67, + "draftFt": 13, + "lengthM": 31.799784, + "widthM": 8.433816, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1680135, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 49, + "mooringNumber": "C-15", + "legacyMooringNumber": "C15", + "area": "C", + "status": "under_offer", + "lengthFt": 124.67, + "widthFt": 30.81, + "draftFt": 13, + "lengthM": 37.999416, + "widthM": 9.390888, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1680135, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 118, + "mooringNumber": "C-16", + "legacyMooringNumber": "C16", + "area": "C", + "status": "available", + "lengthFt": 124.67, + "widthFt": 30.81, + "draftFt": 13, + "lengthM": 37.999416, + "widthM": 9.390888, + "draftM": 3.9624, + "widthIsMinimum": false, + "nominalBoatSize": 120, + "nominalBoatSizeM": 36.576, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 83, + "voltage": 480, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": "Bull bollard type A", + "bollardCapacity": "20 ton break load", + "access": "Car to Quai, Cart to Vessel", + "price": 1680135, + "bowFacing": "West", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 119, + "mooringNumber": "C-17", + "legacyMooringNumber": "C17", + "area": "C", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 22.54, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.870192, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Quay PT, Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Side Pier / Finger", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 120, + "mooringNumber": "C-18", + "legacyMooringNumber": "C18", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 121, + "mooringNumber": "C-19", + "legacyMooringNumber": "C19", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 122, + "mooringNumber": "C-20", + "legacyMooringNumber": "C20", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 123, + "mooringNumber": "C-21", + "legacyMooringNumber": "C21", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 124, + "mooringNumber": "C-22", + "legacyMooringNumber": "C22", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 125, + "mooringNumber": "C-23", + "legacyMooringNumber": "C23", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 126, + "mooringNumber": "C-24", + "legacyMooringNumber": "C24", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 127, + "mooringNumber": "C-25", + "legacyMooringNumber": "C25", + "area": "C", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 128, + "mooringNumber": "C-26", + "legacyMooringNumber": "C26", + "area": "C", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 129, + "mooringNumber": "C-27", + "legacyMooringNumber": "C27", + "area": "C", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": false, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 130, + "mooringNumber": "C-28", + "legacyMooringNumber": "C28", + "area": "C", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 22.54, + "draftFt": 13, + "lengthM": 20.4978, + "widthM": 6.870192, + "draftM": 3.9624, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 50, + "mooringNumber": "D-01", + "legacyMooringNumber": "D1", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 22.54, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.870192, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Quay SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Side Pier / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 51, + "mooringNumber": "D-02", + "legacyMooringNumber": "D2", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 22.54, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.870192, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 52, + "mooringNumber": "D-03", + "legacyMooringNumber": "D3", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 53, + "mooringNumber": "D-04", + "legacyMooringNumber": "D4", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 54, + "mooringNumber": "D-05", + "legacyMooringNumber": "D5", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 55, + "mooringNumber": "D-06", + "legacyMooringNumber": "D6", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": false, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 56, + "mooringNumber": "D-07", + "legacyMooringNumber": "D7", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 57, + "mooringNumber": "D-08", + "legacyMooringNumber": "D8", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 58, + "mooringNumber": "D-09", + "legacyMooringNumber": "D9", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 59, + "mooringNumber": "D-10", + "legacyMooringNumber": "D10", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 61, + "mooringNumber": "D-12", + "legacyMooringNumber": "D12", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 62, + "mooringNumber": "D-13", + "legacyMooringNumber": "D13", + "area": "D", + "status": "available", + "lengthFt": 51.5, + "widthFt": 19.62, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.980176, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 63, + "mooringNumber": "D-14", + "legacyMooringNumber": "D14", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 64, + "mooringNumber": "D-15", + "legacyMooringNumber": "D15", + "area": "D", + "status": "available", + "lengthFt": 51, + "widthFt": 19.62, + "draftFt": 8.56, + "lengthM": 15.5448, + "widthM": 5.980176, + "draftM": 2.609088, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 65, + "mooringNumber": "D-16", + "legacyMooringNumber": "D16", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": false, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 66, + "mooringNumber": "D-17", + "legacyMooringNumber": "D17", + "area": "D", + "status": "available", + "lengthFt": 51.5, + "widthFt": 19.62, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.980176, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 67, + "mooringNumber": "D-18", + "legacyMooringNumber": "D18", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 69, + "mooringNumber": "D-20", + "legacyMooringNumber": "D20", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.9, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.32232, + "widthIsMinimum": false, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 70, + "mooringNumber": "D-21", + "legacyMooringNumber": "D21", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 71, + "mooringNumber": "D-22", + "legacyMooringNumber": "D22", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 10.92, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 72, + "mooringNumber": "D-23", + "legacyMooringNumber": "D23", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 73, + "mooringNumber": "D-24", + "legacyMooringNumber": "D24", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 13, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.9624, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 14.42, + "waterDepthM": 4.395216, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 74, + "mooringNumber": "D-25", + "legacyMooringNumber": "D25", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 75, + "mooringNumber": "D-26", + "legacyMooringNumber": "D26", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 13, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 3.9624, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 77, + "mooringNumber": "D-28", + "legacyMooringNumber": "D28", + "area": "D", + "status": "available", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 15.67, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 4.776216, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 78, + "mooringNumber": "D-29", + "legacyMooringNumber": "D29", + "area": "D", + "status": "available", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": false, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 11.17, + "waterDepthM": 3.404616, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 79, + "mooringNumber": "D-30", + "legacyMooringNumber": "D30", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 15.67, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 4.776216, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 80, + "mooringNumber": "D-31", + "legacyMooringNumber": "D31", + "area": "D", + "status": "sold", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": false, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 81, + "mooringNumber": "D-32", + "legacyMooringNumber": "D32", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 15.67, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 4.776216, + "widthIsMinimum": true, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 17.32, + "waterDepthM": 5.279136, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 82, + "mooringNumber": "D-33", + "legacyMooringNumber": "D33", + "area": "D", + "status": "available", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 12.17, + "waterDepthM": 3.709416, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 83, + "mooringNumber": "D-34", + "legacyMooringNumber": "D34", + "area": "D", + "status": "under_offer", + "lengthFt": 67.25, + "widthFt": 20.88, + "draftFt": 15.67, + "lengthM": 20.4978, + "widthM": 6.364224, + "draftM": 4.776216, + "widthIsMinimum": false, + "nominalBoatSize": 65, + "nominalBoatSizeM": 19.812, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A5", + "cleatCapacity": "20-24 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 132, + "mooringNumber": "D-35", + "legacyMooringNumber": "D35", + "area": "D", + "status": "available", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 10.08, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 3.072384, + "widthIsMinimum": false, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 133, + "mooringNumber": "D-37", + "legacyMooringNumber": "D37", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 10.92, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 134, + "mooringNumber": "D-39", + "legacyMooringNumber": "D39", + "area": "D", + "status": "under_offer", + "lengthFt": 51.5, + "widthFt": 17.7, + "draftFt": 10.92, + "lengthM": 15.6972, + "widthM": 5.39496, + "draftM": 3.328416, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 16.08, + "waterDepthM": 4.901184, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 135, + "mooringNumber": "D-41", + "legacyMooringNumber": "D41", + "area": "D", + "status": "sold", + "lengthFt": 51.5, + "widthFt": 17.96, + "draftFt": 8.58, + "lengthM": 15.6972, + "widthM": 5.474208, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 50, + "nominalBoatSizeM": 15.24, + "waterDepth": 17.42, + "waterDepthM": 5.309616, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB, PT", + "powerCapacity": 12, + "voltage": 250, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Cart to Vessel", + "price": 728058, + "bowFacing": "South", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 84, + "mooringNumber": "E-01", + "legacyMooringNumber": "E1", + "area": "E", + "status": "sold", + "lengthFt": 42, + "widthFt": 17.52, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 5.340096, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "No", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "2x Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 90, + "mooringNumber": "E-07", + "legacyMooringNumber": "E7", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 91, + "mooringNumber": "E-08", + "legacyMooringNumber": "E8", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 92, + "mooringNumber": "E-09", + "legacyMooringNumber": "E9", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 93, + "mooringNumber": "E-10", + "legacyMooringNumber": "E10", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 94, + "mooringNumber": "E-11", + "legacyMooringNumber": "E11", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 95, + "mooringNumber": "E-12", + "legacyMooringNumber": "E12", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 96, + "mooringNumber": "E-13", + "legacyMooringNumber": "E13", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 97, + "mooringNumber": "E-14", + "legacyMooringNumber": "E14", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 8.58, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 2.615184, + "widthIsMinimum": false, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 9.5, + "waterDepthM": 2.8956, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 98, + "mooringNumber": "E-15", + "legacyMooringNumber": "E15", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15.88, + "draftFt": 10.08, + "lengthM": 12.8016, + "widthM": 4.840224, + "draftM": 3.072384, + "widthIsMinimum": true, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 11.17, + "waterDepthM": 3.404616, + "waterDepthIsMinimum": true, + "sidePontoon": "Yes SB", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": 280022, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + }, + { + "legacyId": 137, + "mooringNumber": "E-18", + "legacyMooringNumber": "E18", + "area": "E", + "status": "available", + "lengthFt": 42, + "widthFt": 15, + "draftFt": 12.08, + "lengthM": 12.8016, + "widthM": 4.572, + "draftM": 3.681984, + "widthIsMinimum": false, + "nominalBoatSize": 40, + "nominalBoatSizeM": 12.192, + "waterDepth": 13.42, + "waterDepthM": 4.090416, + "waterDepthIsMinimum": false, + "sidePontoon": "Yes PT", + "powerCapacity": 4, + "voltage": 125, + "mooringType": "Finger / Med Mooring", + "cleatType": "A3", + "cleatCapacity": "10-14 ton break load", + "bollardType": null, + "bollardCapacity": null, + "access": "Car to Quai, Cart to Vessel", + "price": null, + "bowFacing": "North", + "berthApproved": false, + "statusOverrideMode": null + } +] From 21868ee5fcf3b6ca5f55ac0048383edbc48dad44 Mon Sep 17 00:00:00 2001 From: Matt Ciaccio Date: Sun, 3 May 2026 15:59:36 +0200 Subject: [PATCH 3/3] feat(berths,seed): polish detail display + prune ports to Port Nimara + Amador Berth detail (src/components/berths/berth-tabs.tsx): - Numeric display polish, exposed by the new NocoDB-sourced seed: - Power capacity now renders with kW unit (e.g. "330 kW") - Voltage now renders with V unit (e.g. "480 V") - All metric/imperial values rounded to <= 2 decimals (was: "62.999112 m" -> now: "62.99 m") - Nominal Boat Size shows full ft + m pair (was: ft only) Seed ports (src/lib/db/seed.ts): - Drop Marina Azzurra and Harbor Royale; install now seeds only: - Port Nimara (the real install) - Port Amador (secondary, for multi-tenant isolation tests / Panama scaffolding) - Existing dev DBs are not touched; this only affects fresh `pnpm db:seed` runs. Users wanting to migrate should drop existing rows in the obsolete ports manually before re-seeding. Verification: - lint clean, tsc unchanged from baseline (36 pre-existing errors), 858/858 vitest passing. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/components/berths/berth-tabs.tsx | 42 ++++++++++++++++++++++++---- src/lib/db/seed.ts | 32 ++++++++++----------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/components/berths/berth-tabs.tsx b/src/components/berths/berth-tabs.tsx index 2fb1514..aa66f70 100644 --- a/src/components/berths/berth-tabs.tsx +++ b/src/components/berths/berth-tabs.tsx @@ -57,13 +57,45 @@ function SpecRow({ label, value }: { label: string; value: React.ReactNode }) { } function OverviewTab({ berth }: { berth: BerthData }) { + // Round to at most 2 decimals; trim trailing zeros so "5.00" -> "5". + const fmt = (v: string | null, fractionDigits = 2): string | null => { + if (v == null || v === '') return null; + const n = Number(v); + if (Number.isNaN(n)) return v; + return n.toLocaleString('en-US', { + minimumFractionDigits: 0, + maximumFractionDigits: fractionDigits, + }); + }; + const formatDim = (ft: string | null, m: string | null) => { const parts = []; - if (ft) parts.push(`${ft} ft`); - if (m) parts.push(`${m} m`); + const ftFmt = fmt(ft); + const mFmt = fmt(m); + if (ftFmt) parts.push(`${ftFmt} ft`); + if (mFmt) parts.push(`${mFmt} m`); return parts.length > 0 ? parts.join(' / ') : null; }; + const formatNominalBoatSize = (ft: string | null, m: string | null): string | null => { + const ftFmt = fmt(ft, 0); + const mFmt = fmt(m); + const parts: string[] = []; + if (ftFmt) parts.push(`${ftFmt} ft`); + if (mFmt) parts.push(`${mFmt} m`); + return parts.length > 0 ? parts.join(' / ') : null; + }; + + const formatPower = (kw: string | null) => { + const v = fmt(kw, 0); + return v ? `${v} kW` : null; + }; + + const formatVoltage = (v: string | null) => { + const fv = fmt(v, 0); + return fv ? `${fv} V` : null; + }; + const price = berth.price ? new Intl.NumberFormat('en-US', { style: 'currency', @@ -97,7 +129,7 @@ function OverviewTab({ berth }: { berth: BerthData }) { Infrastructure - - + + diff --git a/src/lib/db/seed.ts b/src/lib/db/seed.ts index 1a351d5..c23ca10 100644 --- a/src/lib/db/seed.ts +++ b/src/lib/db/seed.ts @@ -2,16 +2,16 @@ * Seed script for Port Nimara CRM. * * Top-level orchestrator: - * 1. Create 3 ports (idempotent): - * - Port Nimara - * - Marina Azzurra - * - Harbor Royale + * 1. Create the operational ports (idempotent): + * - Port Nimara (primary install — the real marina) + * - Port Amador (secondary, kept for multi-tenant isolation tests + * and as scaffolding for a future Panama install) * 2. Create 5 system roles with full permission maps * 3. Create the super admin user profile placeholder (matt@portnimara.com) * 4. For each port, call `seedPortData(portId, portSlug)` from seed-data.ts * to produce the realistic multi-cardinality fixture - * (berths, clients, companies, yachts, memberships, interests, - * reservations, ownership-transfer history). + * (117 berths from the NocoDB snapshot, plus clients, companies, yachts, + * memberships, interests, reservations, ownership-transfer history). * 5. Print a summary. * * Run with: pnpm db:seed @@ -413,19 +413,15 @@ const PORT_DEFINITIONS: Array<{ defaultCurrency: 'USD', timezone: 'America/Anguilla', }, + // Second port kept for multi-tenant isolation tests (cross-port scoping, + // permission boundaries). Drop or rename if the production install is + // single-port. { - name: 'Marina Azzurra', - slug: 'marina-azzurra', - primaryColor: '#2E86AB', - defaultCurrency: 'EUR', - timezone: 'Europe/Rome', - }, - { - name: 'Harbor Royale', - slug: 'harbor-royale', - primaryColor: '#8B1E3F', - defaultCurrency: 'GBP', - timezone: 'Europe/London', + name: 'Port Amador', + slug: 'port-amador', + primaryColor: '#D97706', + defaultCurrency: 'USD', + timezone: 'America/Panama', }, ];