Adds an "Email to vendor" button on the PO detail (available once approved,
through CLOSED, and again after payment) that opens an Outlook draft addressed
to the vendor's primary contact with a time-limited PDF download link.
Since mailto: can't attach files, the PDF is rendered and stored, and the draft
carries a link (the approach chosen for this issue):
- PdfService/: new standalone Express + Playwright microservice (GstService/
EpfoService pattern) — POST /pdf { url } renders a page to a real PDF via
headless Chromium. SSRF-guarded (shared token + optional origin allowlist).
- export route: accepts a server-only `svc` token (PDF_SERVICE_TOKEN) so
PdfService can fetch /api/po/[id]/export?format=pdf without a user session;
`pdf=1` drops the print button + window.print() auto-trigger.
- lib/pdf-service.ts renderPoPdf(); prepareVendorEmail() server action renders →
uploads to R2 (po-pdf/…) → presigns a 7-day link → returns a mailto draft.
- po-detail: EmailVendorButton, shown when approved + vendor has a contact email.
- Gated by PDF_SERVICE_URL/PDF_SERVICE_TOKEN; friendly error if unconfigured.
- No DB model/migration. Tests: prepareVendorEmail (6, PdfService/storage mocked).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
78 lines
4.2 KiB
Text
78 lines
4.2 KiB
Text
# =============================================================
|
|
# Pelagia Portal — Environment Variables
|
|
# Copy this file to .env.local and fill in your values
|
|
#
|
|
# DEVELOPMENT (NODE_ENV=development, i.e. `pnpm dev`):
|
|
# - File uploads are stored locally in .dev-uploads/ — no R2 needed
|
|
# - Emails are logged to the terminal — no Resend key needed
|
|
# - Only AUTH + DATABASE vars are required to run the app locally
|
|
#
|
|
# PRODUCTION (NODE_ENV=production, i.e. `pnpm build && pnpm start`):
|
|
# - All sections below must be filled in
|
|
# =============================================================
|
|
|
|
# ── Auth ─────────────────────────────────────────────────────
|
|
NEXTAUTH_SECRET=your-32-char-secret-here-generate-with-openssl
|
|
NEXTAUTH_URL=http://localhost:3000
|
|
|
|
# ── Microsoft Entra ID (Azure AD) SSO ────────────────────────
|
|
# Register an app at https://entra.microsoft.com
|
|
# Required redirect URI: {NEXTAUTH_URL}/api/auth/callback/microsoft-entra-id
|
|
# Grant: openid, profile, email (Microsoft Graph delegated permissions)
|
|
AZURE_AD_CLIENT_ID=your-azure-app-client-id
|
|
AZURE_AD_CLIENT_SECRET=your-azure-app-client-secret
|
|
AZURE_AD_TENANT_ID=your-azure-tenant-id
|
|
|
|
# ── Database ──────────────────────────────────────────────────
|
|
# Local PostgreSQL or Supabase
|
|
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/pelagia_portal"
|
|
# Supabase connection pooling URL (use for serverless deployments)
|
|
# DATABASE_POOL_URL=
|
|
|
|
# ── Cloudflare R2 Storage (production only) ──────────────────
|
|
# Not required in development — files are stored in .dev-uploads/
|
|
R2_ACCOUNT_ID=your-cloudflare-account-id
|
|
R2_ACCESS_KEY_ID=your-r2-access-key-id
|
|
R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
|
|
R2_BUCKET_NAME=pelagia-portal
|
|
R2_PUBLIC_URL=https://your-bucket.your-account.r2.cloudflarestorage.com
|
|
|
|
# ── Email / Resend (production only) ─────────────────────────
|
|
# Not required in development — emails are printed to the terminal
|
|
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx
|
|
EMAIL_FROM=noreply@pelagiaportal.com
|
|
EMAIL_FROM_NAME="Pelagia Portal"
|
|
|
|
# ── GST Lookup microservice ───────────────────────────────────
|
|
# Run the GstService/ microservice alongside the app.
|
|
# Development default (localhost:3002) is used if this is unset.
|
|
# Start the service with: cd GstService && npm run dev
|
|
GST_SERVICE_URL=http://localhost:3003
|
|
|
|
# ── EPFO / UAN lookup microservice (crewing) ──────────────────
|
|
# Run the EpfoService/ microservice alongside the app (default localhost:3004).
|
|
# Start with: cd EpfoService && npm run dev
|
|
# Runs in STUB mode unless EPFO_LIVE=true (the live portal selectors/OTP must be
|
|
# validated against a real session first). Aadhaar is NOT handled here (manual).
|
|
EPFO_SERVICE_URL=http://localhost:3004
|
|
|
|
# ── PDF render microservice ("Email PO to vendor", issue #14) ──
|
|
# Run the PdfService/ microservice alongside the app (default localhost:3005).
|
|
# Start with: cd PdfService && npm install && npm run dev
|
|
# PDF_SERVICE_TOKEN is a shared secret: the app puts it on the export URL and
|
|
# PdfService echoes it in the x-pdf-token header. APP_INTERNAL_URL is the base URL
|
|
# PdfService can reach the app at (falls back to NEXTAUTH_URL).
|
|
PDF_SERVICE_URL=http://localhost:3005
|
|
PDF_SERVICE_TOKEN=dev-pdf-token-change-me
|
|
# APP_INTERNAL_URL=http://localhost:3000
|
|
|
|
# ── Forgejo issue reporting (Report Issue button) ─────────────
|
|
# Token needs write:issue scope on the repo below.
|
|
FORGEJO_URL=https://git.pelagiamarine.com
|
|
FORGEJO_REPO=shad0w/pelagia-portal
|
|
FORGEJO_TOKEN=
|
|
|
|
# ── Non-production banner ─────────────────────────────────────
|
|
# When set, a fixed "internal dev / staging" banner is shown (EnvBanner).
|
|
# Leave UNSET in production. Staging sets this automatically.
|
|
# NEXT_PUBLIC_ENV_LABEL="INTERNAL DEV / STAGING - NOT PRODUCTION"
|