Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
/**
|
|
|
|
|
* Test factory helpers.
|
2026-04-23 18:06:37 +02:00
|
|
|
*
|
|
|
|
|
* Two flavours:
|
|
|
|
|
* 1. Async DB-inserting factories (makePort, makeClient, makeBerth, makeYacht,
|
|
|
|
|
* makeCompany, ...) — insert a row via the app's `db` handle and return the
|
|
|
|
|
* inserted record. Use these from integration tests that need real FK /
|
|
|
|
|
* unique-index enforcement. They require DATABASE_URL to be reachable.
|
|
|
|
|
* 2. Plain-data helpers (makeAuditMeta, makeCreateClientInput, makeCreate*)
|
|
|
|
|
* — return in-memory objects suitable for unit tests with mocked `db`.
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
*/
|
|
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
import { db } from '@/lib/db';
|
|
|
|
|
import { ports, type NewPort, type Port } from '@/lib/db/schema/ports';
|
|
|
|
|
import { clients, type NewClient, type Client } from '@/lib/db/schema/clients';
|
|
|
|
|
import { berths, type NewBerth, type Berth } from '@/lib/db/schema/berths';
|
|
|
|
|
import { yachts, yachtOwnershipHistory, type NewYacht, type Yacht } from '@/lib/db/schema/yachts';
|
|
|
|
|
import { companies, type NewCompany, type Company } from '@/lib/db/schema/companies';
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
// ─── Port ────────────────────────────────────────────────────────────────────
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
export async function makePort(args?: { overrides?: Partial<NewPort> }): Promise<Port> {
|
|
|
|
|
const suffix = Math.random().toString(36).slice(2, 10);
|
|
|
|
|
const [port] = await db
|
|
|
|
|
.insert(ports)
|
|
|
|
|
.values({
|
|
|
|
|
name: args?.overrides?.name ?? `Test Port ${suffix}`,
|
|
|
|
|
slug: args?.overrides?.slug ?? `test-port-${suffix}`,
|
|
|
|
|
...args?.overrides,
|
|
|
|
|
})
|
|
|
|
|
.returning();
|
|
|
|
|
return port!;
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
// ─── Client ──────────────────────────────────────────────────────────────────
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
export async function makeClient(args: {
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
portId: string;
|
2026-04-23 18:06:37 +02:00
|
|
|
overrides?: Partial<NewClient>;
|
|
|
|
|
}): Promise<Client> {
|
|
|
|
|
const [client] = await db
|
|
|
|
|
.insert(clients)
|
|
|
|
|
.values({
|
|
|
|
|
portId: args.portId,
|
|
|
|
|
fullName: args.overrides?.fullName ?? `Test Client ${Math.random().toString(36).slice(2, 8)}`,
|
|
|
|
|
...args.overrides,
|
|
|
|
|
})
|
|
|
|
|
.returning();
|
|
|
|
|
return client!;
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
// ─── Berth ────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export async function makeBerth(args: {
|
|
|
|
|
portId: string;
|
|
|
|
|
overrides?: Partial<NewBerth>;
|
|
|
|
|
}): Promise<Berth> {
|
|
|
|
|
const [berth] = await db
|
|
|
|
|
.insert(berths)
|
|
|
|
|
.values({
|
|
|
|
|
portId: args.portId,
|
|
|
|
|
mooringNumber: args.overrides?.mooringNumber ?? `B-${Math.random().toString(36).slice(2, 8)}`,
|
|
|
|
|
...args.overrides,
|
|
|
|
|
})
|
|
|
|
|
.returning();
|
|
|
|
|
return berth!;
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
// ─── Yacht ───────────────────────────────────────────────────────────────────
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
export async function makeYacht(args: {
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
portId: string;
|
2026-04-23 18:06:37 +02:00
|
|
|
ownerType: 'client' | 'company';
|
|
|
|
|
ownerId: string;
|
feat(yachts): list + owner-scoped list + autocomplete
Adds `listYachts`, `listYachtsForOwner`, and `autocomplete` to the
yacht service so UIs can page/filter yachts per port, look up all
yachts tied to a given client/company, and power search-as-you-type.
`listYachts` delegates to the shared port-scoped `buildListQuery`,
supporting search over name/hullNumber/registration plus ownerType,
ownerId and status filters; `autocomplete` caps at 10 results and is
tenant-scoped; `listYachtsForOwner` returns all yachts whose current
owner matches, newest first. Extends `makeYacht` factory to accept
flat `name`, `status`, `hullNumber`, `registration` overrides.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:03:36 +02:00
|
|
|
name?: string;
|
|
|
|
|
status?: 'active' | 'retired' | 'sold_away';
|
|
|
|
|
hullNumber?: string;
|
|
|
|
|
registration?: string;
|
2026-04-23 18:06:37 +02:00
|
|
|
overrides?: Partial<NewYacht>;
|
|
|
|
|
}): Promise<Yacht> {
|
|
|
|
|
const [yacht] = await db
|
|
|
|
|
.insert(yachts)
|
|
|
|
|
.values({
|
|
|
|
|
portId: args.portId,
|
feat(yachts): list + owner-scoped list + autocomplete
Adds `listYachts`, `listYachtsForOwner`, and `autocomplete` to the
yacht service so UIs can page/filter yachts per port, look up all
yachts tied to a given client/company, and power search-as-you-type.
`listYachts` delegates to the shared port-scoped `buildListQuery`,
supporting search over name/hullNumber/registration plus ownerType,
ownerId and status filters; `autocomplete` caps at 10 results and is
tenant-scoped; `listYachtsForOwner` returns all yachts whose current
owner matches, newest first. Extends `makeYacht` factory to accept
flat `name`, `status`, `hullNumber`, `registration` overrides.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:03:36 +02:00
|
|
|
name: args.name ?? args.overrides?.name ?? `Yacht ${Math.random().toString(36).slice(2, 8)}`,
|
2026-04-23 18:06:37 +02:00
|
|
|
currentOwnerType: args.ownerType,
|
|
|
|
|
currentOwnerId: args.ownerId,
|
feat(yachts): list + owner-scoped list + autocomplete
Adds `listYachts`, `listYachtsForOwner`, and `autocomplete` to the
yacht service so UIs can page/filter yachts per port, look up all
yachts tied to a given client/company, and power search-as-you-type.
`listYachts` delegates to the shared port-scoped `buildListQuery`,
supporting search over name/hullNumber/registration plus ownerType,
ownerId and status filters; `autocomplete` caps at 10 results and is
tenant-scoped; `listYachtsForOwner` returns all yachts whose current
owner matches, newest first. Extends `makeYacht` factory to accept
flat `name`, `status`, `hullNumber`, `registration` overrides.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:03:36 +02:00
|
|
|
...(args.status !== undefined ? { status: args.status } : {}),
|
|
|
|
|
...(args.hullNumber !== undefined ? { hullNumber: args.hullNumber } : {}),
|
|
|
|
|
...(args.registration !== undefined ? { registration: args.registration } : {}),
|
2026-04-23 18:06:37 +02:00
|
|
|
...args.overrides,
|
|
|
|
|
})
|
|
|
|
|
.returning();
|
|
|
|
|
await db.insert(yachtOwnershipHistory).values({
|
|
|
|
|
yachtId: yacht!.id,
|
|
|
|
|
ownerType: args.ownerType,
|
|
|
|
|
ownerId: args.ownerId,
|
|
|
|
|
startDate: new Date(),
|
|
|
|
|
endDate: null,
|
|
|
|
|
createdBy: 'test',
|
|
|
|
|
});
|
|
|
|
|
return yacht!;
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}
|
|
|
|
|
|
2026-04-23 18:06:37 +02:00
|
|
|
// ─── Company ─────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export async function makeCompany(args: {
|
|
|
|
|
portId: string;
|
|
|
|
|
overrides?: Partial<NewCompany>;
|
|
|
|
|
}): Promise<Company> {
|
|
|
|
|
const [company] = await db
|
|
|
|
|
.insert(companies)
|
|
|
|
|
.values({
|
|
|
|
|
portId: args.portId,
|
|
|
|
|
name: args.overrides?.name ?? `Company ${Math.random().toString(36).slice(2, 8)}`,
|
|
|
|
|
...args.overrides,
|
|
|
|
|
})
|
|
|
|
|
.returning();
|
|
|
|
|
return company!;
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Webhook ──────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface WebhookData {
|
|
|
|
|
id: string;
|
|
|
|
|
portId: string;
|
|
|
|
|
name: string;
|
|
|
|
|
url: string;
|
|
|
|
|
secret: string | null;
|
|
|
|
|
events: string[];
|
|
|
|
|
isActive: boolean;
|
|
|
|
|
createdBy: string;
|
|
|
|
|
createdAt: Date;
|
|
|
|
|
updatedAt: Date;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function makeWebhook(overrides?: Partial<WebhookData>): WebhookData {
|
|
|
|
|
return {
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
portId: crypto.randomUUID(),
|
|
|
|
|
name: 'Test Webhook',
|
|
|
|
|
url: 'https://example.com/webhook',
|
|
|
|
|
secret: null,
|
|
|
|
|
events: ['client.created'],
|
|
|
|
|
isActive: true,
|
|
|
|
|
createdBy: crypto.randomUUID(),
|
|
|
|
|
createdAt: new Date(),
|
|
|
|
|
updatedAt: new Date(),
|
|
|
|
|
...overrides,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Audit Log ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
export interface AuditMeta {
|
|
|
|
|
userId: string;
|
|
|
|
|
portId: string;
|
|
|
|
|
ipAddress: string;
|
|
|
|
|
userAgent: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function makeAuditMeta(overrides?: Partial<AuditMeta>): AuditMeta {
|
|
|
|
|
return {
|
|
|
|
|
userId: crypto.randomUUID(),
|
|
|
|
|
portId: crypto.randomUUID(),
|
|
|
|
|
ipAddress: '127.0.0.1',
|
|
|
|
|
userAgent: 'vitest/1.0',
|
|
|
|
|
...overrides,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Auth Context ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
import type { RolePermissions } from '@/lib/db/schema/users';
|
|
|
|
|
|
|
|
|
|
/** Full permissions — every action allowed. */
|
|
|
|
|
export function makeFullPermissions(): RolePermissions {
|
|
|
|
|
return {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: true, merge: true, export: true },
|
2026-04-23 18:06:37 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
change_stage: true,
|
|
|
|
|
generate_eoi: true,
|
|
|
|
|
export: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
berths: { view: true, edit: true, import: true, manage_waiting_list: true },
|
2026-04-23 18:06:37 +02:00
|
|
|
documents: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
send_for_signing: true,
|
|
|
|
|
upload_signed: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
},
|
|
|
|
|
expenses: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
export: true,
|
|
|
|
|
scan_receipt: true,
|
|
|
|
|
},
|
|
|
|
|
invoices: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
send: true,
|
|
|
|
|
record_payment: true,
|
|
|
|
|
export: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
files: { view: true, upload: true, delete: true, manage_folders: true },
|
|
|
|
|
email: { view: true, send: true, configure_account: true },
|
2026-04-23 18:06:37 +02:00
|
|
|
reminders: {
|
|
|
|
|
view_own: true,
|
|
|
|
|
view_all: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit_own: true,
|
|
|
|
|
edit_all: true,
|
|
|
|
|
assign_others: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
calendar: { connect: true, view_events: true },
|
|
|
|
|
reports: { view_dashboard: true, view_analytics: true, export: true },
|
|
|
|
|
document_templates: { view: true, generate: true, manage: true },
|
2026-04-24 12:30:06 +02:00
|
|
|
yachts: { view: true, create: true, edit: true, delete: true, transfer: true },
|
|
|
|
|
companies: { view: true, create: true, edit: true, delete: true },
|
|
|
|
|
memberships: { view: true, manage: true },
|
|
|
|
|
reservations: { view: true, create: true, activate: true, cancel: true },
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
admin: {
|
|
|
|
|
manage_users: true,
|
|
|
|
|
view_audit_log: true,
|
|
|
|
|
manage_settings: true,
|
|
|
|
|
manage_webhooks: true,
|
|
|
|
|
manage_reports: true,
|
|
|
|
|
manage_custom_fields: true,
|
|
|
|
|
manage_forms: true,
|
|
|
|
|
manage_tags: true,
|
|
|
|
|
system_backup: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Read-only viewer permissions — no create/update/delete. */
|
|
|
|
|
export function makeViewerPermissions(): RolePermissions {
|
|
|
|
|
return {
|
|
|
|
|
clients: { view: true, create: false, edit: false, delete: false, merge: false, export: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
change_stage: false,
|
|
|
|
|
generate_eoi: false,
|
|
|
|
|
export: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
berths: { view: true, edit: false, import: false, manage_waiting_list: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
documents: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: false,
|
|
|
|
|
send_for_signing: false,
|
|
|
|
|
upload_signed: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
},
|
|
|
|
|
expenses: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
export: false,
|
|
|
|
|
scan_receipt: false,
|
|
|
|
|
},
|
|
|
|
|
invoices: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
send: false,
|
|
|
|
|
record_payment: false,
|
|
|
|
|
export: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
files: { view: true, upload: false, delete: false, manage_folders: false },
|
|
|
|
|
email: { view: true, send: false, configure_account: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
reminders: {
|
|
|
|
|
view_own: true,
|
|
|
|
|
view_all: false,
|
|
|
|
|
create: false,
|
|
|
|
|
edit_own: false,
|
|
|
|
|
edit_all: false,
|
|
|
|
|
assign_others: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
calendar: { connect: false, view_events: true },
|
|
|
|
|
reports: { view_dashboard: true, view_analytics: false, export: false },
|
|
|
|
|
document_templates: { view: true, generate: false, manage: false },
|
2026-04-24 12:30:06 +02:00
|
|
|
yachts: { view: true, create: false, edit: false, delete: false, transfer: false },
|
|
|
|
|
companies: { view: true, create: false, edit: false, delete: false },
|
|
|
|
|
memberships: { view: true, manage: false },
|
|
|
|
|
reservations: { view: true, create: false, activate: false, cancel: false },
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
admin: {
|
|
|
|
|
manage_users: false,
|
|
|
|
|
view_audit_log: false,
|
|
|
|
|
manage_settings: false,
|
|
|
|
|
manage_webhooks: false,
|
|
|
|
|
manage_reports: false,
|
|
|
|
|
manage_custom_fields: false,
|
|
|
|
|
manage_forms: false,
|
|
|
|
|
manage_tags: false,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Sales agent permissions — own clients/interests, no admin. */
|
|
|
|
|
export function makeSalesAgentPermissions(): RolePermissions {
|
|
|
|
|
return {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: false, merge: false, export: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
change_stage: true,
|
|
|
|
|
generate_eoi: true,
|
|
|
|
|
export: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
berths: { view: true, edit: false, import: false, manage_waiting_list: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
documents: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
send_for_signing: true,
|
|
|
|
|
upload_signed: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
},
|
|
|
|
|
expenses: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
export: false,
|
|
|
|
|
scan_receipt: true,
|
|
|
|
|
},
|
|
|
|
|
invoices: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
send: false,
|
|
|
|
|
record_payment: false,
|
|
|
|
|
export: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
files: { view: true, upload: true, delete: false, manage_folders: false },
|
|
|
|
|
email: { view: true, send: true, configure_account: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
reminders: {
|
|
|
|
|
view_own: true,
|
|
|
|
|
view_all: false,
|
|
|
|
|
create: true,
|
|
|
|
|
edit_own: true,
|
|
|
|
|
edit_all: false,
|
|
|
|
|
assign_others: false,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
calendar: { connect: true, view_events: true },
|
|
|
|
|
reports: { view_dashboard: true, view_analytics: false, export: false },
|
|
|
|
|
document_templates: { view: true, generate: true, manage: false },
|
2026-04-24 12:30:06 +02:00
|
|
|
yachts: { view: true, create: true, edit: true, delete: false, transfer: false },
|
|
|
|
|
companies: { view: true, create: true, edit: false, delete: false },
|
|
|
|
|
memberships: { view: true, manage: false },
|
|
|
|
|
reservations: { view: true, create: true, activate: true, cancel: false },
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
admin: {
|
|
|
|
|
manage_users: false,
|
|
|
|
|
view_audit_log: false,
|
|
|
|
|
manage_settings: false,
|
|
|
|
|
manage_webhooks: false,
|
|
|
|
|
manage_reports: false,
|
|
|
|
|
manage_custom_fields: false,
|
|
|
|
|
manage_forms: false,
|
|
|
|
|
manage_tags: false,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Sales manager — can do most things, limited admin. */
|
|
|
|
|
export function makeSalesManagerPermissions(): RolePermissions {
|
|
|
|
|
return {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: true, merge: true, export: true },
|
2026-04-23 18:06:37 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
change_stage: true,
|
|
|
|
|
generate_eoi: true,
|
|
|
|
|
export: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
berths: { view: true, edit: true, import: false, manage_waiting_list: true },
|
2026-04-23 18:06:37 +02:00
|
|
|
documents: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
send_for_signing: true,
|
|
|
|
|
upload_signed: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
},
|
|
|
|
|
expenses: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
export: true,
|
|
|
|
|
scan_receipt: true,
|
|
|
|
|
},
|
|
|
|
|
invoices: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
send: true,
|
|
|
|
|
record_payment: true,
|
|
|
|
|
export: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
files: { view: true, upload: true, delete: true, manage_folders: true },
|
|
|
|
|
email: { view: true, send: true, configure_account: false },
|
2026-04-23 18:06:37 +02:00
|
|
|
reminders: {
|
|
|
|
|
view_own: true,
|
|
|
|
|
view_all: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit_own: true,
|
|
|
|
|
edit_all: true,
|
|
|
|
|
assign_others: true,
|
|
|
|
|
},
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
calendar: { connect: true, view_events: true },
|
|
|
|
|
reports: { view_dashboard: true, view_analytics: true, export: true },
|
|
|
|
|
document_templates: { view: true, generate: true, manage: false },
|
2026-04-24 12:30:06 +02:00
|
|
|
yachts: { view: true, create: true, edit: true, delete: false, transfer: true },
|
|
|
|
|
companies: { view: true, create: true, edit: true, delete: false },
|
|
|
|
|
memberships: { view: true, manage: true },
|
|
|
|
|
reservations: { view: true, create: true, activate: true, cancel: true },
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
admin: {
|
|
|
|
|
manage_users: false,
|
|
|
|
|
view_audit_log: true,
|
|
|
|
|
manage_settings: false,
|
|
|
|
|
manage_webhooks: false,
|
|
|
|
|
manage_reports: true,
|
|
|
|
|
manage_custom_fields: false,
|
|
|
|
|
manage_forms: false,
|
|
|
|
|
manage_tags: true,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Director — everything except system backup. */
|
|
|
|
|
export function makeDirectorPermissions(): RolePermissions {
|
|
|
|
|
return {
|
|
|
|
|
...makeFullPermissions(),
|
|
|
|
|
admin: {
|
|
|
|
|
...makeFullPermissions().admin,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─── Minimal valid CreateClientInput ─────────────────────────────────────────
|
|
|
|
|
/** Returns a minimal valid CreateClientInput object for use in service calls. */
|
|
|
|
|
export function makeCreateClientInput(overrides?: { fullName?: string; portId?: string }) {
|
|
|
|
|
return {
|
|
|
|
|
fullName: overrides?.fullName ?? 'Test Client',
|
|
|
|
|
contacts: [{ channel: 'email' as const, value: 'test@example.com', isPrimary: true }],
|
|
|
|
|
isProxy: false,
|
|
|
|
|
tagIds: [] as string[],
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Returns a minimal valid CreateInterestInput object. */
|
|
|
|
|
export function makeCreateInterestInput(overrides?: {
|
|
|
|
|
clientId?: string;
|
2026-04-23 18:06:37 +02:00
|
|
|
pipelineStage?:
|
|
|
|
|
| 'open'
|
|
|
|
|
| 'details_sent'
|
|
|
|
|
| 'in_communication'
|
|
|
|
|
| 'visited'
|
|
|
|
|
| 'signed_eoi_nda'
|
|
|
|
|
| 'deposit_10pct'
|
|
|
|
|
| 'contract'
|
|
|
|
|
| 'completed';
|
Initial commit: Port Nimara CRM (Layers 0-4)
Full CRM rebuild with Next.js 15, TypeScript, Tailwind, Drizzle ORM,
PostgreSQL, Redis, BullMQ, MinIO, and Socket.io. Includes 461 source
files covering clients, berths, interests/pipeline, documents/EOI,
expenses/invoices, email, notifications, dashboard, admin, and
client portal. CI/CD via Gitea Actions with Docker builds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 11:52:51 +01:00
|
|
|
}) {
|
|
|
|
|
return {
|
|
|
|
|
clientId: overrides?.clientId ?? crypto.randomUUID(),
|
|
|
|
|
pipelineStage: overrides?.pipelineStage ?? ('open' as const),
|
|
|
|
|
reminderEnabled: false,
|
|
|
|
|
tagIds: [] as string[],
|
|
|
|
|
};
|
|
|
|
|
}
|