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
|
|
|
/**
|
|
|
|
|
* Seed script for Port Nimara CRM.
|
|
|
|
|
*
|
2026-04-24 13:26:37 +02:00
|
|
|
* Top-level orchestrator:
|
|
|
|
|
* 1. Create 3 ports (idempotent):
|
|
|
|
|
* - Port Nimara
|
|
|
|
|
* - Marina Azzurra
|
|
|
|
|
* - Harbor Royale
|
|
|
|
|
* 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).
|
|
|
|
|
* 5. Print a summary.
|
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-24 13:26:37 +02:00
|
|
|
* Run with: pnpm db:seed
|
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
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import 'dotenv/config';
|
2026-04-24 13:26:37 +02:00
|
|
|
import { eq } from 'drizzle-orm';
|
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
|
|
|
import { db } from './index';
|
|
|
|
|
import { ports } from './schema/ports';
|
|
|
|
|
import { roles, userProfiles } from './schema/users';
|
|
|
|
|
import type { RolePermissions } from './schema/users';
|
2026-04-24 13:26:37 +02:00
|
|
|
import { seedPortData, type SeedSummary } from './seed-data';
|
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
|
|
|
|
|
|
|
|
// ─── Permission Maps ─────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const ALL_PERMISSIONS: RolePermissions = {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: true, merge: true, export: true },
|
2026-04-24 12:30:06 +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-24 12:30:06 +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-24 12:30:06 +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 },
|
|
|
|
|
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,
|
|
|
|
|
},
|
feat(platform): residential module + admin UI + reliability fixes
Residential platform
- New schema: residentialClients, residentialInterests (separate from
marina/yacht clients) with migration 0010
- Service layer with CRUD + audit + sockets + per-port portal toggle
- v1 + public API routes (/api/v1/residential/*, /api/public/residential-inquiries)
- List + detail pages with inline editing for clients and interests
- Per-user residentialAccess toggle on userPortRoles (migration 0011)
- Permission keys: residential_clients, residential_interests
- Sidebar nav + role form integration
- Smoke spec covering page loads, UI create flow, public endpoint
Admin & shared UI
- Admin → Forms (form templates CRUD) with validators + service
- Notification preferences page (in-app + email per type)
- Email composition + accounts list + threads view
- Branded auth shell shared across CRM + portal auth surfaces
- Inline editing extended to yacht/company/interest detail pages
- InlineTagEditor + per-entity tags endpoints (yachts, companies)
- Notes service polymorphic across clients/interests/yachts/companies
- Client list columns: yachtCount + companyCount badges
- Reservation file-download via presigned URL (replaces stale <a href>)
Route handler refactor
- Extracted yachts/companies/berths reservation handlers to sibling
handlers.ts files (Next.js 15 route.ts only allows specific exports)
Reliability fixes
- apiFetch double-stringify bug fixed across 13 components
(apiFetch already JSON.stringifies its body; passing a stringified
body produced double-encoded JSON which failed zod validation)
- SocketProvider gated behind useSyncExternalStore-based mount check
to avoid useSession() SSR crashes under React 19 + Next 15
- apiFetch falls back to URL-pathname → port-id resolution when the
Zustand store hasn't hydrated yet (fresh contexts, e2e tests)
- CRM invite flow (schema, service, route, email, dev script)
- Dashboard route → [portSlug]/dashboard/page.tsx + redirect
- Document the dev-server restart-after-migration gotcha in CLAUDE.md
Tests
- 5-case residential smoke spec
- Integration test updates for new service signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:54:32 +02:00
|
|
|
residential_clients: { view: true, create: true, edit: true, delete: true },
|
|
|
|
|
residential_interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
change_stage: 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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const DIRECTOR_PERMISSIONS: RolePermissions = {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: true, merge: true, export: true },
|
2026-04-24 12:30:06 +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-24 12:30:06 +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-24 12:30:06 +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 },
|
|
|
|
|
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: false,
|
|
|
|
|
},
|
feat(platform): residential module + admin UI + reliability fixes
Residential platform
- New schema: residentialClients, residentialInterests (separate from
marina/yacht clients) with migration 0010
- Service layer with CRUD + audit + sockets + per-port portal toggle
- v1 + public API routes (/api/v1/residential/*, /api/public/residential-inquiries)
- List + detail pages with inline editing for clients and interests
- Per-user residentialAccess toggle on userPortRoles (migration 0011)
- Permission keys: residential_clients, residential_interests
- Sidebar nav + role form integration
- Smoke spec covering page loads, UI create flow, public endpoint
Admin & shared UI
- Admin → Forms (form templates CRUD) with validators + service
- Notification preferences page (in-app + email per type)
- Email composition + accounts list + threads view
- Branded auth shell shared across CRM + portal auth surfaces
- Inline editing extended to yacht/company/interest detail pages
- InlineTagEditor + per-entity tags endpoints (yachts, companies)
- Notes service polymorphic across clients/interests/yachts/companies
- Client list columns: yachtCount + companyCount badges
- Reservation file-download via presigned URL (replaces stale <a href>)
Route handler refactor
- Extracted yachts/companies/berths reservation handlers to sibling
handlers.ts files (Next.js 15 route.ts only allows specific exports)
Reliability fixes
- apiFetch double-stringify bug fixed across 13 components
(apiFetch already JSON.stringifies its body; passing a stringified
body produced double-encoded JSON which failed zod validation)
- SocketProvider gated behind useSyncExternalStore-based mount check
to avoid useSession() SSR crashes under React 19 + Next 15
- apiFetch falls back to URL-pathname → port-id resolution when the
Zustand store hasn't hydrated yet (fresh contexts, e2e tests)
- CRM invite flow (schema, service, route, email, dev script)
- Dashboard route → [portSlug]/dashboard/page.tsx + redirect
- Document the dev-server restart-after-migration gotcha in CLAUDE.md
Tests
- 5-case residential smoke spec
- Integration test updates for new service signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:54:32 +02:00
|
|
|
residential_clients: { view: true, create: true, edit: true, delete: true },
|
|
|
|
|
residential_interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: true,
|
|
|
|
|
change_stage: 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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const SALES_MANAGER_PERMISSIONS: RolePermissions = {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: false, merge: true, export: true },
|
2026-04-24 12:30:06 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
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: false, import: false, manage_waiting_list: true },
|
2026-04-24 12:30:06 +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: 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: false, manage_folders: true },
|
|
|
|
|
email: { view: true, send: true, configure_account: true },
|
2026-04-24 12:30:06 +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 },
|
|
|
|
|
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: true,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
feat(platform): residential module + admin UI + reliability fixes
Residential platform
- New schema: residentialClients, residentialInterests (separate from
marina/yacht clients) with migration 0010
- Service layer with CRUD + audit + sockets + per-port portal toggle
- v1 + public API routes (/api/v1/residential/*, /api/public/residential-inquiries)
- List + detail pages with inline editing for clients and interests
- Per-user residentialAccess toggle on userPortRoles (migration 0011)
- Permission keys: residential_clients, residential_interests
- Sidebar nav + role form integration
- Smoke spec covering page loads, UI create flow, public endpoint
Admin & shared UI
- Admin → Forms (form templates CRUD) with validators + service
- Notification preferences page (in-app + email per type)
- Email composition + accounts list + threads view
- Branded auth shell shared across CRM + portal auth surfaces
- Inline editing extended to yacht/company/interest detail pages
- InlineTagEditor + per-entity tags endpoints (yachts, companies)
- Notes service polymorphic across clients/interests/yachts/companies
- Client list columns: yachtCount + companyCount badges
- Reservation file-download via presigned URL (replaces stale <a href>)
Route handler refactor
- Extracted yachts/companies/berths reservation handlers to sibling
handlers.ts files (Next.js 15 route.ts only allows specific exports)
Reliability fixes
- apiFetch double-stringify bug fixed across 13 components
(apiFetch already JSON.stringifies its body; passing a stringified
body produced double-encoded JSON which failed zod validation)
- SocketProvider gated behind useSyncExternalStore-based mount check
to avoid useSession() SSR crashes under React 19 + Next 15
- apiFetch falls back to URL-pathname → port-id resolution when the
Zustand store hasn't hydrated yet (fresh contexts, e2e tests)
- CRM invite flow (schema, service, route, email, dev script)
- Dashboard route → [portSlug]/dashboard/page.tsx + redirect
- Document the dev-server restart-after-migration gotcha in CLAUDE.md
Tests
- 5-case residential smoke spec
- Integration test updates for new service signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:54:32 +02:00
|
|
|
residential_clients: { view: false, create: false, edit: false, delete: false },
|
|
|
|
|
residential_interests: {
|
|
|
|
|
view: false,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
change_stage: 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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const SALES_AGENT_PERMISSIONS: RolePermissions = {
|
|
|
|
|
clients: { view: true, create: true, edit: true, delete: false, merge: false, export: true },
|
2026-04-24 12:30:06 +02:00
|
|
|
interests: {
|
|
|
|
|
view: true,
|
|
|
|
|
create: true,
|
|
|
|
|
edit: true,
|
|
|
|
|
delete: false,
|
|
|
|
|
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: false, import: false, manage_waiting_list: true },
|
2026-04-24 12:30:06 +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: 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: false, manage_folders: false },
|
|
|
|
|
email: { view: true, send: true, configure_account: true },
|
2026-04-24 12:30:06 +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: 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: false },
|
|
|
|
|
companies: { view: true, create: true, edit: false, delete: false },
|
|
|
|
|
memberships: { view: true, manage: false },
|
|
|
|
|
reservations: { view: true, create: true, activate: true, cancel: false },
|
|
|
|
|
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: true,
|
|
|
|
|
system_backup: false,
|
|
|
|
|
},
|
feat(platform): residential module + admin UI + reliability fixes
Residential platform
- New schema: residentialClients, residentialInterests (separate from
marina/yacht clients) with migration 0010
- Service layer with CRUD + audit + sockets + per-port portal toggle
- v1 + public API routes (/api/v1/residential/*, /api/public/residential-inquiries)
- List + detail pages with inline editing for clients and interests
- Per-user residentialAccess toggle on userPortRoles (migration 0011)
- Permission keys: residential_clients, residential_interests
- Sidebar nav + role form integration
- Smoke spec covering page loads, UI create flow, public endpoint
Admin & shared UI
- Admin → Forms (form templates CRUD) with validators + service
- Notification preferences page (in-app + email per type)
- Email composition + accounts list + threads view
- Branded auth shell shared across CRM + portal auth surfaces
- Inline editing extended to yacht/company/interest detail pages
- InlineTagEditor + per-entity tags endpoints (yachts, companies)
- Notes service polymorphic across clients/interests/yachts/companies
- Client list columns: yachtCount + companyCount badges
- Reservation file-download via presigned URL (replaces stale <a href>)
Route handler refactor
- Extracted yachts/companies/berths reservation handlers to sibling
handlers.ts files (Next.js 15 route.ts only allows specific exports)
Reliability fixes
- apiFetch double-stringify bug fixed across 13 components
(apiFetch already JSON.stringifies its body; passing a stringified
body produced double-encoded JSON which failed zod validation)
- SocketProvider gated behind useSyncExternalStore-based mount check
to avoid useSession() SSR crashes under React 19 + Next 15
- apiFetch falls back to URL-pathname → port-id resolution when the
Zustand store hasn't hydrated yet (fresh contexts, e2e tests)
- CRM invite flow (schema, service, route, email, dev script)
- Dashboard route → [portSlug]/dashboard/page.tsx + redirect
- Document the dev-server restart-after-migration gotcha in CLAUDE.md
Tests
- 5-case residential smoke spec
- Integration test updates for new service signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:54:32 +02:00
|
|
|
residential_clients: { view: false, create: false, edit: false, delete: false },
|
|
|
|
|
residential_interests: {
|
|
|
|
|
view: false,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
change_stage: 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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const VIEWER_PERMISSIONS: RolePermissions = {
|
|
|
|
|
clients: { view: true, create: false, edit: false, delete: false, merge: false, export: false },
|
2026-04-24 12:30:06 +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-24 12:30:06 +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-24 12:30:06 +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 },
|
|
|
|
|
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,
|
|
|
|
|
},
|
feat(platform): residential module + admin UI + reliability fixes
Residential platform
- New schema: residentialClients, residentialInterests (separate from
marina/yacht clients) with migration 0010
- Service layer with CRUD + audit + sockets + per-port portal toggle
- v1 + public API routes (/api/v1/residential/*, /api/public/residential-inquiries)
- List + detail pages with inline editing for clients and interests
- Per-user residentialAccess toggle on userPortRoles (migration 0011)
- Permission keys: residential_clients, residential_interests
- Sidebar nav + role form integration
- Smoke spec covering page loads, UI create flow, public endpoint
Admin & shared UI
- Admin → Forms (form templates CRUD) with validators + service
- Notification preferences page (in-app + email per type)
- Email composition + accounts list + threads view
- Branded auth shell shared across CRM + portal auth surfaces
- Inline editing extended to yacht/company/interest detail pages
- InlineTagEditor + per-entity tags endpoints (yachts, companies)
- Notes service polymorphic across clients/interests/yachts/companies
- Client list columns: yachtCount + companyCount badges
- Reservation file-download via presigned URL (replaces stale <a href>)
Route handler refactor
- Extracted yachts/companies/berths reservation handlers to sibling
handlers.ts files (Next.js 15 route.ts only allows specific exports)
Reliability fixes
- apiFetch double-stringify bug fixed across 13 components
(apiFetch already JSON.stringifies its body; passing a stringified
body produced double-encoded JSON which failed zod validation)
- SocketProvider gated behind useSyncExternalStore-based mount check
to avoid useSession() SSR crashes under React 19 + Next 15
- apiFetch falls back to URL-pathname → port-id resolution when the
Zustand store hasn't hydrated yet (fresh contexts, e2e tests)
- CRM invite flow (schema, service, route, email, dev script)
- Dashboard route → [portSlug]/dashboard/page.tsx + redirect
- Document the dev-server restart-after-migration gotcha in CLAUDE.md
Tests
- 5-case residential smoke spec
- Integration test updates for new service signatures
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:54:32 +02:00
|
|
|
residential_clients: { view: false, create: false, edit: false, delete: false },
|
|
|
|
|
residential_interests: {
|
|
|
|
|
view: false,
|
|
|
|
|
create: false,
|
|
|
|
|
edit: false,
|
|
|
|
|
delete: false,
|
|
|
|
|
change_stage: 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
|
|
|
};
|
|
|
|
|
|
2026-04-24 13:26:37 +02:00
|
|
|
// ─── Port Definitions ────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const PORT_DEFINITIONS: Array<{
|
|
|
|
|
name: string;
|
|
|
|
|
slug: string;
|
|
|
|
|
primaryColor: string;
|
|
|
|
|
defaultCurrency: string;
|
|
|
|
|
timezone: string;
|
|
|
|
|
}> = [
|
|
|
|
|
{
|
|
|
|
|
name: 'Port Nimara',
|
|
|
|
|
slug: 'port-nimara',
|
|
|
|
|
primaryColor: '#0F4C81',
|
|
|
|
|
defaultCurrency: 'USD',
|
|
|
|
|
timezone: 'America/Anguilla',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
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',
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
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
|
|
|
// ─── Seed Function ────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
async function seed() {
|
|
|
|
|
console.log('Seeding Port Nimara CRM...');
|
|
|
|
|
|
2026-04-24 13:26:37 +02:00
|
|
|
// ── 1. Ports ────────────────────────────────────────────────────────────────
|
|
|
|
|
console.log('Creating ports...');
|
|
|
|
|
const portIds: Array<{ id: string; name: string; slug: string }> = [];
|
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-24 13:26:37 +02:00
|
|
|
for (const def of PORT_DEFINITIONS) {
|
|
|
|
|
const [inserted] = await db
|
|
|
|
|
.insert(ports)
|
|
|
|
|
.values({
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: def.name,
|
|
|
|
|
slug: def.slug,
|
|
|
|
|
logoUrl: null,
|
|
|
|
|
primaryColor: def.primaryColor,
|
|
|
|
|
defaultCurrency: def.defaultCurrency,
|
|
|
|
|
timezone: def.timezone,
|
|
|
|
|
settings: {},
|
|
|
|
|
isActive: true,
|
|
|
|
|
})
|
|
|
|
|
.onConflictDoNothing()
|
|
|
|
|
.returning();
|
|
|
|
|
|
|
|
|
|
if (inserted) {
|
|
|
|
|
console.log(` Port created: ${def.name} (${inserted.id})`);
|
|
|
|
|
portIds.push({ id: inserted.id, name: def.name, slug: def.slug });
|
|
|
|
|
} else {
|
|
|
|
|
// Port already existed — look it up so we can still seed fixtures for it.
|
|
|
|
|
const [existing] = await db.select().from(ports).where(eq(ports.slug, def.slug)).limit(1);
|
|
|
|
|
if (existing) {
|
|
|
|
|
console.log(` Port exists: ${def.name} (${existing.id})`);
|
|
|
|
|
portIds.push({ id: existing.id, name: def.name, slug: def.slug });
|
|
|
|
|
} else {
|
|
|
|
|
console.warn(` Port insert conflict but lookup returned no row: ${def.slug}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 2. System Roles ─────────────────────────────────────────────────────────
|
|
|
|
|
console.log('Creating system roles...');
|
|
|
|
|
|
|
|
|
|
const systemRoles = [
|
|
|
|
|
{
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: 'super_admin',
|
|
|
|
|
description: 'Full system access. Bypasses all permission checks.',
|
|
|
|
|
permissions: ALL_PERMISSIONS,
|
|
|
|
|
isGlobal: true,
|
|
|
|
|
isSystem: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: 'director',
|
|
|
|
|
description: 'Operational admin within assigned port(s). Can manage users and settings.',
|
|
|
|
|
permissions: DIRECTOR_PERMISSIONS,
|
|
|
|
|
isGlobal: true,
|
|
|
|
|
isSystem: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: 'sales_manager',
|
|
|
|
|
description: 'Full sales access. Can view all reminders, assign tasks, and export reports.',
|
|
|
|
|
permissions: SALES_MANAGER_PERMISSIONS,
|
|
|
|
|
isGlobal: true,
|
|
|
|
|
isSystem: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: 'sales_agent',
|
2026-04-24 12:30:06 +02:00
|
|
|
description:
|
|
|
|
|
'Standard sales role. View/create/edit clients and interests, manage own reminders.',
|
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
|
|
|
permissions: SALES_AGENT_PERMISSIONS,
|
|
|
|
|
isGlobal: true,
|
|
|
|
|
isSystem: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
name: 'viewer',
|
|
|
|
|
description: 'Read-only access to all records.',
|
|
|
|
|
permissions: VIEWER_PERMISSIONS,
|
|
|
|
|
isGlobal: true,
|
|
|
|
|
isSystem: true,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for (const role of systemRoles) {
|
|
|
|
|
await db.insert(roles).values(role).onConflictDoNothing();
|
2026-04-24 13:26:37 +02:00
|
|
|
console.log(` Role: ${role.name}`);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 3. Super Admin User Profile ─────────────────────────────────────────────
|
|
|
|
|
// Note: Better Auth creates the actual `user` record on first login.
|
|
|
|
|
// We create the profile extension now, linked to a known user_id.
|
|
|
|
|
// The Better Auth user_id for matt@portnimara.com must match this value
|
|
|
|
|
// once Better Auth is configured. Use a stable placeholder ID here.
|
|
|
|
|
console.log('Creating super admin user profile...');
|
|
|
|
|
|
|
|
|
|
const superAdminUserId = 'super-admin-matt-portnimara';
|
|
|
|
|
|
|
|
|
|
await db
|
|
|
|
|
.insert(userProfiles)
|
|
|
|
|
.values({
|
|
|
|
|
id: crypto.randomUUID(),
|
|
|
|
|
userId: superAdminUserId,
|
|
|
|
|
displayName: 'Matt',
|
|
|
|
|
avatarUrl: null,
|
|
|
|
|
phone: null,
|
|
|
|
|
isSuperAdmin: true,
|
|
|
|
|
isActive: true,
|
|
|
|
|
lastLoginAt: null,
|
|
|
|
|
preferences: {},
|
|
|
|
|
})
|
|
|
|
|
.onConflictDoNothing();
|
|
|
|
|
|
2026-04-24 13:26:37 +02:00
|
|
|
console.log(` Super admin profile for user_id: ${superAdminUserId}`);
|
|
|
|
|
|
|
|
|
|
// ── 4. Per-port fixtures ────────────────────────────────────────────────────
|
|
|
|
|
console.log('');
|
|
|
|
|
console.log('Seeding per-port fixtures...');
|
|
|
|
|
|
|
|
|
|
const summaries: Array<{ name: string; summary: SeedSummary | null }> = [];
|
|
|
|
|
for (const p of portIds) {
|
|
|
|
|
console.log(` [${p.slug}] seeding fixture data...`);
|
|
|
|
|
const summary = await seedPortData(p.id, p.slug);
|
|
|
|
|
summaries.push({ name: p.name, summary });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 5. Summary ─────────────────────────────────────────────────────────────
|
|
|
|
|
console.log('');
|
|
|
|
|
console.log('─── Summary ───────────────────────────────────────────────');
|
|
|
|
|
for (const s of summaries) {
|
|
|
|
|
if (s.summary === null) {
|
|
|
|
|
console.log(` ✓ Port "${s.name}" — already seeded (skipped)`);
|
|
|
|
|
} else {
|
|
|
|
|
const x = s.summary;
|
|
|
|
|
console.log(
|
|
|
|
|
` ✓ Port "${s.name}" — ${x.berths} berths, ${x.clients} clients, ${x.companies} companies, ${x.yachts} yachts, ${x.interests} interests, ${x.reservations} reservations`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
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
|
|
|
console.log('');
|
|
|
|
|
console.log('Seed complete!');
|
|
|
|
|
console.log('');
|
|
|
|
|
console.log('NOTE: The Better Auth user for matt@portnimara.com must be created');
|
|
|
|
|
console.log(`separately. Once created, update user_profiles.user_id to match`);
|
|
|
|
|
console.log(`the actual Better Auth user ID (currently placeholder: ${superAdminUserId})`);
|
|
|
|
|
|
|
|
|
|
process.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seed().catch((err) => {
|
|
|
|
|
console.error('Seed failed:', err);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
});
|