Commit Graph

5 Commits

Author SHA1 Message Date
Matt Ciaccio
da44e8ecbe feat(documenso): version-aware field placement + void abstractions
Adds DOCUMENSO_API_VERSION env (default v1) plus per-port override.
Introduces placeFields, placeDefaultSignatureFields, and voidDocument
that hide v1 (per-field POST, pixel coords) vs v2 (bulk POST, percent +
fieldMeta) differences. cancelDocument now voids in Documenso first and
treats transient void failures as recoverable so the CRM stays the
system of record. 16 unit specs cover dispatch, layout math, idempotent
404, and v1 pixel conversion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 02:22:04 +02:00
Matt Ciaccio
4877b97f27 feat(admin): per-port email/Documenso/branding/reminder settings + invitations
All checks were successful
Build & Push Docker Images / lint (pull_request) Successful in 1m1s
Build & Push Docker Images / build-and-push (pull_request) Has been skipped
Centralizes everything operators need to configure into the admin panel,
each setting per-port with env fallback.

New admin pages
- /admin              landing page linking to every admin section as a card
- /admin/email        FROM name+address, reply-to, signature/footer HTML,
                      optional SMTP host/port/user/pass override
- /admin/documenso    API URL+key override, EOI Documenso template ID,
                      default EOI pathway (documenso-template vs inapp),
                      "Test connection" button
- /admin/branding     logo URL, primary color, app name, email
                      header/footer HTML
- /admin/reminders    port-level defaults for new interests +
                      port-wide daily-digest delivery window
- /admin/invitations  send / list / resend / revoke CRM invitations

Per-user reminder digest
- /notifications/preferences gains a Reminder digest card:
  immediate / daily / weekly / off, with HH:MM, day-of-week,
  IANA timezone fields. Stored in user_profiles.preferences.reminders.

Plumbing
- port-config.ts typed accessors (getPortEmailConfig, getPortDocumensoConfig,
  getPortBrandingConfig, getPortReminderConfig) — settings → env fallback.
- sendEmail accepts optional portId; resolves From/SMTP from settings
  when supplied.
- documensoFetch + downloadSignedPdf accept optional portId; each public
  function takes it through. checkDocumensoHealth() backs the test button.
- crm-invite.service gains listCrmInvites / revokeCrmInvite / resendCrmInvite
  with audit-log entries (revoke_invite, resend_invite added to AuditAction).
- AdminLandingPage card grid + shared SettingsFormCard component to remove
  per-page form boilerplate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 23:21:54 +02:00
Matt Ciaccio
4a859245b7 test(documenso): real-API E2E spec + 2.x response normalization
The documenso-template pathway was returning 201 with documensoId=null
because Documenso 2.x renamed `id` → `documentId` and recipient `id` →
`recipientId` in its API responses. Our DocumensoDocument interface
still expected the legacy v1.13 shape, so destructuring silently yielded
undefined and the documents row got NULL'd.

- Add normalizeDocument() in documenso-client that reads either field
  name and surfaces the legacy `id` form downstream consumers expect
- Apply normalization at every callsite that returns DocumensoDocument
  (createDocument, generateDocumentFromTemplate, sendDocument, getDocument)
- New realapi Playwright project (opt-in: --project=realapi) targeting
  tests/e2e/realapi/, with 2-min timeout for real-network calls
- New spec: documenso-real-api.spec.ts seeds client/yacht/berth/interest
  via the v1 API, fires generate-and-sign through the documenso-template
  pathway, asserts the response carries a documensoId, then GETs the
  document directly from Documenso to confirm it exists with PENDING
  status and recipients populated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 15:25:06 +02:00
Matt Ciaccio
f8255cedb8 feat(eoi): dual-path generateAndSign (inapp + documenso-template)
generateAndSign now accepts a `pathway` parameter:

- `inapp` (existing): resolve in-app template -> pdfme -> MinIO -> Documenso
  createDocument + sendDocument.
- `documenso-template` (new): build EOI context from interestId, assemble
  the Documenso template payload, and call Documenso's
  /api/v1/templates/{id}/generate-document. Documenso owns the PDF; we
  still record a documents row for tracking.

Adds generateDocumentFromTemplate helper to the Documenso client and new
env vars (DOCUMENSO_TEMPLATE_ID_EOI + client/developer/approval recipient
IDs) with defaults matching the legacy flow. Covered by 6 new integration
tests (637/637 green).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 18:43:41 +02:00
67d7e6e3d5 Initial commit: Port Nimara CRM (Layers 0-4)
Some checks failed
Build & Push Docker Images / build-and-push (push) Has been cancelled
Build & Push Docker Images / deploy (push) Has been cancelled
Build & Push Docker Images / lint (push) Has been cancelled
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